gherkin-ruby 0.0.2 → 0.1.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.
@@ -0,0 +1,359 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.7
4
+ # from Racc grammer file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+
9
+ require_relative "lexer"
10
+ require_relative "../ast"
11
+
12
+ module Gherkin
13
+ class Parser < Racc::Parser
14
+
15
+ module_eval(<<'...end gherkin.y/module_eval...', 'gherkin.y', 97)
16
+
17
+ def parse(input)
18
+ scan_str(input)
19
+ end
20
+ ...end gherkin.y/module_eval...
21
+ ##### State transition tables begin ###
22
+
23
+ racc_action_table = [
24
+ 14, 3, 14, 15, 14, 26, 14, 11, 13, 3,
25
+ 38, 31, 32, 33, 34, 35, 14, 14, 11, 13,
26
+ 41, 31, 32, 33, 34, 35, 31, 32, 33, 34,
27
+ 35, 31, 32, 33, 34, 35, 31, 32, 33, 34,
28
+ 35, 3, 3, 7, 11, 13, 31, 32, 33, 34,
29
+ 35, 3, 3, 3, 18, 3, 44, 14, 45, 20,
30
+ 21, 48, 3, 14, 3, 14, 27, 3, 14, 14,
31
+ 8, 24 ]
32
+
33
+ racc_action_check = [
34
+ 19, 12, 4, 4, 22, 12, 51, 22, 22, 38,
35
+ 19, 51, 51, 51, 51, 51, 40, 25, 2, 2,
36
+ 25, 40, 40, 40, 40, 40, 47, 47, 47, 47,
37
+ 47, 52, 52, 52, 52, 52, 17, 17, 17, 17,
38
+ 17, 9, 0, 0, 9, 9, 28, 28, 28, 28,
39
+ 28, 6, 24, 18, 5, 29, 30, 36, 37, 7,
40
+ 8, 41, 42, 43, 45, 46, 15, 48, 49, 50,
41
+ 1, 11 ]
42
+
43
+ racc_action_pointer = [
44
+ 40, 70, 13, nil, 0, 50, 49, 47, 60, 39,
45
+ nil, 59, -1, nil, nil, 54, nil, 29, 51, -2,
46
+ nil, nil, 2, nil, 50, 15, nil, nil, 39, 53,
47
+ 44, nil, nil, nil, nil, nil, 55, 46, 7, nil,
48
+ 14, 49, 60, 61, nil, 62, 63, 19, 65, 66,
49
+ 67, 4, 24 ]
50
+
51
+ racc_action_default = [
52
+ -31, -31, -1, -3, -31, -5, -7, -31, -31, -2,
53
+ -24, -31, -31, -29, -4, -31, -6, -31, -31, -8,
54
+ -10, 53, -31, -25, -31, -31, -30, -11, -14, -31,
55
+ -31, -19, -20, -21, -22, -23, -15, -9, -31, -26,
56
+ -31, -31, -31, -16, -18, -31, -12, -27, -31, -17,
57
+ -13, -31, -28 ]
58
+
59
+ racc_goto_table = [
60
+ 4, 10, 28, 42, 6, 16, 19, 5, 23, 22,
61
+ 37, 17, 25, 9, 2, 1, nil, nil, 36, nil,
62
+ nil, 39, 42, nil, 40, 47, nil, 42, nil, 43,
63
+ nil, nil, nil, nil, nil, nil, 52, nil, 46, nil,
64
+ nil, nil, 49, nil, nil, 50, nil, nil, 51 ]
65
+
66
+ racc_goto_check = [
67
+ 4, 13, 10, 11, 7, 6, 4, 5, 13, 4,
68
+ 8, 9, 4, 3, 2, 1, nil, nil, 4, nil,
69
+ nil, 13, 11, nil, 4, 10, nil, 11, nil, 4,
70
+ nil, nil, nil, nil, nil, nil, 10, nil, 4, nil,
71
+ nil, nil, 4, nil, nil, 4, nil, nil, 4 ]
72
+
73
+ racc_goto_pointer = [
74
+ nil, 15, 14, 11, 0, 7, 0, 4, -9, 6,
75
+ -15, -25, nil, -1, nil ]
76
+
77
+ racc_goto_default = [
78
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
79
+ nil, 29, 30, nil, 12 ]
80
+
81
+ racc_reduce_table = [
82
+ 0, 0, :racc_error,
83
+ 1, 14, :_reduce_1,
84
+ 2, 14, :_reduce_2,
85
+ 1, 17, :_reduce_none,
86
+ 2, 17, :_reduce_none,
87
+ 1, 15, :_reduce_5,
88
+ 2, 15, :_reduce_6,
89
+ 1, 18, :_reduce_7,
90
+ 2, 18, :_reduce_8,
91
+ 3, 18, :_reduce_9,
92
+ 2, 20, :_reduce_10,
93
+ 3, 20, :_reduce_11,
94
+ 2, 21, :_reduce_none,
95
+ 3, 21, :_reduce_none,
96
+ 2, 19, :_reduce_14,
97
+ 2, 22, :_reduce_15,
98
+ 2, 23, :_reduce_16,
99
+ 3, 23, :_reduce_17,
100
+ 2, 24, :_reduce_18,
101
+ 1, 25, :_reduce_none,
102
+ 1, 25, :_reduce_none,
103
+ 1, 25, :_reduce_none,
104
+ 1, 25, :_reduce_none,
105
+ 1, 25, :_reduce_none,
106
+ 1, 16, :_reduce_24,
107
+ 2, 16, :_reduce_25,
108
+ 3, 16, :_reduce_26,
109
+ 4, 26, :_reduce_27,
110
+ 6, 26, :_reduce_28,
111
+ 1, 27, :_reduce_29,
112
+ 2, 27, :_reduce_30 ]
113
+
114
+ racc_reduce_n = 31
115
+
116
+ racc_shift_n = 53
117
+
118
+ racc_token_table = {
119
+ false => 0,
120
+ :error => 1,
121
+ :NEWLINE => 2,
122
+ :FEATURE => 3,
123
+ :BACKGROUND => 4,
124
+ :SCENARIO => 5,
125
+ :TAG => 6,
126
+ :GIVEN => 7,
127
+ :WHEN => 8,
128
+ :THEN => 9,
129
+ :AND => 10,
130
+ :BUT => 11,
131
+ :TEXT => 12 }
132
+
133
+ racc_nt_base = 13
134
+
135
+ racc_use_result_var = true
136
+
137
+ Racc_arg = [
138
+ racc_action_table,
139
+ racc_action_check,
140
+ racc_action_default,
141
+ racc_action_pointer,
142
+ racc_goto_table,
143
+ racc_goto_check,
144
+ racc_goto_default,
145
+ racc_goto_pointer,
146
+ racc_nt_base,
147
+ racc_reduce_table,
148
+ racc_token_table,
149
+ racc_shift_n,
150
+ racc_reduce_n,
151
+ racc_use_result_var ]
152
+
153
+ Racc_token_to_s_table = [
154
+ "$end",
155
+ "error",
156
+ "NEWLINE",
157
+ "FEATURE",
158
+ "BACKGROUND",
159
+ "SCENARIO",
160
+ "TAG",
161
+ "GIVEN",
162
+ "WHEN",
163
+ "THEN",
164
+ "AND",
165
+ "BUT",
166
+ "TEXT",
167
+ "$start",
168
+ "Root",
169
+ "Feature",
170
+ "Scenarios",
171
+ "Newline",
172
+ "FeatureHeader",
173
+ "Background",
174
+ "FeatureName",
175
+ "Description",
176
+ "BackgroundHeader",
177
+ "Steps",
178
+ "Step",
179
+ "Keyword",
180
+ "Scenario",
181
+ "Tags" ]
182
+
183
+ Racc_debug_parser = false
184
+
185
+ ##### State transition tables end #####
186
+
187
+ # reduce 0 omitted
188
+
189
+ module_eval(<<'.,.,', 'gherkin.y', 14)
190
+ def _reduce_1(val, _values, result)
191
+ result = val[0];
192
+ result
193
+ end
194
+ .,.,
195
+
196
+ module_eval(<<'.,.,', 'gherkin.y', 17)
197
+ def _reduce_2(val, _values, result)
198
+ result = val[0]; result.scenarios = val[1]
199
+ result
200
+ end
201
+ .,.,
202
+
203
+ # reduce 3 omitted
204
+
205
+ # reduce 4 omitted
206
+
207
+ module_eval(<<'.,.,', 'gherkin.y', 26)
208
+ def _reduce_5(val, _values, result)
209
+ result = val[0]
210
+ result
211
+ end
212
+ .,.,
213
+
214
+ module_eval(<<'.,.,', 'gherkin.y', 28)
215
+ def _reduce_6(val, _values, result)
216
+ result = val[0]; result.background = val[1]
217
+ result
218
+ end
219
+ .,.,
220
+
221
+ module_eval(<<'.,.,', 'gherkin.y', 32)
222
+ def _reduce_7(val, _values, result)
223
+ result = val[0]
224
+ result
225
+ end
226
+ .,.,
227
+
228
+ module_eval(<<'.,.,', 'gherkin.y', 33)
229
+ def _reduce_8(val, _values, result)
230
+ result = val[0]
231
+ result
232
+ end
233
+ .,.,
234
+
235
+ module_eval(<<'.,.,', 'gherkin.y', 35)
236
+ def _reduce_9(val, _values, result)
237
+ result = val[0]
238
+ result
239
+ end
240
+ .,.,
241
+
242
+ module_eval(<<'.,.,', 'gherkin.y', 39)
243
+ def _reduce_10(val, _values, result)
244
+ result = AST::Feature.new(val[1]); result.pos(filename, lineno)
245
+ result
246
+ end
247
+ .,.,
248
+
249
+ module_eval(<<'.,.,', 'gherkin.y', 40)
250
+ def _reduce_11(val, _values, result)
251
+ result = AST::Feature.new(val[2]); result.pos(filename, lineno)
252
+ result
253
+ end
254
+ .,.,
255
+
256
+ # reduce 12 omitted
257
+
258
+ # reduce 13 omitted
259
+
260
+ module_eval(<<'.,.,', 'gherkin.y', 50)
261
+ def _reduce_14(val, _values, result)
262
+ result = val[0]; result.steps = val[1]
263
+ result
264
+ end
265
+ .,.,
266
+
267
+ module_eval(<<'.,.,', 'gherkin.y', 54)
268
+ def _reduce_15(val, _values, result)
269
+ result = AST::Background.new; result.pos(filename, lineno)
270
+ result
271
+ end
272
+ .,.,
273
+
274
+ module_eval(<<'.,.,', 'gherkin.y', 58)
275
+ def _reduce_16(val, _values, result)
276
+ result = [val[0]]
277
+ result
278
+ end
279
+ .,.,
280
+
281
+ module_eval(<<'.,.,', 'gherkin.y', 59)
282
+ def _reduce_17(val, _values, result)
283
+ result = val[0] << val[1]
284
+ result
285
+ end
286
+ .,.,
287
+
288
+ module_eval(<<'.,.,', 'gherkin.y', 63)
289
+ def _reduce_18(val, _values, result)
290
+ result = AST::Step.new(val[1], val[0]); result.pos(filename, lineno)
291
+ result
292
+ end
293
+ .,.,
294
+
295
+ # reduce 19 omitted
296
+
297
+ # reduce 20 omitted
298
+
299
+ # reduce 21 omitted
300
+
301
+ # reduce 22 omitted
302
+
303
+ # reduce 23 omitted
304
+
305
+ module_eval(<<'.,.,', 'gherkin.y', 71)
306
+ def _reduce_24(val, _values, result)
307
+ result = [val[0]]
308
+ result
309
+ end
310
+ .,.,
311
+
312
+ module_eval(<<'.,.,', 'gherkin.y', 72)
313
+ def _reduce_25(val, _values, result)
314
+ result = val[0] << val[1]
315
+ result
316
+ end
317
+ .,.,
318
+
319
+ module_eval(<<'.,.,', 'gherkin.y', 73)
320
+ def _reduce_26(val, _values, result)
321
+ result = val[0] << val[2]
322
+ result
323
+ end
324
+ .,.,
325
+
326
+ module_eval(<<'.,.,', 'gherkin.y', 78)
327
+ def _reduce_27(val, _values, result)
328
+ result = AST::Scenario.new(val[1], val[3]); result.pos(filename, lineno - 1)
329
+ result
330
+ end
331
+ .,.,
332
+
333
+ module_eval(<<'.,.,', 'gherkin.y', 81)
334
+ def _reduce_28(val, _values, result)
335
+ result = AST::Scenario.new(val[3], val[5], val[0]); result.pos(filename, lineno - 2)
336
+ result
337
+ end
338
+ .,.,
339
+
340
+ module_eval(<<'.,.,', 'gherkin.y', 85)
341
+ def _reduce_29(val, _values, result)
342
+ result = [AST::Tag.new(val[0])]
343
+ result
344
+ end
345
+ .,.,
346
+
347
+ module_eval(<<'.,.,', 'gherkin.y', 86)
348
+ def _reduce_30(val, _values, result)
349
+ result = val[0] << AST::Tag.new(val[1])
350
+ result
351
+ end
352
+ .,.,
353
+
354
+ def _reduce_none(val, _values, result)
355
+ val[0]
356
+ end
357
+
358
+ end # class Parser
359
+ end # module Gherkin
@@ -1,43 +1 @@
1
- require 'parslet'
2
-
3
- module Gherkin
4
- class Parser < Parslet::Parser
5
- def indent(num=2)
6
- str(' ' * num)
7
- end
8
-
9
- rule(:space) { match('\s').repeat }
10
- rule(:space?) { space.maybe }
11
- rule(:newline) { match('\n').repeat }
12
- rule(:text) { match('[^\n]').repeat }
13
- rule(:identifier) { match('\w').repeat }
14
-
15
- rule(:feature_line) { str('Feature:') >> space? >> text.as(:name) }
16
- rule(:scenario_line) { indent(2) >> str('Scenario:') >> space? >> text.as(:name) }
17
-
18
- rule(:step_keyword) { str('Given') | str('When') | str('Then') | str('And') | str('But') }
19
-
20
- rule(:comment) { str('#') >> text.as(:comment) }
21
-
22
- rule(:description_text) { (str('Background:') | str('Scenario:') | str('@')).absent? >> text }
23
- rule(:description) { (indent(2) >> description_text >> newline).repeat }
24
-
25
- rule(:background_line) { indent(2) >> str('Background:') }
26
-
27
- rule(:step) { indent(4) >> step_keyword.as(:keyword) >> space? >> text.as(:name) }
28
- rule(:steps) { (step.as(:step) >> newline.maybe).repeat }
29
-
30
- rule(:tags) { indent(2) >> (str('@') >> identifier.as(:tag) >> str(' ').maybe).repeat(1) }
31
-
32
- rule(:scenario) { (tags.as(:tags) >> newline).maybe >> scenario_line >> newline >> steps.as(:steps) }
33
- rule(:scenarios) { (scenario.as(:scenario) >> newline.maybe).repeat }
34
-
35
- rule(:background) { background_line >> newline >> steps.as(:steps) }
36
-
37
- rule(:feature) { feature_line >> newline >> description >> background.as(:background).maybe >> scenarios.as(:scenarios) }
38
-
39
- rule(:main) { feature.as(:feature) }
40
-
41
- root :main
42
- end
43
- end
1
+ require_relative 'parser/parser'
@@ -1,3 +1,3 @@
1
1
  module Gherkin
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/gherkin.rb CHANGED
@@ -1,15 +1,10 @@
1
- require 'parslet'
2
1
  require_relative "gherkin/version"
3
2
  require_relative 'gherkin/ast'
4
3
  require_relative 'gherkin/parser'
5
- require_relative 'gherkin/transform'
6
4
 
7
5
  module Gherkin
8
6
  def self.parse(input)
9
- parser = Parser.new
10
- transform = Transform.new
11
-
12
- parsed = parser.parse input
13
- transform.apply(parsed)
7
+ parser = Parser.new
8
+ parser.parse(input)
14
9
  end
15
10
  end
@@ -32,51 +32,42 @@ module Gherkin
32
32
  node.ancestors.must_include Node
33
33
  end
34
34
 
35
- it 'has a line and column' do
36
- name = OpenStruct.new(line_and_column: [2, 13])
37
- def name.to_s; 'Name'; end
38
-
39
- instance = node.new(name)
35
+ it 'has a line' do
36
+ instance = node.new("Name")
40
37
  instance.name.must_equal 'Name'
41
- instance.line.must_equal 2
42
- instance.column.must_equal 13
38
+ instance.must_respond_to :line
43
39
  end
44
40
  end
45
41
  end
46
42
 
47
43
  describe Feature do
48
44
  it 'is Enumerable' do
49
- name = OpenStruct.new(line_and_column: [2, 13])
50
- def name.to_s; 'Name'; end
51
-
52
45
  background = ['foo', 'bar']
53
46
  elements = ['+foo', '+bar']
54
47
 
55
- instance = Feature.new(name, elements, background )
48
+ instance = Feature.new("My feature", elements, background )
56
49
  instance.background.each.to_a.must_equal ['foo', 'bar']
57
50
  instance.each.to_a.must_equal ['+foo', '+bar']
58
51
  end
59
52
  end
60
53
 
61
54
  describe Scenario do
62
- it 'is Enumerable' do
63
- name = OpenStruct.new(line_and_column: [2, 13])
64
- def name.to_s; 'Name'; end
65
-
66
- elements = ['foo', 'bar']
55
+ let(:steps) do
56
+ steps = [
57
+ OpenStruct.new(line: 4),
58
+ OpenStruct.new(line: 5),
59
+ ]
60
+ end
67
61
 
68
- instance = Scenario.new(name, elements)
69
- instance.each.to_a.must_equal ['foo', 'bar']
62
+ it 'is Enumerable' do
63
+ instance = Scenario.new("Name", steps)
64
+ instance.each.to_a.must_equal steps
70
65
  end
71
66
 
72
67
  it 'has tags' do
73
- name = OpenStruct.new(line_and_column: [2, 13])
74
- def name.to_s; 'Name'; end
75
-
76
- steps = ['foo', 'bar']
77
68
  tags = ['javascript', 'wip']
78
69
 
79
- instance = Scenario.new(name, steps, tags)
70
+ instance = Scenario.new("Name", steps, tags)
80
71
  instance.tags.must_equal tags
81
72
  end
82
73
  end
@@ -99,10 +90,10 @@ module Gherkin
99
90
  end
100
91
 
101
92
  describe 'when there are background steps' do
102
- it 'records line and column' do
93
+ it 'records line' do
103
94
  instance = Background.new(steps)
95
+ instance.pos("file", 3)
104
96
  instance.line.must_equal 3
105
- instance.column.must_equal 3
106
97
  end
107
98
  end
108
99
 
@@ -110,7 +101,6 @@ module Gherkin
110
101
  it 'does not' do
111
102
  instance = Background.new([])
112
103
  instance.line.must_equal nil
113
- instance.column.must_equal nil
114
104
  end
115
105
  end
116
106
  end
@@ -120,15 +110,12 @@ module Gherkin
120
110
  Step.ancestors.must_include Node
121
111
  end
122
112
 
123
- it 'has a line and column' do
124
- name = OpenStruct.new(line_and_column: [2, 13])
125
- def name.to_s; 'Name'; end
126
-
127
- instance = Step.new(name, 'Given')
113
+ it 'has a line' do
114
+ instance = Step.new("Name", 'Given')
115
+ instance.pos("file", 2)
128
116
  instance.name.must_equal 'Name'
129
117
  instance.keyword.must_equal 'Given'
130
118
  instance.line.must_equal 2
131
- instance.column.must_equal 13
132
119
  end
133
120
  end
134
121
  end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ module Gherkin
4
+ describe Parser do
5
+ let(:lexer) { Parser.new }
6
+
7
+ it 'ignores commments' do
8
+ lexer.tokenize("# this is a comment").must_equal []
9
+ end
10
+
11
+ it 'parses newlines' do
12
+ lexer.tokenize("\n\n").must_equal [[:NEWLINE, "\n"], [:NEWLINE, "\n"]]
13
+ end
14
+
15
+ it 'parses text and strips it' do
16
+ lexer.tokenize(" Arbitrary text ").must_equal [[:TEXT, "Arbitrary text"]]
17
+ end
18
+
19
+ it 'parses tags' do
20
+ lexer.tokenize("@javascript @wip").must_equal [
21
+ [:TAG, "javascript"],
22
+ [:TAG, "wip"],
23
+ ]
24
+ end
25
+
26
+ describe 'Keywords' do
27
+ %w(Feature: Background: Scenario:).each do |keyword|
28
+ it "parses #{keyword}:" do
29
+ name = keyword[0..-2]
30
+ lexer.tokenize(keyword).must_equal [[name.upcase.to_sym, name]]
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'Step keywords' do
36
+ %w(Given When Then And But).each do |keyword|
37
+ it "parses #{keyword}" do
38
+ lexer.tokenize(keyword).must_equal [[keyword.upcase.to_sym, keyword]]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,96 @@
1
+ require 'test_helper'
2
+
3
+ module Gherkin
4
+ describe Parser do
5
+ def parse(input)
6
+ parser = Parser.new
7
+ parser.parse(input)
8
+ end
9
+
10
+ describe 'Feature name and description' do
11
+ it 'parses feature header without description' do
12
+ feature = parse(
13
+ "Feature: my feature"
14
+ )
15
+ feature.must_be_kind_of AST::Feature
16
+ feature.name.must_equal "my feature"
17
+ end
18
+
19
+ it 'parses feature header with description' do
20
+ feature = parse(
21
+ "Feature: my feature\n In order to do something\n As a user\n"
22
+ )
23
+ feature.must_be_kind_of AST::Feature
24
+ feature.name.must_equal "my feature"
25
+ end
26
+
27
+ it 'parses feature with background' do
28
+ feature = parse("""
29
+ Feature: Do something
30
+
31
+ Background:
32
+ Given blah foo bar
33
+ Then something else
34
+ """)
35
+ feature.name.must_equal "Do something"
36
+ feature.background.must_be_kind_of AST::Background
37
+ steps = feature.background.steps
38
+
39
+ given_step = steps.first
40
+ then_step = steps.last
41
+
42
+ given_step.keyword.must_equal "Given"
43
+ given_step.name.must_equal "blah foo bar"
44
+ then_step.keyword.must_equal "Then"
45
+ then_step.name.must_equal "something else"
46
+ end
47
+
48
+ it 'parses feature with scenarios' do
49
+ feature = parse("""
50
+ Feature: Do something
51
+
52
+ Scenario: Foo bar baz
53
+ Given blah foo bar
54
+ Then something else
55
+
56
+ Scenario: Foo bar baz blah
57
+ Given blah foo bar
58
+ Then something else
59
+ """)
60
+ scenarios = feature.scenarios
61
+
62
+ first_scenario = scenarios.first
63
+ last_scenario = scenarios.last
64
+
65
+ first_scenario.name.must_equal "Foo bar baz"
66
+ first_scenario.steps.first.name.must_equal "blah foo bar"
67
+ first_scenario.steps.last.name.must_equal "something else"
68
+
69
+ last_scenario.name.must_equal "Foo bar baz blah"
70
+ last_scenario.steps.first.name.must_equal "blah foo bar"
71
+ last_scenario.steps.last.name.must_equal "something else"
72
+ end
73
+
74
+ it 'parses feature with scenarios with tags' do
75
+ feature = parse("""
76
+ Feature: Do something
77
+
78
+ Scenario: Foo bar baz
79
+ Given blah foo bar
80
+ Then something else
81
+
82
+ @javascript @wip
83
+ Scenario: Foo bar baz blah
84
+ Given blah foo bar
85
+ Then something else
86
+ """)
87
+ scenarios = feature.scenarios
88
+
89
+ last_scenario = scenarios.last
90
+
91
+ last_scenario.tags.first.name.must_equal "javascript"
92
+ last_scenario.tags.last.name.must_equal "wip"
93
+ end
94
+ end
95
+ end
96
+ end