cuke_modeler 1.5.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CHANGELOG.md +10 -1
- data/LICENSE.txt +1 -1
- data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +1 -0
- data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +1 -0
- data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +1 -0
- data/lib/cuke_modeler/adapters/gherkin_6_adapter.rb +1 -0
- data/lib/cuke_modeler/containing.rb +1 -0
- data/lib/cuke_modeler/described.rb +1 -0
- data/lib/cuke_modeler/models/step.rb +31 -2
- data/lib/cuke_modeler/named.rb +1 -0
- data/lib/cuke_modeler/nested.rb +1 -0
- data/lib/cuke_modeler/parsed.rb +1 -0
- data/lib/cuke_modeler/parsing.rb +8 -0
- data/lib/cuke_modeler/sourceable.rb +1 -0
- data/lib/cuke_modeler/stepped.rb +1 -0
- data/lib/cuke_modeler/taggable.rb +1 -0
- data/lib/cuke_modeler/version.rb +1 -1
- data/testing/cucumber/features/analysis/step_comparison.feature +25 -0
- data/testing/cucumber/features/analysis/test_comparison.feature +1 -1
- data/testing/cucumber/step_definitions/modeling_steps.rb +5 -0
- data/testing/cucumber/step_definitions/verification_steps.rb +8 -0
- data/testing/rspec/spec/integration/models/step_integration_spec.rb +121 -27
- data/testing/rspec/spec/spec_helper.rb +11 -0
- data/testing/rspec/spec/unit/models/step_unit_spec.rb +1 -1
- data/todo.txt +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92ec631920bf8e2af7095588f0f85bf6f43e109737d39b7b2b92a5e71b00bd82
|
4
|
+
data.tar.gz: c8d6abcdf38a6d71a9281c841a60feb0cf839bfa4c13430009ab56458b7d7ac2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a96083807968d997553eb00ab15f1432e89d96527a0d8a814902c1410a87ea11232ff9de904a063782f5efad3aa6a35c6d9ddbd169e3e2bf248cd11c0ccd6710
|
7
|
+
data.tar.gz: 111e2d71eb17c5ac1cd4378bc92672eb76ac412dc6943fc29430eeb6aeacda2955f77171347e633e8fa71fef1a803913affb7a0994bb4e6fee6084e75bbdb760
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
8
8
|
|
9
9
|
Nothing yet...
|
10
10
|
|
11
|
+
|
12
|
+
## [2.0.0] - 2019-02-11
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
|
16
|
+
- Step models now include doc strings and tables when determining their equality with other steps. Previously, only the base text of the step was included and the doc string/table was explicitly ignored.
|
17
|
+
|
18
|
+
|
11
19
|
## [1.5.1] - 2019-04-14
|
12
20
|
|
13
21
|
### Added
|
@@ -269,7 +277,8 @@ Nothing yet...
|
|
269
277
|
- Initial release
|
270
278
|
|
271
279
|
|
272
|
-
[Unreleased]: https://github.com/enkessler/cuke_modeler/compare/
|
280
|
+
[Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v2.0.0...HEAD
|
281
|
+
[2.0.0]: https://github.com/enkessler/cuke_modeler/compare/v1.5.1...v2.0.0
|
273
282
|
[1.5.1]: https://github.com/enkessler/cuke_modeler/compare/v1.5.0...v1.5.1
|
274
283
|
[1.5.0]: https://github.com/enkessler/cuke_modeler/compare/v1.4.0...v1.5.0
|
275
284
|
[1.4.0]: https://github.com/enkessler/cuke_modeler/compare/v1.3.0...v1.4.0
|
data/LICENSE.txt
CHANGED
@@ -33,9 +33,11 @@ module CukeModeler
|
|
33
33
|
# Returns *true* if the two steps have the same base text (i.e. minus any keyword,
|
34
34
|
# table, or doc string and *false* otherwise.
|
35
35
|
def ==(other_step)
|
36
|
-
return false unless other_step.
|
36
|
+
return false unless other_step.is_a?(CukeModeler::Step)
|
37
37
|
|
38
|
-
|
38
|
+
text_matches?(other_step) &&
|
39
|
+
table_matches?(other_step) &&
|
40
|
+
doc_string_matches?(other_step)
|
39
41
|
end
|
40
42
|
|
41
43
|
# Returns the model objects that belong to this model.
|
@@ -65,5 +67,32 @@ module CukeModeler
|
|
65
67
|
parsed_file.first['feature']['elements'].first['steps'].first
|
66
68
|
end
|
67
69
|
|
70
|
+
def text_matches?(other_step)
|
71
|
+
text == other_step.text
|
72
|
+
end
|
73
|
+
|
74
|
+
def table_matches?(other_step)
|
75
|
+
return false if (!block.is_a?(CukeModeler::Table) || !other_step.block.is_a?(CukeModeler::Table)) && (block.is_a?(CukeModeler::Table) || other_step.block.is_a?(CukeModeler::Table))
|
76
|
+
return true unless block.is_a?(CukeModeler::Table) && other_step.block.is_a?(CukeModeler::Table)
|
77
|
+
|
78
|
+
first_step_values = block.rows.collect { |table_row| table_row.cells.map(&:value) }
|
79
|
+
second_step_values = other_step.block.rows.collect { |table_row| table_row.cells.map(&:value) }
|
80
|
+
|
81
|
+
first_step_values == second_step_values
|
82
|
+
end
|
83
|
+
|
84
|
+
def doc_string_matches?(other_step)
|
85
|
+
return false if (!block.is_a?(CukeModeler::DocString) || !other_step.block.is_a?(CukeModeler::DocString)) && (block.is_a?(CukeModeler::DocString) || other_step.block.is_a?(CukeModeler::DocString))
|
86
|
+
return true unless block.is_a?(CukeModeler::DocString) && other_step.block.is_a?(CukeModeler::DocString)
|
87
|
+
|
88
|
+
first_content = block.content
|
89
|
+
first_content_type = block.content_type
|
90
|
+
second_content = other_step.block.content
|
91
|
+
second_content_type = other_step.block.content_type
|
92
|
+
|
93
|
+
(first_content == second_content) &&
|
94
|
+
(first_content_type == second_content_type)
|
95
|
+
end
|
96
|
+
|
68
97
|
end
|
69
98
|
end
|
data/lib/cuke_modeler/named.rb
CHANGED
data/lib/cuke_modeler/nested.rb
CHANGED
data/lib/cuke_modeler/parsed.rb
CHANGED
data/lib/cuke_modeler/parsing.rb
CHANGED
@@ -30,6 +30,7 @@ module CukeModeler
|
|
30
30
|
require 'gherkin/gherkin'
|
31
31
|
require 'cuke_modeler/adapters/gherkin_6_adapter'
|
32
32
|
|
33
|
+
# NOT A PART OF THE PUBLIC API
|
33
34
|
# The method to use for parsing Gherkin text
|
34
35
|
def self.parsing_method(source_text, filename)
|
35
36
|
messages = Gherkin::Gherkin.from_source(filename, source_text, {:default_dialect => CukeModeler::Parsing.dialect}).to_a
|
@@ -37,6 +38,7 @@ module CukeModeler
|
|
37
38
|
messages.map(&:to_hash).find { |message| message[:gherkinDocument] }[:gherkinDocument]
|
38
39
|
end
|
39
40
|
|
41
|
+
# NOT A PART OF THE PUBLIC API
|
40
42
|
# The adapter to use when converting an AST to a standard internal shape
|
41
43
|
def self.adapter_class
|
42
44
|
CukeModeler::Gherkin6Adapter
|
@@ -48,12 +50,14 @@ module CukeModeler
|
|
48
50
|
|
49
51
|
|
50
52
|
# todo - make these methods private?
|
53
|
+
# NOT A PART OF THE PUBLIC API
|
51
54
|
# The method to use for parsing Gherkin text
|
52
55
|
# Filename isn't used by this version of Gherkin but keeping the parameter so that the calling method only has to know one method signature
|
53
56
|
def self.parsing_method(source_text, _filename)
|
54
57
|
Gherkin::Parser.new.parse(source_text)
|
55
58
|
end
|
56
59
|
|
60
|
+
# NOT A PART OF THE PUBLIC API
|
57
61
|
# The adapter to use when converting an AST to a standard internal shape
|
58
62
|
def self.adapter_class
|
59
63
|
CukeModeler::Gherkin4Adapter
|
@@ -64,12 +68,14 @@ module CukeModeler
|
|
64
68
|
require 'cuke_modeler/adapters/gherkin_3_adapter'
|
65
69
|
|
66
70
|
|
71
|
+
# NOT A PART OF THE PUBLIC API
|
67
72
|
# The method to use for parsing Gherkin text
|
68
73
|
# Filename isn't used by this version of Gherkin but keeping the parameter so that the calling method only has to know one method signature
|
69
74
|
def self.parsing_method(source_text, _filename)
|
70
75
|
Gherkin::Parser.new.parse(source_text)
|
71
76
|
end
|
72
77
|
|
78
|
+
# NOT A PART OF THE PUBLIC API
|
73
79
|
# The adapter to use when converting an AST to a standard internal shape
|
74
80
|
def self.adapter_class
|
75
81
|
CukeModeler::Gherkin3Adapter
|
@@ -83,6 +89,7 @@ module CukeModeler
|
|
83
89
|
require 'cuke_modeler/adapters/gherkin_2_adapter'
|
84
90
|
|
85
91
|
|
92
|
+
# NOT A PART OF THE PUBLIC API
|
86
93
|
# The method to use for parsing Gherkin text
|
87
94
|
def self.parsing_method(source_text, filename)
|
88
95
|
io = StringIO.new
|
@@ -93,6 +100,7 @@ module CukeModeler
|
|
93
100
|
MultiJson.load(io.string)
|
94
101
|
end
|
95
102
|
|
103
|
+
# NOT A PART OF THE PUBLIC API
|
96
104
|
# The adapter to use when converting an AST to a standard internal shape
|
97
105
|
def self.adapter_class
|
98
106
|
CukeModeler::Gherkin2Adapter
|
data/lib/cuke_modeler/stepped.rb
CHANGED
data/lib/cuke_modeler/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: Step comparison
|
2
|
+
|
3
|
+
Step comparison using `==` is done based on 'significant' properties. Keywords, being completely interchangeable, do not affect step equality.
|
4
|
+
|
5
|
+
|
6
|
+
Scenario: Comparison of steps
|
7
|
+
Given a model for the following step:
|
8
|
+
"""
|
9
|
+
Given a step
|
10
|
+
"""
|
11
|
+
And a model for the following step:
|
12
|
+
"""
|
13
|
+
When a step
|
14
|
+
"""
|
15
|
+
And a model for the following step:
|
16
|
+
"""
|
17
|
+
Then a step
|
18
|
+
"""
|
19
|
+
When the models are compared
|
20
|
+
Then all of them are equivalent
|
21
|
+
But none of the models are equivalent with a model for the following step:
|
22
|
+
"""
|
23
|
+
And a step
|
24
|
+
| plus this table |
|
25
|
+
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Feature: Test comparison
|
2
2
|
|
3
|
-
Gherkin elements that contain steps (i.e. backgrounds, scenarios, and outlines) can be compared with one another in order to determine equality. Elements are considered equal if
|
3
|
+
Gherkin elements that contain steps (i.e. backgrounds, scenarios, and outlines) can be compared with one another in order to determine equality. Elements are considered equal if their steps match (see step comparison). Properties that do not affect what a test *does* (e.g. name, description, tags) are ignored for the purposes of comparison.
|
4
4
|
|
5
5
|
|
6
6
|
Scenario: Comparing tests
|
@@ -42,3 +42,8 @@ Given(/^a model for the following outline:$/) do |gherkin_text|
|
|
42
42
|
@models ||= []
|
43
43
|
@models << CukeModeler::Outline.new(gherkin_text)
|
44
44
|
end
|
45
|
+
|
46
|
+
Given(/^a model for the following step:$/) do |gherkin_text|
|
47
|
+
@models ||= []
|
48
|
+
@models << CukeModeler::Step.new(gherkin_text)
|
49
|
+
end
|
@@ -166,6 +166,14 @@ But(/^none of the models are equivalent with a model for the following scenario:
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
|
+
But(/^none of the models are equivalent with a model for the following step:$/) do |gherkin_text|
|
170
|
+
model = CukeModeler::Step.new(gherkin_text)
|
171
|
+
|
172
|
+
@models.each do |other_model|
|
173
|
+
expect(model == other_model).to_not be true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
169
177
|
Then(/^the model returns models for the following comments:$/) do |model_values|
|
170
178
|
model_values = model_values.raw.flatten
|
171
179
|
|
@@ -206,46 +206,140 @@ describe 'Step, Integration' do
|
|
206
206
|
|
207
207
|
describe 'step comparison' do
|
208
208
|
|
209
|
-
|
210
|
-
source_1 = "#{STEP_KEYWORD} a step"
|
211
|
-
source_2 = "#{STEP_KEYWORD} a step"
|
212
|
-
source_3 = "#{STEP_KEYWORD} a different step"
|
209
|
+
context 'a step that has text' do
|
213
210
|
|
214
|
-
|
215
|
-
|
216
|
-
step_3 = clazz.new(source_3)
|
211
|
+
let(:step_text) { "#{STEP_KEYWORD} a step" }
|
212
|
+
let(:base_step) { clazz.new(step_text) }
|
217
213
|
|
214
|
+
context 'compared to a step that has the same text' do
|
218
215
|
|
219
|
-
|
220
|
-
expect(step_1).to_not eq(step_3)
|
221
|
-
end
|
216
|
+
let(:compared_step) { clazz.new(step_text) }
|
222
217
|
|
223
|
-
|
224
|
-
|
225
|
-
|
218
|
+
it 'considers them to be equal' do
|
219
|
+
assert_bidirectional_equality(base_step, compared_step)
|
220
|
+
end
|
226
221
|
|
227
|
-
|
228
|
-
step_2 = clazz.new(source_2)
|
222
|
+
end
|
229
223
|
|
224
|
+
context 'compared to a step that has different text' do
|
230
225
|
|
231
|
-
|
232
|
-
end
|
226
|
+
let(:compared_step) { clazz.new(step_text + ' plus some more') }
|
233
227
|
|
234
|
-
|
235
|
-
|
236
|
-
|
228
|
+
it 'considers them to not be equal' do
|
229
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
230
|
+
end
|
237
231
|
|
238
|
-
|
239
|
-
step_2 = clazz.new(source_2)
|
232
|
+
end
|
240
233
|
|
234
|
+
context 'compared to a step that has a table' do
|
241
235
|
|
242
|
-
|
243
|
-
|
236
|
+
let(:compared_step) { clazz.new(step_text + "\n | foo |") }
|
237
|
+
|
238
|
+
it 'considers them to not be equal' do
|
239
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'compared to a step that has a doc string' do
|
245
|
+
|
246
|
+
let(:compared_step) { clazz.new(step_text + "\n \"\"\"\n foo\n\"\"\"") }
|
247
|
+
|
248
|
+
it 'considers them to not be equal' do
|
249
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
context 'and has table' do
|
256
|
+
|
257
|
+
let(:step_text) { "#{STEP_KEYWORD} a step\n | foo |" }
|
258
|
+
let(:base_step) { clazz.new(step_text) }
|
259
|
+
|
260
|
+
context 'compared to a step that has the same table' do
|
261
|
+
|
262
|
+
let(:compared_step) { clazz.new(step_text) }
|
263
|
+
|
264
|
+
it 'considers them to be equal' do
|
265
|
+
assert_bidirectional_equality(base_step, compared_step)
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'compared to a step that has a different table' do
|
244
271
|
|
245
|
-
|
246
|
-
source_1 = "#{STEP_KEYWORD} a step"
|
247
|
-
source_2 = "#{STEP_KEYWORD} a step\n\"\"\"\nwith a doc string\n\"\"\""
|
272
|
+
let(:compared_step) { clazz.new(step_text + "\n | a different table |") }
|
248
273
|
|
274
|
+
it 'considers them to not be equal' do
|
275
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
context 'and has a doc string' do
|
284
|
+
|
285
|
+
let(:content) { 'foo' }
|
286
|
+
let(:base_step) { clazz.new("#{step_text}\n\"\"\"\n#{content}\n\"\"\"") }
|
287
|
+
|
288
|
+
context 'compared to a step that has the same doc string' do
|
289
|
+
|
290
|
+
let(:compared_step) { clazz.new("#{step_text}\n\"\"\"\n#{content}\n\"\"\"") }
|
291
|
+
|
292
|
+
it 'considers them to be equal' do
|
293
|
+
assert_bidirectional_equality(base_step, compared_step)
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'compared to a step that has a different doc string' do
|
299
|
+
|
300
|
+
let(:compared_step) { clazz.new("#{step_text}\n\"\"\"\n#{content + 'different'}\n\"\"\"") }
|
301
|
+
|
302
|
+
it 'considers them to not be equal' do
|
303
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'and has a content type' do
|
309
|
+
|
310
|
+
let(:content_type) { 'foo' }
|
311
|
+
let(:base_step) { clazz.new("#{step_text}\n\"\"\" #{content_type}\n#{content}\n\"\"\"") }
|
312
|
+
|
313
|
+
|
314
|
+
context 'compared to a step that has the same content type' do
|
315
|
+
|
316
|
+
let(:compared_step) { clazz.new("#{step_text}\n\"\"\" #{content_type}\n#{content}\n\"\"\"") }
|
317
|
+
|
318
|
+
it 'considers them to be equal' do
|
319
|
+
assert_bidirectional_equality(base_step, compared_step)
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
|
324
|
+
context 'compared to a step that has a different content type' do
|
325
|
+
|
326
|
+
let(:compared_step) { clazz.new("#{step_text}\n\"\"\" different #{content_type}\n#{content}\n\"\"\"") }
|
327
|
+
|
328
|
+
it 'considers them to not be equal' do
|
329
|
+
assert_bidirectional_inequality(base_step, compared_step)
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'ignores steps keywords when comparing steps' do
|
341
|
+
source_1 = "#{GIVEN_KEYWORD} a step"
|
342
|
+
source_2 = "#{THEN_KEYWORD} a step"
|
249
343
|
|
250
344
|
step_1 = clazz.new(source_1)
|
251
345
|
step_2 = clazz.new(source_2)
|
@@ -122,4 +122,15 @@ RSpec.configure do |config|
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
+
|
126
|
+
def assert_bidirectional_equality(base_thing, compared_thing)
|
127
|
+
expect(base_thing).to eq(compared_thing)
|
128
|
+
expect(compared_thing).to eq(base_thing)
|
129
|
+
end
|
130
|
+
|
131
|
+
def assert_bidirectional_inequality(base_thing, compared_thing)
|
132
|
+
expect(base_thing).to_not eq(compared_thing)
|
133
|
+
expect(compared_thing).to_not eq(base_thing)
|
134
|
+
end
|
135
|
+
|
125
136
|
end
|
@@ -98,7 +98,7 @@ describe 'Step, Unit', :unit_test => true do
|
|
98
98
|
|
99
99
|
it 'can gracefully be compared to other types of objects' do
|
100
100
|
# Some common types of object
|
101
|
-
[1, 'foo', :bar, [], {}].each do |thing|
|
101
|
+
[1, 'foo', :bar, [], {}, nil].each do |thing|
|
102
102
|
expect { step == thing }.to_not raise_error
|
103
103
|
expect(step == thing).to be false
|
104
104
|
end
|
data/todo.txt
CHANGED
@@ -5,8 +5,8 @@ Show less boilerplate code in the documentation
|
|
5
5
|
replace copying raw data during adaptation (all of the Marshal#load/#unload calls) with simply testing that modification never happens in order to increase performance?
|
6
6
|
|
7
7
|
|
8
|
-
document helper modules as not part of the public API
|
9
8
|
|
9
|
+
# todo - add compatibility with newer versions of Gherkin
|
10
10
|
# todo - incorporate cuke_modeler extensions from other projects
|
11
11
|
# todo - add plenty of testing around weird and minimal gherkin text for all models
|
12
12
|
# todo - add support for `Rule` keyword
|
@@ -22,3 +22,4 @@ replace joined array source text with single string source text/heredocs
|
|
22
22
|
unit testing around parsing/modeling cases (whitespace, indentation, minimalistic feature elements, etc.)
|
23
23
|
replace "\n" usages with the currently set record separator (i.e "\$" )
|
24
24
|
make sure that all classes and tests are covered and attaches to code coverage
|
25
|
+
- make an actual Gherkin 5 adapter (just inherit from the Gherkin 4 adapter)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuke_modeler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Kessler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gherkin
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- lib/cuke_modeler/stepped.rb
|
223
223
|
- lib/cuke_modeler/taggable.rb
|
224
224
|
- lib/cuke_modeler/version.rb
|
225
|
+
- testing/cucumber/features/analysis/step_comparison.feature
|
225
226
|
- testing/cucumber/features/analysis/test_comparison.feature
|
226
227
|
- testing/cucumber/features/modeling/background_modeling.feature
|
227
228
|
- testing/cucumber/features/modeling/background_output.feature
|