cuke_modeler 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +5 -0
  3. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +77 -22
  4. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +25 -1
  5. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +25 -1
  6. data/lib/cuke_modeler/containing.rb +15 -0
  7. data/lib/cuke_modeler/models/background.rb +1 -1
  8. data/lib/cuke_modeler/models/cell.rb +1 -1
  9. data/lib/cuke_modeler/models/comment.rb +47 -0
  10. data/lib/cuke_modeler/models/directory.rb +2 -5
  11. data/lib/cuke_modeler/models/doc_string.rb +1 -1
  12. data/lib/cuke_modeler/models/example.rb +1 -1
  13. data/lib/cuke_modeler/models/feature.rb +1 -1
  14. data/lib/cuke_modeler/models/feature_file.rb +8 -5
  15. data/lib/cuke_modeler/models/outline.rb +1 -1
  16. data/lib/cuke_modeler/models/row.rb +1 -1
  17. data/lib/cuke_modeler/models/scenario.rb +1 -1
  18. data/lib/cuke_modeler/models/step.rb +1 -1
  19. data/lib/cuke_modeler/models/table.rb +1 -1
  20. data/lib/cuke_modeler/models/tag.rb +1 -1
  21. data/lib/cuke_modeler/version.rb +1 -1
  22. data/lib/cuke_modeler.rb +1 -0
  23. data/testing/cucumber/features/modeling/comment_modeling.feature +43 -0
  24. data/testing/cucumber/features/modeling/comment_output.feature +27 -0
  25. data/testing/cucumber/features/modeling/feature_file_modeling.feature +11 -0
  26. data/testing/cucumber/features/modeling/model_structure.feature +2 -2
  27. data/testing/cucumber/features/modeling/tag_output.feature +1 -1
  28. data/testing/cucumber/step_definitions/feature_file_steps.rb +10 -0
  29. data/testing/cucumber/step_definitions/setup_steps.rb +6 -0
  30. data/testing/cucumber/step_definitions/verification_steps.rb +7 -1
  31. data/testing/rspec/spec/integration/comment_integration_spec.rb +168 -0
  32. data/testing/rspec/spec/integration/feature_file_integration_spec.rb +124 -0
  33. data/testing/rspec/spec/integration/gherkin_2_adapter_spec.rb +36 -3
  34. data/testing/rspec/spec/integration/gherkin_3_adapter_spec.rb +28 -4
  35. data/testing/rspec/spec/integration/gherkin_4_adapter_spec.rb +28 -3
  36. data/testing/rspec/spec/integration/parsing_integration_spec.rb +1 -0
  37. data/testing/rspec/spec/unit/comment_unit_spec.rb +74 -0
  38. data/testing/rspec/spec/unit/feature_file_unit_spec.rb +18 -0
  39. data/todo.txt +2 -0
  40. 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)
@@ -90,7 +90,7 @@ module CukeModeler
90
90
  def parse_source(source_text)
91
91
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_feature.feature')
92
92
 
93
- parsed_file.first
93
+ parsed_file.first['feature']
94
94
  end
95
95
 
96
96
  def background_output_string
@@ -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
@@ -72,7 +72,7 @@ module CukeModeler
72
72
 
73
73
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_outline.feature')
74
74
 
75
- parsed_file.first['elements'].first
75
+ parsed_file.first['feature']['elements'].first
76
76
  end
77
77
 
78
78
  def examples_output_string
@@ -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
@@ -67,7 +67,7 @@ module CukeModeler
67
67
 
68
68
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_scenario.feature')
69
69
 
70
- parsed_file.first['elements'].first
70
+ parsed_file.first['feature']['elements'].first
71
71
  end
72
72
 
73
73
  end
@@ -62,7 +62,7 @@ module CukeModeler
62
62
 
63
63
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
64
64
 
65
- parsed_file.first['elements'].first['steps'].first
65
+ parsed_file.first['feature']['elements'].first['steps'].first
66
66
  end
67
67
 
68
68
  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)
@@ -40,7 +40,7 @@ module CukeModeler
40
40
 
41
41
  parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_tag.feature')
42
42
 
43
- parsed_file.first['tags'].first
43
+ parsed_file.first['feature']['tags'].first
44
44
  end
45
45
 
46
46
  end
@@ -1,4 +1,4 @@
1
1
  module CukeModeler
2
2
  # The gem version
3
- VERSION = "1.1.1"
3
+ VERSION = "1.2.0"
4
4
  end
data/lib/cuke_modeler.rb CHANGED
@@ -29,3 +29,4 @@ require 'cuke_modeler/models/table'
29
29
  require 'cuke_modeler/models/row'
30
30
  require 'cuke_modeler/models/tag'
31
31
  require 'cuke_modeler/models/cell'
32
+ require 'cuke_modeler/models/comment'
@@ -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 and feature file models do not store any parsing data because parsing Gherkin source text
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
@@ -9,7 +9,7 @@ Feature: Tag output
9
9
  """
10
10
  @a_tag
11
11
  """
12
- And a scenario model based on that gherkin
12
+ And a tag model based on that gherkin
13
13
  """
14
14
  @model = CukeModeler::Tag.new(<source_text>)
15
15
  """
@@ -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::FeatureFile, CukeModeler::Directory]
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