cuke_slicer 1.0.0 → 2.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.
- data/.travis.yml +7 -0
- data/Gemfile +2 -0
- data/History.rdoc +11 -0
- data/README.md +14 -1
- data/Rakefile +53 -49
- data/cuke_slicer.gemspec +1 -1
- data/features/step_definitions/action_steps.rb +12 -11
- data/features/step_definitions/setup_steps.rb +24 -0
- data/features/step_definitions/verification_steps.rb +11 -0
- data/features/test_case_extraction.feature +7 -1
- data/features/validation.feature +6 -0
- data/lib/cuke_slicer.rb +10 -10
- data/lib/cuke_slicer/collections/nested_tag_collection.rb +27 -0
- data/lib/cuke_slicer/collections/path_collection.rb +26 -0
- data/lib/cuke_slicer/collections/tag_collection.rb +28 -0
- data/lib/cuke_slicer/extractors/directory_extractor.rb +17 -0
- data/lib/cuke_slicer/extractors/file_extractor.rb +32 -0
- data/lib/cuke_slicer/filters/filter_set.rb +42 -0
- data/lib/cuke_slicer/helpers/extraction_helpers.rb +40 -0
- data/lib/cuke_slicer/helpers/filter_helpers.rb +60 -0
- data/lib/cuke_slicer/helpers/helpers.rb +21 -0
- data/lib/cuke_slicer/helpers/matching_helpers.rb +47 -0
- data/lib/cuke_slicer/slicer.rb +18 -194
- data/lib/cuke_slicer/version.rb +1 -1
- data/spec/slicer_integration_spec.rb +114 -43
- data/spec/slicer_unit_spec.rb +3 -3
- metadata +17 -10
data/lib/cuke_slicer/version.rb
CHANGED
@@ -3,74 +3,93 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe 'Slicer, Integration' do
|
5
5
|
|
6
|
-
let
|
6
|
+
let(:clazz) { CukeSlicer::Slicer }
|
7
7
|
let(:slicer) { clazz.new }
|
8
8
|
let(:test_file) { "#{@default_file_directory}/a_test.feature" }
|
9
|
+
let(:test_file_text) { "Feature: Test feature
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@tag
|
14
|
-
Scenario: Test scenario
|
15
|
-
* some step"
|
11
|
+
@tag
|
12
|
+
Scenario: Test scenario
|
13
|
+
* some step" }
|
16
14
|
|
17
|
-
|
15
|
+
before(:each) do
|
16
|
+
File.write(test_file, test_file_text)
|
18
17
|
end
|
19
18
|
|
20
19
|
|
21
20
|
describe 'slicing' do
|
22
21
|
|
23
|
-
|
24
|
-
slice_output = slicer.slice(test_file)
|
22
|
+
describe 'output' do
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
it 'slicing returns a collection of test source lines' do
|
25
|
+
slice_output = slicer.slice(test_file, :file_line)
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
expect(slice_output).to be_an(Array)
|
28
|
+
expect(slice_output).to_not be_empty
|
29
|
+
|
30
|
+
slice_output.each do |test_case|
|
31
|
+
# Test cases come in 'file_path:line_number' format
|
32
|
+
expect(test_case).to match(/^.+:\d+$/)
|
33
|
+
end
|
32
34
|
end
|
35
|
+
|
36
|
+
it 'slicing returns a collection of test objects' do
|
37
|
+
slice_output = slicer.slice(test_file, :test_object)
|
38
|
+
|
39
|
+
expect(slice_output).to be_an(Array)
|
40
|
+
expect(slice_output).to_not be_empty
|
41
|
+
|
42
|
+
slice_output.each do |test_case|
|
43
|
+
# Test cases come as test objects
|
44
|
+
expect(test_case).to be_a(CukeModeler::Scenario).or be_a(CukeModeler::Row)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'complains if told to provide output in an unknown format' do
|
49
|
+
expect { slicer.slice(test_file, :bad_option) }.to raise_error(ArgumentError, /Invalid Output Format/)
|
50
|
+
end
|
51
|
+
|
33
52
|
end
|
34
53
|
|
35
54
|
it 'can slice without being provided filters' do
|
36
|
-
expect { slicer.slice(test_file) }.to_not raise_error
|
55
|
+
expect { slicer.slice(test_file, :file_line) }.to_not raise_error
|
37
56
|
end
|
38
57
|
|
39
58
|
it 'uses the custom filter, if provided' do
|
40
|
-
expect { |test_block| slicer.slice(@default_file_directory, &test_block) }.to yield_control
|
41
|
-
expect { slicer.slice(@default_file_directory) }.to_not raise_error
|
59
|
+
expect { |test_block| slicer.slice(@default_file_directory, :file_line, &test_block) }.to yield_control
|
60
|
+
expect { slicer.slice(@default_file_directory, :file_line) }.to_not raise_error
|
42
61
|
end
|
43
62
|
|
44
63
|
it 'can slice an empty feature file' do
|
45
64
|
File.open(test_file, 'w') { |file| file.write('') }
|
46
65
|
|
47
|
-
expect { slicer.slice(test_file) }.to_not raise_error
|
66
|
+
expect { slicer.slice(test_file, :file_line) }.to_not raise_error
|
48
67
|
end
|
49
68
|
|
50
69
|
it 'can slice a feature that has no tests' do
|
51
70
|
File.open(test_file, 'w') { |file| file.write('Feature: Empty feature') }
|
52
71
|
|
53
|
-
expect { slicer.slice(test_file) }.to_not raise_error
|
72
|
+
expect { slicer.slice(test_file, :file_line) }.to_not raise_error
|
54
73
|
end
|
55
74
|
|
56
75
|
it 'can slice a directory that contains non-feature files' do
|
57
76
|
File.open("#{@default_file_directory}/not_a_feature.file", 'w') { |file| file.write('foobar') }
|
58
77
|
|
59
|
-
expect { slicer.slice(@default_file_directory) }.to_not raise_error
|
78
|
+
expect { slicer.slice(@default_file_directory, :file_line) }.to_not raise_error
|
60
79
|
end
|
61
80
|
|
62
81
|
|
63
82
|
describe 'target validation' do
|
64
83
|
|
65
84
|
it 'complains if told to slice a non-existent location' do
|
66
|
-
expect { slicer.slice('does/not/exist') }.to raise_error(ArgumentError, /does not exist/)
|
67
|
-
expect { slicer.slice(nil) }.to raise_error(ArgumentError, /does not exist/)
|
85
|
+
expect { slicer.slice('does/not/exist', :file_line) }.to raise_error(ArgumentError, /does not exist/)
|
86
|
+
expect { slicer.slice(nil, :file_line) }.to raise_error(ArgumentError, /does not exist/)
|
68
87
|
end
|
69
88
|
|
70
89
|
it 'complains if told to slice an incorrectly formatted feature file' do
|
71
90
|
File.open(test_file, 'w') { |file| file.write('foobar') }
|
72
91
|
|
73
|
-
expect { slicer.slice(test_file) }.to raise_error(ArgumentError, /syntax.*lexing problem.*#{test_file}/i)
|
92
|
+
expect { slicer.slice(test_file, :file_line) }.to raise_error(ArgumentError, /syntax.*lexing problem.*#{test_file}/i)
|
74
93
|
end
|
75
94
|
|
76
95
|
end
|
@@ -84,13 +103,13 @@ describe 'Slicer, Integration' do
|
|
84
103
|
filters = clazz.known_filters
|
85
104
|
|
86
105
|
filters.each do |filter|
|
87
|
-
not_provided = slicer.slice(test_file)
|
106
|
+
not_provided = slicer.slice(test_file, :file_line)
|
88
107
|
|
89
108
|
case
|
90
109
|
when filter.to_s =~ /path/
|
91
|
-
nothing_provided = slicer.slice(test_file, filter => [])
|
110
|
+
nothing_provided = slicer.slice(test_file, {filter => []}, :file_line)
|
92
111
|
when filter.to_s =~ /tag/
|
93
|
-
nothing_provided = slicer.slice(test_file, filter => [])
|
112
|
+
nothing_provided = slicer.slice(test_file, {filter => []}, :file_line)
|
94
113
|
else
|
95
114
|
raise(ArgumentError, "Unknown filter '#{filter}'")
|
96
115
|
end
|
@@ -114,7 +133,7 @@ describe 'Slicer, Integration' do
|
|
114
133
|
expect(applied_filters.keys).to match_array(filters)
|
115
134
|
|
116
135
|
|
117
|
-
expect { @slice_output = slicer.slice(@default_file_directory, applied_filters, &block_filter) }.to_not raise_error
|
136
|
+
expect { @slice_output = slicer.slice(@default_file_directory, applied_filters, :file_line, &block_filter) }.to_not raise_error
|
118
137
|
expect(@slice_output).to be_an(Array)
|
119
138
|
expect(@slice_output).to_not be_empty
|
120
139
|
end
|
@@ -126,11 +145,11 @@ describe 'Slicer, Integration' do
|
|
126
145
|
path_filter_types = clazz.known_filters.select { |filter| filter.to_s =~ /path/ }
|
127
146
|
|
128
147
|
path_filter_types.each do |filter|
|
129
|
-
expect { slicer.slice(@default_file_directory, filter => '@some_value') }.to_not raise_error
|
130
|
-
expect { slicer.slice(@default_file_directory, filter => /some_pattern/)
|
131
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', /some_pattern/])
|
132
|
-
expect { slicer.slice(@default_file_directory, filter => :something_else) }.to raise_error(ArgumentError, /must be a/i)
|
133
|
-
expect { slicer.slice(@default_file_directory, filter => [:something_else]) }.to raise_error(ArgumentError, /must be a/i)
|
148
|
+
expect { slicer.slice(@default_file_directory, {filter => '@some_value'}, :file_line) }.to_not raise_error
|
149
|
+
expect { slicer.slice(@default_file_directory, {filter => /some_pattern/}, :file_line)}.to_not raise_error
|
150
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', /some_pattern/]}, :file_line)}.to_not raise_error
|
151
|
+
expect { slicer.slice(@default_file_directory, {filter => :something_else}, :file_line) }.to raise_error(ArgumentError, /must be a/i)
|
152
|
+
expect { slicer.slice(@default_file_directory, {filter => [:something_else]}, :file_line) }.to raise_error(ArgumentError, /must be a/i)
|
134
153
|
end
|
135
154
|
end
|
136
155
|
|
@@ -138,13 +157,13 @@ describe 'Slicer, Integration' do
|
|
138
157
|
tag_filter_types = clazz.known_filters.select { |filter| filter.to_s =~ /tag/ }
|
139
158
|
|
140
159
|
tag_filter_types.each do |filter|
|
141
|
-
expect { slicer.slice(@default_file_directory, filter => '@some_value') }.to_not raise_error
|
142
|
-
expect { slicer.slice(@default_file_directory, filter => /some_pattern/) }.to_not raise_error
|
143
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', /some_pattern/]) }.to_not raise_error
|
144
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', [/nested_pattern/]]) }.to_not raise_error
|
145
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', [/nested_pattern/, :bad_value]]) }.to raise_error(ArgumentError, /must be a/i)
|
146
|
-
expect { slicer.slice(@default_file_directory, filter => :something_else) }.to raise_error(ArgumentError, /must be a/i)
|
147
|
-
expect { slicer.slice(@default_file_directory, filter => [:something_else]) }.to raise_error(ArgumentError, /must be a/i)
|
160
|
+
expect { slicer.slice(@default_file_directory, {filter => '@some_value'}, :file_line) }.to_not raise_error
|
161
|
+
expect { slicer.slice(@default_file_directory, {filter => /some_pattern/}, :file_line) }.to_not raise_error
|
162
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', /some_pattern/]}, :file_line) }.to_not raise_error
|
163
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', [/nested_pattern/]]}, :file_line) }.to_not raise_error
|
164
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', [/nested_pattern/, :bad_value]]}, :file_line) }.to raise_error(ArgumentError, /must be a/i)
|
165
|
+
expect { slicer.slice(@default_file_directory, {filter => :something_else}, :file_line) }.to raise_error(ArgumentError, /must be a/i)
|
166
|
+
expect { slicer.slice(@default_file_directory, {filter => [:something_else]}, :file_line) }.to raise_error(ArgumentError, /must be a/i)
|
148
167
|
end
|
149
168
|
end
|
150
169
|
|
@@ -152,8 +171,8 @@ describe 'Slicer, Integration' do
|
|
152
171
|
tag_filter_types = clazz.known_filters.select { |filter| filter.to_s =~ /tag/ }
|
153
172
|
|
154
173
|
tag_filter_types.each do |filter|
|
155
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', [/nested_pattern/]]) }.to_not raise_error
|
156
|
-
expect { slicer.slice(@default_file_directory, filter => ['@some_value', [/nested_pattern/, ['way_too_nested']]]) }.to raise_error(ArgumentError, /cannot.* nested/i)
|
174
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', [/nested_pattern/]]}, :file_line) }.to_not raise_error
|
175
|
+
expect { slicer.slice(@default_file_directory, {filter => ['@some_value', [/nested_pattern/, ['way_too_nested']]]}, :file_line) }.to raise_error(ArgumentError, /cannot.* nested/i)
|
157
176
|
end
|
158
177
|
end
|
159
178
|
|
@@ -161,11 +180,63 @@ describe 'Slicer, Integration' do
|
|
161
180
|
unknown_filter_type = :unknown_filter
|
162
181
|
options = {unknown_filter_type => 'foo'}
|
163
182
|
|
164
|
-
expect { slicer.slice(@default_file_directory, options) }.to raise_error(ArgumentError, /unknown filter.*#{unknown_filter_type}/i)
|
183
|
+
expect { slicer.slice(@default_file_directory, options, :file_line) }.to raise_error(ArgumentError, /unknown filter.*#{unknown_filter_type}/i)
|
165
184
|
end
|
166
185
|
|
167
186
|
end
|
168
187
|
|
169
188
|
end
|
170
189
|
|
190
|
+
describe "bugs that we don't want to happen again" do
|
191
|
+
|
192
|
+
|
193
|
+
# As a nested directory structure was being traversed for slicing, the extraction algorithm was mangling the
|
194
|
+
# current file path such that it would sometimes attempt to search non-existent locations. Sometimes this
|
195
|
+
# resulted in an exception and sometimes this resulted in files getting silently skipped over.
|
196
|
+
|
197
|
+
|
198
|
+
it 'can handle a realistically nested directory structure' do
|
199
|
+
root_directory = @default_file_directory
|
200
|
+
|
201
|
+
# Outer 'before' hook already makes a root level feature file
|
202
|
+
expected_tests = ["#{test_file}:4"]
|
203
|
+
|
204
|
+
# Adding a nested directory
|
205
|
+
nested_directory_1 = "#{root_directory}/nested_directory_1"
|
206
|
+
FileUtils.mkpath(nested_directory_1)
|
207
|
+
test_file = "#{nested_directory_1}/nested_file_1.feature"
|
208
|
+
File.write(test_file, test_file_text)
|
209
|
+
expected_tests << "#{test_file}:4"
|
210
|
+
test_file = "#{nested_directory_1}/nested_file_2.feature"
|
211
|
+
File.write(test_file, test_file_text)
|
212
|
+
expected_tests << "#{test_file}:4"
|
213
|
+
|
214
|
+
# And another one
|
215
|
+
nested_directory_2 = "#{root_directory}/nested_directory_2"
|
216
|
+
FileUtils.mkpath(nested_directory_2)
|
217
|
+
test_file = "#{nested_directory_2}/nested_file_1.feature"
|
218
|
+
File.write(test_file, test_file_text)
|
219
|
+
expected_tests << "#{test_file}:4"
|
220
|
+
test_file = "#{nested_directory_2}/nested_file_2.feature"
|
221
|
+
File.write(test_file, test_file_text)
|
222
|
+
expected_tests << "#{test_file}:4"
|
223
|
+
|
224
|
+
# And one of them has another directory inside of it
|
225
|
+
doubly_nested_directory = "#{nested_directory_1}/doubly_nested_directory"
|
226
|
+
FileUtils.mkpath(doubly_nested_directory)
|
227
|
+
test_file = "#{doubly_nested_directory}/doubly_nested_file_1.feature"
|
228
|
+
File.write(test_file, test_file_text)
|
229
|
+
expected_tests << "#{test_file}:4"
|
230
|
+
test_file = "#{doubly_nested_directory}/doubly_nested_file_2.feature"
|
231
|
+
File.write(test_file, test_file_text)
|
232
|
+
expected_tests << "#{test_file}:4"
|
233
|
+
|
234
|
+
|
235
|
+
# No problems, no missed files
|
236
|
+
expect { @slice_output = slicer.slice(root_directory, :file_line) }.to_not raise_error
|
237
|
+
expect(@slice_output).to match_array(expected_tests)
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
171
242
|
end
|
data/spec/slicer_unit_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe 'Slicer, Unit' do
|
5
5
|
|
6
|
-
let
|
6
|
+
let(:clazz) { CukeSlicer::Slicer }
|
7
7
|
let(:slicer) { clazz.new }
|
8
8
|
|
9
9
|
|
@@ -15,8 +15,8 @@ describe 'Slicer, Unit' do
|
|
15
15
|
expect(slicer).to respond_to(:slice)
|
16
16
|
end
|
17
17
|
|
18
|
-
it 'needs something to slice up and can optionally have applicable filters' do
|
19
|
-
expect(slicer.method(:slice).arity).to eq(-
|
18
|
+
it 'needs something to slice up, an output format, and can optionally have applicable filters' do
|
19
|
+
expect(slicer.method(:slice).arity).to eq(-3)
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'knows what slice filters are available for use' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuke_slicer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-07-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cuke_modeler
|
@@ -116,7 +116,9 @@ extra_rdoc_files: []
|
|
116
116
|
files:
|
117
117
|
- .gitignore
|
118
118
|
- .simplecov
|
119
|
+
- .travis.yml
|
119
120
|
- Gemfile
|
121
|
+
- History.rdoc
|
120
122
|
- LICENSE.txt
|
121
123
|
- README.md
|
122
124
|
- Rakefile
|
@@ -130,13 +132,23 @@ files:
|
|
130
132
|
- features/test_case_filtering.feature
|
131
133
|
- features/validation.feature
|
132
134
|
- lib/cuke_slicer.rb
|
135
|
+
- lib/cuke_slicer/collections/nested_tag_collection.rb
|
136
|
+
- lib/cuke_slicer/collections/path_collection.rb
|
137
|
+
- lib/cuke_slicer/collections/tag_collection.rb
|
138
|
+
- lib/cuke_slicer/extractors/directory_extractor.rb
|
139
|
+
- lib/cuke_slicer/extractors/file_extractor.rb
|
140
|
+
- lib/cuke_slicer/filters/filter_set.rb
|
141
|
+
- lib/cuke_slicer/helpers/extraction_helpers.rb
|
142
|
+
- lib/cuke_slicer/helpers/filter_helpers.rb
|
143
|
+
- lib/cuke_slicer/helpers/helpers.rb
|
144
|
+
- lib/cuke_slicer/helpers/matching_helpers.rb
|
133
145
|
- lib/cuke_slicer/slicer.rb
|
134
146
|
- lib/cuke_slicer/version.rb
|
135
147
|
- spec/cuke_slicer_spec.rb
|
136
148
|
- spec/slicer_integration_spec.rb
|
137
149
|
- spec/slicer_unit_spec.rb
|
138
150
|
- spec/spec_helper.rb
|
139
|
-
homepage:
|
151
|
+
homepage: https://github.com/grange-insurance/cuke_slicer
|
140
152
|
licenses:
|
141
153
|
- MIT
|
142
154
|
post_install_message:
|
@@ -149,21 +161,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
161
|
- - ! '>='
|
150
162
|
- !ruby/object:Gem::Version
|
151
163
|
version: '0'
|
152
|
-
segments:
|
153
|
-
- 0
|
154
|
-
hash: -1021242189
|
155
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
165
|
none: false
|
157
166
|
requirements:
|
158
167
|
- - ! '>='
|
159
168
|
- !ruby/object:Gem::Version
|
160
169
|
version: '0'
|
161
|
-
segments:
|
162
|
-
- 0
|
163
|
-
hash: -1021242189
|
164
170
|
requirements: []
|
165
171
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.8.
|
172
|
+
rubygems_version: 1.8.28
|
167
173
|
signing_key:
|
168
174
|
specification_version: 3
|
169
175
|
summary: A gem for extracting test cases from a Cucumber test suite.
|
@@ -180,3 +186,4 @@ test_files:
|
|
180
186
|
- spec/slicer_integration_spec.rb
|
181
187
|
- spec/slicer_unit_spec.rb
|
182
188
|
- spec/spec_helper.rb
|
189
|
+
has_rdoc:
|