cuke_modeler 1.1.1 → 1.2.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 +5 -0
- data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +77 -22
- data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +25 -1
- data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +25 -1
- data/lib/cuke_modeler/containing.rb +15 -0
- data/lib/cuke_modeler/models/background.rb +1 -1
- data/lib/cuke_modeler/models/cell.rb +1 -1
- data/lib/cuke_modeler/models/comment.rb +47 -0
- data/lib/cuke_modeler/models/directory.rb +2 -5
- data/lib/cuke_modeler/models/doc_string.rb +1 -1
- data/lib/cuke_modeler/models/example.rb +1 -1
- data/lib/cuke_modeler/models/feature.rb +1 -1
- data/lib/cuke_modeler/models/feature_file.rb +8 -5
- data/lib/cuke_modeler/models/outline.rb +1 -1
- data/lib/cuke_modeler/models/row.rb +1 -1
- data/lib/cuke_modeler/models/scenario.rb +1 -1
- data/lib/cuke_modeler/models/step.rb +1 -1
- data/lib/cuke_modeler/models/table.rb +1 -1
- data/lib/cuke_modeler/models/tag.rb +1 -1
- data/lib/cuke_modeler/version.rb +1 -1
- data/lib/cuke_modeler.rb +1 -0
- data/testing/cucumber/features/modeling/comment_modeling.feature +43 -0
- data/testing/cucumber/features/modeling/comment_output.feature +27 -0
- data/testing/cucumber/features/modeling/feature_file_modeling.feature +11 -0
- data/testing/cucumber/features/modeling/model_structure.feature +2 -2
- data/testing/cucumber/features/modeling/tag_output.feature +1 -1
- data/testing/cucumber/step_definitions/feature_file_steps.rb +10 -0
- data/testing/cucumber/step_definitions/setup_steps.rb +6 -0
- data/testing/cucumber/step_definitions/verification_steps.rb +7 -1
- data/testing/rspec/spec/integration/comment_integration_spec.rb +168 -0
- data/testing/rspec/spec/integration/feature_file_integration_spec.rb +124 -0
- data/testing/rspec/spec/integration/gherkin_2_adapter_spec.rb +36 -3
- data/testing/rspec/spec/integration/gherkin_3_adapter_spec.rb +28 -4
- data/testing/rspec/spec/integration/gherkin_4_adapter_spec.rb +28 -3
- data/testing/rspec/spec/integration/parsing_integration_spec.rb +1 -0
- data/testing/rspec/spec/unit/comment_unit_spec.rb +74 -0
- data/testing/rspec/spec/unit/feature_file_unit_spec.rb +18 -0
- data/todo.txt +2 -0
- metadata +7 -2
@@ -80,13 +80,10 @@ module CukeModeler
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def process_feature_file(file_path)
|
83
|
-
feature_file_data = {'path' => file_path}
|
84
|
-
|
85
83
|
source_text = IO.read(file_path)
|
86
|
-
feature = Parsing::parse_text(source_text, file_path).first
|
87
|
-
|
88
|
-
feature_file_data['feature'] = feature
|
89
84
|
|
85
|
+
feature_file_data = Parsing::parse_text(source_text, file_path).first
|
86
|
+
feature_file_data = feature_file_data.merge({'path' => file_path})
|
90
87
|
|
91
88
|
feature_file_data
|
92
89
|
end
|
@@ -45,7 +45,7 @@ module CukeModeler
|
|
45
45
|
|
46
46
|
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_doc_string.feature')
|
47
47
|
|
48
|
-
parsed_file.first['elements'].first['steps'].first['doc_string']
|
48
|
+
parsed_file.first['feature']['elements'].first['steps'].first['doc_string']
|
49
49
|
end
|
50
50
|
|
51
51
|
def content_type_output_string
|
@@ -124,7 +124,7 @@ module CukeModeler
|
|
124
124
|
|
125
125
|
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_example.feature')
|
126
126
|
|
127
|
-
parsed_file.first['elements'].first['examples'].first
|
127
|
+
parsed_file.first['feature']['elements'].first['examples'].first
|
128
128
|
end
|
129
129
|
|
130
130
|
def determine_buffer_size(index)
|
@@ -4,6 +4,11 @@ module CukeModeler
|
|
4
4
|
|
5
5
|
class FeatureFile < Model
|
6
6
|
|
7
|
+
include Parsed
|
8
|
+
|
9
|
+
|
10
|
+
# The comment models contained by the modeled feature file
|
11
|
+
attr_accessor :comments
|
7
12
|
|
8
13
|
# The feature model contained by the modeled feature file
|
9
14
|
attr_accessor :feature
|
@@ -16,6 +21,7 @@ module CukeModeler
|
|
16
21
|
# populates the object.
|
17
22
|
def initialize(file_path = nil)
|
18
23
|
@path = file_path
|
24
|
+
@comments = []
|
19
25
|
|
20
26
|
super(file_path)
|
21
27
|
|
@@ -49,13 +55,10 @@ module CukeModeler
|
|
49
55
|
|
50
56
|
|
51
57
|
def process_feature_file(file_path)
|
52
|
-
feature_file_data = {'path' => file_path}
|
53
|
-
|
54
58
|
source_text = IO.read(file_path)
|
55
|
-
feature = Parsing::parse_text(source_text, file_path).first
|
56
|
-
|
57
|
-
feature_file_data['feature'] = feature
|
58
59
|
|
60
|
+
feature_file_data = Parsing::parse_text(source_text, file_path).first
|
61
|
+
feature_file_data = feature_file_data.merge({'path' => file_path})
|
59
62
|
|
60
63
|
feature_file_data
|
61
64
|
end
|
@@ -43,7 +43,7 @@ module CukeModeler
|
|
43
43
|
|
44
44
|
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_row.feature')
|
45
45
|
|
46
|
-
parsed_file.first['elements'].first['steps'].first['table']['rows'].first
|
46
|
+
parsed_file.first['feature']['elements'].first['steps'].first['table']['rows'].first
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
@@ -47,7 +47,7 @@ module CukeModeler
|
|
47
47
|
|
48
48
|
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_table.feature')
|
49
49
|
|
50
|
-
parsed_file.first['elements'].first['steps'].first['table']
|
50
|
+
parsed_file.first['feature']['elements'].first['steps'].first['table']
|
51
51
|
end
|
52
52
|
|
53
53
|
def row_output_string(row)
|
data/lib/cuke_modeler/version.rb
CHANGED
data/lib/cuke_modeler.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
Feature: Comment modeling
|
2
|
+
|
3
|
+
Comment models represent a comment portion of a feature. They expose several attributes of the comment
|
4
|
+
that they represent.
|
5
|
+
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given the following gherkin:
|
9
|
+
"""
|
10
|
+
# a comment
|
11
|
+
"""
|
12
|
+
And a comment model based on that gherkin
|
13
|
+
"""
|
14
|
+
@model = CukeModeler::Comment.new(<source_text>)
|
15
|
+
"""
|
16
|
+
|
17
|
+
|
18
|
+
Scenario: Modeling a comments text
|
19
|
+
When the comment's text is requested
|
20
|
+
"""
|
21
|
+
@model.text
|
22
|
+
"""
|
23
|
+
Then the model returns "# a comment"
|
24
|
+
|
25
|
+
Scenario: Modeling a comment's source line
|
26
|
+
Given a feature file with the following gherkin:
|
27
|
+
"""
|
28
|
+
# a comment
|
29
|
+
Feature:
|
30
|
+
"""
|
31
|
+
And a feature file model based on that file
|
32
|
+
"""
|
33
|
+
@model = CukeModeler::FeatureFile.new(<file_path>)
|
34
|
+
"""
|
35
|
+
And the comment model of that feature file model
|
36
|
+
"""
|
37
|
+
@model = @model.comments.first
|
38
|
+
"""
|
39
|
+
When the comment's source line is requested
|
40
|
+
"""
|
41
|
+
@model.source_line
|
42
|
+
"""
|
43
|
+
Then the model returns "1"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Comment output
|
2
|
+
|
3
|
+
A comment model's string output is a Gherkin representation of itself. As such, output from a comment model can be used as
|
4
|
+
input for the same kind of model.
|
5
|
+
|
6
|
+
|
7
|
+
Scenario: Outputting a comment model
|
8
|
+
Given the following gherkin:
|
9
|
+
"""
|
10
|
+
# a comment
|
11
|
+
"""
|
12
|
+
And a comment model based on that gherkin
|
13
|
+
"""
|
14
|
+
@model = CukeModeler::Comment.new(<source_text>)
|
15
|
+
"""
|
16
|
+
When the model is output as a string
|
17
|
+
"""
|
18
|
+
@model.to_s
|
19
|
+
"""
|
20
|
+
Then the following text is provided:
|
21
|
+
"""
|
22
|
+
# a comment
|
23
|
+
"""
|
24
|
+
And the output can be used to make an equivalent model
|
25
|
+
"""
|
26
|
+
CukeModeler::Comment.new(@model.to_s)
|
27
|
+
"""
|
@@ -9,6 +9,8 @@ Feature: Feature file modeling
|
|
9
9
|
Given the directory "test_directory"
|
10
10
|
And the file "test_directory/foo.feature":
|
11
11
|
"""
|
12
|
+
# A comment
|
13
|
+
# Another comment
|
12
14
|
Feature: Bar
|
13
15
|
"""
|
14
16
|
And the feature file is modeled
|
@@ -31,6 +33,15 @@ Feature: Feature file modeling
|
|
31
33
|
"""
|
32
34
|
Then the model returns "foo.feature"
|
33
35
|
|
36
|
+
Scenario: Modeling a feature file's comments
|
37
|
+
When the feature file's comments are requested
|
38
|
+
"""
|
39
|
+
@model.comments
|
40
|
+
"""
|
41
|
+
Then the model returns models for the following comments:
|
42
|
+
| # A comment |
|
43
|
+
| # Another comment |
|
44
|
+
|
34
45
|
Scenario: Modeling a feature file's feature
|
35
46
|
When the feature file's feature is requested
|
36
47
|
"""
|
@@ -36,8 +36,8 @@ being populated dynamically based on an actual test suite.
|
|
36
36
|
|
37
37
|
Scenario: Accessing the parsing data
|
38
38
|
|
39
|
-
Note: Directory
|
40
|
-
does not come into play until the feature level of modeling.
|
39
|
+
Note: Directory models do not store any parsing data because parsing Gherkin source text
|
40
|
+
does not come into play until the feature file level of modeling.
|
41
41
|
|
42
42
|
Given the models provided by CukeModeler
|
43
43
|
Then all of them provide access to the parsing data that was used to create them
|
@@ -4,3 +4,13 @@ Given(/^a feature file model based on "([^"]*)"$/) do |file_name|
|
|
4
4
|
|
5
5
|
@model = CukeModeler::FeatureFile.new(file_path)
|
6
6
|
end
|
7
|
+
|
8
|
+
And(/^a feature file model based on that file$/) do |code_text|
|
9
|
+
code_text.gsub!('<file_path>', "'#{@file_path}'")
|
10
|
+
|
11
|
+
eval(code_text)
|
12
|
+
end
|
13
|
+
|
14
|
+
And(/^the comment model of that feature file model$/) do |code_text|
|
15
|
+
eval(code_text)
|
16
|
+
end
|
@@ -26,3 +26,9 @@ end
|
|
26
26
|
Given(/^the following gherkin:$/) do |text|
|
27
27
|
@source_text = text
|
28
28
|
end
|
29
|
+
|
30
|
+
Given(/^a feature file with the following gherkin:$/) do |file_text|
|
31
|
+
@file_path = "#{@default_file_directory}/#{@default_feature_file_name}"
|
32
|
+
|
33
|
+
File.open(@file_path, 'w') { |file| file.write(file_text) }
|
34
|
+
end
|
@@ -94,7 +94,7 @@ end
|
|
94
94
|
|
95
95
|
Then(/^all of them provide access to the parsing data that was used to create them$/) do |code_text|
|
96
96
|
original_text = code_text
|
97
|
-
unparsed_models = [CukeModeler::Model, CukeModeler::
|
97
|
+
unparsed_models = [CukeModeler::Model, CukeModeler::Directory]
|
98
98
|
|
99
99
|
@available_model_classes.each do |clazz|
|
100
100
|
next if unparsed_models.include?(clazz)
|
@@ -164,3 +164,9 @@ But(/^none of the models are equivalent with a model for the following scenario:
|
|
164
164
|
expect(model == other_model).to_not be true
|
165
165
|
end
|
166
166
|
end
|
167
|
+
|
168
|
+
Then(/^the model returns models for the following comments:$/) do |model_values|
|
169
|
+
model_values = model_values.raw.flatten
|
170
|
+
|
171
|
+
expect(@result.collect { |model| model.text }).to eq(model_values)
|
172
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../spec_helper"
|
2
|
+
|
3
|
+
|
4
|
+
describe 'Comment, Integration' do
|
5
|
+
|
6
|
+
let(:clazz) { CukeModeler::Comment }
|
7
|
+
|
8
|
+
|
9
|
+
describe 'common behavior' do
|
10
|
+
|
11
|
+
it_should_behave_like 'a model, integration'
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe 'unique behavior' do
|
17
|
+
|
18
|
+
it 'can be instantiated with the minimum viable Gherkin' do
|
19
|
+
source = '# a comment'
|
20
|
+
|
21
|
+
expect { clazz.new(source) }.to_not raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can parse text that uses a non-default dialect' do
|
25
|
+
original_dialect = CukeModeler::Parsing.dialect
|
26
|
+
CukeModeler::Parsing.dialect = 'en-au'
|
27
|
+
|
28
|
+
begin
|
29
|
+
source_text = '# a comment'
|
30
|
+
|
31
|
+
expect { @model = clazz.new(source_text) }.to_not raise_error
|
32
|
+
|
33
|
+
# Sanity check in case modeling failed in a non-explosive manner
|
34
|
+
expect(@model.text).to eq('# a comment')
|
35
|
+
ensure
|
36
|
+
# Making sure that our changes don't escape a test and ruin the rest of the suite
|
37
|
+
CukeModeler::Parsing.dialect = original_dialect
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'provides a descriptive filename when being parsed from stand alone text' do
|
42
|
+
source = 'bad comment text'
|
43
|
+
|
44
|
+
expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_comment\.feature'/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'stores the original data generated by the parsing adapter', :gherkin4 => true do
|
48
|
+
comment = clazz.new('# a comment')
|
49
|
+
data = comment.parsing_data
|
50
|
+
|
51
|
+
expect(data.keys).to match_array([:type, :location, :text])
|
52
|
+
expect(data[:type]).to eq(:Comment)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
|
56
|
+
comment = clazz.new('# a comment')
|
57
|
+
data = comment.parsing_data
|
58
|
+
|
59
|
+
expect(data.keys).to match_array([:type, :location, :text])
|
60
|
+
expect(data[:type]).to eq('Comment')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'stores the original data generated by the parsing adapter', :gherkin2 => true do
|
64
|
+
comment = clazz.new('# a comment')
|
65
|
+
data = comment.parsing_data
|
66
|
+
|
67
|
+
expect(data.keys).to match_array(['value', 'line'])
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
describe 'getting ancestors' do
|
72
|
+
|
73
|
+
before(:each) do
|
74
|
+
source = "# feature comment
|
75
|
+
#{@feature_keyword}: Test feature"
|
76
|
+
|
77
|
+
file_path = "#{@default_file_directory}/comment_test_file.feature"
|
78
|
+
File.open(file_path, 'w') { |file| file.write(source) }
|
79
|
+
end
|
80
|
+
|
81
|
+
let(:directory) { CukeModeler::Directory.new(@default_file_directory) }
|
82
|
+
let(:comment) { directory.feature_files.first.comments.first }
|
83
|
+
|
84
|
+
|
85
|
+
it 'can get its directory' do
|
86
|
+
ancestor = comment.get_ancestor(:directory)
|
87
|
+
|
88
|
+
expect(ancestor).to equal(directory)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'can get its feature file' do
|
92
|
+
ancestor = comment.get_ancestor(:feature_file)
|
93
|
+
|
94
|
+
expect(ancestor).to equal(directory.feature_files.first)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns nil if it does not have the requested type of ancestor' do
|
98
|
+
ancestor = comment.get_ancestor(:example)
|
99
|
+
|
100
|
+
expect(ancestor).to be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
describe 'model population' do
|
107
|
+
|
108
|
+
context 'from source text' do
|
109
|
+
|
110
|
+
let(:source_text) { '# a comment' }
|
111
|
+
let(:comment) { clazz.new(source_text) }
|
112
|
+
|
113
|
+
|
114
|
+
it "models the comment's text" do
|
115
|
+
expect(comment.text).to eq('# a comment')
|
116
|
+
end
|
117
|
+
|
118
|
+
it "models the comment's source line" do
|
119
|
+
path = "#{@default_file_directory}/#{@default_feature_file_name}"
|
120
|
+
source_text = "# a comment
|
121
|
+
#{@feature_keyword}:"
|
122
|
+
|
123
|
+
File.open(path, "w") { |file| file.puts source_text }
|
124
|
+
comment = CukeModeler::FeatureFile.new(path).comments.first
|
125
|
+
|
126
|
+
expect(comment.source_line).to eq(1)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'removes surrounding whitespace' do
|
130
|
+
comment = clazz.new(' # a comment ')
|
131
|
+
|
132
|
+
expect(comment.text).to eq('# a comment')
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
describe 'comment output' do
|
141
|
+
|
142
|
+
it 'can be remade from its own output' do
|
143
|
+
source = '# a comment'
|
144
|
+
comment = clazz.new(source)
|
145
|
+
|
146
|
+
comment_output = comment.to_s
|
147
|
+
remade_comment_output = clazz.new(comment_output).to_s
|
148
|
+
|
149
|
+
expect(remade_comment_output).to eq(comment_output)
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
context 'from source text' do
|
154
|
+
|
155
|
+
it 'can output a comment' do
|
156
|
+
source = '# a comment'
|
157
|
+
comment = clazz.new(source)
|
158
|
+
|
159
|
+
expect(comment.to_s).to eq('# a comment')
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|