cucumber 0.1.10 → 0.1.11

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,3 +1,21 @@
1
+ == 0.1.11
2
+
3
+ Bugfix release with a couple of minor additional features to the command line options.
4
+
5
+ == New features
6
+ * Capture output from cucumber in Autotest (Alan Larkin)
7
+ * Update cucumber generator to work with latest Webrat (Bryan Helkamp)
8
+ * CUCUMBR LIKEZ 2 SPEEK WIF KATS. KTHXBAI (Aimee Daniells)
9
+ * Support for dynamically pluggable formatters (#99 Joseph Wilk)
10
+ * --verbose mode to see ruby files and feature files loaded by Cucumber (#106 Joseph Wilk)
11
+
12
+ == Bugfixes
13
+ * The jcode library is not loaded on JRuby/Rails. Workaround for http://tinyurl.com/55uu3u. (Aslak Hellesøy)
14
+ * Support including modules for class passed to --format (#109 Joseph Wilk)
15
+
16
+ == Removed features
17
+ * The cucumber gem no longer depends on the rspec gem. It must be downloaded manually if RSpec is used.
18
+
1
19
  == 0.1.10 2008-11-25
2
20
 
3
21
  This release mostly has smaller bugfixes. The most significant new feature is how
@@ -166,6 +166,7 @@ lib/cucumber/treetop_parser/feature_ar.rb
166
166
  lib/cucumber/treetop_parser/feature_cy.rb
167
167
  lib/cucumber/treetop_parser/feature_da.rb
168
168
  lib/cucumber/treetop_parser/feature_de.rb
169
+ lib/cucumber/treetop_parser/feature_en-lol.rb
169
170
  lib/cucumber/treetop_parser/feature_en-tx.rb
170
171
  lib/cucumber/treetop_parser/feature_en.rb
171
172
  lib/cucumber/treetop_parser/feature_es.rb
data/Rakefile CHANGED
@@ -5,5 +5,4 @@ require 'config/hoe' # setup Hoe + all gem configuration
5
5
  Dir['gem_tasks/**/*.rake'].each { |rake| load rake }
6
6
 
7
7
  # Hoe gives us :default => :test, but we don't have Test::Unit tests.
8
- Rake::Task[:default].clear_prerequisites
9
- task :default => [:spec, :features]
8
+ Rake::Task[:default].clear_prerequisites
@@ -58,7 +58,6 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
58
58
  p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
59
59
  #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
60
60
  p.extra_deps = [ ['term-ansicolor', '>= 1.0.3'], ['treetop', '>= 1.2.4'], ['diff-lcs', '>= 1.1.2'] ]
61
- p.extra_dev_deps = [ ['rspec', '>= 1.1.11'] ]
62
61
 
63
62
  #p.spec_extras = {} # A hash of extra values to set in the gemspec.
64
63
 
@@ -1,21 +1,35 @@
1
- begin
1
+ def unable_to_load
2
+ STDERR.puts <<-EOS
3
+ To use rspec for testing you must install rspec gem:
4
+ gem install rspec
5
+
6
+ EOS
7
+ nil
8
+ end
9
+
10
+ def require_spec
2
11
  require 'spec'
3
12
  rescue LoadError
13
+ require_spec_with_rubygems
14
+ end
15
+
16
+ def require_spec_with_rubygems
4
17
  require 'rubygems'
5
18
  require 'spec'
6
- end
7
- begin
8
- require 'spec/rake/spectask'
9
19
  rescue LoadError
10
- puts <<-EOS
11
- To use rspec for testing you must install rspec gem:
12
- gem install rspec
13
- EOS
14
- exit(0)
20
+ unable_to_load
15
21
  end
16
22
 
17
- desc "Run the specs under spec/models"
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
21
- end
23
+ if require_spec
24
+ begin
25
+ require 'spec/rake/spectask'
26
+ rescue LoadError
27
+ unable_to_load
28
+ end
29
+
30
+ desc "Run the Cucumber specs"
31
+ Spec::Rake::SpecTask.new do |t|
32
+ t.spec_opts = ['--options', "spec/spec.opts"]
33
+ t.spec_files = FileList['spec/**/*_spec.rb']
34
+ end
35
+ end
@@ -70,7 +70,29 @@ module Autotest::CucumberMixin
70
70
  cmd = self.make_cucumber_cmd self.scenarios_to_run, dirty_scenarios_file.path
71
71
  return if cmd.empty?
72
72
  puts cmd unless $q
73
- system cmd
73
+ old_sync = $stdout.sync
74
+ $stdout.sync = true
75
+ self.results = []
76
+ line = []
77
+ begin
78
+ open("| #{cmd}", "r") do |f|
79
+ until f.eof? do
80
+ c = f.getc
81
+ putc c
82
+ line << c
83
+ if c == ?\n then
84
+ self.results << if RUBY_VERSION >= "1.9" then
85
+ line.join
86
+ else
87
+ line.pack "c*"
88
+ end
89
+ line.clear
90
+ end
91
+ end
92
+ end
93
+ ensure
94
+ $stdout.sync = old_sync
95
+ end
74
96
  self.scenarios_to_run = dirty_scenarios_file.readlines.map { |l| l.chomp }
75
97
  self.tainted = true unless self.scenarios_to_run == []
76
98
  end
@@ -1,7 +1,6 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- require 'jcode'
5
4
  require 'cucumber/platform'
6
5
  require 'rubygems'
7
6
  require 'treetop/runtime'
@@ -69,12 +69,11 @@ module Cucumber
69
69
  end
70
70
  opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{DEFAULT_FORMAT})",
71
71
  "Available formats: #{FORMATS.join(", ")}",
72
+ "You can also provide your own formatter classes as long as they have been",
73
+ "previously required using --require or if they are in the folder",
74
+ "structure such that cucumber will require them automatically.",
72
75
  "This option can be specified multiple times.") do |v|
73
- unless FORMATS.index(v)
74
- @error_stream.puts "Invalid format: #{v}\n"
75
- @error_stream.puts opts.help
76
- exit 1
77
- end
76
+
78
77
  @options[:formats][v] ||= []
79
78
  @options[:formats][v] << @out_stream
80
79
  @active_format = v
@@ -114,13 +113,16 @@ module Cucumber
114
113
  @options[:snippets] = false
115
114
  @options[:source] = false
116
115
  end
116
+ opts.on("-v", "--verbose", "Show the files and features loaded") do
117
+ @options[:verbose] = true
118
+ end
117
119
  opts.on_tail("--version", "Show version") do
118
- puts VERSION::STRING
119
- exit
120
+ @out_stream.puts VERSION::STRING
121
+ Kernel.exit
120
122
  end
121
123
  opts.on_tail("--help", "You're looking at it") do
122
- puts opts.help
123
- exit
124
+ @out_stream.puts opts.help
125
+ Kernel.exit
124
126
  end
125
127
  end.parse!
126
128
 
@@ -159,8 +161,8 @@ Defined profiles in cucumber.yml:
159
161
  def execute!(step_mother, executor, features)
160
162
  Term::ANSIColor.coloring = @options[:color] unless @options[:color].nil?
161
163
  Cucumber.load_language(@options[:lang])
162
- executor.formatters = build_formatter_broadcaster(step_mother)
163
164
  require_files
165
+ executor.formatters = build_formatter_broadcaster(step_mother)
164
166
  load_plain_text_features(features)
165
167
  executor.lines_for_features = @options[:lines_for_features]
166
168
  executor.scenario_names = @options[:scenario_names] if @options[:scenario_names]
@@ -188,6 +190,7 @@ Defined profiles in cucumber.yml:
188
190
  require "cucumber/treetop_parser/feature_#{@options[:lang]}"
189
191
  require "cucumber/treetop_parser/feature_parser"
190
192
 
193
+ verbose_log("Ruby files required:")
191
194
  requires = @options[:require] || feature_dirs
192
195
  libs = requires.map do |path|
193
196
  path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
@@ -196,11 +199,13 @@ Defined profiles in cucumber.yml:
196
199
  libs.each do |lib|
197
200
  begin
198
201
  require lib
202
+ verbose_log(" * #{lib}")
199
203
  rescue LoadError => e
200
204
  e.message << "\nFailed to load #{lib}"
201
205
  raise e
202
206
  end
203
207
  end
208
+ verbose_log("\n")
204
209
  end
205
210
 
206
211
  def feature_files
@@ -226,9 +231,12 @@ Defined profiles in cucumber.yml:
226
231
  def load_plain_text_features(features)
227
232
  parser = TreetopParser::FeatureParser.new
228
233
 
234
+ verbose_log("Features:")
229
235
  feature_files.each do |f|
230
236
  features << parser.parse_feature(f)
237
+ verbose_log(" * #{f}")
231
238
  end
239
+ verbose_log("\n"*2)
232
240
  end
233
241
 
234
242
  def build_formatter_broadcaster(step_mother)
@@ -247,7 +255,15 @@ Defined profiles in cucumber.yml:
247
255
  when 'autotest'
248
256
  formatter_broadcaster.register(Formatters::AutotestFormatter.new(output_broadcaster))
249
257
  else
250
- raise "Unknown formatter: #{@options[:format]}"
258
+ begin
259
+ formatter_class = constantize(format)
260
+ formatter_broadcaster.register(formatter_class.new(output_broadcaster, step_mother, @options))
261
+ rescue NameError => e
262
+ @error_stream.puts "Invalid format: #{format}\n"
263
+ exit_with_help
264
+ rescue Exception => e
265
+ exit_with_error("Error creating formatter: #{format}\n#{e}\n")
266
+ end
251
267
  end
252
268
  end
253
269
  formatter_broadcaster
@@ -263,6 +279,25 @@ Defined profiles in cucumber.yml:
263
279
 
264
280
  private
265
281
 
282
+ def constantize(camel_cased_word)
283
+ names = camel_cased_word.split('::')
284
+ names.shift if names.empty? || names.first.empty?
285
+
286
+ constant = Object
287
+ names.each do |name|
288
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
289
+ end
290
+ constant
291
+ end
292
+
293
+ def verbose_log(string)
294
+ @out_stream.puts(string) if @options[:verbose]
295
+ end
296
+
297
+ def exit_with_help
298
+ parse_options!(%w{--help})
299
+ end
300
+
266
301
  def exit_with_error(error_message)
267
302
  @error_stream << error_message
268
303
  Kernel.exit 1
@@ -19,4 +19,11 @@ class String
19
19
  end
20
20
  s
21
21
  end
22
+
23
+ if $CUCUMBER_JRUBY && $CUCUMBER_RAILS
24
+ # Workaround for http://tinyurl.com/55uu3u
25
+ alias jlength length
26
+ else
27
+ require 'jcode'
28
+ end
22
29
  end
@@ -1,5 +1,3 @@
1
- require 'cucumber/core_ext/proc'
2
-
3
1
  module Cucumber
4
2
  class Executor
5
3
  attr_reader :failed
@@ -63,6 +63,17 @@
63
63
  then: Dann
64
64
  and: Und
65
65
  but: Aber
66
+ # LOLCAT
67
+ "en-lol":
68
+ feature: OH HAI
69
+ scenario: MISHUN
70
+ more_examples: MOAR EXAMPLZ
71
+ given_scenario: SRSLY
72
+ given: GIVN
73
+ when: WEN
74
+ then: DEN
75
+ and: AN
76
+ but: BUT
66
77
  # Texan
67
78
  "en-tx":
68
79
  feature: Feature
@@ -6,6 +6,7 @@ $CUCUMBER_JRUBY = defined?(JRUBY_VERSION)
6
6
  $CUCUMBER_IRONRUBY = Config::CONFIG['sitedir'] =~ /IronRuby/
7
7
  $CUCUMBER_WINDOWS = Config::CONFIG['host_os'] =~ /mswin|mingw/
8
8
  $CUCUMBER_WINDOWS_MRI = $CUCUMBER_WINDOWS && !$CUCUMBER_JRUBY && !$CUCUMBER_IRONRUBY
9
+ $CUCUMBER_RAILS = defined?(Rails)
9
10
 
10
11
  if $CUCUMBER_IRONRUBY
11
12
  ENV['GEM_PATH'] ||= "C:/ruby/lib/ruby/gems/1.8"
@@ -1,5 +1,4 @@
1
1
  require 'cucumber/tree/top_down_visitor'
2
- require 'cucumber/core_ext/proc'
3
2
 
4
3
  module Cucumber
5
4
  class Pending < StandardError
@@ -21,6 +20,7 @@ module Cucumber
21
20
  PENDING = lambda do |*_|
22
21
  raise Pending
23
22
  end
23
+ require 'cucumber/core_ext/proc'
24
24
  PENDING.extend(CoreExt::CallIn)
25
25
  PENDING.name = "PENDING"
26
26
 
@@ -1,6 +1,4 @@
1
1
  %w{features feature scenario step given_scenario table top_down_visitor}.each{|f| require "cucumber/tree/#{f}"}
2
- require 'cucumber/core_ext/proc'
3
- require 'cucumber/core_ext/string'
4
2
 
5
3
  module Cucumber
6
4
  module Tree
@@ -43,6 +43,7 @@ module Cucumber
43
43
  attr_reader :name, :line
44
44
 
45
45
  def initialize(feature, name, line, &proc)
46
+ require 'cucumber/core_ext/string'
46
47
  @feature, @name, @line = feature, name, line
47
48
  @steps_and_given_scenarios = []
48
49
  instance_eval(&proc) if block_given?
@@ -148,7 +149,7 @@ module Cucumber
148
149
  def steps
149
150
  if template_steps_bound?
150
151
  @unbound_steps = nil
151
- @steps ||= build_steps
152
+ @bound_steps ||= build_steps
152
153
  else
153
154
  @unbound_steps ||= build_steps
154
155
  end
@@ -0,0 +1,1591 @@
1
+ module Cucumber
2
+ # :stopdoc:
3
+ module TreetopParser
4
+ module Feature
5
+ include Treetop::Runtime
6
+
7
+ def root
8
+ @root || :root
9
+ end
10
+
11
+ module Root0
12
+ def header
13
+ elements[1]
14
+ end
15
+
16
+ def scenario_sequence
17
+ elements[2]
18
+ end
19
+
20
+ end
21
+
22
+ module Root1
23
+ def compile
24
+ feature = Tree::Feature.new(header.text_value.strip)
25
+ scenario_sequence.compile(feature)
26
+ feature
27
+ end
28
+ end
29
+
30
+ def _nt_root
31
+ start_index = index
32
+ if node_cache[:root].has_key?(index)
33
+ cached = node_cache[:root][index]
34
+ @index = cached.interval.end if cached
35
+ return cached
36
+ end
37
+
38
+ i0, s0 = index, []
39
+ r2 = _nt_space
40
+ if r2
41
+ r1 = r2
42
+ else
43
+ r1 = SyntaxNode.new(input, index...index)
44
+ end
45
+ s0 << r1
46
+ if r1
47
+ r3 = _nt_header
48
+ s0 << r3
49
+ if r3
50
+ r4 = _nt_scenario_sequence
51
+ s0 << r4
52
+ if r4
53
+ r6 = _nt_space
54
+ if r6
55
+ r5 = r6
56
+ else
57
+ r5 = SyntaxNode.new(input, index...index)
58
+ end
59
+ s0 << r5
60
+ end
61
+ end
62
+ end
63
+ if s0.last
64
+ r0 = (SyntaxNode).new(input, i0...index, s0)
65
+ r0.extend(Root0)
66
+ r0.extend(Root1)
67
+ else
68
+ self.index = i0
69
+ r0 = nil
70
+ end
71
+
72
+ node_cache[:root][start_index] = r0
73
+
74
+ return r0
75
+ end
76
+
77
+ module Header0
78
+ end
79
+
80
+ def _nt_header
81
+ start_index = index
82
+ if node_cache[:header].has_key?(index)
83
+ cached = node_cache[:header][index]
84
+ @index = cached.interval.end if cached
85
+ return cached
86
+ end
87
+
88
+ s0, i0 = [], index
89
+ loop do
90
+ i1, s1 = index, []
91
+ i2 = index
92
+ i3 = index
93
+ r4 = _nt_scenario_keyword
94
+ if r4
95
+ r3 = r4
96
+ else
97
+ r5 = _nt_comment_to_eol
98
+ if r5
99
+ r3 = r5
100
+ else
101
+ self.index = i3
102
+ r3 = nil
103
+ end
104
+ end
105
+ if r3
106
+ r2 = nil
107
+ else
108
+ self.index = i2
109
+ r2 = SyntaxNode.new(input, index...index)
110
+ end
111
+ s1 << r2
112
+ if r2
113
+ if index < input_length
114
+ r6 = (SyntaxNode).new(input, index...(index + 1))
115
+ @index += 1
116
+ else
117
+ terminal_parse_failure("any character")
118
+ r6 = nil
119
+ end
120
+ s1 << r6
121
+ end
122
+ if s1.last
123
+ r1 = (SyntaxNode).new(input, i1...index, s1)
124
+ r1.extend(Header0)
125
+ else
126
+ self.index = i1
127
+ r1 = nil
128
+ end
129
+ if r1
130
+ s0 << r1
131
+ else
132
+ break
133
+ end
134
+ end
135
+ if s0.empty?
136
+ self.index = i0
137
+ r0 = nil
138
+ else
139
+ r0 = SyntaxNode.new(input, i0...index, s0)
140
+ end
141
+
142
+ node_cache[:header][start_index] = r0
143
+
144
+ return r0
145
+ end
146
+
147
+ module ScenarioSequence0
148
+ def space
149
+ elements[0]
150
+ end
151
+
152
+ def scenario_or_table
153
+ elements[1]
154
+ end
155
+ end
156
+
157
+ module ScenarioSequence1
158
+ def head
159
+ elements[0]
160
+ end
161
+
162
+ def tail
163
+ elements[1]
164
+ end
165
+ end
166
+
167
+ module ScenarioSequence2
168
+ def compile(feature)
169
+ ([head] + tail).each do |scenario_or_table|
170
+ scenario_or_table.compile(feature) if scenario_or_table.respond_to?(:compile)
171
+ end
172
+ end
173
+
174
+ def tail
175
+ super.elements.map { |elt| elt.scenario_or_table }
176
+ end
177
+ end
178
+
179
+ def _nt_scenario_sequence
180
+ start_index = index
181
+ if node_cache[:scenario_sequence].has_key?(index)
182
+ cached = node_cache[:scenario_sequence][index]
183
+ @index = cached.interval.end if cached
184
+ return cached
185
+ end
186
+
187
+ i0, s0 = index, []
188
+ r2 = _nt_scenario
189
+ if r2
190
+ r1 = r2
191
+ else
192
+ r1 = SyntaxNode.new(input, index...index)
193
+ end
194
+ s0 << r1
195
+ if r1
196
+ s3, i3 = [], index
197
+ loop do
198
+ i4, s4 = index, []
199
+ r5 = _nt_space
200
+ s4 << r5
201
+ if r5
202
+ r6 = _nt_scenario_or_table
203
+ s4 << r6
204
+ end
205
+ if s4.last
206
+ r4 = (SyntaxNode).new(input, i4...index, s4)
207
+ r4.extend(ScenarioSequence0)
208
+ else
209
+ self.index = i4
210
+ r4 = nil
211
+ end
212
+ if r4
213
+ s3 << r4
214
+ else
215
+ break
216
+ end
217
+ end
218
+ r3 = SyntaxNode.new(input, i3...index, s3)
219
+ s0 << r3
220
+ end
221
+ if s0.last
222
+ r0 = (SyntaxNode).new(input, i0...index, s0)
223
+ r0.extend(ScenarioSequence1)
224
+ r0.extend(ScenarioSequence2)
225
+ else
226
+ self.index = i0
227
+ r0 = nil
228
+ end
229
+
230
+ node_cache[:scenario_sequence][start_index] = r0
231
+
232
+ return r0
233
+ end
234
+
235
+ module Scenario0
236
+ def space
237
+ elements[0]
238
+ end
239
+
240
+ def step_sequence
241
+ elements[1]
242
+ end
243
+ end
244
+
245
+ module Scenario1
246
+ def scenario_keyword
247
+ elements[0]
248
+ end
249
+
250
+ def name
251
+ elements[2]
252
+ end
253
+
254
+ def steps
255
+ elements[3]
256
+ end
257
+ end
258
+
259
+ module Scenario2
260
+ def compile(feature)
261
+ line = input.line_of(interval.first)
262
+ scenario = feature.add_scenario(name.text_value.strip, line)
263
+ steps.step_sequence.compile(scenario) if steps.respond_to?(:step_sequence)
264
+ # TODO - GET RID OF THIS last_scenario NASTINESS
265
+ # Use a better datastructure, like a linked list...
266
+ Feature.last_scenario = scenario
267
+ end
268
+ end
269
+
270
+ def _nt_scenario
271
+ start_index = index
272
+ if node_cache[:scenario].has_key?(index)
273
+ cached = node_cache[:scenario][index]
274
+ @index = cached.interval.end if cached
275
+ return cached
276
+ end
277
+
278
+ i0, s0 = index, []
279
+ r1 = _nt_scenario_keyword
280
+ s0 << r1
281
+ if r1
282
+ r3 = _nt_space
283
+ if r3
284
+ r2 = r3
285
+ else
286
+ r2 = SyntaxNode.new(input, index...index)
287
+ end
288
+ s0 << r2
289
+ if r2
290
+ r4 = _nt_line_to_eol
291
+ s0 << r4
292
+ if r4
293
+ i6, s6 = index, []
294
+ r7 = _nt_space
295
+ s6 << r7
296
+ if r7
297
+ r8 = _nt_step_sequence
298
+ s6 << r8
299
+ end
300
+ if s6.last
301
+ r6 = (SyntaxNode).new(input, i6...index, s6)
302
+ r6.extend(Scenario0)
303
+ else
304
+ self.index = i6
305
+ r6 = nil
306
+ end
307
+ if r6
308
+ r5 = r6
309
+ else
310
+ r5 = SyntaxNode.new(input, index...index)
311
+ end
312
+ s0 << r5
313
+ end
314
+ end
315
+ end
316
+ if s0.last
317
+ r0 = (SyntaxNode).new(input, i0...index, s0)
318
+ r0.extend(Scenario1)
319
+ r0.extend(Scenario2)
320
+ else
321
+ self.index = i0
322
+ r0 = nil
323
+ end
324
+
325
+ node_cache[:scenario][start_index] = r0
326
+
327
+ return r0
328
+ end
329
+
330
+ def _nt_scenario_or_table
331
+ start_index = index
332
+ if node_cache[:scenario_or_table].has_key?(index)
333
+ cached = node_cache[:scenario_or_table][index]
334
+ @index = cached.interval.end if cached
335
+ return cached
336
+ end
337
+
338
+ i0 = index
339
+ r1 = _nt_scenario
340
+ if r1
341
+ r0 = r1
342
+ else
343
+ r2 = _nt_more_examples
344
+ if r2
345
+ r0 = r2
346
+ else
347
+ self.index = i0
348
+ r0 = nil
349
+ end
350
+ end
351
+
352
+ node_cache[:scenario_or_table][start_index] = r0
353
+
354
+ return r0
355
+ end
356
+
357
+ module MoreExamples0
358
+ def more_examples_keyword
359
+ elements[0]
360
+ end
361
+
362
+ def table
363
+ elements[1]
364
+ end
365
+ end
366
+
367
+ module MoreExamples1
368
+ def compile(f)
369
+ table.compile(f)
370
+ end
371
+ end
372
+
373
+ def _nt_more_examples
374
+ start_index = index
375
+ if node_cache[:more_examples].has_key?(index)
376
+ cached = node_cache[:more_examples][index]
377
+ @index = cached.interval.end if cached
378
+ return cached
379
+ end
380
+
381
+ i0, s0 = index, []
382
+ r1 = _nt_more_examples_keyword
383
+ s0 << r1
384
+ if r1
385
+ r2 = _nt_table
386
+ s0 << r2
387
+ end
388
+ if s0.last
389
+ r0 = (SyntaxNode).new(input, i0...index, s0)
390
+ r0.extend(MoreExamples0)
391
+ r0.extend(MoreExamples1)
392
+ else
393
+ self.index = i0
394
+ r0 = nil
395
+ end
396
+
397
+ node_cache[:more_examples][start_index] = r0
398
+
399
+ return r0
400
+ end
401
+
402
+ module Table0
403
+ def eol
404
+ elements[1]
405
+ end
406
+
407
+ def table_line
408
+ elements[3]
409
+ end
410
+ end
411
+
412
+ module Table1
413
+ def space
414
+ elements[0]
415
+ end
416
+
417
+ def head
418
+ elements[1]
419
+ end
420
+
421
+ def body
422
+ elements[2]
423
+ end
424
+ end
425
+
426
+ module Table2
427
+ def compile(feature)
428
+ Feature.last_scenario.table_header = head.cell_values
429
+ body.each do |table_line|
430
+ feature.add_row_scenario(Feature.last_scenario, table_line.cell_values, table_line.line)
431
+ end
432
+ end
433
+
434
+ def matrix
435
+ ([head] + body).map do |table_line|
436
+ table_line.cell_values # We're losing the line - we'll get it back when we make our own class
437
+ end
438
+ end
439
+
440
+ def to_arg
441
+ Model::Table.new(matrix)
442
+ end
443
+
444
+ def body
445
+ super.elements.map { |elt| elt.table_line }
446
+ end
447
+ end
448
+
449
+ def _nt_table
450
+ start_index = index
451
+ if node_cache[:table].has_key?(index)
452
+ cached = node_cache[:table][index]
453
+ @index = cached.interval.end if cached
454
+ return cached
455
+ end
456
+
457
+ i0, s0 = index, []
458
+ r1 = _nt_space
459
+ s0 << r1
460
+ if r1
461
+ r2 = _nt_table_line
462
+ s0 << r2
463
+ if r2
464
+ s3, i3 = [], index
465
+ loop do
466
+ i4, s4 = index, []
467
+ s5, i5 = [], index
468
+ loop do
469
+ r6 = _nt_blank
470
+ if r6
471
+ s5 << r6
472
+ else
473
+ break
474
+ end
475
+ end
476
+ r5 = SyntaxNode.new(input, i5...index, s5)
477
+ s4 << r5
478
+ if r5
479
+ r7 = _nt_eol
480
+ s4 << r7
481
+ if r7
482
+ r9 = _nt_space
483
+ if r9
484
+ r8 = r9
485
+ else
486
+ r8 = SyntaxNode.new(input, index...index)
487
+ end
488
+ s4 << r8
489
+ if r8
490
+ r10 = _nt_table_line
491
+ s4 << r10
492
+ end
493
+ end
494
+ end
495
+ if s4.last
496
+ r4 = (SyntaxNode).new(input, i4...index, s4)
497
+ r4.extend(Table0)
498
+ else
499
+ self.index = i4
500
+ r4 = nil
501
+ end
502
+ if r4
503
+ s3 << r4
504
+ else
505
+ break
506
+ end
507
+ end
508
+ r3 = SyntaxNode.new(input, i3...index, s3)
509
+ s0 << r3
510
+ end
511
+ end
512
+ if s0.last
513
+ r0 = (SyntaxNode).new(input, i0...index, s0)
514
+ r0.extend(Table1)
515
+ r0.extend(Table2)
516
+ else
517
+ self.index = i0
518
+ r0 = nil
519
+ end
520
+
521
+ node_cache[:table][start_index] = r0
522
+
523
+ return r0
524
+ end
525
+
526
+ module TableLine0
527
+ def cell_value
528
+ elements[1]
529
+ end
530
+
531
+ def separator
532
+ elements[3]
533
+ end
534
+ end
535
+
536
+ module TableLine1
537
+ def separator
538
+ elements[0]
539
+ end
540
+
541
+ def cells
542
+ elements[1]
543
+ end
544
+ end
545
+
546
+ module TableLine2
547
+ def cell_values
548
+ cells.elements.map { |elt| elt.cell_value.text_value.strip }
549
+ end
550
+
551
+ def line
552
+ input.line_of(interval.first)
553
+ end
554
+ end
555
+
556
+ def _nt_table_line
557
+ start_index = index
558
+ if node_cache[:table_line].has_key?(index)
559
+ cached = node_cache[:table_line][index]
560
+ @index = cached.interval.end if cached
561
+ return cached
562
+ end
563
+
564
+ i0, s0 = index, []
565
+ r1 = _nt_separator
566
+ s0 << r1
567
+ if r1
568
+ s2, i2 = [], index
569
+ loop do
570
+ i3, s3 = index, []
571
+ s4, i4 = [], index
572
+ loop do
573
+ r5 = _nt_blank
574
+ if r5
575
+ s4 << r5
576
+ else
577
+ break
578
+ end
579
+ end
580
+ r4 = SyntaxNode.new(input, i4...index, s4)
581
+ s3 << r4
582
+ if r4
583
+ r6 = _nt_cell_value
584
+ s3 << r6
585
+ if r6
586
+ s7, i7 = [], index
587
+ loop do
588
+ r8 = _nt_blank
589
+ if r8
590
+ s7 << r8
591
+ else
592
+ break
593
+ end
594
+ end
595
+ r7 = SyntaxNode.new(input, i7...index, s7)
596
+ s3 << r7
597
+ if r7
598
+ r9 = _nt_separator
599
+ s3 << r9
600
+ end
601
+ end
602
+ end
603
+ if s3.last
604
+ r3 = (SyntaxNode).new(input, i3...index, s3)
605
+ r3.extend(TableLine0)
606
+ else
607
+ self.index = i3
608
+ r3 = nil
609
+ end
610
+ if r3
611
+ s2 << r3
612
+ else
613
+ break
614
+ end
615
+ end
616
+ if s2.empty?
617
+ self.index = i2
618
+ r2 = nil
619
+ else
620
+ r2 = SyntaxNode.new(input, i2...index, s2)
621
+ end
622
+ s0 << r2
623
+ end
624
+ if s0.last
625
+ r0 = (SyntaxNode).new(input, i0...index, s0)
626
+ r0.extend(TableLine1)
627
+ r0.extend(TableLine2)
628
+ else
629
+ self.index = i0
630
+ r0 = nil
631
+ end
632
+
633
+ node_cache[:table_line][start_index] = r0
634
+
635
+ return r0
636
+ end
637
+
638
+ module CellValue0
639
+ end
640
+
641
+ def _nt_cell_value
642
+ start_index = index
643
+ if node_cache[:cell_value].has_key?(index)
644
+ cached = node_cache[:cell_value][index]
645
+ @index = cached.interval.end if cached
646
+ return cached
647
+ end
648
+
649
+ s0, i0 = [], index
650
+ loop do
651
+ i1, s1 = index, []
652
+ i2 = index
653
+ i3 = index
654
+ r4 = _nt_separator
655
+ if r4
656
+ r3 = r4
657
+ else
658
+ r5 = _nt_eol
659
+ if r5
660
+ r3 = r5
661
+ else
662
+ self.index = i3
663
+ r3 = nil
664
+ end
665
+ end
666
+ if r3
667
+ r2 = nil
668
+ else
669
+ self.index = i2
670
+ r2 = SyntaxNode.new(input, index...index)
671
+ end
672
+ s1 << r2
673
+ if r2
674
+ if index < input_length
675
+ r6 = (SyntaxNode).new(input, index...(index + 1))
676
+ @index += 1
677
+ else
678
+ terminal_parse_failure("any character")
679
+ r6 = nil
680
+ end
681
+ s1 << r6
682
+ end
683
+ if s1.last
684
+ r1 = (SyntaxNode).new(input, i1...index, s1)
685
+ r1.extend(CellValue0)
686
+ else
687
+ self.index = i1
688
+ r1 = nil
689
+ end
690
+ if r1
691
+ s0 << r1
692
+ else
693
+ break
694
+ end
695
+ end
696
+ r0 = SyntaxNode.new(input, i0...index, s0)
697
+
698
+ node_cache[:cell_value][start_index] = r0
699
+
700
+ return r0
701
+ end
702
+
703
+ module StepSequence0
704
+ def space
705
+ elements[0]
706
+ end
707
+
708
+ def step
709
+ elements[1]
710
+ end
711
+ end
712
+
713
+ module StepSequence1
714
+ def head
715
+ elements[0]
716
+ end
717
+
718
+ def tail
719
+ elements[1]
720
+ end
721
+ end
722
+
723
+ module StepSequence2
724
+ def compile(scenario)
725
+ ([head] + tail).each do |step|
726
+ step.compile(scenario)
727
+ end
728
+ end
729
+
730
+ def tail
731
+ super.elements.map { |elt| elt.step }
732
+ end
733
+ end
734
+
735
+ def _nt_step_sequence
736
+ start_index = index
737
+ if node_cache[:step_sequence].has_key?(index)
738
+ cached = node_cache[:step_sequence][index]
739
+ @index = cached.interval.end if cached
740
+ return cached
741
+ end
742
+
743
+ i0, s0 = index, []
744
+ r1 = _nt_step
745
+ s0 << r1
746
+ if r1
747
+ s2, i2 = [], index
748
+ loop do
749
+ i3, s3 = index, []
750
+ r4 = _nt_space
751
+ s3 << r4
752
+ if r4
753
+ r5 = _nt_step
754
+ s3 << r5
755
+ end
756
+ if s3.last
757
+ r3 = (SyntaxNode).new(input, i3...index, s3)
758
+ r3.extend(StepSequence0)
759
+ else
760
+ self.index = i3
761
+ r3 = nil
762
+ end
763
+ if r3
764
+ s2 << r3
765
+ else
766
+ break
767
+ end
768
+ end
769
+ r2 = SyntaxNode.new(input, i2...index, s2)
770
+ s0 << r2
771
+ end
772
+ if s0.last
773
+ r0 = (SyntaxNode).new(input, i0...index, s0)
774
+ r0.extend(StepSequence1)
775
+ r0.extend(StepSequence2)
776
+ else
777
+ self.index = i0
778
+ r0 = nil
779
+ end
780
+
781
+ node_cache[:step_sequence][start_index] = r0
782
+
783
+ return r0
784
+ end
785
+
786
+ def _nt_step
787
+ start_index = index
788
+ if node_cache[:step].has_key?(index)
789
+ cached = node_cache[:step][index]
790
+ @index = cached.interval.end if cached
791
+ return cached
792
+ end
793
+
794
+ i0 = index
795
+ r1 = _nt_given_scenario
796
+ if r1
797
+ r0 = r1
798
+ else
799
+ r2 = _nt_plain_step
800
+ if r2
801
+ r0 = r2
802
+ else
803
+ self.index = i0
804
+ r0 = nil
805
+ end
806
+ end
807
+
808
+ node_cache[:step][start_index] = r0
809
+
810
+ return r0
811
+ end
812
+
813
+ module GivenScenario0
814
+ def given_scenario_keyword
815
+ elements[0]
816
+ end
817
+
818
+ def name
819
+ elements[2]
820
+ end
821
+ end
822
+
823
+ module GivenScenario1
824
+ def compile(scenario)
825
+ line = input.line_of(interval.first)
826
+ scenario.create_given_scenario(name.text_value.strip, line)
827
+ end
828
+ end
829
+
830
+ def _nt_given_scenario
831
+ start_index = index
832
+ if node_cache[:given_scenario].has_key?(index)
833
+ cached = node_cache[:given_scenario][index]
834
+ @index = cached.interval.end if cached
835
+ return cached
836
+ end
837
+
838
+ i0, s0 = index, []
839
+ r1 = _nt_given_scenario_keyword
840
+ s0 << r1
841
+ if r1
842
+ r3 = _nt_space
843
+ if r3
844
+ r2 = r3
845
+ else
846
+ r2 = SyntaxNode.new(input, index...index)
847
+ end
848
+ s0 << r2
849
+ if r2
850
+ r4 = _nt_line_to_eol
851
+ s0 << r4
852
+ end
853
+ end
854
+ if s0.last
855
+ r0 = (SyntaxNode).new(input, i0...index, s0)
856
+ r0.extend(GivenScenario0)
857
+ r0.extend(GivenScenario1)
858
+ else
859
+ self.index = i0
860
+ r0 = nil
861
+ end
862
+
863
+ node_cache[:given_scenario][start_index] = r0
864
+
865
+ return r0
866
+ end
867
+
868
+ module PlainStep0
869
+ def step_keyword
870
+ elements[0]
871
+ end
872
+
873
+ def name
874
+ elements[2]
875
+ end
876
+
877
+ def multi
878
+ elements[3]
879
+ end
880
+ end
881
+
882
+ module PlainStep1
883
+ def compile(scenario)
884
+ line = input.line_of(interval.first)
885
+ step = scenario.create_step(step_keyword.text_value, name.text_value.strip, line)
886
+
887
+ if multi.respond_to?(:to_arg)
888
+ step.extra_args << multi.to_arg
889
+ end
890
+ end
891
+ end
892
+
893
+ def _nt_plain_step
894
+ start_index = index
895
+ if node_cache[:plain_step].has_key?(index)
896
+ cached = node_cache[:plain_step][index]
897
+ @index = cached.interval.end if cached
898
+ return cached
899
+ end
900
+
901
+ i0, s0 = index, []
902
+ r1 = _nt_step_keyword
903
+ s0 << r1
904
+ if r1
905
+ r3 = _nt_space
906
+ if r3
907
+ r2 = r3
908
+ else
909
+ r2 = SyntaxNode.new(input, index...index)
910
+ end
911
+ s0 << r2
912
+ if r2
913
+ r4 = _nt_line_to_eol
914
+ s0 << r4
915
+ if r4
916
+ r6 = _nt_multiline_arg
917
+ if r6
918
+ r5 = r6
919
+ else
920
+ r5 = SyntaxNode.new(input, index...index)
921
+ end
922
+ s0 << r5
923
+ end
924
+ end
925
+ end
926
+ if s0.last
927
+ r0 = (SyntaxNode).new(input, i0...index, s0)
928
+ r0.extend(PlainStep0)
929
+ r0.extend(PlainStep1)
930
+ else
931
+ self.index = i0
932
+ r0 = nil
933
+ end
934
+
935
+ node_cache[:plain_step][start_index] = r0
936
+
937
+ return r0
938
+ end
939
+
940
+ def _nt_multiline_arg
941
+ start_index = index
942
+ if node_cache[:multiline_arg].has_key?(index)
943
+ cached = node_cache[:multiline_arg][index]
944
+ @index = cached.interval.end if cached
945
+ return cached
946
+ end
947
+
948
+ i0 = index
949
+ r1 = _nt_table
950
+ if r1
951
+ r0 = r1
952
+ else
953
+ r2 = _nt_multiline_string
954
+ if r2
955
+ r0 = r2
956
+ else
957
+ self.index = i0
958
+ r0 = nil
959
+ end
960
+ end
961
+
962
+ node_cache[:multiline_arg][start_index] = r0
963
+
964
+ return r0
965
+ end
966
+
967
+ module MultilineString0
968
+ end
969
+
970
+ module MultilineString1
971
+ def eol
972
+ elements[0]
973
+ end
974
+
975
+ def indent
976
+ elements[1]
977
+ end
978
+
979
+ def triple_quote
980
+ elements[2]
981
+ end
982
+
983
+ def string
984
+ elements[3]
985
+ end
986
+
987
+ def triple_quote
988
+ elements[4]
989
+ end
990
+ end
991
+
992
+ module MultilineString2
993
+ def to_arg
994
+ indent_length = indent.text_value.length
995
+ significant_lines = string.text_value.split("\n")[1..-2]
996
+ significant_lines.map do |l|
997
+ l[indent_length..-1]
998
+ end.join("\n")
999
+ end
1000
+ end
1001
+
1002
+ def _nt_multiline_string
1003
+ start_index = index
1004
+ if node_cache[:multiline_string].has_key?(index)
1005
+ cached = node_cache[:multiline_string][index]
1006
+ @index = cached.interval.end if cached
1007
+ return cached
1008
+ end
1009
+
1010
+ i0, s0 = index, []
1011
+ r1 = _nt_eol
1012
+ s0 << r1
1013
+ if r1
1014
+ r2 = _nt_space
1015
+ s0 << r2
1016
+ if r2
1017
+ r3 = _nt_triple_quote
1018
+ s0 << r3
1019
+ if r3
1020
+ s4, i4 = [], index
1021
+ loop do
1022
+ i5, s5 = index, []
1023
+ i6 = index
1024
+ r7 = _nt_triple_quote
1025
+ if r7
1026
+ r6 = nil
1027
+ else
1028
+ self.index = i6
1029
+ r6 = SyntaxNode.new(input, index...index)
1030
+ end
1031
+ s5 << r6
1032
+ if r6
1033
+ if index < input_length
1034
+ r8 = (SyntaxNode).new(input, index...(index + 1))
1035
+ @index += 1
1036
+ else
1037
+ terminal_parse_failure("any character")
1038
+ r8 = nil
1039
+ end
1040
+ s5 << r8
1041
+ end
1042
+ if s5.last
1043
+ r5 = (SyntaxNode).new(input, i5...index, s5)
1044
+ r5.extend(MultilineString0)
1045
+ else
1046
+ self.index = i5
1047
+ r5 = nil
1048
+ end
1049
+ if r5
1050
+ s4 << r5
1051
+ else
1052
+ break
1053
+ end
1054
+ end
1055
+ r4 = SyntaxNode.new(input, i4...index, s4)
1056
+ s0 << r4
1057
+ if r4
1058
+ r9 = _nt_triple_quote
1059
+ s0 << r9
1060
+ end
1061
+ end
1062
+ end
1063
+ end
1064
+ if s0.last
1065
+ r0 = (SyntaxNode).new(input, i0...index, s0)
1066
+ r0.extend(MultilineString1)
1067
+ r0.extend(MultilineString2)
1068
+ else
1069
+ self.index = i0
1070
+ r0 = nil
1071
+ end
1072
+
1073
+ node_cache[:multiline_string][start_index] = r0
1074
+
1075
+ return r0
1076
+ end
1077
+
1078
+ def _nt_triple_quote
1079
+ start_index = index
1080
+ if node_cache[:triple_quote].has_key?(index)
1081
+ cached = node_cache[:triple_quote][index]
1082
+ @index = cached.interval.end if cached
1083
+ return cached
1084
+ end
1085
+
1086
+ if input.index('"""', index) == index
1087
+ r0 = (SyntaxNode).new(input, index...(index + 3))
1088
+ @index += 3
1089
+ else
1090
+ terminal_parse_failure('"""')
1091
+ r0 = nil
1092
+ end
1093
+
1094
+ node_cache[:triple_quote][start_index] = r0
1095
+
1096
+ return r0
1097
+ end
1098
+
1099
+ def _nt_separator
1100
+ start_index = index
1101
+ if node_cache[:separator].has_key?(index)
1102
+ cached = node_cache[:separator][index]
1103
+ @index = cached.interval.end if cached
1104
+ return cached
1105
+ end
1106
+
1107
+ if input.index('|', index) == index
1108
+ r0 = (SyntaxNode).new(input, index...(index + 1))
1109
+ @index += 1
1110
+ else
1111
+ terminal_parse_failure('|')
1112
+ r0 = nil
1113
+ end
1114
+
1115
+ node_cache[:separator][start_index] = r0
1116
+
1117
+ return r0
1118
+ end
1119
+
1120
+ def _nt_space
1121
+ start_index = index
1122
+ if node_cache[:space].has_key?(index)
1123
+ cached = node_cache[:space][index]
1124
+ @index = cached.interval.end if cached
1125
+ return cached
1126
+ end
1127
+
1128
+ s0, i0 = [], index
1129
+ loop do
1130
+ i1 = index
1131
+ r2 = _nt_white
1132
+ if r2
1133
+ r1 = r2
1134
+ else
1135
+ r3 = _nt_comment_to_eol
1136
+ if r3
1137
+ r1 = r3
1138
+ else
1139
+ self.index = i1
1140
+ r1 = nil
1141
+ end
1142
+ end
1143
+ if r1
1144
+ s0 << r1
1145
+ else
1146
+ break
1147
+ end
1148
+ end
1149
+ if s0.empty?
1150
+ self.index = i0
1151
+ r0 = nil
1152
+ else
1153
+ r0 = SyntaxNode.new(input, i0...index, s0)
1154
+ end
1155
+
1156
+ node_cache[:space][start_index] = r0
1157
+
1158
+ return r0
1159
+ end
1160
+
1161
+ module LineToEol0
1162
+ end
1163
+
1164
+ def _nt_line_to_eol
1165
+ start_index = index
1166
+ if node_cache[:line_to_eol].has_key?(index)
1167
+ cached = node_cache[:line_to_eol][index]
1168
+ @index = cached.interval.end if cached
1169
+ return cached
1170
+ end
1171
+
1172
+ s0, i0 = [], index
1173
+ loop do
1174
+ i1, s1 = index, []
1175
+ i2 = index
1176
+ r3 = _nt_eol
1177
+ if r3
1178
+ r2 = nil
1179
+ else
1180
+ self.index = i2
1181
+ r2 = SyntaxNode.new(input, index...index)
1182
+ end
1183
+ s1 << r2
1184
+ if r2
1185
+ if index < input_length
1186
+ r4 = (SyntaxNode).new(input, index...(index + 1))
1187
+ @index += 1
1188
+ else
1189
+ terminal_parse_failure("any character")
1190
+ r4 = nil
1191
+ end
1192
+ s1 << r4
1193
+ end
1194
+ if s1.last
1195
+ r1 = (SyntaxNode).new(input, i1...index, s1)
1196
+ r1.extend(LineToEol0)
1197
+ else
1198
+ self.index = i1
1199
+ r1 = nil
1200
+ end
1201
+ if r1
1202
+ s0 << r1
1203
+ else
1204
+ break
1205
+ end
1206
+ end
1207
+ r0 = SyntaxNode.new(input, i0...index, s0)
1208
+
1209
+ node_cache[:line_to_eol][start_index] = r0
1210
+
1211
+ return r0
1212
+ end
1213
+
1214
+ module CommentToEol0
1215
+ def line_to_eol
1216
+ elements[1]
1217
+ end
1218
+ end
1219
+
1220
+ def _nt_comment_to_eol
1221
+ start_index = index
1222
+ if node_cache[:comment_to_eol].has_key?(index)
1223
+ cached = node_cache[:comment_to_eol][index]
1224
+ @index = cached.interval.end if cached
1225
+ return cached
1226
+ end
1227
+
1228
+ i0, s0 = index, []
1229
+ if input.index('#', index) == index
1230
+ r1 = (SyntaxNode).new(input, index...(index + 1))
1231
+ @index += 1
1232
+ else
1233
+ terminal_parse_failure('#')
1234
+ r1 = nil
1235
+ end
1236
+ s0 << r1
1237
+ if r1
1238
+ r2 = _nt_line_to_eol
1239
+ s0 << r2
1240
+ end
1241
+ if s0.last
1242
+ r0 = (SyntaxNode).new(input, i0...index, s0)
1243
+ r0.extend(CommentToEol0)
1244
+ else
1245
+ self.index = i0
1246
+ r0 = nil
1247
+ end
1248
+
1249
+ node_cache[:comment_to_eol][start_index] = r0
1250
+
1251
+ return r0
1252
+ end
1253
+
1254
+ def _nt_white
1255
+ start_index = index
1256
+ if node_cache[:white].has_key?(index)
1257
+ cached = node_cache[:white][index]
1258
+ @index = cached.interval.end if cached
1259
+ return cached
1260
+ end
1261
+
1262
+ i0 = index
1263
+ r1 = _nt_blank
1264
+ if r1
1265
+ r0 = r1
1266
+ else
1267
+ r2 = _nt_eol
1268
+ if r2
1269
+ r0 = r2
1270
+ else
1271
+ self.index = i0
1272
+ r0 = nil
1273
+ end
1274
+ end
1275
+
1276
+ node_cache[:white][start_index] = r0
1277
+
1278
+ return r0
1279
+ end
1280
+
1281
+ def _nt_blank
1282
+ start_index = index
1283
+ if node_cache[:blank].has_key?(index)
1284
+ cached = node_cache[:blank][index]
1285
+ @index = cached.interval.end if cached
1286
+ return cached
1287
+ end
1288
+
1289
+ if input.index(Regexp.new('[ \\t]'), index) == index
1290
+ r0 = (SyntaxNode).new(input, index...(index + 1))
1291
+ @index += 1
1292
+ else
1293
+ r0 = nil
1294
+ end
1295
+
1296
+ node_cache[:blank][start_index] = r0
1297
+
1298
+ return r0
1299
+ end
1300
+
1301
+ module Eol0
1302
+ end
1303
+
1304
+ def _nt_eol
1305
+ start_index = index
1306
+ if node_cache[:eol].has_key?(index)
1307
+ cached = node_cache[:eol][index]
1308
+ @index = cached.interval.end if cached
1309
+ return cached
1310
+ end
1311
+
1312
+ i0 = index
1313
+ i1, s1 = index, []
1314
+ if input.index("\r", index) == index
1315
+ r2 = (SyntaxNode).new(input, index...(index + 1))
1316
+ @index += 1
1317
+ else
1318
+ terminal_parse_failure("\r")
1319
+ r2 = nil
1320
+ end
1321
+ s1 << r2
1322
+ if r2
1323
+ if input.index("\n", index) == index
1324
+ r4 = (SyntaxNode).new(input, index...(index + 1))
1325
+ @index += 1
1326
+ else
1327
+ terminal_parse_failure("\n")
1328
+ r4 = nil
1329
+ end
1330
+ if r4
1331
+ r3 = r4
1332
+ else
1333
+ r3 = SyntaxNode.new(input, index...index)
1334
+ end
1335
+ s1 << r3
1336
+ end
1337
+ if s1.last
1338
+ r1 = (SyntaxNode).new(input, i1...index, s1)
1339
+ r1.extend(Eol0)
1340
+ else
1341
+ self.index = i1
1342
+ r1 = nil
1343
+ end
1344
+ if r1
1345
+ r0 = r1
1346
+ else
1347
+ if input.index("\n", index) == index
1348
+ r5 = (SyntaxNode).new(input, index...(index + 1))
1349
+ @index += 1
1350
+ else
1351
+ terminal_parse_failure("\n")
1352
+ r5 = nil
1353
+ end
1354
+ if r5
1355
+ r0 = r5
1356
+ else
1357
+ self.index = i0
1358
+ r0 = nil
1359
+ end
1360
+ end
1361
+
1362
+ node_cache[:eol][start_index] = r0
1363
+
1364
+ return r0
1365
+ end
1366
+
1367
+ def _nt_step_keyword
1368
+ start_index = index
1369
+ if node_cache[:step_keyword].has_key?(index)
1370
+ cached = node_cache[:step_keyword][index]
1371
+ @index = cached.interval.end if cached
1372
+ return cached
1373
+ end
1374
+
1375
+ i0 = index
1376
+ if input.index("GIVN", index) == index
1377
+ r1 = (SyntaxNode).new(input, index...(index + 4))
1378
+ @index += 4
1379
+ else
1380
+ terminal_parse_failure("GIVN")
1381
+ r1 = nil
1382
+ end
1383
+ if r1
1384
+ r0 = r1
1385
+ else
1386
+ if input.index("WEN", index) == index
1387
+ r2 = (SyntaxNode).new(input, index...(index + 3))
1388
+ @index += 3
1389
+ else
1390
+ terminal_parse_failure("WEN")
1391
+ r2 = nil
1392
+ end
1393
+ if r2
1394
+ r0 = r2
1395
+ else
1396
+ if input.index("DEN", index) == index
1397
+ r3 = (SyntaxNode).new(input, index...(index + 3))
1398
+ @index += 3
1399
+ else
1400
+ terminal_parse_failure("DEN")
1401
+ r3 = nil
1402
+ end
1403
+ if r3
1404
+ r0 = r3
1405
+ else
1406
+ if input.index("AN", index) == index
1407
+ r4 = (SyntaxNode).new(input, index...(index + 2))
1408
+ @index += 2
1409
+ else
1410
+ terminal_parse_failure("AN")
1411
+ r4 = nil
1412
+ end
1413
+ if r4
1414
+ r0 = r4
1415
+ else
1416
+ if input.index("BUT", index) == index
1417
+ r5 = (SyntaxNode).new(input, index...(index + 3))
1418
+ @index += 3
1419
+ else
1420
+ terminal_parse_failure("BUT")
1421
+ r5 = nil
1422
+ end
1423
+ if r5
1424
+ r0 = r5
1425
+ else
1426
+ self.index = i0
1427
+ r0 = nil
1428
+ end
1429
+ end
1430
+ end
1431
+ end
1432
+ end
1433
+
1434
+ node_cache[:step_keyword][start_index] = r0
1435
+
1436
+ return r0
1437
+ end
1438
+
1439
+ module ScenarioKeyword0
1440
+ end
1441
+
1442
+ def _nt_scenario_keyword
1443
+ start_index = index
1444
+ if node_cache[:scenario_keyword].has_key?(index)
1445
+ cached = node_cache[:scenario_keyword][index]
1446
+ @index = cached.interval.end if cached
1447
+ return cached
1448
+ end
1449
+
1450
+ i0, s0 = index, []
1451
+ if input.index("MISHUN", index) == index
1452
+ r1 = (SyntaxNode).new(input, index...(index + 6))
1453
+ @index += 6
1454
+ else
1455
+ terminal_parse_failure("MISHUN")
1456
+ r1 = nil
1457
+ end
1458
+ s0 << r1
1459
+ if r1
1460
+ if input.index(":", index) == index
1461
+ r3 = (SyntaxNode).new(input, index...(index + 1))
1462
+ @index += 1
1463
+ else
1464
+ terminal_parse_failure(":")
1465
+ r3 = nil
1466
+ end
1467
+ if r3
1468
+ r2 = r3
1469
+ else
1470
+ r2 = SyntaxNode.new(input, index...index)
1471
+ end
1472
+ s0 << r2
1473
+ end
1474
+ if s0.last
1475
+ r0 = (SyntaxNode).new(input, i0...index, s0)
1476
+ r0.extend(ScenarioKeyword0)
1477
+ else
1478
+ self.index = i0
1479
+ r0 = nil
1480
+ end
1481
+
1482
+ node_cache[:scenario_keyword][start_index] = r0
1483
+
1484
+ return r0
1485
+ end
1486
+
1487
+ module MoreExamplesKeyword0
1488
+ end
1489
+
1490
+ def _nt_more_examples_keyword
1491
+ start_index = index
1492
+ if node_cache[:more_examples_keyword].has_key?(index)
1493
+ cached = node_cache[:more_examples_keyword][index]
1494
+ @index = cached.interval.end if cached
1495
+ return cached
1496
+ end
1497
+
1498
+ i0, s0 = index, []
1499
+ if input.index("MOAR EXAMPLZ", index) == index
1500
+ r1 = (SyntaxNode).new(input, index...(index + 12))
1501
+ @index += 12
1502
+ else
1503
+ terminal_parse_failure("MOAR EXAMPLZ")
1504
+ r1 = nil
1505
+ end
1506
+ s0 << r1
1507
+ if r1
1508
+ if input.index(":", index) == index
1509
+ r3 = (SyntaxNode).new(input, index...(index + 1))
1510
+ @index += 1
1511
+ else
1512
+ terminal_parse_failure(":")
1513
+ r3 = nil
1514
+ end
1515
+ if r3
1516
+ r2 = r3
1517
+ else
1518
+ r2 = SyntaxNode.new(input, index...index)
1519
+ end
1520
+ s0 << r2
1521
+ end
1522
+ if s0.last
1523
+ r0 = (SyntaxNode).new(input, i0...index, s0)
1524
+ r0.extend(MoreExamplesKeyword0)
1525
+ else
1526
+ self.index = i0
1527
+ r0 = nil
1528
+ end
1529
+
1530
+ node_cache[:more_examples_keyword][start_index] = r0
1531
+
1532
+ return r0
1533
+ end
1534
+
1535
+ module GivenScenarioKeyword0
1536
+ end
1537
+
1538
+ def _nt_given_scenario_keyword
1539
+ start_index = index
1540
+ if node_cache[:given_scenario_keyword].has_key?(index)
1541
+ cached = node_cache[:given_scenario_keyword][index]
1542
+ @index = cached.interval.end if cached
1543
+ return cached
1544
+ end
1545
+
1546
+ i0, s0 = index, []
1547
+ if input.index("SRSLY", index) == index
1548
+ r1 = (SyntaxNode).new(input, index...(index + 5))
1549
+ @index += 5
1550
+ else
1551
+ terminal_parse_failure("SRSLY")
1552
+ r1 = nil
1553
+ end
1554
+ s0 << r1
1555
+ if r1
1556
+ if input.index(":", index) == index
1557
+ r3 = (SyntaxNode).new(input, index...(index + 1))
1558
+ @index += 1
1559
+ else
1560
+ terminal_parse_failure(":")
1561
+ r3 = nil
1562
+ end
1563
+ if r3
1564
+ r2 = r3
1565
+ else
1566
+ r2 = SyntaxNode.new(input, index...index)
1567
+ end
1568
+ s0 << r2
1569
+ end
1570
+ if s0.last
1571
+ r0 = (SyntaxNode).new(input, i0...index, s0)
1572
+ r0.extend(GivenScenarioKeyword0)
1573
+ else
1574
+ self.index = i0
1575
+ r0 = nil
1576
+ end
1577
+
1578
+ node_cache[:given_scenario_keyword][start_index] = r0
1579
+
1580
+ return r0
1581
+ end
1582
+
1583
+ end
1584
+
1585
+ class FeatureParser < Treetop::Runtime::CompiledParser
1586
+ include Feature
1587
+ end
1588
+
1589
+
1590
+ end
1591
+ end