foodcritic 7.0.1 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +10 -10
- data/Rakefile +21 -21
- data/bin/foodcritic +1 -1
- data/chef_dsl_metadata/chef_12.12.13.json +17809 -0
- data/chef_dsl_metadata/chef_12.13.37.json +18021 -0
- data/features/step_definitions/cookbook_steps.rb +456 -457
- data/features/support/command_helpers.rb +120 -120
- data/features/support/cookbook_helpers.rb +87 -87
- data/features/support/env.rb +6 -6
- data/foodcritic.gemspec +22 -22
- data/lib/foodcritic.rb +20 -20
- data/lib/foodcritic/api.rb +94 -91
- data/lib/foodcritic/chef.rb +14 -14
- data/lib/foodcritic/command_line.rb +35 -35
- data/lib/foodcritic/domain.rb +4 -4
- data/lib/foodcritic/dsl.rb +1 -2
- data/lib/foodcritic/linter.rb +31 -32
- data/lib/foodcritic/notifications.rb +5 -5
- data/lib/foodcritic/output.rb +5 -5
- data/lib/foodcritic/rake_task.rb +7 -7
- data/lib/foodcritic/rules.rb +234 -234
- data/lib/foodcritic/template.rb +1 -1
- data/lib/foodcritic/version.rb +1 -1
- data/lib/foodcritic/xml.rb +5 -5
- data/spec/foodcritic/api_spec.rb +275 -275
- data/spec/foodcritic/chef_spec.rb +11 -11
- data/spec/foodcritic/command_line_spec.rb +7 -7
- data/spec/foodcritic/domain_spec.rb +20 -20
- data/spec/foodcritic/linter_spec.rb +10 -11
- data/spec/foodcritic/template_spec.rb +8 -8
- data/spec/regression/regression_spec.rb +3 -3
- data/spec/regression_helpers.rb +10 -10
- data/spec/spec_helper.rb +6 -6
- metadata +5 -3
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../spec_helper"
|
2
2
|
|
3
3
|
describe FoodCritic::Chef do
|
4
4
|
|
@@ -6,28 +6,28 @@ describe FoodCritic::Chef do
|
|
6
6
|
|
7
7
|
describe "#chef_dsl_methods" do
|
8
8
|
it "returns an enumerable" do
|
9
|
-
api.chef_dsl_methods.each{|m| m}
|
9
|
+
api.chef_dsl_methods.each { |m| m }
|
10
10
|
end
|
11
11
|
it "does not return an empty" do
|
12
12
|
api.chef_dsl_methods.wont_be_empty
|
13
13
|
end
|
14
14
|
it "returns dsl methods as symbols" do
|
15
|
-
assert api.chef_dsl_methods.all?{|m| m == m.to_sym}
|
15
|
+
assert api.chef_dsl_methods.all? { |m| m == m.to_sym }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe "#resource_attribute?" do
|
20
20
|
it "raises if the resource_type is nil" do
|
21
|
-
lambda{api.resource_attribute?(nil, :name)}.must_raise(ArgumentError)
|
21
|
+
lambda { api.resource_attribute?(nil, :name) }.must_raise(ArgumentError)
|
22
22
|
end
|
23
23
|
it "raises if the resource_type is empty" do
|
24
|
-
lambda{api.resource_attribute?(
|
24
|
+
lambda { api.resource_attribute?("", :name) }.must_raise(ArgumentError)
|
25
25
|
end
|
26
26
|
it "raises if the attribute_name is nil" do
|
27
|
-
lambda{api.resource_attribute?(:file, nil)}.must_raise(ArgumentError)
|
27
|
+
lambda { api.resource_attribute?(:file, nil) }.must_raise(ArgumentError)
|
28
28
|
end
|
29
29
|
it "raises if the attribute_name is empty" do
|
30
|
-
lambda{api.resource_attribute?(:file,
|
30
|
+
lambda { api.resource_attribute?(:file, "") }.must_raise(ArgumentError)
|
31
31
|
end
|
32
32
|
it "returns true if the resource attribute is known" do
|
33
33
|
assert api.resource_attribute?(:file, :name)
|
@@ -42,21 +42,21 @@ describe FoodCritic::Chef do
|
|
42
42
|
refute api.resource_attribute?("file", :size)
|
43
43
|
end
|
44
44
|
it "allows the attribute_name to be passed as a string" do
|
45
|
-
assert api.resource_attribute?(:file,
|
45
|
+
assert api.resource_attribute?(:file, "mode")
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
describe "#valid_query?" do
|
50
50
|
it "raises if the query is nil" do
|
51
|
-
lambda{api.valid_query?(nil)}.must_raise(ArgumentError)
|
51
|
+
lambda { api.valid_query?(nil) }.must_raise(ArgumentError)
|
52
52
|
end
|
53
53
|
it "raises if the query is empty" do
|
54
|
-
lambda{api.valid_query?(
|
54
|
+
lambda { api.valid_query?("") }.must_raise(ArgumentError)
|
55
55
|
end
|
56
56
|
it "coerces the provided object to a string" do
|
57
57
|
query = Class.new do
|
58
58
|
def to_s
|
59
|
-
|
59
|
+
"*:*"
|
60
60
|
end
|
61
61
|
end.new
|
62
62
|
assert api.valid_query?(query)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../spec_helper"
|
2
2
|
|
3
3
|
describe FoodCritic::CommandLine do
|
4
4
|
it "is instantiable" do
|
@@ -15,7 +15,7 @@ describe FoodCritic::CommandLine do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "returns multiple items for multiple specified directories" do
|
18
|
-
FoodCritic::CommandLine.new(
|
18
|
+
FoodCritic::CommandLine.new(%w{example another_example}).cookbook_paths.must_equal %w{example another_example}
|
19
19
|
end
|
20
20
|
|
21
21
|
it "ignores known arguments" do
|
@@ -28,11 +28,11 @@ describe FoodCritic::CommandLine do
|
|
28
28
|
FoodCritic::CommandLine.new([]).role_paths.must_be_empty
|
29
29
|
end
|
30
30
|
it "returns the provided role path" do
|
31
|
-
FoodCritic::CommandLine.new([
|
31
|
+
FoodCritic::CommandLine.new(["-R", "roles"]).role_paths.must_equal(%w{roles})
|
32
32
|
end
|
33
33
|
it "returns the provided role paths when there are multiple" do
|
34
|
-
FoodCritic::CommandLine.new([
|
35
|
-
|
34
|
+
FoodCritic::CommandLine.new(["-R", "roles1",
|
35
|
+
"-R", "roles2"]).role_paths.must_equal(%w{roles1 roles2})
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -58,7 +58,7 @@ describe FoodCritic::CommandLine do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "returns false if any on the specified paths do not exist" do
|
61
|
-
refute FoodCritic::CommandLine.new(
|
61
|
+
refute FoodCritic::CommandLine.new(%w{lib lib2}).valid_paths?
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -68,7 +68,7 @@ describe FoodCritic::CommandLine do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "returns true if --list is specified" do
|
71
|
-
assert FoodCritic::CommandLine.new([
|
71
|
+
assert FoodCritic::CommandLine.new(["--list"]).list_rules?
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../spec_helper"
|
2
2
|
|
3
3
|
describe FoodCritic::Review do
|
4
4
|
it "is instantiable with no warnings" do
|
5
|
-
FoodCritic::Review.new(
|
5
|
+
FoodCritic::Review.new("example", [])
|
6
6
|
end
|
7
7
|
describe "#cookbook_paths" do
|
8
8
|
it "returns the cookbook paths provided" do
|
9
|
-
FoodCritic::Review.new([
|
9
|
+
FoodCritic::Review.new(["example"], []).cookbook_paths.must_equal ["example"]
|
10
10
|
end
|
11
11
|
it "returns the cookbook paths provided when there are multiple" do
|
12
|
-
FoodCritic::Review.new(
|
12
|
+
FoodCritic::Review.new(%w{example example2}, []).cookbook_paths.must_equal %w{example example2}
|
13
13
|
end
|
14
14
|
end
|
15
15
|
describe "#warnings" do
|
16
16
|
it "returns empty when there are no warnings" do
|
17
|
-
FoodCritic::Review.new(
|
17
|
+
FoodCritic::Review.new("example", []).warnings.must_be_empty
|
18
18
|
end
|
19
19
|
it "makes the warnings available" do
|
20
|
-
warning =
|
21
|
-
FoodCritic::Review.new(
|
20
|
+
warning = "Danger Will Robinson"
|
21
|
+
FoodCritic::Review.new("example", [warning]).warnings.must_equal [warning]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -28,51 +28,51 @@ describe FoodCritic::RuleList do
|
|
28
28
|
FoodCritic::RuleList.new([])
|
29
29
|
end
|
30
30
|
|
31
|
-
let(:rule) { FoodCritic::Rule.new(
|
31
|
+
let(:rule) { FoodCritic::Rule.new("FCTEST001", "Test rule") }
|
32
32
|
|
33
33
|
describe "#rules" do
|
34
34
|
|
35
|
-
it
|
35
|
+
it "is empty when instantiated with an empty rule list" do
|
36
36
|
assert FoodCritic::RuleList.new([]).rules.empty?
|
37
37
|
end
|
38
38
|
|
39
|
-
it
|
39
|
+
it "contains the given rule" do
|
40
40
|
assert FoodCritic::RuleList.new([rule]).rules.include?(rule)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
describe FoodCritic::Rule do
|
46
|
-
let(:rule) { FoodCritic::Rule.new(
|
46
|
+
let(:rule) { FoodCritic::Rule.new("FCTEST001", "Test rule") }
|
47
47
|
|
48
48
|
describe '#matches_tags?' do
|
49
49
|
it "matches the rule's code" do
|
50
|
-
rule.matches_tags?([
|
50
|
+
rule.matches_tags?(["FCTEST001"]).must_equal true
|
51
51
|
end
|
52
52
|
|
53
53
|
it "doesn't match an unrelated code" do
|
54
|
-
rule.matches_tags?([
|
54
|
+
rule.matches_tags?(["FCTEST999"]).must_equal false
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
describe '#tags' do
|
59
59
|
it "returns any + the rule's code" do
|
60
|
-
rule.tags.must_equal
|
60
|
+
rule.tags.must_equal %w{any FCTEST001}
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
describe FoodCritic::Warning do
|
66
|
-
let(:rule) { FoodCritic::Rule.new(
|
67
|
-
let(:match_opts) { {:filename =>
|
66
|
+
let(:rule) { FoodCritic::Rule.new("FCTEST001", "Test rule") }
|
67
|
+
let(:match_opts) { { :filename => "foo/recipes.default.rb", :line => 5, :column => 40 } }
|
68
68
|
|
69
69
|
describe "failure indication" do
|
70
|
-
it
|
71
|
-
FoodCritic::Warning.new(rule, match_opts, {:fail_tags => []}).failed?.must_equal false
|
70
|
+
it "is false if no fail_tags match" do
|
71
|
+
FoodCritic::Warning.new(rule, match_opts, { :fail_tags => [] }).failed?.must_equal false
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
75
|
-
FoodCritic::Warning.new(rule, match_opts, {:fail_tags => [
|
74
|
+
it "is true if fail_tags do match" do
|
75
|
+
FoodCritic::Warning.new(rule, match_opts, { :fail_tags => ["any"] }).failed?.must_equal true
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../spec_helper"
|
2
2
|
|
3
3
|
describe FoodCritic::Linter do
|
4
4
|
let(:linter) { FoodCritic::Linter.new }
|
@@ -18,25 +18,25 @@ describe FoodCritic::Linter do
|
|
18
18
|
describe "#check" do
|
19
19
|
|
20
20
|
it "requires a cookbook_path, role_path or environment_path to be specified" do
|
21
|
-
lambda{ linter.check({}) }.must_raise ArgumentError
|
21
|
+
lambda { linter.check({}) }.must_raise ArgumentError
|
22
22
|
end
|
23
23
|
|
24
24
|
[:cookbook, :role, :environment].each do |path_type|
|
25
25
|
key = "#{path_type}_paths".to_sym
|
26
26
|
it "requires a #{path_type}_path by itself not to be nil" do
|
27
|
-
lambda{ linter.check(key => nil) }.must_raise ArgumentError
|
27
|
+
lambda { linter.check(key => nil) }.must_raise ArgumentError
|
28
28
|
end
|
29
29
|
it "requires a #{path_type}_path by itself not to be empty" do
|
30
|
-
lambda{ linter.check(key => []) }.must_raise ArgumentError
|
30
|
+
lambda { linter.check(key => []) }.must_raise ArgumentError
|
31
31
|
end
|
32
32
|
it "accepts a scalar with a single #{path_type} path" do
|
33
|
-
linter.check(key =>
|
33
|
+
linter.check(key => ".")
|
34
34
|
end
|
35
35
|
it "accepts an array of #{path_type} paths" do
|
36
|
-
linter.check(key => [
|
36
|
+
linter.check(key => ["."])
|
37
37
|
end
|
38
38
|
it "returns a review when a #{path_type} path is provided" do
|
39
|
-
linter.check(key => [
|
39
|
+
linter.check(key => ["."]).must_respond_to(:warnings)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -53,10 +53,9 @@ describe FoodCritic::Linter do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
56
|
describe "#load_files!" do
|
58
57
|
let(:default_rules_file) do
|
59
|
-
File.expand_path(File.join(File.dirname(__FILE__),
|
58
|
+
File.expand_path(File.join(File.dirname(__FILE__), "../../lib/foodcritic/rules.rb"))
|
60
59
|
end
|
61
60
|
|
62
61
|
let(:rule_dsl_load_mock) { MiniTest::Mock.new }
|
@@ -67,7 +66,7 @@ describe FoodCritic::Linter do
|
|
67
66
|
end
|
68
67
|
|
69
68
|
it "should include rules found in gems if the :search_gems option is true" do
|
70
|
-
gem_rules = [
|
69
|
+
gem_rules = ["/path/to/rules1.rb", "/path/to/rules2.rb"]
|
71
70
|
expected_rules = [default_rules_file, gem_rules].flatten
|
72
71
|
rule_dsl_load_mock.expect(:call, nil, [expected_rules, nil])
|
73
72
|
|
@@ -80,7 +79,7 @@ describe FoodCritic::Linter do
|
|
80
79
|
end
|
81
80
|
|
82
81
|
it "should include files found in :include_rules option" do
|
83
|
-
include_rules = [
|
82
|
+
include_rules = ["/path/to/rules1.rb", "/path/to/rules2.rb"]
|
84
83
|
expected_rules = [default_rules_file, include_rules].flatten
|
85
84
|
rule_dsl_load_mock.expect(:call, nil, [expected_rules, nil])
|
86
85
|
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../spec_helper"
|
2
2
|
|
3
3
|
describe FoodCritic::Template::ExpressionExtractor do
|
4
|
-
let(:extractor){ FoodCritic::Template::ExpressionExtractor.new }
|
4
|
+
let(:extractor) { FoodCritic::Template::ExpressionExtractor.new }
|
5
5
|
describe "#expressions" do
|
6
6
|
it "returns empty if the template is empty" do
|
7
|
-
extractor.extract(
|
7
|
+
extractor.extract("").must_be_empty
|
8
8
|
end
|
9
9
|
it "returns empty if the template contains no erb at all" do
|
10
10
|
extractor.extract(%q{
|
@@ -16,8 +16,8 @@ describe FoodCritic::Template::ExpressionExtractor do
|
|
16
16
|
<% if true %>
|
17
17
|
Hello World!
|
18
18
|
<% end %>
|
19
|
-
}).must_equal([{:type => :statement, :code =>
|
20
|
-
{:type => :statement, :code =>
|
19
|
+
}).must_equal([{ :type => :statement, :code => "if true", :line => 2 },
|
20
|
+
{ :type => :statement, :code => "end", :line => 4 }])
|
21
21
|
end
|
22
22
|
it "does not evaluate erb statements" do
|
23
23
|
extractor.extract(%q{
|
@@ -27,7 +27,7 @@ describe FoodCritic::Template::ExpressionExtractor do
|
|
27
27
|
it "extracts an expression from within the template" do
|
28
28
|
extractor.extract(%q{
|
29
29
|
<%= foo %>
|
30
|
-
}).must_equal([{:type => :expression, :code =>
|
30
|
+
}).must_equal([{ :type => :expression, :code => "foo", :line => 2 }])
|
31
31
|
end
|
32
32
|
it "does not evaluate erb expressions" do
|
33
33
|
extractor.extract(%q{
|
@@ -41,8 +41,8 @@ describe FoodCritic::Template::ExpressionExtractor do
|
|
41
41
|
URIEncoding="UTF-8"
|
42
42
|
redirectPort="<%= node["tomcat"]["ssl_port"] %>" />
|
43
43
|
}).must_equal([
|
44
|
-
{:type => :expression, :code => 'node["tomcat"]["port"]', :line => 2},
|
45
|
-
{:type => :expression, :code => 'node["tomcat"]["ssl_port"]', :line => 5}
|
44
|
+
{ :type => :expression, :code => 'node["tomcat"]["port"]', :line => 2 },
|
45
|
+
{ :type => :expression, :code => 'node["tomcat"]["ssl_port"]', :line => 5 },
|
46
46
|
])
|
47
47
|
end
|
48
48
|
it "excludes comment-only expressions" do
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../regression_helpers"
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe "regression test" do
|
4
4
|
|
5
5
|
let(:expected_lint_output) do
|
6
|
-
File.read(
|
6
|
+
File.read("spec/regression/expected-output.txt")
|
7
7
|
end
|
8
8
|
|
9
9
|
let(:actual_lint_output) do
|
data/spec/regression_helpers.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require_relative "spec_helper"
|
2
|
+
require "fileutils"
|
3
|
+
require "pathname"
|
4
4
|
|
5
5
|
def lint_regression_cookbooks
|
6
|
-
working_dir = Pathname.new(
|
6
|
+
working_dir = Pathname.new("tmp/regression")
|
7
7
|
FileUtils.mkdir_p(working_dir)
|
8
8
|
|
9
|
-
pinned_cookbooks(
|
9
|
+
pinned_cookbooks("spec/regression/cookbooks.txt").each do |cbk|
|
10
10
|
clone_cookbook(working_dir, cbk)
|
11
11
|
end
|
12
12
|
|
@@ -15,23 +15,23 @@ end
|
|
15
15
|
|
16
16
|
def pinned_cookbooks(path)
|
17
17
|
File.read(path).lines.map do |line|
|
18
|
-
name, ref = line.strip.split(
|
19
|
-
{:name => name, :ref => ref}
|
18
|
+
name, ref = line.strip.split(":")
|
19
|
+
{ :name => name, :ref => ref }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def clone_cookbook(clone_path, cbk)
|
24
24
|
target_path = clone_path + cbk[:name]
|
25
25
|
unless Dir.exist?(target_path)
|
26
|
-
|
26
|
+
`git clone -q git://github.com/chef-cookbooks/#{cbk[:name]}.git #{target_path}`
|
27
27
|
raise "Unable to clone git://github.com/chef-cookbooks/#{cbk[:name]}.git" unless $?.success?
|
28
28
|
end
|
29
|
-
|
29
|
+
`cd #{target_path} && git checkout -q #{cbk[:ref]}`
|
30
30
|
raise "Unable to checkout revision for #{cbk[:name]}" unless $?.success?
|
31
31
|
end
|
32
32
|
|
33
33
|
def lint_cookbooks(cookbook_path)
|
34
|
-
result =
|
34
|
+
result = `cd #{cookbook_path} && foodcritic .`
|
35
35
|
raise "Unable to lint #{cookbook_path}" unless $?.success?
|
36
36
|
result
|
37
37
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "simplecov"
|
3
3
|
SimpleCov.start do
|
4
|
-
add_filter
|
4
|
+
add_filter "/spec/"
|
5
5
|
end
|
6
6
|
rescue LoadError
|
7
|
-
warn
|
7
|
+
warn "warning: simplecov gem not found; skipping coverage"
|
8
8
|
end
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "minitest/pride"
|
11
|
+
require "minitest/spec"
|
12
12
|
|
13
|
-
require_relative
|
13
|
+
require_relative "../lib/foodcritic"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foodcritic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Crump
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber-core
|
@@ -159,6 +159,8 @@ files:
|
|
159
159
|
- chef_dsl_metadata/chef_12.1.2.json
|
160
160
|
- chef_dsl_metadata/chef_12.10.24.json
|
161
161
|
- chef_dsl_metadata/chef_12.11.18.json
|
162
|
+
- chef_dsl_metadata/chef_12.12.13.json
|
163
|
+
- chef_dsl_metadata/chef_12.13.37.json
|
162
164
|
- chef_dsl_metadata/chef_12.2.1.json
|
163
165
|
- chef_dsl_metadata/chef_12.3.0.json
|
164
166
|
- chef_dsl_metadata/chef_12.4.0.json
|
@@ -301,5 +303,5 @@ rubyforge_project:
|
|
301
303
|
rubygems_version: 2.6.6
|
302
304
|
signing_key:
|
303
305
|
specification_version: 4
|
304
|
-
summary: foodcritic-7.0
|
306
|
+
summary: foodcritic-7.1.0
|
305
307
|
test_files: []
|