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.
@@ -1,4 +1,4 @@
1
1
  module CukeSlicer
2
2
  # The current version for the gem.
3
- VERSION = "1.0.0"
3
+ VERSION = "2.0.0"
4
4
  end
@@ -3,74 +3,93 @@ require 'spec_helper'
3
3
 
4
4
  describe 'Slicer, Integration' do
5
5
 
6
- let!(:clazz) { CukeSlicer::Slicer }
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
- before(:each) do
11
- file_text = "Feature: Test feature
12
-
13
- @tag
14
- Scenario: Test scenario
15
- * some step"
11
+ @tag
12
+ Scenario: Test scenario
13
+ * some step" }
16
14
 
17
- File.open(test_file, 'w') { |file| file.write(file_text) }
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
- it 'slicing returns a collection of test cases' do
24
- slice_output = slicer.slice(test_file)
22
+ describe 'output' do
25
23
 
26
- expect(slice_output).to be_an(Array)
27
- expect(slice_output).to_not be_empty
24
+ it 'slicing returns a collection of test source lines' do
25
+ slice_output = slicer.slice(test_file, :file_line)
28
26
 
29
- slice_output.each do |test_case|
30
- # Test cases come in 'file_path:line_number' format
31
- expect(test_case).to match(/^.+:\d+$/)
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/) }.to_not raise_error
131
- expect { slicer.slice(@default_file_directory, filter => ['@some_value', /some_pattern/]) }.to_not raise_error
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
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
 
4
4
  describe 'Slicer, Unit' do
5
5
 
6
- let!(:clazz) { CukeSlicer::Slicer }
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(-2)
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: 1.0.0
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-04-01 00:00:00.000000000 Z
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.24
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: