cane 2.6.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +6 -0
- data/README.md +1 -1
- data/lib/cane/abc_check.rb +1 -1
- data/lib/cane/doc_check.rb +2 -2
- data/lib/cane/rake_task.rb +1 -1
- data/lib/cane/style_check.rb +2 -2
- data/lib/cane/version.rb +1 -1
- data/spec/abc_check_spec.rb +31 -12
- data/spec/cane_spec.rb +7 -7
- data/spec/cli_spec.rb +5 -5
- data/spec/doc_check_spec.rb +29 -27
- data/spec/encoding_aware_iterator_spec.rb +5 -5
- data/spec/file_spec.rb +3 -1
- data/spec/fixtures/a/1.rb +1 -0
- data/spec/fixtures/b/1.rb +1 -0
- data/spec/json_formatter_spec.rb +2 -1
- data/spec/parser_spec.rb +35 -35
- data/spec/rake_task_spec.rb +8 -8
- data/spec/runner_spec.rb +4 -4
- data/spec/spec_helper.rb +3 -3
- data/spec/style_check_spec.rb +35 -4
- data/spec/threshold_check_spec.rb +41 -23
- data/spec/violation_formatter_spec.rb +6 -6
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3038468a984c0181fcd109612a08c5f263b93ff9
|
4
|
+
data.tar.gz: d11758c7e61a2553b747c6fdea13fcf248d7cfd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f46e8fe84b99920e0259bc8ce71c5bc2a2f05dc49993283caf033cdfc7f85a0c59c62ad55059945e044c58660d594cfeceea4b457ed06f446a6ae04ce819459
|
7
|
+
data.tar.gz: d1d407ce3b860e2d915356dbe2339edda226040a506b78a561b80bcadcc4fa012c65d3aac69affb00b01ad1d11aa9a2b51285e352369270b72479feeadd9456c
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Cane History
|
2
2
|
|
3
|
+
## 3.0.0 - 10 March 2016 (f602b9)
|
4
|
+
|
5
|
+
* Compat: Rake 11 supported
|
6
|
+
* Compat: Ruby 1.9 no longer supported.
|
7
|
+
* Feature: Glob options now take arrays.
|
8
|
+
|
3
9
|
## 2.6.2 - 20 April 2014 (8f54b4)
|
4
10
|
|
5
11
|
* Bugfix: Commented methods no longer trigger a documentation violation for
|
data/README.md
CHANGED
@@ -211,7 +211,7 @@ A good README should include at a minimum:
|
|
211
211
|
|
212
212
|
## Compatibility
|
213
213
|
|
214
|
-
Requires
|
214
|
+
Requires CRuby 2.0, since it depends on the `ripper` library to calculate
|
215
215
|
complexity metrics. This only applies to the Ruby used to run Cane, not the
|
216
216
|
project it is being run against. In other words, you can run Cane against your
|
217
217
|
1.8 or JRuby project.
|
data/lib/cane/abc_check.rb
CHANGED
data/lib/cane/doc_check.rb
CHANGED
@@ -114,7 +114,7 @@ module Cane
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def file_names
|
117
|
-
Dir
|
117
|
+
Dir.glob(opts.fetch(:doc_glob)).reject { |file| excluded?(file) }
|
118
118
|
end
|
119
119
|
|
120
120
|
def method_definition?(line)
|
@@ -139,7 +139,7 @@ module Cane
|
|
139
139
|
|
140
140
|
def exclusions
|
141
141
|
@exclusions ||= opts.fetch(:doc_exclude, []).flatten.map do |i|
|
142
|
-
Dir
|
142
|
+
Dir.glob(i)
|
143
143
|
end.flatten.to_set
|
144
144
|
end
|
145
145
|
|
data/lib/cane/rake_task.rb
CHANGED
data/lib/cane/style_check.rb
CHANGED
@@ -60,7 +60,7 @@ module Cane
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def file_list
|
63
|
-
Dir
|
63
|
+
Dir.glob(opts.fetch(:style_glob)).reject {|f| excluded?(f) }
|
64
64
|
end
|
65
65
|
|
66
66
|
def measure
|
@@ -73,7 +73,7 @@ module Cane
|
|
73
73
|
|
74
74
|
def exclusions
|
75
75
|
@exclusions ||= opts.fetch(:style_exclude, []).flatten.map do |i|
|
76
|
-
Dir
|
76
|
+
Dir.glob(i)
|
77
77
|
end.flatten.to_set
|
78
78
|
end
|
79
79
|
|
data/lib/cane/version.rb
CHANGED
data/spec/abc_check_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Cane::AbcCheck do
|
|
18
18
|
RUBY
|
19
19
|
|
20
20
|
violations = check(file_name, abc_max: 1, no_abc: true).violations
|
21
|
-
violations.
|
21
|
+
expect(violations).to be_empty
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'creates an AbcMaxViolation for each method above the threshold' do
|
@@ -36,9 +36,10 @@ describe Cane::AbcCheck do
|
|
36
36
|
RUBY
|
37
37
|
|
38
38
|
violations = check(file_name, abc_max: 1, no_abc: false).violations
|
39
|
-
violations.length.
|
40
|
-
violations[0].values_at(:file, :label, :value).
|
39
|
+
expect(violations.length).to eq(1)
|
40
|
+
expect(violations[0].values_at(:file, :label, :value)).to eq(
|
41
41
|
[file_name, "Harness#complex_method", 2]
|
42
|
+
)
|
42
43
|
end
|
43
44
|
|
44
45
|
it 'sorts violations by complexity' do
|
@@ -56,9 +57,9 @@ describe Cane::AbcCheck do
|
|
56
57
|
RUBY
|
57
58
|
|
58
59
|
violations = check(file_name, abc_max: 0).violations
|
59
|
-
violations.length.
|
60
|
+
expect(violations.length).to eq(2)
|
60
61
|
complexities = violations.map {|x| x[:value] }
|
61
|
-
complexities.
|
62
|
+
expect(complexities).to eq(complexities.sort.reverse)
|
62
63
|
end
|
63
64
|
|
64
65
|
it 'creates a violation when code cannot be parsed' do
|
@@ -67,9 +68,9 @@ describe Cane::AbcCheck do
|
|
67
68
|
RUBY
|
68
69
|
|
69
70
|
violations = check(file_name).violations
|
70
|
-
violations.length.
|
71
|
-
violations[0][:file].
|
72
|
-
violations[0][:description].
|
71
|
+
expect(violations.length).to eq(1)
|
72
|
+
expect(violations[0][:file]).to eq(file_name)
|
73
|
+
expect(violations[0][:description]).to be_instance_of(String)
|
73
74
|
end
|
74
75
|
|
75
76
|
it 'skips declared exclusions' do
|
@@ -105,9 +106,10 @@ describe Cane::AbcCheck do
|
|
105
106
|
abc_max: 0,
|
106
107
|
abc_exclude: exclusions
|
107
108
|
).violations
|
108
|
-
violations.length.
|
109
|
-
violations[0].values_at(:file, :label, :value).
|
109
|
+
expect(violations.length).to eq(1)
|
110
|
+
expect(violations[0].values_at(:file, :label, :value)).to eq(
|
110
111
|
[file_name, "Harness::Nested#other_meth", 1]
|
112
|
+
)
|
111
113
|
end
|
112
114
|
|
113
115
|
it "creates an AbcMaxViolation for method in assigned anonymous class" do
|
@@ -135,7 +137,7 @@ describe Cane::AbcCheck do
|
|
135
137
|
RUBY
|
136
138
|
|
137
139
|
violations = check(file_name, abc_max: 1).violations
|
138
|
-
violations[0][:label].
|
140
|
+
expect(violations[0][:label]).to eq("(anon)#test_method")
|
139
141
|
end
|
140
142
|
|
141
143
|
def self.it_should_extract_method_name(name, label=name, sep='#')
|
@@ -150,7 +152,7 @@ describe Cane::AbcCheck do
|
|
150
152
|
RUBY
|
151
153
|
|
152
154
|
violations = check(file_name, abc_max: 1).violations
|
153
|
-
violations[0][:label].
|
155
|
+
expect(violations[0][:label]).to eq("Harness#{sep}#{label}")
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
@@ -161,4 +163,21 @@ describe Cane::AbcCheck do
|
|
161
163
|
it_should_extract_method_name 'GET'
|
162
164
|
it_should_extract_method_name '`'
|
163
165
|
it_should_extract_method_name '>='
|
166
|
+
|
167
|
+
describe "#file_names" do
|
168
|
+
context "abc_glob is an array" do
|
169
|
+
it "returns an array of relative file paths" do
|
170
|
+
glob = [
|
171
|
+
'spec/fixtures/a/**/*.{rb,prawn}',
|
172
|
+
'spec/fixtures/b/**/*.rb'
|
173
|
+
]
|
174
|
+
check = described_class.new(abc_glob: glob)
|
175
|
+
expect(check.send(:file_names)).to eq([
|
176
|
+
'spec/fixtures/a/1.rb',
|
177
|
+
'spec/fixtures/a/3.prawn',
|
178
|
+
'spec/fixtures/b/1.rb'
|
179
|
+
])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
164
183
|
end
|
data/spec/cane_spec.rb
CHANGED
@@ -49,12 +49,12 @@ describe 'The cane application' do
|
|
49
49
|
--check #{class_name}
|
50
50
|
--unhappy-file #{fn}
|
51
51
|
)
|
52
|
-
output.
|
53
|
-
output.
|
54
|
-
output.
|
52
|
+
expect(output).to include("Lines violated style requirements")
|
53
|
+
expect(output).to include("Methods exceeded maximum allowed ABC complexity")
|
54
|
+
expect(output).to include(
|
55
55
|
"Class and Module definitions require explanatory comments"
|
56
56
|
)
|
57
|
-
exitstatus.
|
57
|
+
expect(exitstatus).to eq(1)
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'handles invalid unicode input' do
|
@@ -62,19 +62,19 @@ describe 'The cane application' do
|
|
62
62
|
|
63
63
|
_, exitstatus = run("--style-glob #{fn} --abc-glob #{fn} --doc-glob #{fn}")
|
64
64
|
|
65
|
-
exitstatus.
|
65
|
+
expect(exitstatus).to eq(0)
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'can run tasks in parallel' do
|
69
69
|
# This spec isn't great, but there is no good way to actually observe that
|
70
70
|
# tasks run in parallel and we want to verify the conditional is correct.
|
71
|
-
Cane.task_runner(parallel: true).
|
71
|
+
expect(Cane.task_runner(parallel: true)).to eq(Parallel)
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'colorizes output' do
|
75
75
|
output, exitstatus = run("--color --abc-max 0")
|
76
76
|
|
77
|
-
output.
|
77
|
+
expect(output).to include("\e[31m")
|
78
78
|
end
|
79
79
|
|
80
80
|
after do
|
data/spec/cli_spec.rb
CHANGED
@@ -9,16 +9,16 @@ describe Cane::CLI do
|
|
9
9
|
let!(:cane) { class_double("Cane").as_stubbed_const }
|
10
10
|
|
11
11
|
it 'runs Cane with the given arguments' do
|
12
|
-
parser.
|
13
|
-
cane.
|
12
|
+
expect(parser).to receive(:parse).with("--args").and_return(args: true)
|
13
|
+
expect(cane).to receive(:run).with(args: true).and_return("tracer")
|
14
14
|
|
15
|
-
described_class.run("--args").
|
15
|
+
expect(described_class.run("--args")).to eq("tracer")
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'does not run Cane if parser was able to handle input' do
|
19
|
-
parser.
|
19
|
+
expect(parser).to receive(:parse).with("--args").and_return("tracer")
|
20
20
|
|
21
|
-
described_class.run("--args").
|
21
|
+
expect(described_class.run("--args")).to eq("tracer")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/spec/doc_check_spec.rb
CHANGED
@@ -43,19 +43,19 @@ end
|
|
43
43
|
RUBY
|
44
44
|
|
45
45
|
violations = check(file_name).violations
|
46
|
-
violations.length.
|
46
|
+
expect(violations.length).to eq(3)
|
47
47
|
|
48
|
-
violations[0].values_at(:file, :line, :label).
|
48
|
+
expect(violations[0].values_at(:file, :line, :label)).to eq([
|
49
49
|
file_name, 3, "NoDoc"
|
50
|
-
]
|
50
|
+
])
|
51
51
|
|
52
|
-
violations[1].values_at(:file, :line, :label).
|
52
|
+
expect(violations[1].values_at(:file, :line, :label)).to eq([
|
53
53
|
file_name, 15, "AlsoNeedsDoc"
|
54
|
-
]
|
54
|
+
])
|
55
55
|
|
56
|
-
violations[2].values_at(:file, :line, :label).
|
56
|
+
expect(violations[2].values_at(:file, :line, :label)).to eq([
|
57
57
|
file_name, 17, "ButThisNeedsDoc"
|
58
|
-
]
|
58
|
+
])
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'does not create violations for single line classes without methods' do
|
@@ -71,15 +71,15 @@ end
|
|
71
71
|
RUBY
|
72
72
|
|
73
73
|
violations = check(file_name).violations
|
74
|
-
violations.length.
|
74
|
+
expect(violations.length).to eq(2)
|
75
75
|
|
76
|
-
violations[0].values_at(:file, :line, :label).
|
76
|
+
expect(violations[0].values_at(:file, :line, :label)).to eq([
|
77
77
|
file_name, 1, "NeedsDoc"
|
78
|
-
]
|
78
|
+
])
|
79
79
|
|
80
|
-
violations[1].values_at(:file, :line, :label).
|
80
|
+
expect(violations[1].values_at(:file, :line, :label)).to eq([
|
81
81
|
file_name, 2, "AlsoNeedsDoc"
|
82
|
-
]
|
82
|
+
])
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'ignores magic encoding comments' do
|
@@ -93,39 +93,41 @@ class Doc; end
|
|
93
93
|
RUBY
|
94
94
|
|
95
95
|
violations = check(file_name).violations
|
96
|
-
violations.length.
|
96
|
+
expect(violations.length).to eq(2)
|
97
97
|
|
98
|
-
violations[0].values_at(:file, :line, :label).
|
98
|
+
expect(violations[0].values_at(:file, :line, :label)).to eq([
|
99
99
|
file_name, 2, "NoDoc"
|
100
|
-
]
|
101
|
-
violations[1].values_at(:file, :line, :label).
|
100
|
+
])
|
101
|
+
expect(violations[1].values_at(:file, :line, :label)).to eq([
|
102
102
|
file_name, 4, "AlsoNoDoc"
|
103
|
-
]
|
103
|
+
])
|
104
104
|
end
|
105
105
|
|
106
106
|
it 'creates a violation for missing README' do
|
107
107
|
file = class_double("Cane::File").as_stubbed_const
|
108
108
|
stub_const("Cane::File", file)
|
109
|
-
file.
|
109
|
+
expect(file).to receive(:case_insensitive_glob).with(
|
110
|
+
"README*"
|
111
|
+
).and_return([])
|
110
112
|
|
111
113
|
violations = check("").violations
|
112
|
-
violations.length.
|
114
|
+
expect(violations.length).to eq(1)
|
113
115
|
|
114
|
-
violations[0].values_at(:description, :label).
|
116
|
+
expect(violations[0].values_at(:description, :label)).to eq([
|
115
117
|
"Missing documentation", "No README found"
|
116
|
-
]
|
118
|
+
])
|
117
119
|
end
|
118
120
|
|
119
121
|
it 'does not create a violation when readme exists' do
|
120
122
|
file = class_double("Cane::File").as_stubbed_const
|
121
123
|
stub_const("Cane::File", file)
|
122
|
-
file
|
123
|
-
.
|
124
|
+
expect(file)
|
125
|
+
.to receive(:case_insensitive_glob)
|
124
126
|
.with("README*")
|
125
127
|
.and_return(%w(readme.md))
|
126
128
|
|
127
129
|
violations = check("").violations
|
128
|
-
violations.length.
|
130
|
+
expect(violations.length).to eq(0)
|
129
131
|
end
|
130
132
|
|
131
133
|
it 'skips declared exclusions' do
|
@@ -138,7 +140,7 @@ class Doc; end
|
|
138
140
|
doc_exclude: [file_name]
|
139
141
|
).violations
|
140
142
|
|
141
|
-
violations.length.
|
143
|
+
expect(violations.length).to eq(0)
|
142
144
|
end
|
143
145
|
|
144
146
|
it 'skips declared glob-based exclusions' do
|
@@ -151,7 +153,7 @@ class Doc; end
|
|
151
153
|
doc_exclude: ["#{File.dirname(file_name)}/*"]
|
152
154
|
).violations
|
153
155
|
|
154
|
-
violations.length.
|
156
|
+
expect(violations.length).to eq(0)
|
155
157
|
end
|
156
158
|
|
157
159
|
it 'skips class inside an array' do
|
@@ -163,6 +165,6 @@ class Doc; end
|
|
163
165
|
RUBY
|
164
166
|
|
165
167
|
violations = check(file_name).violations
|
166
|
-
violations.length.
|
168
|
+
expect(violations.length).to eq(0)
|
167
169
|
end
|
168
170
|
end
|
@@ -9,18 +9,18 @@ describe Cane::EncodingAwareIterator do
|
|
9
9
|
it 'handles non-UTF8 input' do
|
10
10
|
lines = ["\xc3\x28"]
|
11
11
|
result = described_class.new(lines).map.with_index do |line, number|
|
12
|
-
line.
|
12
|
+
expect(line).to be_kind_of(String)
|
13
13
|
[line =~ /\s/, number]
|
14
14
|
end
|
15
|
-
result.
|
15
|
+
expect(result).to eq([[nil, 0]])
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'does not enter an infinite loop on persistently bad input' do
|
19
|
-
|
19
|
+
expect{
|
20
20
|
described_class.new([""]).map.with_index do |line, number|
|
21
21
|
"\xc3\x28" =~ /\s/
|
22
22
|
end
|
23
|
-
}.
|
23
|
+
}.to raise_error(ArgumentError)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'allows each with no block' do
|
@@ -28,6 +28,6 @@ describe Cane::EncodingAwareIterator do
|
|
28
28
|
described_class.new([""]).each.with_index do |line, number|
|
29
29
|
called_with_line = line
|
30
30
|
end
|
31
|
-
called_with_line.
|
31
|
+
expect(called_with_line).to eq("")
|
32
32
|
end
|
33
33
|
end
|
data/spec/file_spec.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
puts "wooo I am a/1.rb"
|
@@ -0,0 +1 @@
|
|
1
|
+
puts "wooo I am b/1.rb"
|
data/spec/json_formatter_spec.rb
CHANGED
@@ -5,7 +5,8 @@ require 'cane/json_formatter'
|
|
5
5
|
describe Cane::JsonFormatter do
|
6
6
|
it 'outputs violations as JSON' do
|
7
7
|
violations = [{description: 'Fail', line: 3}]
|
8
|
-
JSON.parse(described_class.new(violations).to_s).
|
8
|
+
expect(JSON.parse(described_class.new(violations).to_s)).to eq(
|
9
9
|
[{'description' => 'Fail', 'line' => 3}]
|
10
|
+
)
|
10
11
|
end
|
11
12
|
end
|
data/spec/parser_spec.rb
CHANGED
@@ -13,71 +13,71 @@ describe Cane::CLI::Parser do
|
|
13
13
|
|
14
14
|
it 'allows style options to be configured' do
|
15
15
|
output, result = run("--style-glob myfile --style-measure 3")
|
16
|
-
result[:style_glob].
|
17
|
-
result[:style_measure].
|
16
|
+
expect(result[:style_glob]).to eq('myfile')
|
17
|
+
expect(result[:style_measure]).to eq(3)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'allows checking gte of a value in a file' do
|
21
21
|
output, result = run("--gte myfile,90")
|
22
|
-
result[:gte].
|
22
|
+
expect(result[:gte]).to eq([['myfile', '90']])
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'allows checking eq of a value in a file' do
|
26
26
|
output, result = run("--eq myfile,90")
|
27
|
-
result[:eq].
|
27
|
+
expect(result[:eq]).to eq([['myfile', '90']])
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'allows checking lte of a value in a file' do
|
31
31
|
output, result = run("--lte myfile,90")
|
32
|
-
result[:lte].
|
32
|
+
expect(result[:lte]).to eq([['myfile', '90']])
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'allows checking lt of a value in a file' do
|
36
36
|
output, result = run("--lt myfile,90")
|
37
|
-
result[:lt].
|
37
|
+
expect(result[:lt]).to eq([['myfile', '90']])
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'allows checking gt of a value in a file' do
|
41
41
|
output, resugt = run("--gt myfile,90")
|
42
|
-
resugt[:gt].
|
42
|
+
expect(resugt[:gt]).to eq([['myfile', '90']])
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'allows upper bound of failed checks' do
|
46
46
|
output, result = run("--max-violations 1")
|
47
|
-
result[:max_violations].
|
47
|
+
expect(result[:max_violations]).to eq(1)
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'uses positional arguments as shortcut for individual files' do
|
51
51
|
output, result = run("--all mysinglefile")
|
52
|
-
result[:abc_glob].
|
53
|
-
result[:style_glob].
|
54
|
-
result[:doc_glob].
|
52
|
+
expect(result[:abc_glob]).to eq('mysinglefile')
|
53
|
+
expect(result[:style_glob]).to eq('mysinglefile')
|
54
|
+
expect(result[:doc_glob]).to eq('mysinglefile')
|
55
55
|
|
56
56
|
output, result = run("--all mysinglefile --abc-glob myotherfile")
|
57
|
-
result[:abc_glob].
|
58
|
-
result[:style_glob].
|
59
|
-
result[:doc_glob].
|
57
|
+
expect(result[:abc_glob]).to eq('myotherfile')
|
58
|
+
expect(result[:style_glob]).to eq('mysinglefile')
|
59
|
+
expect(result[:doc_glob]).to eq('mysinglefile')
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'displays a help message' do
|
63
63
|
output, result = run("--help")
|
64
64
|
|
65
|
-
result.
|
66
|
-
output.
|
65
|
+
expect(result).to be
|
66
|
+
expect(output).to include("Usage:")
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'handles invalid options by showing help' do
|
70
70
|
output, result = run("--bogus")
|
71
71
|
|
72
|
-
output.
|
73
|
-
result.
|
72
|
+
expect(output).to include("Usage:")
|
73
|
+
expect(result).not_to be
|
74
74
|
end
|
75
75
|
|
76
76
|
it 'displays version' do
|
77
77
|
output, result = run("--version")
|
78
78
|
|
79
|
-
result.
|
80
|
-
output.
|
79
|
+
expect(result).to be
|
80
|
+
expect(output).to include(Cane::VERSION)
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'supports exclusions' do
|
@@ -88,18 +88,18 @@ describe Cane::CLI::Parser do
|
|
88
88
|
].join(' ')
|
89
89
|
|
90
90
|
_, result = run(options)
|
91
|
-
result[:abc_exclude].
|
92
|
-
result[:doc_exclude].
|
93
|
-
result[:style_exclude].
|
91
|
+
expect(result[:abc_exclude]).to eq([['Harness#complex_method']])
|
92
|
+
expect(result[:doc_exclude]).to eq([['myfile']])
|
93
|
+
expect(result[:style_exclude]).to eq([['myfile']])
|
94
94
|
end
|
95
95
|
|
96
96
|
describe 'argument ordering' do
|
97
97
|
it 'gives precedence to the last argument #1' do
|
98
98
|
_, result = run("--doc-glob myfile --no-doc")
|
99
|
-
result[:no_doc].
|
99
|
+
expect(result[:no_doc]).to be
|
100
100
|
|
101
101
|
_, result = run("--no-doc --doc-glob myfile")
|
102
|
-
result[:no_doc].
|
102
|
+
expect(result[:no_doc]).not_to be
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
@@ -111,34 +111,34 @@ describe Cane::CLI::Parser do
|
|
111
111
|
EOS
|
112
112
|
file = class_double("Cane::File").as_stubbed_const
|
113
113
|
stub_const("Cane::File", file)
|
114
|
-
file.
|
115
|
-
file.
|
114
|
+
expect(file).to receive(:exists?).with('./.cane').and_return(true)
|
115
|
+
expect(file).to receive(:contents).with('./.cane').and_return(defaults)
|
116
116
|
|
117
117
|
_, result = run("--style-glob myotherfile")
|
118
118
|
|
119
|
-
result[:no_doc].
|
120
|
-
result[:abc_glob].
|
121
|
-
result[:style_glob].
|
119
|
+
expect(result[:no_doc]).to be
|
120
|
+
expect(result[:abc_glob]).to eq('myfile')
|
121
|
+
expect(result[:style_glob]).to eq('myotherfile')
|
122
122
|
end
|
123
123
|
|
124
124
|
it 'allows parallel option' do
|
125
125
|
_, result = run("--parallel")
|
126
|
-
result[:parallel].
|
126
|
+
expect(result[:parallel]).to be
|
127
127
|
end
|
128
128
|
|
129
129
|
it 'handles ambiguous options' do
|
130
130
|
output, result = run("-abc-max")
|
131
|
-
output.
|
132
|
-
result.
|
131
|
+
expect(output).to include("Usage:")
|
132
|
+
expect(result).not_to be
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'handles no_readme option' do
|
136
136
|
_, result = run("--no-readme")
|
137
|
-
result[:no_readme].
|
137
|
+
expect(result[:no_readme]).to be
|
138
138
|
end
|
139
139
|
|
140
140
|
it 'handles json option' do
|
141
141
|
_, result = run("--json")
|
142
|
-
result[:json].
|
142
|
+
expect(result[:json]).to be
|
143
143
|
end
|
144
144
|
end
|
data/spec/rake_task_spec.rb
CHANGED
@@ -21,15 +21,15 @@ describe Cane::RakeTask do
|
|
21
21
|
cane.parallel = false
|
22
22
|
end
|
23
23
|
|
24
|
-
task.no_abc.
|
24
|
+
expect(task.no_abc).to eq(true)
|
25
25
|
|
26
|
-
task.
|
26
|
+
expect(task).to receive(:abort)
|
27
27
|
out = capture_stdout do
|
28
28
|
Rake::Task['quality'].invoke
|
29
29
|
end
|
30
30
|
|
31
|
-
out.
|
32
|
-
out.
|
31
|
+
expect(out).to include("Quality threshold crossed")
|
32
|
+
expect(out).to include("theopt")
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'can be configured using a .cane file' do
|
@@ -39,12 +39,12 @@ describe Cane::RakeTask do
|
|
39
39
|
cane.canefile = make_file(conf)
|
40
40
|
end
|
41
41
|
|
42
|
-
task.
|
42
|
+
expect(task).to receive(:abort)
|
43
43
|
out = capture_stdout do
|
44
44
|
Rake::Task['canefile_quality'].invoke
|
45
45
|
end
|
46
46
|
|
47
|
-
out.
|
47
|
+
expect(out).to include("Quality threshold crossed")
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'defaults to using a canefile without a block' do
|
@@ -54,12 +54,12 @@ describe Cane::RakeTask do
|
|
54
54
|
|
55
55
|
task = Cane::RakeTask.new(:canefile_quality)
|
56
56
|
|
57
|
-
task.
|
57
|
+
expect(task).to receive(:abort)
|
58
58
|
out = capture_stdout do
|
59
59
|
Rake::Task['canefile_quality'].invoke
|
60
60
|
end
|
61
61
|
|
62
|
-
out.
|
62
|
+
expect(out).to include("Quality threshold crossed")
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
data/spec/runner_spec.rb
CHANGED
@@ -5,20 +5,20 @@ require 'cane/runner'
|
|
5
5
|
describe Cane::Runner do
|
6
6
|
describe '#run' do
|
7
7
|
it 'returns true iff fewer violations than max allowed' do
|
8
|
-
described_class.new(checks: [], max_violations: 0).run.
|
9
|
-
described_class.new(checks: [], max_violations: -1).run.
|
8
|
+
expect(described_class.new(checks: [], max_violations: 0).run).to be
|
9
|
+
expect(described_class.new(checks: [], max_violations: -1).run).not_to be
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'returns JSON output' do
|
13
13
|
formatter = class_double("Cane::JsonFormatter").as_stubbed_const
|
14
|
-
formatter.
|
14
|
+
expect(formatter).to receive(:new).and_return("JSON")
|
15
15
|
buffer = StringIO.new("")
|
16
16
|
|
17
17
|
described_class.new(
|
18
18
|
out: buffer, checks: [], max_violations: 0, json: true
|
19
19
|
).run
|
20
20
|
|
21
|
-
buffer.string.
|
21
|
+
expect(buffer.string).to eq("JSON")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -37,15 +37,15 @@ end
|
|
37
37
|
RSpec::Matchers.define :have_violation do |label|
|
38
38
|
match do |check|
|
39
39
|
violations = check.violations
|
40
|
-
violations.length.
|
41
|
-
violations[0][:label].
|
40
|
+
expect(violations.length).to eq(1)
|
41
|
+
expect(violations[0][:label]).to eq(label)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
RSpec::Matchers.define :have_no_violations do |label|
|
46
46
|
match do |check|
|
47
47
|
violations = check.violations
|
48
|
-
violations.length.
|
48
|
+
expect(violations.length).to eq(0)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
data/spec/style_check_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe Cane::StyleCheck do
|
|
19
19
|
file_name = make_file(ruby_with_style_issue)
|
20
20
|
|
21
21
|
violations = check(file_name, style_measure: 8).violations
|
22
|
-
violations.length.
|
22
|
+
expect(violations.length).to eq(3)
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'skips declared exclusions' do
|
@@ -30,7 +30,7 @@ describe Cane::StyleCheck do
|
|
30
30
|
style_exclude: [file_name]
|
31
31
|
).violations
|
32
32
|
|
33
|
-
violations.length.
|
33
|
+
expect(violations.length).to eq(0)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'skips declared glob-based exclusions' do
|
@@ -41,7 +41,7 @@ describe Cane::StyleCheck do
|
|
41
41
|
style_exclude: ["#{File.dirname(file_name)}/*"]
|
42
42
|
).violations
|
43
43
|
|
44
|
-
violations.length.
|
44
|
+
expect(violations.length).to eq(0)
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'does not include trailing new lines in the character count' do
|
@@ -52,7 +52,38 @@ describe Cane::StyleCheck do
|
|
52
52
|
style_exclude: [file_name]
|
53
53
|
).violations
|
54
54
|
|
55
|
-
violations.length.
|
55
|
+
expect(violations.length).to eq(0)
|
56
56
|
end
|
57
57
|
|
58
|
+
describe "#file_list" do
|
59
|
+
context "style_glob is an array" do
|
60
|
+
it "returns an array of relative file paths" do
|
61
|
+
glob = [
|
62
|
+
'spec/fixtures/a/**/*.{rb,prawn}',
|
63
|
+
'spec/fixtures/b/**/*.haml'
|
64
|
+
]
|
65
|
+
check = described_class.new(style_glob: glob)
|
66
|
+
expect(check.send(:file_list)).to eq([
|
67
|
+
'spec/fixtures/a/1.rb',
|
68
|
+
'spec/fixtures/a/3.prawn',
|
69
|
+
'spec/fixtures/b/3/i.haml'
|
70
|
+
])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "style_exclude is an array" do
|
75
|
+
it "returns an array of relative file paths" do
|
76
|
+
glob = [
|
77
|
+
'spec/fixtures/a/**/*.{rb,prawn}',
|
78
|
+
'spec/fixtures/b/**/*.haml'
|
79
|
+
]
|
80
|
+
exclude = [
|
81
|
+
'spec/fixtures/a/**/*.prawn',
|
82
|
+
'spec/fixtures/b/**/*.haml'
|
83
|
+
]
|
84
|
+
check = described_class.new(style_exclude: exclude, style_glob: glob)
|
85
|
+
expect(check.send(:file_list)).to eq(['spec/fixtures/a/1.rb'])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
58
89
|
end
|
@@ -22,14 +22,14 @@ describe Cane::ThresholdCheck do
|
|
22
22
|
|
23
23
|
context "when the current coverage cannot be read" do
|
24
24
|
it do
|
25
|
-
run(:gte, 20).
|
25
|
+
expect(run(:gte, 20)).to \
|
26
26
|
have_violation('x is unavailable, should be >= 20.0')
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
context "when the coverage threshold is incorrectly specified" do
|
31
31
|
it do
|
32
|
-
described_class.new(gte: [['20', 'bogus_file']]).
|
32
|
+
expect(described_class.new(gte: [['20', 'bogus_file']])).to \
|
33
33
|
have_violation('bogus_file is not a number or a file')
|
34
34
|
end
|
35
35
|
end
|
@@ -38,37 +38,53 @@ describe Cane::ThresholdCheck do
|
|
38
38
|
before do
|
39
39
|
file = class_double("Cane::File").as_stubbed_const
|
40
40
|
stub_const("Cane::File", file)
|
41
|
-
file.
|
41
|
+
expect(file).to receive(:contents).with('x').and_return("8\n")
|
42
42
|
end
|
43
43
|
|
44
44
|
context '>' do
|
45
|
-
it { run(:gt, 7).
|
46
|
-
it {
|
47
|
-
|
45
|
+
it { expect(run(:gt, 7)).to have_no_violations }
|
46
|
+
it {
|
47
|
+
expect(run(:gt, 8)).to have_violation('x is 8.0, should be > 8.0')
|
48
|
+
}
|
49
|
+
it {
|
50
|
+
expect(run(:gt, 9)).to have_violation('x is 8.0, should be > 9.0')
|
51
|
+
}
|
48
52
|
end
|
49
53
|
|
50
54
|
context '>=' do
|
51
|
-
it { run(:gte, 7).
|
52
|
-
it { run(:gte, 8).
|
53
|
-
it {
|
55
|
+
it { expect(run(:gte, 7)).to have_no_violations }
|
56
|
+
it { expect(run(:gte, 8)).to have_no_violations }
|
57
|
+
it {
|
58
|
+
expect(run(:gte, 9)).to have_violation('x is 8.0, should be >= 9.0')
|
59
|
+
}
|
54
60
|
end
|
55
61
|
|
56
62
|
context '==' do
|
57
|
-
it {
|
58
|
-
|
59
|
-
|
63
|
+
it {
|
64
|
+
expect(run(:eq, 7)).to have_violation('x is 8.0, should be == 7.0')
|
65
|
+
}
|
66
|
+
it { expect(run(:eq, 8)).to have_no_violations }
|
67
|
+
it {
|
68
|
+
expect(run(:eq, 9)).to have_violation('x is 8.0, should be == 9.0')
|
69
|
+
}
|
60
70
|
end
|
61
71
|
|
62
72
|
context '<=' do
|
63
|
-
it {
|
64
|
-
|
65
|
-
|
73
|
+
it {
|
74
|
+
expect(run(:lte, 7)).to have_violation('x is 8.0, should be <= 7.0')
|
75
|
+
}
|
76
|
+
it { expect(run(:lte, 8)).to have_no_violations }
|
77
|
+
it { expect(run(:lte, 9)).to have_no_violations }
|
66
78
|
end
|
67
79
|
|
68
80
|
context '<' do
|
69
|
-
it {
|
70
|
-
|
71
|
-
|
81
|
+
it {
|
82
|
+
expect(run(:lt, 7)).to have_violation('x is 8.0, should be < 7.0')
|
83
|
+
}
|
84
|
+
it {
|
85
|
+
expect(run(:lt, 8)).to have_violation('x is 8.0, should be < 8.0')
|
86
|
+
}
|
87
|
+
it { expect(run(:lt, 9)).to have_no_violations }
|
72
88
|
end
|
73
89
|
end
|
74
90
|
|
@@ -76,25 +92,27 @@ describe Cane::ThresholdCheck do
|
|
76
92
|
|
77
93
|
context "normalizing a user supplied value to a threshold" do
|
78
94
|
it "normalizes an integer to itself" do
|
79
|
-
subject.normalized_limit(99).
|
95
|
+
expect(subject.normalized_limit(99)).to eq(99)
|
80
96
|
end
|
81
97
|
|
82
98
|
it "normalizes a float to itself" do
|
83
|
-
subject.normalized_limit(99.6).
|
99
|
+
expect(subject.normalized_limit(99.6)).to eq(99.6)
|
84
100
|
end
|
85
101
|
|
86
102
|
it "normalizes a valid file to its contents" do
|
87
|
-
subject.normalized_limit(make_file('99.5')).
|
103
|
+
expect(subject.normalized_limit(make_file('99.5'))).to eq(99.5)
|
88
104
|
end
|
89
105
|
|
90
106
|
it "normalizes an invalid file to an unavailable value" do
|
91
107
|
limit = subject.normalized_limit("/File.does.not.exist")
|
92
|
-
limit.
|
108
|
+
expect(limit).to be_a Cane::ThresholdCheck::UnavailableValue
|
93
109
|
end
|
94
110
|
|
95
111
|
|
96
112
|
it 'normalizes a json file to a float' do
|
97
|
-
subject.normalized_limit(make_file(simplecov_last_run)).
|
113
|
+
expect(subject.normalized_limit(make_file(simplecov_last_run))).to eq(
|
114
|
+
93.88
|
115
|
+
)
|
98
116
|
end
|
99
117
|
|
100
118
|
end
|
@@ -10,30 +10,30 @@ describe Cane::ViolationFormatter do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'includes number of violations in the group header' do
|
13
|
-
described_class.new([violation("FAIL")]).to_s.
|
13
|
+
expect(described_class.new([violation("FAIL")]).to_s).to include("(1)")
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'includes total number of violations' do
|
17
17
|
violations = [violation("FAIL1"), violation("FAIL2")]
|
18
18
|
result = described_class.new(violations).to_s
|
19
|
-
result.
|
19
|
+
expect(result).to include("Total Violations: 2")
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'does not colorize output by default' do
|
23
23
|
result = described_class.new([violation("FAIL")]).to_s
|
24
|
-
result.
|
24
|
+
expect(result).not_to include("\e[31m")
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'colorizes output when passed color: true' do
|
28
28
|
result = described_class.new([violation("FAIL")], color: true).to_s
|
29
|
-
result.
|
30
|
-
result.
|
29
|
+
expect(result).to include("\e[31m")
|
30
|
+
expect(result).to include("\e[0m")
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'does not colorize output if max_violations is not crossed' do
|
34
34
|
options = { color: true, max_violations: 1 }
|
35
35
|
result = described_class.new([violation("FAIL")], options).to_s
|
36
36
|
|
37
|
-
result.
|
37
|
+
expect(result).not_to include("\e[31m")
|
38
38
|
end
|
39
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Shay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel
|
@@ -116,6 +116,8 @@ files:
|
|
116
116
|
- spec/doc_check_spec.rb
|
117
117
|
- spec/encoding_aware_iterator_spec.rb
|
118
118
|
- spec/file_spec.rb
|
119
|
+
- spec/fixtures/a/1.rb
|
120
|
+
- spec/fixtures/b/1.rb
|
119
121
|
- spec/json_formatter_spec.rb
|
120
122
|
- spec/parser_spec.rb
|
121
123
|
- spec/rake_task_spec.rb
|
@@ -144,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
146
|
version: '0'
|
145
147
|
requirements: []
|
146
148
|
rubyforge_project:
|
147
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.4.5
|
148
150
|
signing_key:
|
149
151
|
specification_version: 4
|
150
152
|
summary: Fails your build if code quality thresholds are not met. Provides complexity
|
@@ -156,6 +158,8 @@ test_files:
|
|
156
158
|
- spec/doc_check_spec.rb
|
157
159
|
- spec/encoding_aware_iterator_spec.rb
|
158
160
|
- spec/file_spec.rb
|
161
|
+
- spec/fixtures/a/1.rb
|
162
|
+
- spec/fixtures/b/1.rb
|
159
163
|
- spec/json_formatter_spec.rb
|
160
164
|
- spec/parser_spec.rb
|
161
165
|
- spec/rake_task_spec.rb
|
@@ -164,4 +168,3 @@ test_files:
|
|
164
168
|
- spec/style_check_spec.rb
|
165
169
|
- spec/threshold_check_spec.rb
|
166
170
|
- spec/violation_formatter_spec.rb
|
167
|
-
has_rdoc: false
|