cucumber 0.6.4 → 0.7.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/Rakefile +3 -5
- data/VERSION.yml +3 -3
- data/cucumber.gemspec +35 -55
- data/cucumber.yml +3 -2
- data/examples/i18n/Rakefile +1 -0
- data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +1 -1
- data/examples/i18n/eo/.gitignore +1 -0
- data/examples/i18n/eo/Rakefile +6 -0
- data/examples/i18n/eo/features/adicio.feature +17 -0
- data/examples/i18n/eo/features/divido.feature +10 -0
- data/examples/i18n/eo/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/eo/lib/calculator.rb +14 -0
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +1 -1
- data/examples/i18n/ru/features/division.feature +1 -1
- data/examples/i18n/uk/Rakefile +6 -0
- data/examples/i18n/uk/features/addition.feature +11 -0
- data/examples/i18n/uk/features/consecutive_calculations.feature +17 -0
- data/examples/i18n/uk/features/division.feature +16 -0
- data/examples/i18n/uk/features/step_definitons/calculator_steps.rb +19 -0
- data/examples/i18n/uk/features/support/env.rb +5 -0
- data/examples/i18n/uk/features/support/world.rb +8 -0
- data/examples/i18n/uk/lib/calculator.rb +24 -0
- data/examples/i18n/uz/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/sinatra/features/add.feature +1 -1
- data/examples/sinatra/features/step_definitions/add_steps.rb +1 -1
- data/examples/sinatra/features/support/env.rb +2 -19
- data/examples/sinatra/views/add.erb +7 -5
- data/features/announce.feature +46 -39
- data/features/background.feature +3 -0
- data/features/call_many_steps.feature +1 -1
- data/features/cucumber_cli_outlines.feature +12 -0
- data/features/drb_server_integration.feature +1 -1
- data/features/exception_in_after_block.feature +3 -0
- data/features/exception_in_after_step_block.feature +3 -0
- data/features/html_formatter/a.html +29 -29
- data/features/language_help.feature +57 -52
- data/features/multiline_names.feature +1 -0
- data/features/step_definitions/cucumber_steps.rb +2 -1
- data/features/usage_and_stepdefs_formatter.feature +30 -30
- data/features/wire_protocol.feature +12 -9
- data/features/wire_protocol_table_diffing.feature +8 -6
- data/features/wire_protocol_timeouts.feature +5 -4
- data/gem_tasks/treetop.rake +13 -0
- data/lib/autotest/cucumber_mixin.rb +1 -1
- data/lib/cucumber/ast.rb +1 -0
- data/lib/cucumber/ast/background.rb +14 -4
- data/lib/cucumber/ast/examples.rb +2 -0
- data/lib/cucumber/ast/feature.rb +26 -5
- data/lib/cucumber/ast/feature_element.rb +18 -9
- data/lib/cucumber/ast/outline_table.rb +13 -1
- data/lib/cucumber/ast/py_string.rb +26 -9
- data/lib/cucumber/ast/scenario.rb +13 -7
- data/lib/cucumber/ast/scenario_outline.rb +18 -6
- data/lib/cucumber/ast/step.rb +4 -4
- data/lib/cucumber/ast/step_invocation.rb +5 -2
- data/lib/cucumber/ast/table.rb +26 -1
- data/lib/cucumber/ast/tags.rb +3 -1
- data/lib/cucumber/ast/tree_walker.rb +2 -18
- data/lib/cucumber/cli/configuration.rb +2 -2
- data/lib/cucumber/cli/options.rb +16 -21
- data/lib/cucumber/feature_file.rb +25 -7
- data/lib/cucumber/formatter/ansicolor.rb +6 -1
- data/lib/cucumber/formatter/console.rb +4 -3
- data/lib/cucumber/formatter/html.rb +8 -5
- data/lib/cucumber/formatter/junit.rb +5 -4
- data/lib/cucumber/formatter/pdf.rb +2 -3
- data/lib/cucumber/formatter/pretty.rb +5 -5
- data/lib/cucumber/formatter/usage.rb +2 -2
- data/lib/cucumber/parser.rb +0 -6
- data/lib/cucumber/parser/gherkin_builder.rb +142 -0
- data/lib/cucumber/platform.rb +0 -2
- data/lib/cucumber/rb_support/rb_language.rb +7 -12
- data/lib/cucumber/step_mother.rb +4 -26
- data/spec/cucumber/ast/background_spec.rb +0 -1
- data/spec/cucumber/ast/feature_factory.rb +2 -4
- data/spec/cucumber/ast/feature_spec.rb +0 -2
- data/spec/cucumber/ast/py_string_spec.rb +2 -13
- data/spec/cucumber/ast/scenario_outline_spec.rb +0 -1
- data/spec/cucumber/ast/scenario_spec.rb +0 -1
- data/spec/cucumber/ast/step_spec.rb +1 -1
- data/spec/cucumber/ast/table_spec.rb +2 -2
- data/spec/cucumber/cli/main_spec.rb +1 -1
- data/spec/cucumber/cli/options_spec.rb +2 -2
- data/spec/cucumber/formatter/html_spec.rb +20 -1
- data/spec/cucumber/formatter/junit_spec.rb +1 -0
- data/spec/cucumber/formatter/spec_helper.rb +7 -5
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +0 -1
- data/spec/cucumber/step_mother_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- metadata +67 -93
- data/lib/cucumber/cli/language_help_formatter.rb +0 -72
- data/lib/cucumber/filter.rb +0 -43
- data/lib/cucumber/languages.yml +0 -536
- data/lib/cucumber/parser/common.rb +0 -182
- data/lib/cucumber/parser/common.tt +0 -21
- data/lib/cucumber/parser/feature.rb +0 -1591
- data/lib/cucumber/parser/feature.tt +0 -287
- data/lib/cucumber/parser/i18n.tt +0 -35
- data/lib/cucumber/parser/natural_language.rb +0 -118
- data/lib/cucumber/parser/py_string.rb +0 -285
- data/lib/cucumber/parser/py_string.tt +0 -45
- data/lib/cucumber/parser/table.rb +0 -314
- data/lib/cucumber/parser/table.tt +0 -60
- data/lib/cucumber/parser/treetop_ext.rb +0 -54
- data/lib/cucumber/tag_expression.rb +0 -41
- data/spec/cucumber/ast/feature_element_spec.rb +0 -41
- data/spec/cucumber/ast/step_collection_spec.rb +0 -17
- data/spec/cucumber/parser/feature_parser_spec.rb +0 -400
- data/spec/cucumber/parser/table_parser_spec.rb +0 -52
- data/spec/cucumber/tag_expression_spec.rb +0 -125
- data/spec/cucumber/treetop_parser/empty_feature.feature +0 -4
- data/spec/cucumber/treetop_parser/empty_scenario.feature +0 -9
- data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +0 -3
- data/spec/cucumber/treetop_parser/fit_scenario.feature +0 -8
- data/spec/cucumber/treetop_parser/given_scenario.feature +0 -9
- data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +0 -7
- data/spec/cucumber/treetop_parser/multiline_steps.feature +0 -17
- data/spec/cucumber/treetop_parser/multiple_tables.feature +0 -27
- data/spec/cucumber/treetop_parser/scenario_outline.feature +0 -16
- data/spec/cucumber/treetop_parser/spaces.feature +0 -12
- data/spec/cucumber/treetop_parser/test_dos.feature +0 -25
- data/spec/cucumber/treetop_parser/with_comments.feature +0 -23
- data/spec/cucumber/treetop_parser/with_tags.feature +0 -18
data/lib/cucumber/ast/tags.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'gherkin/parser/tag_expression'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Ast
|
3
5
|
class Tags #:nodoc:
|
@@ -15,7 +17,7 @@ module Cucumber
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def accept_hook?(hook)
|
18
|
-
TagExpression.
|
20
|
+
Gherkin::Parser::TagExpression.new(hook.tag_expressions).eval(@tag_names)
|
19
21
|
end
|
20
22
|
|
21
23
|
def to_sexp
|
@@ -41,8 +41,8 @@ module Cucumber
|
|
41
41
|
broadcast(tag_name)
|
42
42
|
end
|
43
43
|
|
44
|
-
def visit_feature_name(name)
|
45
|
-
broadcast(name)
|
44
|
+
def visit_feature_name(keyword, name)
|
45
|
+
broadcast(keyword, name)
|
46
46
|
end
|
47
47
|
|
48
48
|
# +feature_element+ is either Scenario or ScenarioOutline
|
@@ -75,22 +75,6 @@ module Cucumber
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def visit_examples_name(keyword, name)
|
78
|
-
unless keyword =~ /:$/
|
79
|
-
message = <<EOS
|
80
|
-
|
81
|
-
|
82
|
-
(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)
|
83
|
-
|
84
|
-
DEPRECATION WARNING
|
85
|
-
|
86
|
-
Future versions of Cucumber will not recognize #{keyword}
|
87
|
-
unless it is followed by a colon. Make this change in
|
88
|
-
your features now to prevent this warning from appearing.
|
89
|
-
|
90
|
-
(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)(::)
|
91
|
-
EOS
|
92
|
-
announce(message)
|
93
|
-
end
|
94
78
|
broadcast(keyword, name)
|
95
79
|
end
|
96
80
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'cucumber/cli/options'
|
3
3
|
require 'cucumber/constantize'
|
4
|
-
require '
|
4
|
+
require 'gherkin/parser/tag_expression'
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
module Cli
|
@@ -26,7 +26,7 @@ module Cucumber
|
|
26
26
|
arrange_formats
|
27
27
|
raise("You can't use both --strict and --wip") if strict? && wip?
|
28
28
|
|
29
|
-
@options[:tag_expression] = TagExpression.
|
29
|
+
@options[:tag_expression] = Gherkin::Parser::TagExpression.new(@options[:tag_expressions])
|
30
30
|
return @args.replace(@options.expanded_args_without_drb) if drb?
|
31
31
|
|
32
32
|
set_environment_variables
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'cucumber/cli/profile_loader'
|
2
2
|
require 'cucumber/formatter/ansicolor'
|
3
|
-
require '
|
3
|
+
require 'gherkin/parser/tag_expression'
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
module Cli
|
@@ -279,6 +279,10 @@ module Cucumber
|
|
279
279
|
@profiles - [@default_profile]
|
280
280
|
end
|
281
281
|
|
282
|
+
def filters
|
283
|
+
@options.values_at(:name_regexps, :tag_expressions).select{|v| !v.empty?}.first || []
|
284
|
+
end
|
285
|
+
|
282
286
|
protected
|
283
287
|
|
284
288
|
attr_reader :options, :profiles, :expanded_args
|
@@ -286,15 +290,15 @@ module Cucumber
|
|
286
290
|
|
287
291
|
private
|
288
292
|
|
289
|
-
|
290
|
-
|
291
|
-
|
293
|
+
def non_stdout_formats
|
294
|
+
@options[:formats].select {|format, output| output != @out_stream }
|
295
|
+
end
|
292
296
|
|
293
|
-
|
294
|
-
|
295
|
-
|
297
|
+
def stdout_formats
|
298
|
+
@options[:formats].select {|format, output| output == @out_stream }
|
299
|
+
end
|
296
300
|
|
297
|
-
|
301
|
+
def extract_environment_variables
|
298
302
|
@args.delete_if do |arg|
|
299
303
|
if arg =~ /^(\w+)=(.*)$/
|
300
304
|
@options[:env_vars][$1] = $2
|
@@ -303,10 +307,6 @@ module Cucumber
|
|
303
307
|
end
|
304
308
|
end
|
305
309
|
|
306
|
-
def tag_filter(tag_string)
|
307
|
-
tags = TagExpression.parse(tag_string)
|
308
|
-
end
|
309
|
-
|
310
310
|
def disable_profile_loading?
|
311
311
|
@disable_profile_loading
|
312
312
|
end
|
@@ -325,7 +325,6 @@ module Cucumber
|
|
325
325
|
Options.parse(profile_args, @out_stream, @error_stream, :skip_profile_information => true)
|
326
326
|
)
|
327
327
|
end
|
328
|
-
|
329
328
|
end
|
330
329
|
|
331
330
|
def default_profile_should_be_used?
|
@@ -367,19 +366,15 @@ module Cucumber
|
|
367
366
|
self
|
368
367
|
end
|
369
368
|
|
370
|
-
# TODO: Move to Language
|
371
369
|
def list_keywords_and_exit(lang)
|
372
|
-
|
373
|
-
|
374
|
-
end
|
375
|
-
require 'cucumber/cli/language_help_formatter'
|
376
|
-
LanguageHelpFormatter.list_keywords(@out_stream, lang)
|
370
|
+
require 'gherkin/i18n'
|
371
|
+
@out_stream.write(Gherkin::I18n.get(lang).keyword_table)
|
377
372
|
Kernel.exit(0)
|
378
373
|
end
|
379
374
|
|
380
375
|
def list_languages_and_exit
|
381
|
-
require '
|
382
|
-
|
376
|
+
require 'gherkin/i18n'
|
377
|
+
@out_stream.write(Gherkin::I18n.language_table)
|
383
378
|
Kernel.exit(0)
|
384
379
|
end
|
385
380
|
|
@@ -1,5 +1,7 @@
|
|
1
|
-
require 'cucumber/parser/
|
2
|
-
require '
|
1
|
+
require 'cucumber/parser/gherkin_builder'
|
2
|
+
require 'gherkin/parser/filter_listener'
|
3
|
+
require 'gherkin/parser/parser'
|
4
|
+
require 'gherkin/i18n_lexer'
|
3
5
|
|
4
6
|
module Cucumber
|
5
7
|
class FeatureFile
|
@@ -22,11 +24,26 @@ module Cucumber
|
|
22
24
|
# If +options+ contains tags, the result will
|
23
25
|
# be filtered.
|
24
26
|
def parse(step_mother, options)
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
filters = @lines || options.filters
|
28
|
+
|
29
|
+
builder = Cucumber::Parser::GherkinBuilder.new
|
30
|
+
filter_listener = Gherkin::Parser::FilterListener.new(builder, filters)
|
31
|
+
parser = Gherkin::Parser::Parser.new(filter_listener, true, "root")
|
32
|
+
lexer = Gherkin::I18nLexer.new(parser, false)
|
33
|
+
|
34
|
+
begin
|
35
|
+
lexer.scan(source)
|
36
|
+
ast = builder.ast
|
37
|
+
return nil if ast.nil? # Filter caused nothing to match
|
38
|
+
ast.language = lexer.i18n_language
|
39
|
+
ast.file = @path
|
40
|
+
ast
|
41
|
+
rescue Gherkin::LexingError => e
|
42
|
+
e.message.insert(0, "#{@path}: ")
|
43
|
+
raise e
|
44
|
+
end
|
28
45
|
end
|
29
|
-
|
46
|
+
|
30
47
|
def source
|
31
48
|
@source ||= if @path =~ /^http/
|
32
49
|
require 'open-uri'
|
@@ -43,6 +60,7 @@ module Cucumber
|
|
43
60
|
end
|
44
61
|
|
45
62
|
def lang
|
63
|
+
# TODO: Gherkin has logic for this. Remove.
|
46
64
|
line_one = source.split(/\n/)[0]
|
47
65
|
if line_one =~ LANGUAGE_PATTERN
|
48
66
|
$1.strip
|
@@ -51,4 +69,4 @@ module Cucumber
|
|
51
69
|
end
|
52
70
|
end
|
53
71
|
end
|
54
|
-
end
|
72
|
+
end
|
@@ -22,7 +22,7 @@ module Cucumber
|
|
22
22
|
end
|
23
23
|
|
24
24
|
format = format_for(status, :param)
|
25
|
-
line = keyword +
|
25
|
+
line = keyword + step_match.format_args(format) + comment
|
26
26
|
format_string(line, status)
|
27
27
|
end
|
28
28
|
|
@@ -63,9 +63,10 @@ module Cucumber
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def print_stats(features, profiles = [])
|
66
|
-
@failures = step_mother.scenarios(:failed).select { |s| s.is_a?(Cucumber::Ast::Scenario) }
|
66
|
+
@failures = step_mother.scenarios(:failed).select { |s| s.is_a?(Cucumber::Ast::Scenario) || s.is_a?(Cucumber::Ast::OutlineTable::ExampleRow) }
|
67
|
+
@failures.collect! { |s| (s.is_a?(Cucumber::Ast::OutlineTable::ExampleRow)) ? s.scenario_outline : s }
|
67
68
|
|
68
|
-
if !@failures.empty?
|
69
|
+
if !@failures.empty?
|
69
70
|
@io.puts format_string("Failing Scenarios:", :failed)
|
70
71
|
@failures.each do |failure|
|
71
72
|
profiles_string = profiles.empty? ? '' : (profiles.map{|profile| "-p #{profile}" }).join(' ') + ' '
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'erb'
|
1
2
|
require 'cucumber/formatter/ordered_xml_markup'
|
2
3
|
require 'cucumber/formatter/duration'
|
3
4
|
require 'cucumber/formatter/io'
|
@@ -109,11 +110,11 @@ module Cucumber
|
|
109
110
|
@builder.span(tag_name, :class => 'tag')
|
110
111
|
end
|
111
112
|
|
112
|
-
def feature_name(name)
|
113
|
+
def feature_name(keyword, name)
|
113
114
|
lines = name.split(/\r?\n/)
|
114
115
|
return if lines.empty?
|
115
116
|
@builder.h2 do |h2|
|
116
|
-
@builder.span(lines[0], :class => 'val')
|
117
|
+
@builder.span(keyword + ': ' + lines[0], :class => 'val')
|
117
118
|
end
|
118
119
|
@builder.p(:class => 'narrative') do
|
119
120
|
lines[1..-1].each do |line|
|
@@ -383,11 +384,14 @@ module Cucumber
|
|
383
384
|
features.each do |feature|
|
384
385
|
#get background steps
|
385
386
|
if feature.instance_variable_get("@background")
|
386
|
-
background = feature.instance_variable_get("@background")
|
387
|
-
|
387
|
+
background = feature.instance_variable_get("@background")
|
388
|
+
background.init
|
389
|
+
background_steps = background.instance_variable_get("@steps").instance_variable_get("@steps")
|
390
|
+
count += background_steps.size
|
388
391
|
end
|
389
392
|
#get scenarios
|
390
393
|
feature.instance_variable_get("@feature_elements").each do |scenario|
|
394
|
+
scenario.init
|
391
395
|
#get steps
|
392
396
|
steps = scenario.instance_variable_get("@steps").instance_variable_get("@steps")
|
393
397
|
count += steps.size
|
@@ -417,7 +421,6 @@ module Cucumber
|
|
417
421
|
step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
|
418
422
|
@builder.div(:class => 'step_name') do |div|
|
419
423
|
@builder.span(keyword, :class => 'keyword')
|
420
|
-
@builder.text!(' ')
|
421
424
|
@builder.span(:class => 'step val') do |name|
|
422
425
|
name << h(step_name).gsub(/<span class="(.*?)">/, '<span class="\1">').gsub(/<\/span>/, '</span>')
|
423
426
|
end
|
@@ -49,15 +49,16 @@ module Cucumber
|
|
49
49
|
@in_background = false
|
50
50
|
end
|
51
51
|
|
52
|
-
def feature_name(name)
|
52
|
+
def feature_name(keyword, name)
|
53
53
|
raise UnNamedFeatureError.new(@current_feature.file) if name.empty?
|
54
54
|
lines = name.split(/\r?\n/)
|
55
|
-
@feature_name = lines[0]
|
55
|
+
@feature_name = lines[0]
|
56
56
|
end
|
57
57
|
|
58
58
|
def scenario_name(keyword, name, file_colon_line, source_indent)
|
59
|
+
# TODO: What's all this ugly weird code doing? Why not just use keyword and name????
|
59
60
|
scenario_name = name.strip.delete(".\r\n")
|
60
|
-
scenario_name = "Unnamed scenario" if name
|
61
|
+
scenario_name = "Unnamed scenario" if name == ""
|
61
62
|
@scenario = scenario_name
|
62
63
|
description = "Scenario"
|
63
64
|
description << " outline" if keyword.include?('Scenario Outline')
|
@@ -73,7 +74,7 @@ module Cucumber
|
|
73
74
|
|
74
75
|
duration = Time.now - @steps_start
|
75
76
|
if steps.failed?
|
76
|
-
steps.each { |step| @output += "#{step.keyword}
|
77
|
+
steps.each { |step| @output += "#{step.keyword}#{step.name}\n" }
|
77
78
|
@output += "\nMessage:\n"
|
78
79
|
end
|
79
80
|
build_testcase(duration, steps.status, steps.exception)
|
@@ -94,12 +94,11 @@ module Cucumber
|
|
94
94
|
puts "\ndone"
|
95
95
|
end
|
96
96
|
|
97
|
-
def feature_name(name)
|
97
|
+
def feature_name(keyword, name)
|
98
98
|
@pdf.start_new_page
|
99
|
-
name["Feature:"] = "" if name["Feature:"]
|
100
99
|
names = name.split("\n")
|
101
100
|
@pdf.fill_color GREY
|
102
|
-
@pdf.text(
|
101
|
+
@pdf.text(keyword, :align => :center)
|
103
102
|
@pdf.fill_color BLACK
|
104
103
|
names.each_with_index do |nameline, i|
|
105
104
|
case i
|
@@ -60,8 +60,8 @@ module Cucumber
|
|
60
60
|
@indent = 1
|
61
61
|
end
|
62
62
|
|
63
|
-
def feature_name(name)
|
64
|
-
@io.puts(name)
|
63
|
+
def feature_name(keyword, name)
|
64
|
+
@io.puts("#{keyword}: #{name}")
|
65
65
|
@io.puts
|
66
66
|
@io.flush
|
67
67
|
end
|
@@ -102,7 +102,7 @@ module Cucumber
|
|
102
102
|
puts unless @visiting_first_example_name
|
103
103
|
@visiting_first_example_name = false
|
104
104
|
names = name.strip.empty? ? [name.strip] : name.split("\n")
|
105
|
-
@io.puts(" #{keyword} #{names[0]}")
|
105
|
+
@io.puts(" #{keyword}: #{names[0]}")
|
106
106
|
names[1..-1].each {|s| @io.puts " #{s}" } unless names.empty?
|
107
107
|
@io.flush
|
108
108
|
@indent = 6
|
@@ -119,7 +119,7 @@ module Cucumber
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def scenario_name(keyword, name, file_colon_line, source_indent)
|
122
|
-
print_feature_element_name
|
122
|
+
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
123
123
|
end
|
124
124
|
|
125
125
|
def before_step(step)
|
@@ -210,7 +210,7 @@ module Cucumber
|
|
210
210
|
def print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
211
211
|
@io.puts if @scenario_indent == 6
|
212
212
|
names = name.empty? ? [name] : name.split("\n")
|
213
|
-
line = "#{keyword} #{names[0]}".indent(@scenario_indent)
|
213
|
+
line = "#{keyword}: #{names[0]}".indent(@scenario_indent)
|
214
214
|
@io.print(line)
|
215
215
|
if @options[:source]
|
216
216
|
line_comment = " # #{file_colon_line}".indent(source_indent)
|
@@ -69,7 +69,7 @@ module Cucumber
|
|
69
69
|
@io.print format_string(stepdef_key.regexp_source, stepdef_key.status)
|
70
70
|
if @options[:source]
|
71
71
|
indent = max_length - stepdef_key.regexp_source.jlength
|
72
|
-
line_comment = "
|
72
|
+
line_comment = " # #{stepdef_key.file_colon_line}".indent(indent)
|
73
73
|
@io.print(format_string(line_comment, :comment))
|
74
74
|
end
|
75
75
|
@io.puts
|
@@ -98,7 +98,7 @@ module Cucumber
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def max_step_length
|
101
|
-
@stepdef_to_match.values.flatten.map do |step|
|
101
|
+
@stepdef_to_match.values.to_a.flatten.map do |step|
|
102
102
|
step[:keyword].jlength + step[:step_match].format_args.jlength
|
103
103
|
end.max
|
104
104
|
end
|
data/lib/cucumber/parser.rb
CHANGED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'cucumber/ast'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Parser
|
5
|
+
# This class conforms to the Gherkin event API and builds the
|
6
|
+
# "legacy" AST. It will be replaced later when we have a new "clean"
|
7
|
+
# AST.
|
8
|
+
class GherkinBuilder
|
9
|
+
|
10
|
+
def ast
|
11
|
+
@feature || @multiline_arg
|
12
|
+
end
|
13
|
+
|
14
|
+
def tag(name, line)
|
15
|
+
@tags ||= []
|
16
|
+
@tags << name
|
17
|
+
end
|
18
|
+
|
19
|
+
def comment(content, line)
|
20
|
+
@comments ||= []
|
21
|
+
@comments << content
|
22
|
+
end
|
23
|
+
|
24
|
+
def feature(keyword, name, line)
|
25
|
+
@feature = Ast::Feature.new(
|
26
|
+
nil,
|
27
|
+
Ast::Comment.new(grab_comments!('')),
|
28
|
+
Ast::Tags.new(nil, grab_tags!('')),
|
29
|
+
keyword,
|
30
|
+
name,
|
31
|
+
[]
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def background(keyword, name, line)
|
36
|
+
@background = Ast::Background.new(
|
37
|
+
Ast::Comment.new(grab_comments!('')),
|
38
|
+
line,
|
39
|
+
keyword,
|
40
|
+
name,
|
41
|
+
steps=[]
|
42
|
+
)
|
43
|
+
@feature.background = @background
|
44
|
+
@background.feature = @feature
|
45
|
+
@step_container = @background
|
46
|
+
end
|
47
|
+
|
48
|
+
def scenario(keyword, name, line)
|
49
|
+
grab_table!
|
50
|
+
scenario = Ast::Scenario.new(
|
51
|
+
@background,
|
52
|
+
Ast::Comment.new(grab_comments!('')),
|
53
|
+
Ast::Tags.new(nil, grab_tags!('')),
|
54
|
+
line,
|
55
|
+
keyword,
|
56
|
+
name,
|
57
|
+
steps=[]
|
58
|
+
)
|
59
|
+
@feature.add_feature_element(scenario)
|
60
|
+
@background.feature_elements << scenario if @background
|
61
|
+
@step_container = scenario
|
62
|
+
end
|
63
|
+
|
64
|
+
def scenario_outline(keyword, name, line)
|
65
|
+
grab_table!
|
66
|
+
scenario_outline = Ast::ScenarioOutline.new(
|
67
|
+
@background,
|
68
|
+
Ast::Comment.new(grab_comments!('')),
|
69
|
+
Ast::Tags.new(nil, grab_tags!('')),
|
70
|
+
line,
|
71
|
+
keyword,
|
72
|
+
name,
|
73
|
+
steps=[],
|
74
|
+
example_sections=[]
|
75
|
+
)
|
76
|
+
@feature.add_feature_element(scenario_outline)
|
77
|
+
@background.feature_elements << scenario_outline if @background
|
78
|
+
@step_container = scenario_outline
|
79
|
+
end
|
80
|
+
|
81
|
+
def examples(keyword, name, line)
|
82
|
+
grab_table!
|
83
|
+
@examples_fields = [Ast::Comment.new(grab_comments!('')), line, keyword, name]
|
84
|
+
end
|
85
|
+
|
86
|
+
def step(keyword, name, line)
|
87
|
+
grab_table!
|
88
|
+
@table_owner = Ast::Step.new(line, keyword, name)
|
89
|
+
@step_container.add_step(@table_owner)
|
90
|
+
end
|
91
|
+
|
92
|
+
def row(row, line)
|
93
|
+
@rows ||= []
|
94
|
+
@rows << row
|
95
|
+
class << row
|
96
|
+
attr_accessor :line
|
97
|
+
end
|
98
|
+
row.line = line
|
99
|
+
end
|
100
|
+
|
101
|
+
def py_string(string, line)
|
102
|
+
@multiline_arg = Ast::PyString.new(string)
|
103
|
+
@table_owner.multiline_arg = @multiline_arg if @table_owner
|
104
|
+
end
|
105
|
+
|
106
|
+
def eof
|
107
|
+
grab_table!
|
108
|
+
end
|
109
|
+
|
110
|
+
def syntax_error(state, event, legal_events, line)
|
111
|
+
# raise "SYNTAX ERROR"
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def grab_table!
|
117
|
+
return if @rows.nil?
|
118
|
+
if @examples_fields
|
119
|
+
@examples_fields << @rows
|
120
|
+
@step_container.add_examples(@examples_fields)
|
121
|
+
@examples_fields = nil
|
122
|
+
else
|
123
|
+
@multiline_arg = Ast::Table.new(@rows)
|
124
|
+
@table_owner.multiline_arg = @multiline_arg if @table_owner
|
125
|
+
end
|
126
|
+
@rows = nil
|
127
|
+
end
|
128
|
+
|
129
|
+
def grab_tags!(indent)
|
130
|
+
tags = @tags ? @tags : []
|
131
|
+
@tags = nil
|
132
|
+
tags
|
133
|
+
end
|
134
|
+
|
135
|
+
def grab_comments!(indent)
|
136
|
+
comments = @comments ? indent + @comments.join("\n#{indent}") : ''
|
137
|
+
@comments = nil
|
138
|
+
comments
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|