cucumber 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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