puppet-lint-1.1.0/0000755000004100000410000000000012421260622014017 5ustar www-datawww-datapuppet-lint-1.1.0/Rakefile0000644000004100000410000000015012421260622015460 0ustar www-datawww-datarequire 'rake' require 'rspec/core/rake_task' task :default => :test RSpec::Core::RakeTask.new(:test) puppet-lint-1.1.0/bin/0000755000004100000410000000000012421260622014567 5ustar www-datawww-datapuppet-lint-1.1.0/bin/puppet-lint0000755000004100000410000000021212421260622016771 0ustar www-datawww-data#!/usr/bin/env ruby $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib]) require 'puppet-lint' exit PuppetLint::Bin.new(ARGV).run puppet-lint-1.1.0/Gemfile0000644000004100000410000000004712421260622015313 0ustar www-datawww-datasource 'https://rubygems.org' gemspec puppet-lint-1.1.0/spec/0000755000004100000410000000000012421260622014751 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint_spec.rb0000644000004100000410000000100612421260622020566 0ustar www-datawww-datarequire 'spec_helper' describe PuppetLint do subject { PuppetLint.new } it 'should accept manifests as a string' do subject.code = "class foo { }" expect(subject.code).to_not be_nil end it 'should have support for % with a hash' do string = 'replace %{hash}' % {:hash => 'replaced'} expect(string).to match('replace replaced') end it 'should not break regular % support' do string = 'replace %s %s' % ['get','replaced'] expect(string).to match('replace get replaced') end end puppet-lint-1.1.0/spec/puppet-lint/0000755000004100000410000000000012421260622017232 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/0000755000004100000410000000000012421260622020713 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/0000755000004100000410000000000012421260622023505 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb0000644000004100000410000000332512421260622030222 0ustar www-datawww-datarequire 'spec_helper' describe 'parameter_order' do let(:msg) { 'optional parameter listed before required parameter' } context 'define with attrs in order' do let(:code) { "define foo($bar, $baz='gronk') { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'define with parameter that calls a function' do let(:code) { "define foo($bar=extlookup($name)) {}" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'define with attrs out of order' do let(:code) { "define foo($bar='baz', $gronk) { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(24) end end context 'class/define parameter set to another variable' do let(:code) { " define foo($bar, $baz = $name, $gronk=$::fqdn) { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class/define parameter set to another variable with incorrect order' do let(:code) { " define foo($baz = $name, $bar, $gronk=$::fqdn) { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(2).in_column(32) end end context 'issue-101' do let(:code) { " define b ( $foo, $bar='', $baz={} ) { } " } it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb0000644000004100000410000000142712421260622033635 0ustar www-datawww-datarequire 'spec_helper' describe 'class_inherits_from_params_class' do let(:msg) { 'class inheriting from params class' } context 'parameterised class that inherits from a params class' do let(:code) { " # commented class foo($bar = $name) inherits foo::params { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(3).in_column(40) end end context 'class without parameters' do let(:code) {" class myclass { if ( $::lsbdistcodename == 'squeeze' ) { #TODO } } "} it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb0000644000004100000410000000765412421260622030036 0ustar www-datawww-datarequire 'spec_helper' describe 'variable_scope' do let(:msg) { 'top-scope variable being used without an explicit namespace' } context 'class with no variables declared accessing top scope' do let(:code) { " class foo { $bar = $baz }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(3).in_column(16) end end context 'class with no variables declared accessing top scope explicitly' do let(:code) { " class foo { $bar = $::baz }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class with no variables declared accessing local array index' do let(:code) { " class foo { $bar = ['one', 'two', 'three'] $baz = $bar[1] }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class with no variables declared accessing local hash key' do let(:code) { " class foo { $bar = { 'one' => 1, 'two' => 2, 'three' => 3, } $baz = $bar['two'] }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class with variables declared accessing local scope' do let(:code) { " class foo { $bar = 1 $baz = $bar }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class with parameters accessing local scope' do let(:code) { " class foo($bar='UNSET') { $baz = $bar }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'defined type with no variables declared accessing top scope' do let(:code) { " define foo() { $bar = $fqdn }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(3).in_column(16) end end context 'defined type with no variables declared accessing top scope explicitly' do let(:code) { " define foo() { $bar = $::fqdn }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context '$name should be auto defined' do let(:code) { " define foo() { $bar = $name $baz = $title $gronk = $module_name $meep = $1 }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'define with required parameter' do let(:code) { " define tomcat::base ( $max_perm_gen, $owner = hiera('app_user'), $system_properties = {}, ) { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'future parser blocks' do let(:code) { " class foo() { $foo = [1,2] $foo.each |$a, $b| { $a $c } $b } " } it 'should only detect a single problem' do expect(problems).to have(2).problem end it 'should create two warnings' do expect(problems).to contain_warning(msg).on_line(8).in_column(9) expect(problems).to contain_warning(msg).on_line(6).in_column(11) end end %w{alias audit before loglevel noop notify require schedule stage subscribe tag}.each do |metaparam| context "referencing #{metaparam} metaparam value as a variable" do let(:code) { " class foo() { $#{metaparam} } " } it 'should not detect any problems' do expect(problems).to have(0).problems end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb0000644000004100000410000000310612421260622032240 0ustar www-datawww-datarequire 'spec_helper' describe 'nested_classes_or_defines' do let(:class_msg) { 'class defined inside a class' } let(:define_msg) { 'defined type defined inside a class' } context 'class on its own' do let(:code) { "class foo { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class inside a class' do let(:code) { " class foo { class bar { } }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(class_msg).on_line(3).in_column(9) end end context 'instantiating a parametised class inside a class' do let(:code) { " class bar { class { 'foo': bar => 'foobar' } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'instantiating a parametised class inside a define' do let(:code) { " define bar() { class { 'foo': bar => 'foobar' } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'define inside a class' do let(:code) { " class foo { define bar() { } }" } it 'should only detect a single problem' do expect(problems).to have(1).problems end it 'should create a warning' do expect(problems).to contain_warning(define_msg).on_line(3).in_column(9) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb0000644000004100000410000000116512421260622032461 0ustar www-datawww-datarequire 'spec_helper' describe 'right_to_left_relationship' do let(:msg) { 'right-to-left (<-) relationship' } context 'chain 2 resources left to right' do let(:code) { "Class[foo] -> Class[bar]" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'chain 2 resources right to left' do let(:code) { "Class[foo] <- Class[bar]" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(12) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb0000644000004100000410000000475212421260622030610 0ustar www-datawww-datarequire 'spec_helper' describe 'autoloader_layout' do context 'foo::bar in foo/manifests/bar.pp' do let(:code) { "class foo::bar { }" } let(:path) { 'foo/manifests/bar.pp' } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'foo::bar::baz in foo/manifests/bar/baz.pp' do let(:code) { 'define foo::bar::baz() { }' } let(:path) { 'foo/manifests/bar/baz.pp' } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'foo in foo/manifests/init.pp' do let(:code) { 'class foo { }' } let(:path) { 'foo/manifests/init.pp' } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'foo::bar in foo/manifests/init.pp' do let(:code) { 'class foo::bar { }' } let(:path) { 'foo/manifests/init.pp' } let(:msg) { 'foo::bar not in autoload module layout' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(1).in_column(7) end end context 'foo included in bar/manifests/init.pp' do let(:code) { " class bar { class {'foo': someparam => 'somevalue', } } " } let(:path) { 'bar/manifests/init.pp' } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'foo in puppet-foo/manifests/init.pp' do let(:code) { 'class foo { }' } let(:path) { 'puppet-foo/manifests/init.pp' } it 'should detect a single problem' do expect(problems).to have(1).problems end end context 'foo in puppet-foo/manifests/bar.pp with relative option' do before do PuppetLint.configuration.relative = true end after do PuppetLint.configuration.relative = false end let(:code) { 'class foo { }' } let(:path) { 'puppet-foo/manifests/bar.pp' } it 'should detect a single problem' do expect(problems).to have(1).problems end end context 'foo in puppet-foo/manifests/init.pp with relative option' do before do PuppetLint.configuration.relative = true end after do PuppetLint.configuration.relative = false end let(:code) { 'class foo { }' } let(:path) { 'puppet-foo/manifests/init.pp' } it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb0000644000004100000410000000162512421260622032446 0ustar www-datawww-datarequire 'spec_helper' describe 'inherits_across_namespaces' do let(:msg) { 'class inherits across module namespaces' } context 'class inheriting from parent in same module namespace' do let(:code) { "class foo::bar inherits foo { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class inheriting from sister in same module namespace' do let(:code) { "class foo::bar inherits foo::baz { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'class inheriting from another module namespace' do let(:code) { "class foo::bar inherits baz { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(25) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb0000644000004100000410000000232412421260622031360 0ustar www-datawww-datarequire 'spec_helper' describe 'names_containing_dash' do let(:class_msg) { 'class name containing a dash' } let(:define_msg) { 'defined type name containing a dash' } context 'module named foo-bar' do let(:code) { 'class foo-bar { }' } let(:path) { 'foo-bar/manifests/init.pp' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(class_msg).on_line(1).in_column(7) end end context 'define named foo-bar' do let(:code) { 'define foo::foo-bar { }' } let(:path) { 'foo/manifests/foo-bar.pp' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(define_msg).on_line(1).in_column(8) end end context 'class named bar-foo' do let(:code) { 'class foo::bar-foo { }' } let(:path) { 'foo/manifests/bar-foo.pp' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(class_msg).on_line(1).in_column(7) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_documentation/0000755000004100000410000000000012421260622024721 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb0000644000004100000410000000220012421260622031123 0ustar www-datawww-datarequire 'spec_helper' describe 'documentation' do let(:class_msg) { 'class not documented' } let(:define_msg) { 'defined type not documented' } describe 'undocumented class' do let(:code) { "class test {}" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(class_msg).on_line(1).in_column(1) end end describe 'documented class' do let(:code) { " # foo class test {} "} it 'should not detect any problems' do expect(problems).to have(0).problems end end describe 'undocumented defined type' do let(:code) { "define test {}" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(define_msg).on_line(1).in_column(1) end end describe 'documented defined type' do let(:code) { " # foo define test {} "} it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_comments/0000755000004100000410000000000012421260622023675 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb0000644000004100000410000000333212421260622030113 0ustar www-datawww-datarequire 'spec_helper' describe 'star_comments' do let(:msg) { '/* */ comment found' } context 'with fix disabled' do context 'multiline comment w/ one line of content' do let(:code) { " /* foo */ "} it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(2).in_column(9) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'multiline comment w/ one line of content' do let(:code) { " /* foo */ "} let(:fixed) { " # foo "} it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_fixed(msg).on_line(2).in_column(9) end it 'should convert the multiline comment' do expect(manifest).to eq(fixed) end end context 'multiline comment w/ multiple line of content' do let(:code) { " /* foo * bar * baz */ notify { 'foo': } "} let(:fixed) { " # foo # bar # baz notify { 'foo': } "} it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_fixed(msg).on_line(2).in_column(9) end it 'should convert the multiline comment' do expect(manifest).to eq(fixed) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb0000644000004100000410000000175112421260622030257 0ustar www-datawww-datarequire 'spec_helper' describe 'slash_comments' do let(:msg) { '// comment found' } context 'with fix disabled' do context 'slash comments' do let(:code) { "// foo" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(1) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'slash comments' do let(:code) { '// foo' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(1) end it 'should replace the double slash with a hash' do expect(manifest).to eq("# foo") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_variables/0000755000004100000410000000000012421260622024020 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb0000644000004100000410000000157712421260622032053 0ustar www-datawww-datarequire 'spec_helper' describe 'variable_contains_dash' do let(:msg) { 'variable contains a dash' } context 'a variable containing a dash' do let(:code) { '$foo-bar' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(1) end end context 'variable containing a dash' do let(:code) { '" $foo-bar"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(3) end end context 'variable with an array reference containing a dash' do let(:code) { "$foo[bar-baz]" } it 'should not detect any problems' do expect(problems).to be_empty end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/0000755000004100000410000000000012421260622024204 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb0000644000004100000410000000267612421260622031603 0ustar www-datawww-datarequire 'spec_helper' describe 'trailing_whitespace' do let(:msg) { 'trailing whitespace found' } context 'with fix disabled' do context 'line with trailing whitespace' do let(:code) { "foo " } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(1).in_column(4) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'single line with trailing whitespace' do let(:code) { "foo " } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(4) end it 'should remove the trailing whitespace' do expect(manifest).to eq('foo') end end context 'multiple lines with trailing whitespace' do let(:code) { "foo \nbar" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(4) end it 'should remove the trailing whitespace' do expect(manifest).to eq("foo\nbar") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb0000644000004100000410000000067712421260622030325 0ustar www-datawww-datarequire 'spec_helper' describe '2sp_soft_tabs' do let(:msg) { 'two-space soft tabs not used' } context 'when a line is indented by 3 spaces' do let(:code) { " file { 'foo': foo => bar, }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(3).in_column(1) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb0000644000004100000410000000270312421260622027015 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe '80chars' do let(:msg) { 'line has more than 80 characters' } context 'file resource with a source line > 80c' do let(:code) { " file { source => 'puppet:///modules/certificates/etc/ssl/private/wildcard.example.com.crt', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'file resource with a template line > 80c' do let(:code) { " file { content => template('mymodule/this/is/a/truely/absurdly/long/path/that/should/make/you/feel/bad'), }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'length of lines with UTF-8 characters' do let(:code) { " # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ # ┃ Configuration ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context '81 character line' do let(:code) { 'a' * 81 } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(80) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb0000644000004100000410000000200212421260622027464 0ustar www-datawww-datarequire 'spec_helper' describe 'hard_tabs' do let(:msg) { 'tab character found' } context 'with fix disabled' do context 'hard tabs indents' do let(:code) { "\tfoo => bar," } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(1).in_column(1) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'hard tabs indents' do let(:code) { "\tfoo => bar," } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(1) end it 'should convert the tab characters into spaces' do expect(manifest).to eq(" foo => bar,") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb0000644000004100000410000003063312421260622030740 0ustar www-datawww-datarequire 'spec_helper' describe 'arrow_alignment' do let(:msg) { 'indentation of => is not properly aligned' } context 'with fix disabled' do context 'selectors inside a resource' do let(:code) { " file { 'foo': ensure => $ensure, require => $ensure ? { present => Class['tomcat::install'], absent => undef; }, foo => bar, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'selectors in the middle of a resource' do let(:code) { " file { 'foo': ensure => $ensure ? { present => directory, absent => undef, }, owner => 'tomcat6', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'selector inside a resource' do let(:code) { " ensure => $ensure ? { present => directory, absent => undef, }, owner => 'foo4', group => 'foo4', mode => '0755'," } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'selector inside a hash inside a resource' do let(:code) { " server => { ensure => ensure => $ensure ? { present => directory, absent => undef, }, ip => '192.168.1.1' }, owner => 'foo4', group => 'foo4', mode => '0755'," } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'nested hashes with correct indentation' do let(:code) { " class { 'lvs::base': virtualeservers => { '192.168.2.13' => { vport => '11025', service => 'smtp', scheduler => 'wlc', protocol => 'tcp', checktype => 'external', checkcommand => '/path/to/checkscript', real_servers => { 'server01' => { real_server => '192.168.2.14', real_port => '25', forwarding => 'masq', }, 'server02' => { real_server => '192.168.2.15', real_port => '25', forwarding => 'masq', } } } } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'single resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': foo => 1, bar => 2, gronk => 3, baz => 4, meh => 5, }" } it 'should detect four problems' do expect(problems).to have(4).problems end it 'should create four warnings' do expect(problems).to contain_warning(msg).on_line(3).in_column(15) expect(problems).to contain_warning(msg).on_line(4).in_column(15) expect(problems).to contain_warning(msg).on_line(6).in_column(16) expect(problems).to contain_warning(msg).on_line(7).in_column(15) end end context 'complex resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': foo => 1, bar => $baz ? { gronk => 2, meh => 3, }, meep => 4, bah => 5, }" } it 'should detect three problems' do expect(problems).to have(3).problems end it 'should create three warnings' do expect(problems).to contain_warning(msg).on_line(3).in_column(15) expect(problems).to contain_warning(msg).on_line(6).in_column(17) expect(problems).to contain_warning(msg).on_line(9).in_column(15) end end context 'multi-resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': ; '/tmp/bar': foo => 'bar'; '/tmp/baz': gronk => 'bah', meh => 'no' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(8).in_column(17) end end context 'multiple single line resources' do let(:code) { " file { 'foo': ensure => file } package { 'bar': ensure => present }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'resource with unaligned => in commented line' do let(:code) { " file { 'foo': ensure => directory, # purge => true, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'single line resource spread out on multiple lines' do let(:code) {" file { 'foo': ensure => present, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'multiline resource with a single line of params' do let(:code) { " mymodule::do_thing { 'some thing': whatever => { foo => 'bar', one => 'two' }, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'resource with aligned => too far out' do let(:code) { " file { '/tmp/foo': ensure => file, mode => '0444', }" } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should create 2 warnings' do expect(problems).to contain_warning(msg).on_line(3).in_column(19) expect(problems).to contain_warning(msg).on_line(4).in_column(19) end end context 'resource with multiple params where one is an empty hash' do let(:code) { " foo { 'foo': a => true, b => { } } "} it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'multiline resource with multiple params on a line' do let(:code) { " user { 'test': a => 'foo', bb => 'bar', ccc => 'baz', } " } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should create 2 warnings' do expect(problems).to contain_warning(msg).on_line(3).in_column(13) expect(problems).to contain_warning(msg).on_line(3).in_column(26) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'single resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': foo => 1, bar => 2, gronk => 3, baz => 4, meh => 5, }" } let(:fixed) { " file { '/tmp/foo': foo => 1, bar => 2, gronk => 3, baz => 4, meh => 5, }" } it 'should detect four problems' do expect(problems).to have(4).problems end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(3).in_column(15) expect(problems).to contain_fixed(msg).on_line(4).in_column(15) expect(problems).to contain_fixed(msg).on_line(6).in_column(16) expect(problems).to contain_fixed(msg).on_line(7).in_column(15) end it 'should align the arrows' do expect(manifest).to eq(fixed) end end context 'complex resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': foo => 1, bar => $baz ? { gronk => 2, meh => 3, }, meep => 4, bah => 5, }" } let(:fixed) { " file { '/tmp/foo': foo => 1, bar => $baz ? { gronk => 2, meh => 3, }, meep => 4, bah => 5, }" } it 'should detect three problems' do expect(problems).to have(3).problems end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(3).in_column(15) expect(problems).to contain_fixed(msg).on_line(6).in_column(17) expect(problems).to contain_fixed(msg).on_line(9).in_column(15) end it 'should align the arrows' do expect(manifest).to eq(fixed) end end context 'multi-resource with a misaligned =>' do let(:code) { " file { '/tmp/foo': ; '/tmp/bar': foo => 'bar'; '/tmp/baz': gronk => 'bah', meh => 'no' }" } let(:fixed) { " file { '/tmp/foo': ; '/tmp/bar': foo => 'bar'; '/tmp/baz': gronk => 'bah', meh => 'no' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(8).in_column(17) end it 'should align the arrows' do expect(manifest).to eq(fixed) end end context 'resource with aligned => too far out' do let(:code) { " file { '/tmp/foo': ensure => file, mode => '0444', }" } let(:fixed) { " file { '/tmp/foo': ensure => file, mode => '0444', }" } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should create 2 warnings' do expect(problems).to contain_fixed(msg).on_line(3).in_column(19) expect(problems).to contain_fixed(msg).on_line(4).in_column(19) end it 'should realign the arrows with the minimum whitespace' do expect(manifest).to eq(fixed) end end context 'resource with unaligned => and no whitespace between param and =>' do let(:code) { " user { 'test': param1 => 'foo', param2=> 'bar', } " } let(:fixed) { " user { 'test': param1 => 'foo', param2 => 'bar', } " } it 'should detect 1 problem' do expect(problems).to have(1).problem end it 'should fix the problem' do expect(problems).to contain_fixed(msg).on_line(4).in_column(17) end it 'should add whitespace between the param and the arrow' do expect(manifest).to eq(fixed) end end context 'multiline resource with multiple params on a line' do let(:code) { " user { 'test': a => 'foo', bb => 'bar', ccc => 'baz', } " } let(:fixed) { " user { 'test': a => 'foo', bb => 'bar', ccc => 'baz', } " } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should fix 2 problems' do expect(problems).to contain_fixed(msg).on_line(3).in_column(13) expect(problems).to contain_fixed(msg).on_line(3).in_column(26) end it 'should move the extra param onto its own line and realign' do expect(manifest).to eq(fixed) end end context 'multiline resource with multiple params on a line, extra one longer' do let(:code) { " user { 'test': a => 'foo', bbccc => 'bar', ccc => 'baz', } " } let(:fixed) { " user { 'test': a => 'foo', bbccc => 'bar', ccc => 'baz', } " } it 'should detect 2 problems' do expect(problems).to have(3).problems end it 'should fix 2 problems' do expect(problems).to contain_fixed(msg).on_line(3).in_column(13) expect(problems).to contain_fixed(msg).on_line(3).in_column(29) expect(problems).to contain_fixed(msg).on_line(4).in_column(15) end it 'should move the extra param onto its own line and realign' do expect(manifest).to eq(fixed) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/0000755000004100000410000000000012421260622023541 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb0000644000004100000410000000552412421260622031322 0ustar www-datawww-datarequire 'spec_helper' describe 'only_variable_string' do let(:msg) { 'string containing only a variable' } context 'with fix disabled' do context 'string containing only a variable' do let(:code) { '"${foo}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(3) end end context 'string containing only a variable w/ ref' do let(:code) { '"${foo[0]}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(3) end end context 'string containing only a variable w/ lots of refs' do let(:code) { '"${foo[0][aoeuaoeu][bar][999]}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(3) end end context 'string containing only a variable as a hash key' do let(:code) { " $bar = 'key' $foo = { \"$bar\" => 1, }" } it 'should not detect any problems' do expect(problems).to be_empty end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'string containing only a variable' do let(:code) { '"${foo}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(3) end it 'should unquote the variable' do expect(manifest).to eq("$foo") end end context 'string contaiting only a variable w/ ref' do let(:code) { '"${foo[0]}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(3) end it 'should unquoted the variable' do expect(manifest).to eq("$foo[0]") end end context 'string containing only a variable w/ lots of refs' do let(:code) { '"${foo[0][aoeuaoeu][bar][999]}"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(3) end it 'should unquote the variable' do expect(manifest).to eq("$foo[0][aoeuaoeu][bar][999]") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb0000644000004100000410000000115012421260622032607 0ustar www-datawww-datarequire 'spec_helper' describe 'puppet_url_without_modules' do let(:msg) { 'puppet:// URL without modules/ found' } context 'puppet:// url with modules' do let(:code) { "'puppet:///modules/foo'" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'puppet:// url without modules' do let(:code) { "'puppet:///foo'" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(1) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb0000644000004100000410000001334112421260622031506 0ustar www-datawww-datarequire 'spec_helper' describe 'double_quoted_strings' do let(:msg) { 'double quoted string containing no variables' } context 'with fix disabled' do context 'double quoted string containing a variable inside single quotes' do let(:code) { "exec { \"/usr/bin/wget -O - '${source}' | /usr/bin/apt-key add -\": }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'multiple strings in a line' do let(:code) { "\"aoeu\" '${foo}'" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(1) end end context 'double quoted string nested in a single quoted string' do let(:code) { "'grep \"status=sent\" /var/log/mail.log'" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted string after a comment' do let(:code) { "service { 'foo': } # \"bar\"" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted string containing newline but no variables' do let(:code) { %{"foo\n"} } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted string with backslash for continuation' do let(:code) { %{ class puppet::master::maintenance ( ) { cron { 'puppet_master_reports_cleanup': command => "/usr/bin/find /var/lib/puppet/reports -type f -mtime +15 \ -delete && /usr/bin/find /var/lib/puppet/reports -mindepth 1 \ -empty -type d -delete", minute => '15', hour => '5', } } } } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted true' do let(:code) { "class { 'foo': boolFlag => \"true\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end context 'double quoted false' do let(:code) { "class { 'foo': boolFlag => \"false\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end context 'double quoted stings containing supported escape patterns' do let(:code) {%{ $string1 = "this string contins \n newline" $string2 = "this string contains \ttab" $string3 = "this string contains \${escaped} var" $string4 = "this string contains \\"escaped \\" double quotes" $string5 = "this string contains \\'escaped \\' single quotes" $string6 = "this string contains \r line return" }} it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted string with random escape should be rejected' do let(:code) {%{ $ztring = "this string contains \l random esape" } } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(12) end end context 'single quotes in a double quoted string' do let(:code) { "\"this 'string' 'has' lots of 'quotes'\"" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'double quoted string containing single quoted string' do let(:code) { %[notify { "'foo'": }] } it 'should not detect any problems' do expect(problems).to have(0).problems end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'double quoted string containing a variable inside single quotes' do let(:code) { "exec { \"/usr/bin/wget -O - '${source}' | /usr/bin/apt-key add -\": }" } it 'should not detect any problems' do expect(problems).to have(0).problems end it 'should not modify the manifest' do expect(manifest).to eq(code) end end context 'double quoted string containing a lone dollar' do let(:code) {"\"sed -i 's/^;*[[:space:]]*${name}[[:space:]]*=.*$/${name} = ${value}/g' file\"" } it 'should not detect any problems' do expect(problems).to have(0).problems end it 'should not modify the manifest' do expect(manifest).to eq(code) end end context 'multiple strings in a line' do let(:code) { "\"aoeu\" '${foo}'" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(1) end it 'should convert the double quoted string into single quotes' do expect(manifest).to eq("'aoeu' '${foo}'") end end context 'single quotes in a double quoted string' do let(:code) { "\"this 'string' 'has' lots of 'quotes'\"" } it 'should not detect any problems' do expect(problems).to have(0).problems end it 'should not modify the manifest' do expect(manifest).to eq(code) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb0000644000004100000410000000654312421260622030273 0ustar www-datawww-datarequire 'spec_helper' describe 'quoted_booleans' do let(:msg) { 'quoted boolean value found' } context 'with fix disabled' do context 'quoted false' do let(:code) { "class { 'foo': boolFlag => 'false' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end context 'quoted true' do let(:code) { "class { 'foo': boolFlag => 'true' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end context 'double quoted true' do let(:code) { "class { 'foo': boolFlag => \"true\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end context 'double quoted false' do let(:code) { "class { 'foo': boolFlag => \"false\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(28) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'quoted false' do let(:code) { "class { 'foo': boolFlag => 'false' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(28) end it 'should unquote the boolean' do expect(manifest).to eq("class { 'foo': boolFlag => false }") end end context 'quoted true' do let(:code) { "class { 'foo': boolFlag => 'true' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(28) end it 'should unquote the boolean' do expect(manifest).to eq("class { 'foo': boolFlag => true }") end end context 'double quoted true' do let(:code) { "class { 'foo': boolFlag => \"true\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(28) end it 'should unquote the boolean' do expect(manifest).to eq("class { 'foo': boolFlag => true }") end end context 'double quoted false' do let(:code) { "class { 'foo': boolFlag => \"false\" }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(28) end it 'should unquote the boolean' do expect(manifest).to eq("class { 'foo': boolFlag => false }") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb0000644000004100000410000000354312421260622031611 0ustar www-datawww-datarequire 'spec_helper' describe 'variables_not_enclosed' do let(:msg) { 'variable not enclosed in {}' } context 'with fix disabled' do context 'variable not enclosed in {}' do let(:code) { '" $gronk"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(3) end end context 'variable not enclosed in {} after many tokens' do let(:code) { ("'groovy'\n" * 20) + '" $gronk"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(21).in_column(3) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'variable not enclosed in {}' do let(:code) { '" $gronk"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(3) end it 'should enclose the variable in braces' do expect(manifest).to eq('" ${gronk}"') end end context 'variable not enclosed in {} after many tokens' do let(:code) { ("'groovy'\n" * 20) + '" $gronk"' } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(21).in_column(3) end it 'should enclose the variable in braces' do expect(manifest).to eq(("'groovy'\n" * 20) + '" ${gronk}"') end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb0000644000004100000410000000067312421260622034255 0ustar www-datawww-datarequire 'spec_helper' describe 'single_quote_string_with_variables' do let(:msg) { 'single quoted string containing a variable found' } context 'multiple strings in a line' do let(:code) { "\"aoeu\" '${foo}'" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(1).in_column(8) end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/0000755000004100000410000000000012421260622024062 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb0000644000004100000410000000234612421260622031316 0ustar www-datawww-datarequire 'spec_helper' describe 'ensure_first_param' do let(:msg) { "ensure found on line but it's not the first attribute" } context 'ensure as only attr in a single line resource' do let(:code) { "file { 'foo': ensure => present }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'ensure as only attr in a multi line resource' do let(:code) { " file { 'foo': ensure => present, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'ensure as second attr in a multi line resource' do let(:code) { " file { 'foo': mode => '0000', ensure => present, }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(4).in_column(9) end end context 'ensure as first attr in a multi line resource' do let(:code) { " file { 'foo': ensure => present, mode => '0000', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb0000644000004100000410000000413212421260622030736 0ustar www-datawww-datarequire 'spec_helper' describe 'duplicate_params' do let(:msg) { 'duplicate parameter found in resource' } context 'resource with duplicate parameters' do let(:code) { " file { '/tmp/foo': ensure => present, foo => bar, baz => gronk, foo => meh, }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(6).in_column(9) end end context 'bug #145: resource with a hash and no duplicate parameters' do let(:code) { " class {'fooname': hashes => [ { foo => 'bar01',}, { foo => 'bar02', }, ], }" } it 'should not detect any errors' do expect(problems).to have(0).problems end end context 'bug #145: resource with a hash and duplicate parameters in subhash' do let(:code) { " class {'fooname': hashes => [ { foo => 'bar01', foo => 'bar02', }, ], }" } it 'should only detect a single error' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(5).in_column(13) end end context 'bug #145: resource with a hash and duplicate parameters in parent type' do let(:code) { " class {'fooname': hashes => [ { foo => 'bar01', }, { foo => 'bar02', }, ], something => { hash => 'mini', }, hashes => 'dupe', }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create an error' do expect(problems).to contain_error(msg).on_line(8).in_column(9) end end describe 'bug #145: more hash tests and no duplicate parameters' do let(:code) { " class test { $foo = { param => 'value', } $bar = { param => 'bar', } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb0000644000004100000410000000554512421260622027355 0ustar www-datawww-datarequire 'spec_helper' describe 'file_mode' do let(:msg) { 'mode should be represented as a 4 digit octal value or symbolic mode' } context 'with fix disabled' do context '3 digit file mode' do let(:code) { "file { 'foo': mode => '777' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(23) end end context '4 digit file mode' do let(:code) { "file { 'foo': mode => '0777' }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'file mode as a variable' do let(:code) { "file { 'foo': mode => $file_mode }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'symbolic file mode' do let(:code) { "file { 'foo': mode => 'u=rw,og=r' }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'file mode undef unquoted' do let(:code) { "file { 'foo': mode => undef }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'file mode undef quoted' do let(:code) { "file { 'foo': mode => 'undef' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(23) end end context 'mode as audit value' do let(:code) { "file { '/etc/passwd': audit => [ owner, mode ], }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context '3 digit file mode' do let(:code) { "file { 'foo': mode => '777' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(23) end it 'should zero pad the file mode' do expect(manifest).to eq("file { 'foo': mode => '0777' }") end end context 'file mode undef quoted' do let(:code) { "file { 'foo': mode => 'undef' }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(23) end it 'should not modify the original manifest' do expect(manifest).to eq(code) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb0000644000004100000410000000404012421260622032714 0ustar www-datawww-datarequire 'spec_helper' describe 'ensure_not_symlink_target' do let(:msg) { 'symlink target specified in ensure attr' } context 'with fix disabled' do context 'file resource creating a symlink with seperate target attr' do let(:code) { " file { 'foo': ensure => link, target => '/foo/bar', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'file resource creating a symlink with target specified in ensure' do let(:code) { " file { 'foo': ensure => '/foo/bar', }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(3).in_column(21) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'file resource creating a symlink with seperate target attr' do let(:code) { " file { 'foo': ensure => link, target => '/foo/bar', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end it 'should not modify the manifest' do expect(manifest).to eq(code) end end context 'file resource creating a symlink with target specified in ensure' do let(:code) { " file { 'foo': ensure => '/foo/bar', }" } let(:fixed) { " file { 'foo': ensure => symlink, target => '/foo/bar', }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the problem' do expect(problems).to contain_fixed(msg).on_line(3).in_column(21) end it 'should create a new target param' do expect(manifest).to eq(fixed) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb0000644000004100000410000000211212421260622031264 0ustar www-datawww-datarequire 'spec_helper' describe 'unquoted_file_mode' do let(:msg) { 'unquoted file mode' } context 'with fix disabled' do context '4 digit unquoted file mode' do let(:code) { "file { 'foo': mode => 0777 }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(23) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context '4 digit unquoted file mode w/fix' do let(:code) { "file { 'foo': mode => 0777 }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(23) end it 'should single quote the file mode' do expect(manifest).to eq("file { 'foo': mode => '0777' }") end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb0000644000004100000410000001166512421260622032406 0ustar www-datawww-datarequire 'spec_helper' describe 'unquoted_resource_title' do let(:msg) { 'unquoted resource title' } context 'with fix disabled' do context 'quoted resource title on single line resource' do let(:code) { "file { 'foo': }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'unquoted resource title on single line resource' do let(:code) { "file { foo: }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(8) end end context 'quoted resource title on multi line resource' do let(:code) { " file { 'foo': }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'unquoted resource title on multi line resource' do let(:code) { " file { foo: }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(2).in_column(16) end end context 'condensed resources with quoted titles' do let(:code) { " file { 'foo': ; 'bar': ; }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'condensed resources with an unquoted title' do let(:code) { " file { 'foo': ; bar: ; }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(4).in_column(11) end end context 'single line resource with an array of titles (all quoted)' do let(:code) { "file { ['foo', 'bar']: }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'resource inside a case statement' do let(:code) { " case $ensure { 'absent': { file { \"some_file_${name}\": ensure => absent, } } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'issue #116' do let(:code) { " $config_file_init = $::operatingsystem ? { /(?i:Debian|Ubuntu|Mint)/ => '/etc/default/foo', default => '/etc/sysconfig/foo', }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'case statement' do let(:code) { %{ case $operatingsystem { centos: { $version = '1.2.3' } solaris: { $version = '3.2.1' } default: { fail("Module ${module_name} is not supported on ${operatingsystem}") } }} } it 'should not detect any problems' do expect(problems).to have(0).problems end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'unquoted resource title on single line resource' do let(:code) { "file { foo: }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(8) end it 'should single quote the resource title' do expect(manifest).to eq("file { 'foo': }") end end context 'unquoted resource title on multi line resource' do let(:code) { " file { foo: }" } let(:fixed) { " file { 'foo': }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(2).in_column(16) end it 'should single quote the resource title' do expect(manifest).to eq(fixed) end end context 'condensed resources with an unquoted title' do let(:code) { " file { 'foo': ; bar: ; }" } let(:fixed) { " file { 'foo': ; 'bar': ; }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(4).in_column(11) end it 'should single quote the resource title' do expect(manifest).to eq(fixed) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_nodes/0000755000004100000410000000000012421260622023160 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb0000644000004100000410000000676612421260622030407 0ustar www-datawww-datarequire 'spec_helper' describe 'unquoted_node_name' do let(:msg) { 'unquoted node name found' } context 'with fix disabled' do context 'unquoted node name' do let(:code) { "node foo { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(1).in_column(6) end end context 'default node' do let(:code) { "node default { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'single quoted node name' do let(:code) { "node 'foo' { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'regex node name' do let(:code) { "node /foo/ { }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'multiple bare node names' do let(:code) { "node foo, bar, baz { }" } it 'should detect 3 problems' do expect(problems).to have(3).problems end it 'should create 3 warnings' do expect(problems).to contain_warning(msg).on_line(1).in_column(6) expect(problems).to contain_warning(msg).on_line(1).in_column(11) expect(problems).to contain_warning(msg).on_line(1).in_column(16) end end context 'mixed node name types' do let(:code) { "node foo, 'bar', baz { }" } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should create 2 warnings' do expect(problems).to contain_warning(msg).on_line(1).in_column(6) expect(problems).to contain_warning(msg).on_line(1).in_column(18) end end end context 'with fix enabled' do before do PuppetLint.configuration.fix = true end after do PuppetLint.configuration.fix = false end context 'unquoted node name' do let(:code) { "node foo { }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should fix the manifest' do expect(problems).to contain_fixed(msg).on_line(1).in_column(6) end it 'should quote the node name' do expect(manifest).to eq("node 'foo' { }") end end context 'multiple bare node names' do let(:code) { "node foo, bar, baz { }" } let(:fixed) { "node 'foo', 'bar', 'baz' { }" } it 'should detect 3 problems' do expect(problems).to have(3).problems end it 'should fix the 3 problems' do expect(problems).to contain_fixed(msg).on_line(1).in_column(6) expect(problems).to contain_fixed(msg).on_line(1).in_column(11) expect(problems).to contain_fixed(msg).on_line(1).in_column(16) end it 'should quote all three node names' do expect(manifest).to eq(fixed) end end context 'mixed node name types' do let(:code) { "node foo, 'bar', baz { }" } let(:fixed) { "node 'foo', 'bar', 'baz' { }" } it 'should detect 2 problems' do expect(problems).to have(2).problems end it 'should fix the 2 problems' do expect(problems).to contain_fixed(msg).on_line(1).in_column(6) expect(problems).to contain_fixed(msg).on_line(1).in_column(18) end it 'should quote the 2 unquoted node names' do expect(manifest).to eq(fixed) end end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_conditionals/0000755000004100000410000000000012421260622024536 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb0000644000004100000410000000237512421260622032306 0ustar www-datawww-datarequire 'spec_helper' describe 'case_without_default' do let(:msg) { 'case statement without a default case' } context 'case statement with a default case' do let(:code) { " case $foo { bar: { } default: { } }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end context 'case statement without a default case' do let(:code) { " case $foo { bar: { } baz: { } }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(2).in_column(7) end end context 'issue-117' do let(:code) { " $mem = inline_template('<% mem,unit = scope.lookupvar(\'::memorysize\').split mem = mem.to_f # Normalize mem to bytes case unit when nil: mem *= (1<<0) when \'kB\': mem *= (1<<10) when \'MB\': mem *= (1<<20) when \'GB\': mem *= (1<<30) when \'TB\': mem *= (1<<40) end %><%= mem.to_i %>') "} it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb0000644000004100000410000000137512421260622033165 0ustar www-datawww-datarequire 'spec_helper' describe 'selector_inside_resource' do let(:msg) { 'selector inside resource block' } context 'resource with a selector' do let(:code) { " file { 'foo': ensure => $bar ? { true => present, default => absent, }, }" } it 'should only detect a single problem' do expect(problems).to have(1).problem end it 'should create a warning' do expect(problems).to contain_warning(msg).on_line(3).in_column(16) end end context 'resource with a variable as a attr value' do let(:code) { " file { 'foo', ensure => $bar, }" } it 'should not detect any problems' do expect(problems).to have(0).problems end end end puppet-lint-1.1.0/spec/puppet-lint/configuration_spec.rb0000644000004100000410000000264612421260622023450 0ustar www-datawww-datarequire 'spec_helper' describe PuppetLint::Configuration do subject { PuppetLint::Configuration.new } it 'should create check methods on the fly' do klass = Class.new subject.add_check('foo', klass) expect(subject).to respond_to(:foo_enabled?) expect(subject).to_not respond_to(:bar_enabled?) expect(subject).to respond_to(:enable_foo) expect(subject).to respond_to(:disable_foo) subject.disable_foo expect(subject.settings['foo_disabled']).to be_truthy expect(subject.foo_enabled?).to be_falsey subject.enable_foo expect(subject.settings['foo_disabled']).to be_falsey expect(subject.foo_enabled?).to be_truthy end it 'should know what checks have been added' do klass = Class.new subject.add_check('foo', klass) expect(subject.checks).to include('foo') end it 'should respond nil to unknown config options' do expect(subject.foobarbaz).to be_nil end it 'should create options on the fly' do subject.add_option('bar') expect(subject.bar).to be_nil subject.bar = 'aoeui' expect(subject.bar).to eq('aoeui') end it 'should be able to set sane defaults' do subject.defaults expect(subject.settings).to eq({ 'with_filename' => false, 'fail_on_warnings' => false, 'error_level' => :all, 'log_format' => '', 'with_context' => false, 'fix' => false, 'show_ignored' => false, }) end end puppet-lint-1.1.0/spec/puppet-lint/lexer/0000755000004100000410000000000012421260622020351 5ustar www-datawww-datapuppet-lint-1.1.0/spec/puppet-lint/lexer/token_spec.rb0000644000004100000410000000103212421260622023024 0ustar www-datawww-datarequire 'spec_helper' describe PuppetLint::Lexer::Token do subject do PuppetLint::Lexer::Token.new(:NAME, 'foo', 1, 2) end it { is_expected.to respond_to(:type) } it { is_expected.to respond_to(:value) } it { is_expected.to respond_to(:line) } it { is_expected.to respond_to(:column) } its(:type) { is_expected.to eq(:NAME) } its(:value) { is_expected.to eq('foo') } its(:line) { is_expected.to eq(1) } its(:column) { is_expected.to eq(2) } its(:inspect) { is_expected.to eq("") } end puppet-lint-1.1.0/spec/puppet-lint/bin_spec.rb0000644000004100000410000002132712421260622021346 0ustar www-datawww-datarequire 'spec_helper' require 'rspec/mocks' require 'optparse' class CommandRun attr_accessor :stdout, :stderr, :exitstatus def initialize(args) out = StringIO.new err = StringIO.new $stdout = out $stderr = err PuppetLint.configuration.defaults @exitstatus = PuppetLint::Bin.new(args).run PuppetLint.configuration.defaults @stdout = out.string.strip @stderr = err.string.strip $stdout = STDOUT $stderr = STDERR end end describe PuppetLint::Bin do subject do if args.is_a? Array sane_args = args else sane_args = [args] end CommandRun.new(sane_args) end context 'when running normally' do let(:args) { 'spec/fixtures/test/manifests/init.pp' } its(:exitstatus) { is_expected.to eq(0) } end context 'when running without arguments' do let(:args) { [] } its(:exitstatus) { is_expected.to eq(1) } end context 'when asked to display version' do let(:args) { '--version' } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to eq("puppet-lint #{PuppetLint::VERSION}") } end context 'when passed multiple files' do let(:args) { [ 'spec/fixtures/test/manifests/warning.pp', 'spec/fixtures/test/manifests/fail.pp', ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq([ "#{args[0]} - WARNING: optional parameter listed before required parameter on line 2", "#{args[1]} - ERROR: test::foo not in autoload module layout on line 2", ].join("\n")) } end context 'when passed a malformed file' do let(:args) { 'spec/fixtures/test/manifests/malformed.pp' } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('ERROR: Syntax error (try running `puppet parser validate `) on line 1') } end context 'when limited to errors only' do let(:args) { [ '--error-level', 'error', 'spec/fixtures/test/manifests/warning.pp', 'spec/fixtures/test/manifests/fail.pp', ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/^#{args.last} - ERROR/) } end context 'when limited to warnings only' do let(:args) { [ '--error-level', 'warning', 'spec/fixtures/test/manifests/warning.pp', 'spec/fixtures/test/manifests/fail.pp', ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/WARNING/) } its(:stdout) { is_expected.to_not match(/ERROR/) } end context 'when specifying a specific check to run' do let(:args) { [ '--only-check', 'parameter_order', 'spec/fixtures/test/manifests/warning.pp', 'spec/fixtures/test/manifests/fail.pp', ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to_not match(/ERROR/) } its(:stdout) { is_expected.to match(/WARNING/) } end context 'when asked to display filenames ' do let(:args) { ['--with-filename', 'spec/fixtures/test/manifests/fail.pp'] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(%r{^spec/fixtures/test/manifests/fail\.pp -}) } end context 'when not asked to fail on warnings' do let(:args) { ['spec/fixtures/test/manifests/warning.pp'] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to match(/optional parameter/) } end context 'when asked to provide context to problems' do let(:args) { [ '--with-context', 'spec/fixtures/test/manifests/warning.pp', ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to eq([ 'WARNING: optional parameter listed before required parameter on line 2', '', " define test::warning($foo='bar', $baz) { }", ' ^', ].join("\n")) } end context 'when asked to fail on warnings' do let(:args) { [ '--fail-on-warnings', 'spec/fixtures/test/manifests/warning.pp', ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/optional parameter/) } end context 'when used with an invalid option' do let(:args) { '--foo-bar-baz' } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/invalid option/) } end context 'when passed a file that does not exist' do let(:args) { 'spec/fixtures/test/manifests/enoent.pp' } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/specified file does not exist/) } end context 'when passed a directory' do let(:args) { 'spec/fixtures/' } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(/ERROR/) } end context 'when disabling a check' do let(:args) { [ '--no-autoloader_layout', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to eq("") } end context 'when changing the log format' do context 'to print %{filename}' do let(:args) { [ '--log-format', '%{filename}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('fail.pp') } end context 'to print %{path}' do let(:args) { [ '--log-format', '%{path}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('spec/fixtures/test/manifests/fail.pp') } end context 'to print %{fullpath}' do let(:args) { [ '--log-format', '%{fullpath}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to match(%r{^/.+/spec/fixtures/test/manifests/fail\.pp$}) } end context 'to print %{linenumber}' do let(:args) { [ '--log-format', '%{linenumber}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('2') } its(:stderr) { is_expected.to eq('DEPRECATION: Please use %{line} instead of %{linenumber}') } end context 'to print %{line}' do let(:args) { [ '--log-format', '%{line}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('2') } end context 'to print %{kind}' do let(:args) { [ '--log-format', '%{kind}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('error') } end context 'to print %{KIND}' do let(:args) { [ '--log-format', '%{KIND}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('ERROR') } end context 'to print %{check}' do let(:args) { [ '--log-format', '%{check}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('autoloader_layout') } end context 'to print %{message}' do let(:args) { [ '--log-format', '%{message}', 'spec/fixtures/test/manifests/fail.pp' ] } its(:exitstatus) { is_expected.to eq(1) } its(:stdout) { is_expected.to eq('test::foo not in autoload module layout') } end end context 'when hiding ignored problems' do let(:args) { [ 'spec/fixtures/test/manifests/ignore.pp' ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to_not match(/IGNORED/) } end context 'when showing ignored problems' do let(:args) { [ '--show-ignored', 'spec/fixtures/test/manifests/ignore.pp', ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to match(/IGNORED/) } end context 'when showing ignored problems with a reason' do let(:args) { [ '--show-ignored', 'spec/fixtures/test/manifests/ignore_reason.pp', ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to eq([ "IGNORED: double quoted string containing no variables on line 1", " for a good reason", ].join("\n")) } end context 'ignoring multiple checks on a line' do let(:args) { [ 'spec/fixtures/test/manifests/ignore_multiple_line.pp', ] } its(:exitstatus) { is_expected.to eq(0) } end context 'ignoring multiple checks in a block' do let(:args) { [ 'spec/fixtures/test/manifests/ignore_multiple_block.pp', ] } its(:exitstatus) { is_expected.to eq(0) } its(:stdout) { is_expected.to match(/^.*line 6$/) } end end puppet-lint-1.1.0/spec/puppet-lint/lexer_spec.rb0000644000004100000410000005722712421260622021725 0ustar www-datawww-datarequire 'spec_helper' describe PuppetLint::Lexer do before do @lexer = PuppetLint::Lexer.new end context 'invalid code' do it 'should bork' do expect { @lexer.tokenise('^') }.to raise_error(PuppetLint::LexerError) end end context '#new_token' do it 'should calculate the line number for an empty string' do token = @lexer.new_token(:TEST, 'test', 4) expect(token.line).to eq(1) end it 'should calculate the line number for a multi line string' do @lexer.instance_variable_set('@line_no', 2) token = @lexer.new_token(:TEST, 'test', 4) expect(token.line).to eq(2) end it 'should calculate the column number for an empty string' do token = @lexer.new_token(:TEST, 'test', 4) expect(token.column).to eq(1) end it 'should calculate the column number for a single line string' do @lexer.instance_variable_set('@column', 'this is a test'.size) token = @lexer.new_token(:TEST, 'test', 4) expect(token.column).to eq(14) end it 'should calculate the column number for a multi line string' do @lexer.instance_variable_set('@line_no', 4) @lexer.instance_variable_set('@column', "gronk".size) token = @lexer.new_token(:TEST, 'test', 4) expect(token.column).to eq(5) end end context '#get_string_segment' do it 'should get a segment with a single terminator' do data = StringScanner.new('foo"bar') value, terminator = @lexer.get_string_segment(data, '"') expect(value).to eq('foo') expect(terminator).to eq('"') end it 'should get a segment with multiple terminators' do data = StringScanner.new('foo"bar$baz') value, terminator = @lexer.get_string_segment(data, "'$") expect(value).to eq('foo"bar') expect(terminator).to eq('$') end it 'should not get a segment with an escaped terminator' do data = StringScanner.new('foo"bar') value, terminator = @lexer.get_string_segment(data, '$') expect(value).to be_nil expect(terminator).to be_nil end end context '#interpolate_string' do it 'should handle a string with no variables' do @lexer.interpolate_string('foo bar baz"',1, 1) token = @lexer.tokens.first expect(@lexer.tokens.length).to eq(1) expect(token.type).to eq(:STRING) expect(token.value).to eq('foo bar baz') expect(token.line).to eq(1) expect(token.column).to eq(1) end it 'should handle a string with a newline' do @lexer.interpolate_string(%{foo\nbar"}, 1, 1) token = @lexer.tokens.first expect(@lexer.tokens.length).to eq(1) expect(token.type).to eq(:STRING) expect(token.value).to eq("foo\nbar") expect(token.line).to eq(1) expect(token.column).to eq(1) end it 'should handle a string with a single variable and suffix' do @lexer.interpolate_string('${foo}bar"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('foo') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(3) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('bar') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(8) end it 'should handle a string with a single variable and surrounding text' do @lexer.interpolate_string('foo${bar}baz"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('foo') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(6) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('baz') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(11) end it 'should handle a string with multiple variables and surrounding text' do @lexer.interpolate_string('foo${bar}baz${gronk}meh"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(5) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('foo') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(6) expect(tokens[2].type).to eq(:DQMID) expect(tokens[2].value).to eq('baz') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(11) expect(tokens[3].type).to eq(:VARIABLE) expect(tokens[3].value).to eq('gronk') expect(tokens[3].line).to eq(1) expect(tokens[3].column).to eq(15) expect(tokens[4].type).to eq(:DQPOST) expect(tokens[4].value).to eq('meh') expect(tokens[4].line).to eq(1) expect(tokens[4].column).to eq(22) end it 'should handle a string with only a single variable' do @lexer.interpolate_string('${bar}"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(3) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(8) end it 'should handle a variable with an array reference' do @lexer.interpolate_string('${foo[bar][baz]}"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('foo[bar][baz]') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(3) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(18) end it 'should handle a string with only many variables' do @lexer.interpolate_string('${bar}${gronk}"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(5) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(3) expect(tokens[2].type).to eq(:DQMID) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(8) expect(tokens[3].type).to eq(:VARIABLE) expect(tokens[3].value).to eq('gronk') expect(tokens[3].line).to eq(1) expect(tokens[3].column).to eq(9) expect(tokens[4].type).to eq(:DQPOST) expect(tokens[4].value).to eq('') expect(tokens[4].line).to eq(1) expect(tokens[4].column).to eq(16) end it 'should handle a string with only an unenclosed variable' do @lexer.interpolate_string('$foo"', 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:UNENC_VARIABLE) expect(tokens[1].value).to eq('foo') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(2) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(6) end it 'should handle a string with a nested string inside it' do @lexer.interpolate_string(%q{string with ${'a nested single quoted string'} inside it"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('string with ') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:SSTRING) expect(tokens[1].value).to eq('a nested single quoted string') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(16) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq(' inside it') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(48) end it 'should handle a string with nested math' do @lexer.interpolate_string(%q{string with ${(3+5)/4} nested math"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(9) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('string with ') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:LPAREN) expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(16) expect(tokens[2].type).to eq(:NUMBER) expect(tokens[2].value).to eq('3') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(17) expect(tokens[3].type).to eq(:PLUS) expect(tokens[3].line).to eq(1) expect(tokens[3].column).to eq(18) expect(tokens[4].type).to eq(:NUMBER) expect(tokens[4].value).to eq('5') expect(tokens[4].line).to eq(1) expect(tokens[4].column).to eq(19) expect(tokens[5].type).to eq(:RPAREN) expect(tokens[5].line).to eq(1) expect(tokens[5].column).to eq(20) expect(tokens[6].type).to eq(:DIV) expect(tokens[6].line).to eq(1) expect(tokens[6].column).to eq(21) expect(tokens[7].type).to eq(:NUMBER) expect(tokens[7].value).to eq('4') expect(tokens[7].line).to eq(1) expect(tokens[7].column).to eq(22) expect(tokens[8].type).to eq(:DQPOST) expect(tokens[8].value).to eq(' nested math') expect(tokens[8].line).to eq(1) expect(tokens[8].column).to eq(24) end it 'should handle a string with a nested array' do @lexer.interpolate_string(%q{string with ${['an array ', $v2]} in it"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(8) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('string with ') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:LBRACK) expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(16) expect(tokens[2].type).to eq(:SSTRING) expect(tokens[2].value).to eq('an array ') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(17) expect(tokens[3].type).to eq(:COMMA) expect(tokens[3].line).to eq(1) expect(tokens[3].column).to eq(28) expect(tokens[4].type).to eq(:WHITESPACE) expect(tokens[4].value).to eq(' ') expect(tokens[4].line).to eq(1) expect(tokens[4].column).to eq(29) expect(tokens[5].type).to eq(:VARIABLE) expect(tokens[5].value).to eq('v2') expect(tokens[5].line).to eq(1) expect(tokens[5].column).to eq(30) expect(tokens[6].type).to eq(:RBRACK) expect(tokens[6].line).to eq(1) expect(tokens[6].column).to eq(33) expect(tokens[7].type).to eq(:DQPOST) expect(tokens[7].value).to eq(' in it') expect(tokens[7].line).to eq(1) expect(tokens[7].column).to eq(35) end it 'should handle a string of $s' do @lexer.interpolate_string(%q{$$$$"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(1) expect(tokens[0].type).to eq(:STRING) expect(tokens[0].value).to eq('$$$$') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) end it 'should handle "$foo$bar"' do @lexer.interpolate_string(%q{$foo$bar"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(5) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:UNENC_VARIABLE) expect(tokens[1].value).to eq('foo') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(2) expect(tokens[2].type).to eq(:DQMID) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(6) expect(tokens[3].type).to eq(:UNENC_VARIABLE) expect(tokens[3].value).to eq('bar') expect(tokens[3].line).to eq(1) expect(tokens[3].column).to eq(6) expect(tokens[4].type).to eq(:DQPOST) expect(tokens[4].value).to eq('') expect(tokens[4].line).to eq(1) expect(tokens[4].column).to eq(10) end it 'should handle "foo$bar$"' do @lexer.interpolate_string(%q{foo$bar$"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('foo') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:UNENC_VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(5) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('$') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(9) end it 'should handle "foo$$bar"' do @lexer.interpolate_string(%q{foo$$bar"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('foo$') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:UNENC_VARIABLE) expect(tokens[1].value).to eq('bar') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(6) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(10) end it 'should handle an empty string' do @lexer.interpolate_string(%q{"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(1) expect(tokens[0].type).to eq(:STRING) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) end it 'should handle "$foo::::bar"' do @lexer.interpolate_string(%q{$foo::::bar"}, 1, 1) tokens = @lexer.tokens expect(tokens.length).to eq(3) expect(tokens[0].type).to eq(:DQPRE) expect(tokens[0].value).to eq('') expect(tokens[0].line).to eq(1) expect(tokens[0].column).to eq(1) expect(tokens[1].type).to eq(:UNENC_VARIABLE) expect(tokens[1].value).to eq('foo') expect(tokens[1].line).to eq(1) expect(tokens[1].column).to eq(2) expect(tokens[2].type).to eq(:DQPOST) expect(tokens[2].value).to eq('::::bar') expect(tokens[2].line).to eq(1) expect(tokens[2].column).to eq(6) end end [ 'case', 'class', 'default', 'define', 'import', 'if', 'elsif', 'else', 'inherits', 'node', 'and', 'or', 'undef', 'true', 'false', 'in', 'unless', ].each do |keyword| it "should handle '#{keyword}' as a keyword" do token = @lexer.tokenise(keyword).first expect(token.type).to eq(keyword.upcase.to_sym) expect(token.value).to eq(keyword) end end [ [:LBRACK, '['], [:RBRACK, ']'], [:LBRACE, '{'], [:RBRACE, '}'], [:LPAREN, '('], [:RPAREN, ')'], [:EQUALS, '='], [:ISEQUAL, '=='], [:GREATEREQUAL, '>='], [:GREATERTHAN, '>'], [:LESSTHAN, '<'], [:LESSEQUAL, '<='], [:NOTEQUAL, '!='], [:NOT, '!'], [:COMMA, ','], [:DOT, '.'], [:COLON, ':'], [:AT, '@'], [:LLCOLLECT, '<<|'], [:RRCOLLECT, '|>>'], [:LCOLLECT, '<|'], [:RCOLLECT, '|>'], [:SEMIC, ';'], [:QMARK, '?'], [:BACKSLASH, '\\'], [:FARROW, '=>'], [:PARROW, '+>'], [:APPENDS, '+='], [:PLUS, '+'], [:MINUS, '-'], [:DIV, '/'], [:TIMES, '*'], [:MODULO, '%'], [:PIPE, '|'], [:LSHIFT, '<<'], [:RSHIFT, '>>'], [:MATCH, '=~'], [:NOMATCH, '!~'], [:IN_EDGE, '->'], [:OUT_EDGE, '<-'], [:IN_EDGE_SUB, '~>'], [:OUT_EDGE_SUB, '<~'], [:NEWLINE, "\r"], [:NEWLINE, "\n"], [:NEWLINE, "\r\n"], ].each do |name, string| it "should have a token named '#{name.to_s}'" do token = @lexer.tokenise(string).first expect(token.type).to eq(name) expect(token.value).to eq(string) end end context ':CLASSREF' do it 'should match single capitalised alphanumeric term' do token = @lexer.tokenise('One').first expect(token.type).to eq(:CLASSREF) expect(token.value).to eq('One') end it 'should match two capitalised alphanumeric terms sep by ::' do token = @lexer.tokenise('One::Two').first expect(token.type).to eq(:CLASSREF) expect(token.value).to eq('One::Two') end it 'should match many capitalised alphanumeric terms sep by ::' do token = @lexer.tokenise('One::Two::Three::Four::Five').first expect(token.type).to eq(:CLASSREF) expect(token.value).to eq('One::Two::Three::Four::Five') end it 'should match capitalised terms prefixed by ::' do token = @lexer.tokenise('::One').first expect(token.type).to eq(:CLASSREF) expect(token.value).to eq('::One') end end context ':NAME' do it 'should match lowercase alphanumeric terms' do token = @lexer.tokenise('one-two').first expect(token.type).to eq(:NAME) expect(token.value).to eq('one-two') end it 'should match lowercase alphanumeric terms sep by ::' do token = @lexer.tokenise('one::two').first expect(token.type).to eq(:NAME) expect(token.value).to eq('one::two') end it 'should match many lowercase alphanumeric terms sep by ::' do token = @lexer.tokenise('one::two::three::four::five').first expect(token.type).to eq(:NAME) expect(token.value).to eq('one::two::three::four::five') end it 'should match lowercase alphanumeric terms prefixed by ::' do token = @lexer.tokenise('::1one::2two::3three').first expect(token.type).to eq(:NAME) expect(token.value).to eq('::1one::2two::3three') end end context ':NUMBER' do it 'should match numeric terms' do token = @lexer.tokenise('1234567890').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('1234567890') end it 'should match float terms' do token = @lexer.tokenise('12345.6789').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('12345.6789') end it 'should match hexadecimal terms' do token = @lexer.tokenise('0xCAFE1029').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('0xCAFE1029') end it 'should match float with exponent terms' do token = @lexer.tokenise('10e23').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('10e23') end it 'should match float with negative exponent terms' do token = @lexer.tokenise('10e-23').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('10e-23') end it 'should match float with exponent terms' do token = @lexer.tokenise('1.234e5').first expect(token.type).to eq(:NUMBER) expect(token.value).to eq('1.234e5') end end context ':COMMENT' do it 'should match everything on a line after #' do token = @lexer.tokenise('foo # bar baz')[2] expect(token.type).to eq(:COMMENT) expect(token.value).to eq(' bar baz') end end context ':MLCOMMENT' do it 'should match comments on a single line' do token = @lexer.tokenise('/* foo bar */').first expect(token.type).to eq(:MLCOMMENT) expect(token.value).to eq('foo bar') end it 'should match comments on multiple lines' do token = @lexer.tokenise("/* foo\n * bar\n*/").first expect(token.type).to eq(:MLCOMMENT) expect(token.value).to eq("foo\nbar") end end context ':SLASH_COMMENT' do it 'should match everyone on a line after //' do token = @lexer.tokenise('foo // bar baz')[2] expect(token.type).to eq(:SLASH_COMMENT) expect(token.value).to eq(' bar baz') end end context ':SSTRING' do it 'should match a single quoted string' do token = @lexer.tokenise("'single quoted string'").first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string') end it "should match a single quoted string with an escaped '" do token = @lexer.tokenise(%q{'single quoted string with "\\'"'}).first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string with "\\\'"') end it "should match a single quoted string with an escaped $" do token = @lexer.tokenise(%q{'single quoted string with "\$"'}).first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string with "\\$"') end it "should match a single quoted string with an escaped ." do token = @lexer.tokenise(%q{'single quoted string with "\."'}).first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string with "\\."') end it "should match a single quoted string with an escaped \\n" do token = @lexer.tokenise(%q{'single quoted string with "\n"'}).first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string with "\\n"') end it "should match a single quoted string with an escaped \\" do token = @lexer.tokenise(%q{'single quoted string with "\\\\"'}).first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('single quoted string with "\\\\"') end it "should match an empty string" do token = @lexer.tokenise("''").first expect(token.type).to eq(:SSTRING) expect(token.value).to eq('') end it "should match an empty string ending with \\\\" do token = @lexer.tokenise("'foo\\\\'").first expect(token.type).to eq(:SSTRING) expect(token.value).to eq(%{foo\\\\}) end end context ':REGEX' do it 'should match anything enclosed in //' do token = @lexer.tokenise('/this is a regex/').first expect(token.type).to eq(:REGEX) expect(token.value).to eq('this is a regex') end it 'should not match if there is \n in the regex' do token = @lexer.tokenise("/this is \n a regex/").first expect(token.type).to_not eq(:REGEX) end it 'should not consider \/ to be the end of the regex' do token = @lexer.tokenise('/this is \/ a regex/').first expect(token.type).to eq(:REGEX) expect(token.value).to eq('this is \\/ a regex') end it 'should not match chained division' do tokens = @lexer.tokenise('$x = $a/$b/$c') expect(tokens.select { |r| r.type == :REGEX }).to be_empty end end context ':STRING' do it 'should parse strings with \\\\\\' do expect { @lexer.tokenise("exec { \"/bin/echo \\\\\\\"${environment}\\\\\\\"\": }") }.to_not raise_error end end end puppet-lint-1.1.0/spec/puppet-lint/ignore_overrides_spec.rb0000644000004100000410000000605612421260622024145 0ustar www-datawww-datarequire 'spec_helper' describe 'quoted_booleans', :type => :lint do let(:msg) { 'quoted boolean value found' } context 'with a single line ignore' do let(:code) { " 'true' 'true' # lint:ignore:quoted_booleans 'false' " } it 'should detect three problems' do expect(problems).to have(3).problems end it 'should have two warnings' do expect(problems).to contain_warning(msg).on_line(2).in_column(7) expect(problems).to contain_warning(msg).on_line(4).in_column(7) end it 'should have one ignored problem' do expect(problems).to contain_ignored(msg).on_line(3).in_column(7) end end context 'with a single line ignore and a reason' do let(:code) { " 'true' 'true' # lint:ignore:quoted_booleans some good reason 'false' " } it 'should detect three problems' do expect(problems).to have(3).problems end it 'should have two warnings' do expect(problems).to contain_warning(msg).on_line(2).in_column(7) expect(problems).to contain_warning(msg).on_line(4).in_column(7) end it 'should have one ignored problem with a reason' do expect(problems).to contain_ignored(msg).on_line(3).in_column(7).with_reason('some good reason') end end context 'with a block ignore' do let(:code) { " 'true' # lint:ignore:quoted_booleans 'false' 'true' # lint:endignore 'true' " } it 'should detect four problems' do expect(problems).to have(4).problems end it 'should have two warnings' do expect(problems).to contain_warning(msg).on_line(2).in_column(7) expect(problems).to contain_warning(msg).on_line(7).in_column(7) end it 'should have two ignored problems' do expect(problems).to contain_ignored(msg).on_line(4).in_column(7) expect(problems).to contain_ignored(msg).on_line(5).in_column(7) end end context 'with a block ignore and a reason' do let(:code) { " 'true' # lint:ignore:quoted_booleans another reason 'false' 'true' # lint:endignore 'true' " } it 'should detect four problems' do expect(problems).to have(4).problems end it 'should have two warnings' do expect(problems).to contain_warning(msg).on_line(2).in_column(7) expect(problems).to contain_warning(msg).on_line(7).in_column(7) end it 'should have two ignored problems with a reason' do expect(problems).to contain_ignored(msg).on_line(4).in_column(7).with_reason('another reason') expect(problems).to contain_ignored(msg).on_line(5).in_column(7).with_reason('another reason') end end context 'disable multiple checks on a line with a reason' do let(:code) { '"true" # lint:ignore:quoted_booleans lint:ignore:double_quoted_string a reason' } it 'should detect 1 problems' do expect(problems).to have(1).problems end it 'should have one ignored problems' do expect(problems).to contain_ignored(msg).on_line(1).in_column(1).with_reason('a reason') end end end puppet-lint-1.1.0/spec/spec_helper.rb0000644000004100000410000000651412421260622017575 0ustar www-datawww-datarequire 'puppet-lint' require 'rspec/its' require 'rspec/collection_matchers' module RSpec module LintExampleGroup class HaveProblem def initialize(method, message) @expected_problem = { :kind => method.to_s.gsub(/\Acontain_/, '').to_sym, :message => message, } @description = ["contain a #{@expected_problem[:kind]}"] end def on_line(line) @expected_problem[:line] = line @description << "on line #{line}" self end def in_column(column) @expected_problem[:column] = column @description << "starting in column #{column}" self end def with_reason(reason) @expected_problem[:reason] = reason @description << "with reason '#{reason}'" self end def matches?(problems) @problems = problems problems.any? do |problem| ret = true @expected_problem.each do |key, value| if !problem.key?(key) ret = false break elsif problem[key] != value ret = false break end end ret end end def description @description.join(' ') end def check_attr(attr, prefix) unless @expected_problem[attr] == @problems.first[attr] expected = @expected_problem[attr].inspect actual = @problems.first[attr].inspect "#{prefix} #{expected}, but it was #{actual}" end end def failure_message case @problems.length when 0 "expected that the check would create a problem but it did not" when 1 messages = ["expected that the problem"] messages << check_attr(:kind, 'would be of kind') messages << check_attr(:message, 'would have the message') messages << check_attr(:linenumber, 'would be on line') messages << check_attr(:column, 'would start on column') messages.compact.join("\n ") else [ "expected that the check would create", PP.pp(@expected_problem, '').strip, "but it instead created", PP.pp(@problems, ''), ].join("\n") end end def failure_message_when_negated "expected that the check would not create the problem, but it did" end end def method_missing(method, *args, &block) return HaveProblem.new(method, args.first) if method.to_s =~ /\Acontain_/ super end def problems subject.problems end def manifest subject.manifest end def subject klass = PuppetLint::Checks.new filepath = self.respond_to?(:path) ? path : '' klass.load_data(filepath, code) check_name = self.class.top_level_description.to_sym check = PuppetLint.configuration.check_object[check_name].new klass.problems = check.run if PuppetLint.configuration.fix klass.problems = check.fix_problems end klass end end end RSpec.configure do |config| config.mock_framework = :rspec config.include RSpec::LintExampleGroup, { :type => :lint, :file_path => Regexp.compile(%w{spec puppet-lint plugins}.join('[\\\/]')), } config.expect_with :rspec do |c| c.syntax = :expect end end puppet-lint-1.1.0/spec/fixtures/0000755000004100000410000000000012421260622016622 5ustar www-datawww-datapuppet-lint-1.1.0/spec/fixtures/test/0000755000004100000410000000000012421260622017601 5ustar www-datawww-datapuppet-lint-1.1.0/spec/fixtures/test/manifests/0000755000004100000410000000000012421260622021572 5ustar www-datawww-datapuppet-lint-1.1.0/spec/fixtures/test/manifests/ignore_multiple_block.pp0000644000004100000410000000015012421260622026477 0ustar www-datawww-data# lint:ignore:double_quoted_strings lint:ignore:quoted_booleans "true" "false" # lint:endignore "true" puppet-lint-1.1.0/spec/fixtures/test/manifests/warning.pp0000644000004100000410000000006112421260622023575 0ustar www-datawww-data# foo define test::warning($foo='bar', $baz) { } puppet-lint-1.1.0/spec/fixtures/test/manifests/fail.pp0000644000004100000410000000003212421260622023041 0ustar www-datawww-data# foo class test::foo { } puppet-lint-1.1.0/spec/fixtures/test/manifests/ignore.pp0000644000004100000410000000005312421260622023414 0ustar www-datawww-data"test" # lint:ignore:double_quoted_strings puppet-lint-1.1.0/spec/fixtures/test/manifests/ignore_reason.pp0000644000004100000410000000007512421260622024767 0ustar www-datawww-data"test" # lint:ignore:double_quoted_strings for a good reason puppet-lint-1.1.0/spec/fixtures/test/manifests/malformed.pp0000644000004100000410000000004612421260622024101 0ustar www-datawww-dataclass { 'apacheds': master => true' } puppet-lint-1.1.0/spec/fixtures/test/manifests/ignore_multiple_line.pp0000644000004100000410000000022612421260622026340 0ustar www-datawww-data"true" # lint:ignore:double_quoted_strings lint:ignore:quoted_booleans "false" # lint:ignore:quoted_booleans lint:ignore:double_quoted_strings reason puppet-lint-1.1.0/spec/fixtures/test/manifests/init.pp0000644000004100000410000000002512421260622023073 0ustar www-datawww-data# foo class test { } puppet-lint-1.1.0/.travis.yml0000644000004100000410000000021712421260622016130 0ustar www-datawww-databefore_install: gem update --system 2.1.11 rvm: - 1.8.7 - 1.9.2 - 1.9.3 - 2.0.0 - 2.1.0 notifications: email: - tim@github.com puppet-lint-1.1.0/lib/0000755000004100000410000000000012421260622014565 5ustar www-datawww-datapuppet-lint-1.1.0/lib/puppet-lint/0000755000004100000410000000000012421260622017046 5ustar www-datawww-datapuppet-lint-1.1.0/lib/puppet-lint/bin.rb0000644000004100000410000000371012421260622020144 0ustar www-datawww-datarequire 'puppet-lint/optparser' # Internal: The logic of the puppet-lint bin script, contained in a class for # ease of testing. class PuppetLint::Bin # Public: Initialise a new PuppetLint::Bin. # # args - An Array of command line argument Strings to be passed to the option # parser. # # Examples # # PuppetLint::Bin.new(ARGV).run def initialize(args) @args = args end # Public: Run puppet-lint as a command line tool. # # Returns an Integer exit code to be passed back to the shell. def run opts = PuppetLint::OptParser.build begin opts.parse!(@args) rescue OptionParser::InvalidOption puts "puppet-lint: #{$!.message}" puts "puppet-lint: try 'puppet-lint --help' for more information" return 1 end if PuppetLint.configuration.display_version puts "puppet-lint #{PuppetLint::VERSION}" return 0 end if @args[0].nil? puts "puppet-lint: no file specified" puts "puppet-lint: try 'puppet-lint --help' for more information" return 1 end begin path = @args[0] if File.directory?(path) path = Dir.glob("#{path}/**/*.pp") else path = @args end if path.length > 1 PuppetLint.configuration.with_filename = true end return_val = 0 path.each do |f| l = PuppetLint.new l.file = f l.run l.print_problems if l.errors? or (l.warnings? and PuppetLint.configuration.fail_on_warnings) return_val = 1 end if PuppetLint.configuration.fix && !l.problems.any? { |e| e[:check] == :syntax } File.open(f, 'w') do |fd| fd.write l.manifest end end end return return_val rescue PuppetLint::NoCodeError puts "puppet-lint: no file specified or specified file does not exist" puts "puppet-lint: try 'puppet-lint --help' for more information" return 1 end end end puppet-lint-1.1.0/lib/puppet-lint/configuration.rb0000644000004100000410000000735212421260622022251 0ustar www-datawww-dataclass PuppetLint # Public: A singleton class to store the running configuration of # puppet-lint. class Configuration # Internal: Add helper methods for a new check to the # PuppetLint::Configuration object. # # check - The String name of the check. # # Returns nothing. # # Signature # # _enabled? # disable_ # enable_ def self.add_check(check) # Public: Determine if the named check is enabled. # # Returns true if the check is enabled, otherwise return false. define_method("#{check}_enabled?") do settings["#{check}_disabled"] == true ? false : true end # Public: Disable the named check. # # Returns nothing. define_method("disable_#{check}") do settings["#{check}_disabled"] = true end # Public: Enable the named check. # # Returns nothing. define_method("enable_#{check}") do settings["#{check}_disabled"] = false end end # Public: Catch situations where options are being set for the first time # and create the necessary methods to get & set the option in the future. # # args - An Array of values to set the option to. # method - The String name of the option. # block - Unused. # # Returns nothing. # # Signature # #