cane 2.6.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|