cucumber 1.2.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +14 -6
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +2 -2
- data/History.md +38 -2
- data/bin/cucumber +2 -11
- data/cucumber.gemspec +3 -3
- data/cucumber.yml +5 -1
- data/examples/test_unit/Gemfile +4 -0
- data/examples/test_unit/features/step_definitions/test_unit_steps.rb +1 -4
- data/examples/watir/README.textile +2 -2
- data/examples/watir/features/support/env.rb +10 -7
- data/features/.cucumber/stepdefs.json +747 -1354
- data/features/assertions.feature +6 -2
- data/features/background.feature +3 -0
- data/features/backtraces.feature +3 -3
- data/features/before_hook.feature +43 -0
- data/features/bootstrap.feature +14 -2
- data/features/custom_formatter.feature +1 -1
- data/features/drb_server_integration.feature +3 -3
- data/features/formatter_callbacks.feature +2 -2
- data/features/formatter_step_file_colon_line.feature +1 -1
- data/features/html_formatter.feature +52 -1
- data/features/json_formatter.feature +93 -7
- data/features/load_path.feature +14 -0
- data/features/nested_steps.feature +75 -3
- data/features/nested_steps_i18n.feature +36 -0
- data/features/pretty_formatter.feature +31 -0
- data/features/progress_formatter.feature +31 -0
- data/features/raketask.feature +51 -0
- data/features/rerun_formatter.feature +1 -1
- data/features/stats_formatters.feature +17 -14
- data/features/step_definitions/cucumber_steps.rb +6 -4
- data/features/support/env.rb +31 -4
- data/features/support/feature_factory.rb +17 -0
- data/features/tagged_hooks.feature +37 -195
- data/features/transforms.feature +15 -15
- data/gem_tasks/cucumber.rake +2 -0
- data/gem_tasks/yard.rake +10 -6
- data/legacy_features/README.md +14 -0
- data/legacy_features/language_help.feature +3 -1
- data/legacy_features/report_called_undefined_steps.feature +1 -0
- data/legacy_features/snippets_when_using_star_keyword.feature +1 -0
- data/legacy_features/support/env.rb +4 -0
- data/lib/cucumber/ast/background.rb +35 -35
- data/lib/cucumber/ast/empty_background.rb +33 -0
- data/lib/cucumber/ast/examples.rb +5 -2
- data/lib/cucumber/ast/feature.rb +24 -35
- data/lib/cucumber/ast/features.rb +4 -1
- data/lib/cucumber/ast/has_steps.rb +9 -17
- data/lib/cucumber/ast/location.rb +41 -0
- data/lib/cucumber/ast/scenario.rb +37 -50
- data/lib/cucumber/ast/scenario_outline.rb +62 -49
- data/lib/cucumber/ast/step.rb +23 -27
- data/lib/cucumber/ast/step_collection.rb +16 -0
- data/lib/cucumber/ast/step_invocation.rb +4 -1
- data/lib/cucumber/ast/tree_walker.rb +7 -0
- data/lib/cucumber/cli/configuration.rb +15 -3
- data/lib/cucumber/cli/main.rb +24 -11
- data/lib/cucumber/cli/options.rb +24 -16
- data/lib/cucumber/configuration.rb +4 -0
- data/lib/cucumber/core_ext/disable_mini_and_test_unit_autorun.rb +10 -34
- data/lib/cucumber/core_ext/instance_exec.rb +4 -1
- data/lib/cucumber/core_ext/proc.rb +2 -0
- data/lib/cucumber/feature_file.rb +5 -12
- data/lib/cucumber/formatter/console.rb +10 -0
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +4 -4
- data/lib/cucumber/formatter/html.rb +7 -42
- data/lib/cucumber/formatter/interceptor.rb +4 -0
- data/lib/cucumber/formatter/json_pretty.rb +0 -4
- data/lib/cucumber/formatter/junit.rb +8 -2
- data/lib/cucumber/formatter/pretty.rb +5 -1
- data/lib/cucumber/formatter/progress.rb +4 -0
- data/lib/cucumber/formatter/unicode.rb +12 -25
- data/lib/cucumber/formatter/usage.rb +7 -2
- data/lib/cucumber/js_support/js_snippets.rb +1 -1
- data/lib/cucumber/load_path.rb +13 -0
- data/lib/cucumber/parser/gherkin_builder.rb +237 -81
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/py_support/py_language.rb +1 -1
- data/lib/cucumber/rake/task.rb +5 -1
- data/lib/cucumber/rb_support/rb_language.rb +20 -19
- data/lib/cucumber/rb_support/rb_world.rb +63 -21
- data/lib/cucumber/rb_support/snippet.rb +108 -0
- data/lib/cucumber/runtime.rb +1 -0
- data/lib/cucumber/runtime/support_code.rb +2 -2
- data/lib/cucumber/unit.rb +11 -0
- data/lib/cucumber/wire_support/wire_language.rb +1 -1
- data/spec/cucumber/ast/background_spec.rb +13 -6
- data/spec/cucumber/ast/feature_factory.rb +20 -10
- data/spec/cucumber/ast/features_spec.rb +51 -0
- data/spec/cucumber/ast/scenario_outline_spec.rb +13 -7
- data/spec/cucumber/ast/step_spec.rb +6 -4
- data/spec/cucumber/cli/configuration_spec.rb +34 -1
- data/spec/cucumber/cli/main_spec.rb +36 -26
- data/spec/cucumber/cli/options_spec.rb +28 -19
- data/spec/cucumber/core_ext/proc_spec.rb +13 -1
- data/spec/cucumber/formatter/interceptor_spec.rb +8 -0
- data/spec/cucumber/formatter/junit_spec.rb +33 -0
- data/spec/cucumber/formatter/pretty_spec.rb +391 -0
- data/spec/cucumber/rb_support/rb_language_spec.rb +21 -50
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +2 -4
- data/spec/cucumber/rb_support/snippet_spec.rb +128 -0
- data/spec/cucumber/step_match_spec.rb +2 -6
- metadata +62 -113
- data/.rvmrc +0 -1
- data/features/hooks.feature +0 -59
- data/legacy_features/call_steps_from_stepdefs.feature +0 -154
|
@@ -18,7 +18,6 @@ module Cucumber
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def add_feature(feature)
|
|
21
|
-
feature.features = self
|
|
22
21
|
@features << feature
|
|
23
22
|
end
|
|
24
23
|
|
|
@@ -30,6 +29,10 @@ module Cucumber
|
|
|
30
29
|
end
|
|
31
30
|
@duration = Time.now - start
|
|
32
31
|
end
|
|
32
|
+
|
|
33
|
+
def step_count
|
|
34
|
+
@features.inject(0) { |total, feature| total += feature.step_count }
|
|
35
|
+
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
end
|
|
@@ -4,23 +4,15 @@ require 'gherkin/tag_expression'
|
|
|
4
4
|
module Cucumber
|
|
5
5
|
module Ast
|
|
6
6
|
module HasSteps #:nodoc:
|
|
7
|
-
attr_accessor :feature
|
|
8
|
-
|
|
9
7
|
attr_reader :gherkin_statement, :raw_steps, :title, :description
|
|
10
8
|
def gherkin_statement(statement=nil)
|
|
11
9
|
@gherkin_statement ||= statement
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
def add_step(step)
|
|
15
|
-
@raw_steps << step
|
|
16
|
-
end
|
|
17
|
-
|
|
18
12
|
def attach_steps(steps)
|
|
19
|
-
steps.each
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def file_colon_line(line = @line)
|
|
23
|
-
@feature.file_colon_line(line) if @feature
|
|
13
|
+
steps.each do |step|
|
|
14
|
+
step.feature_element = self
|
|
15
|
+
end
|
|
24
16
|
end
|
|
25
17
|
|
|
26
18
|
def first_line_length
|
|
@@ -49,8 +41,8 @@ module Cucumber
|
|
|
49
41
|
scenario_name_regexps.detect{|n| n =~ name}
|
|
50
42
|
end
|
|
51
43
|
|
|
52
|
-
def backtrace_line(
|
|
53
|
-
|
|
44
|
+
def backtrace_line(step_name = "#{@keyword}: #{name}", line = self.line)
|
|
45
|
+
"#{location.on_line(line)}:in `#{step_name}'"
|
|
54
46
|
end
|
|
55
47
|
|
|
56
48
|
def source_indent(text_length)
|
|
@@ -58,8 +50,7 @@ module Cucumber
|
|
|
58
50
|
end
|
|
59
51
|
|
|
60
52
|
def max_line_length
|
|
61
|
-
|
|
62
|
-
@steps.max_line_length(self)
|
|
53
|
+
steps.max_line_length(self)
|
|
63
54
|
end
|
|
64
55
|
|
|
65
56
|
def accept_hook?(hook)
|
|
@@ -71,12 +62,13 @@ module Cucumber
|
|
|
71
62
|
end
|
|
72
63
|
|
|
73
64
|
def source_tags
|
|
74
|
-
|
|
65
|
+
@tags.tags.to_a + feature_tags.tags.to_a
|
|
75
66
|
end
|
|
76
67
|
|
|
77
68
|
def language
|
|
78
|
-
@
|
|
69
|
+
@language || raise("Language is required for a #{self.class}")
|
|
79
70
|
end
|
|
71
|
+
|
|
80
72
|
end
|
|
81
73
|
end
|
|
82
74
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Cucumber
|
|
2
|
+
module Ast
|
|
3
|
+
|
|
4
|
+
class Location
|
|
5
|
+
attr_reader :file, :line
|
|
6
|
+
|
|
7
|
+
def initialize(file, line)
|
|
8
|
+
@file = file || raise(ArgumentError, "file is mandatory")
|
|
9
|
+
@line = line || raise(ArgumentError, "line is mandatory")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_s
|
|
13
|
+
"#{file}:#{line}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def on_line(new_line)
|
|
17
|
+
Location.new(file, new_line)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module HasLocation
|
|
22
|
+
def file_colon_line
|
|
23
|
+
location.to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def file
|
|
27
|
+
location.file
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def line
|
|
31
|
+
location.line
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def location
|
|
35
|
+
raise('Please set @location in the constructor') unless @location
|
|
36
|
+
raise("@location must be an Ast::Location but is a #{@location.class}") unless @location.is_a?(Location)
|
|
37
|
+
@location
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -1,66 +1,46 @@
|
|
|
1
1
|
require 'cucumber/ast/has_steps'
|
|
2
2
|
require 'cucumber/ast/names'
|
|
3
|
+
require 'cucumber/ast/empty_background'
|
|
4
|
+
require 'cucumber/ast/location'
|
|
5
|
+
require 'cucumber/unit'
|
|
3
6
|
|
|
4
7
|
module Cucumber
|
|
5
8
|
module Ast
|
|
6
9
|
class Scenario #:nodoc:
|
|
7
10
|
include HasSteps
|
|
8
11
|
include Names
|
|
12
|
+
include HasLocation
|
|
9
13
|
|
|
10
|
-
attr_reader
|
|
14
|
+
attr_reader :feature_tags
|
|
15
|
+
attr_accessor :feature
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
false
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def feature_elements
|
|
18
|
-
[]
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def step_collection(step_invocations)
|
|
22
|
-
StepCollection.new(step_invocations)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def init
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def initialize(background, comment, tags, line, keyword, title, description, raw_steps)
|
|
30
|
-
@background = background || EmptyBackground.new
|
|
31
|
-
@comment, @tags, @line, @keyword, @title, @description, @raw_steps = comment, tags, line, keyword, title, description, raw_steps
|
|
17
|
+
def initialize(language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps)
|
|
18
|
+
@language, @location, @background, @comment, @tags, @feature_tags, @keyword, @title, @description, @raw_steps = language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps
|
|
32
19
|
@exception = @executed = nil
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def init
|
|
36
|
-
return if @steps
|
|
37
|
-
@background.init
|
|
38
|
-
@background.feature_elements << self
|
|
39
20
|
attach_steps(@raw_steps)
|
|
40
|
-
step_invocations = @raw_steps.map{|step| step.step_invocation}
|
|
41
|
-
@steps = @background.step_collection(step_invocations)
|
|
42
21
|
end
|
|
43
22
|
|
|
44
23
|
def accept(visitor)
|
|
45
24
|
return if Cucumber.wants_to_quit
|
|
46
25
|
|
|
26
|
+
visitor.visit_comment(@comment) unless @comment.empty?
|
|
27
|
+
visitor.visit_tags(@tags)
|
|
28
|
+
visitor.visit_scenario_name(@keyword, name, file_colon_line, source_indent(first_line_length))
|
|
29
|
+
|
|
30
|
+
skip_invoke! if @background.failed?
|
|
47
31
|
with_visitor(visitor) do
|
|
48
|
-
visitor.
|
|
49
|
-
visitor.visit_tags(@tags)
|
|
50
|
-
visitor.visit_scenario_name(@keyword, name, file_colon_line(@line), source_indent(first_line_length))
|
|
51
|
-
|
|
52
|
-
skip_invoke! if @background.failed?
|
|
53
|
-
visitor.runtime.with_hooks(self, skip_hooks?) do
|
|
54
|
-
skip_invoke! if failed?
|
|
55
|
-
visitor.visit_steps(@steps)
|
|
56
|
-
end
|
|
57
|
-
@executed = true
|
|
32
|
+
visitor.execute(self, skip_hooks?)
|
|
58
33
|
end
|
|
34
|
+
@executed = true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_units(background)
|
|
38
|
+
[Unit.new(background.step_invocations + step_invocations)]
|
|
59
39
|
end
|
|
60
40
|
|
|
61
41
|
# Returns true if one or more steps failed
|
|
62
42
|
def failed?
|
|
63
|
-
|
|
43
|
+
steps.failed? || !!@exception
|
|
64
44
|
end
|
|
65
45
|
|
|
66
46
|
def fail!(exception)
|
|
@@ -75,42 +55,49 @@ module Cucumber
|
|
|
75
55
|
|
|
76
56
|
# Returns the first exception (if any)
|
|
77
57
|
def exception
|
|
78
|
-
@exception ||
|
|
58
|
+
@exception || steps.exception
|
|
79
59
|
end
|
|
80
60
|
|
|
81
61
|
# Returns the status
|
|
82
62
|
def status
|
|
83
63
|
return :failed if @exception
|
|
84
|
-
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def skip_invoke!
|
|
88
|
-
@steps.each{|step_invocation| step_invocation.skip_invoke!}
|
|
64
|
+
steps.status
|
|
89
65
|
end
|
|
90
66
|
|
|
91
67
|
def to_sexp
|
|
92
|
-
sexp = [:scenario,
|
|
68
|
+
sexp = [:scenario, line, @keyword, name]
|
|
93
69
|
comment = @comment.to_sexp
|
|
94
70
|
sexp += [comment] if comment
|
|
95
71
|
tags = @tags.to_sexp
|
|
96
72
|
sexp += tags if tags.any?
|
|
97
|
-
steps
|
|
98
|
-
sexp += steps if steps.any?
|
|
73
|
+
sexp += steps.to_sexp if steps.any?
|
|
99
74
|
sexp
|
|
100
75
|
end
|
|
101
76
|
|
|
102
|
-
|
|
103
77
|
def with_visitor(visitor)
|
|
104
78
|
@current_visitor = visitor
|
|
105
79
|
yield
|
|
106
80
|
@current_visitor = nil
|
|
107
81
|
end
|
|
108
82
|
|
|
83
|
+
def skip_invoke!
|
|
84
|
+
steps.skip_invoke!
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def steps
|
|
88
|
+
@steps ||= @background.step_collection(step_invocations)
|
|
89
|
+
end
|
|
90
|
+
|
|
109
91
|
private
|
|
110
92
|
|
|
93
|
+
def step_invocations
|
|
94
|
+
@raw_steps.map{|step| step.step_invocation}
|
|
95
|
+
end
|
|
96
|
+
|
|
111
97
|
def skip_hooks?
|
|
112
98
|
@background.failed? || @executed
|
|
113
99
|
end
|
|
100
|
+
|
|
114
101
|
end
|
|
115
102
|
end
|
|
116
103
|
end
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
require 'cucumber/ast/has_steps'
|
|
2
2
|
require 'cucumber/ast/names'
|
|
3
|
+
require 'cucumber/ast/empty_background'
|
|
3
4
|
|
|
4
5
|
module Cucumber
|
|
5
6
|
module Ast
|
|
6
7
|
class ScenarioOutline #:nodoc:
|
|
7
8
|
include HasSteps
|
|
8
9
|
include Names
|
|
10
|
+
include HasLocation
|
|
11
|
+
|
|
12
|
+
attr_accessor :feature
|
|
13
|
+
attr_reader :feature_tags
|
|
9
14
|
|
|
10
15
|
module ExamplesArray #:nodoc:
|
|
11
16
|
def accept(visitor)
|
|
@@ -22,50 +27,29 @@ module Cucumber
|
|
|
22
27
|
# * Examples keyword
|
|
23
28
|
# * Examples section name
|
|
24
29
|
# * Raw matrix
|
|
25
|
-
def initialize(background, comment, tags,
|
|
26
|
-
@background, @comment, @tags, @
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def add_examples(example_section, gherkin_examples)
|
|
30
|
-
@example_sections << [example_section, gherkin_examples]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def init
|
|
34
|
-
return if @steps
|
|
30
|
+
def initialize(language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps, example_sections)
|
|
31
|
+
@language, @location, @background, @comment, @tags, @feature_tags, @keyword, @title, @description, @raw_steps, @example_sections = language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps, example_sections
|
|
35
32
|
attach_steps(@raw_steps)
|
|
36
|
-
@steps = StepCollection.new(@raw_steps)
|
|
37
|
-
|
|
38
|
-
@examples_array = @example_sections.map do |example_section_and_gherkin_examples|
|
|
39
|
-
example_section = example_section_and_gherkin_examples[0]
|
|
40
|
-
gherkin_examples = example_section_and_gherkin_examples[1]
|
|
41
|
-
|
|
42
|
-
examples_comment = example_section[0]
|
|
43
|
-
examples_line = example_section[1]
|
|
44
|
-
examples_keyword = example_section[2]
|
|
45
|
-
examples_title = example_section[3]
|
|
46
|
-
examples_description = example_section[4]
|
|
47
|
-
examples_matrix = example_section[5]
|
|
48
|
-
|
|
49
|
-
examples_table = OutlineTable.new(examples_matrix, self)
|
|
50
|
-
ex = Examples.new(examples_comment, examples_line, examples_keyword, examples_title, examples_description, examples_table)
|
|
51
|
-
ex.gherkin_statement(gherkin_examples)
|
|
52
|
-
ex
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
@examples_array.extend(ExamplesArray)
|
|
56
|
-
|
|
57
|
-
@background.feature_elements << self if @background
|
|
58
33
|
end
|
|
59
34
|
|
|
60
35
|
def accept(visitor)
|
|
61
36
|
return if Cucumber.wants_to_quit
|
|
62
37
|
visitor.visit_comment(@comment) unless @comment.empty?
|
|
63
38
|
visitor.visit_tags(@tags)
|
|
64
|
-
visitor.visit_scenario_name(@keyword, name, file_colon_line
|
|
65
|
-
visitor.visit_steps(
|
|
39
|
+
visitor.visit_scenario_name(@keyword, name, file_colon_line, source_indent(first_line_length))
|
|
40
|
+
visitor.visit_steps(steps)
|
|
66
41
|
|
|
67
|
-
skip_invoke! if @background
|
|
68
|
-
visitor.visit_examples_array(
|
|
42
|
+
skip_invoke! if @background.failed?
|
|
43
|
+
visitor.visit_examples_array(examples_array) unless examples_array.empty?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_units(background)
|
|
47
|
+
raise ArgumentError.new("#{background} != #{@background}") unless background == @background # maybe we don't need this argument, but it seems like the leaf AST nodes would be better not being aware of their parents. However step_invocations uses the ivar at the moment, so we'll just do this check to make sure its OK.
|
|
48
|
+
result = []
|
|
49
|
+
each_example_row do |row|
|
|
50
|
+
result << Unit.new(step_invocations(row))
|
|
51
|
+
end
|
|
52
|
+
result
|
|
69
53
|
end
|
|
70
54
|
|
|
71
55
|
def fail!(exception)
|
|
@@ -74,14 +58,11 @@ module Cucumber
|
|
|
74
58
|
end
|
|
75
59
|
|
|
76
60
|
def skip_invoke!
|
|
77
|
-
|
|
78
|
-
@feature.next_feature_element(self) do |next_one|
|
|
79
|
-
next_one.skip_invoke!
|
|
80
|
-
end
|
|
61
|
+
examples_array.each { |examples| examples.skip_invoke! }
|
|
81
62
|
end
|
|
82
63
|
|
|
83
64
|
def step_invocations(cells)
|
|
84
|
-
step_invocations =
|
|
65
|
+
step_invocations = steps.step_invocations_from_cells(cells)
|
|
85
66
|
if @background
|
|
86
67
|
@background.step_collection(step_invocations)
|
|
87
68
|
else
|
|
@@ -90,36 +71,68 @@ module Cucumber
|
|
|
90
71
|
end
|
|
91
72
|
|
|
92
73
|
def each_example_row(&proc)
|
|
93
|
-
|
|
74
|
+
examples_array.each do |examples|
|
|
94
75
|
examples.each_example_row(&proc)
|
|
95
76
|
end
|
|
96
77
|
end
|
|
97
78
|
|
|
98
79
|
def visit_scenario_name(visitor, row)
|
|
99
80
|
visitor.visit_scenario_name(
|
|
100
|
-
|
|
81
|
+
language.keywords('scenario')[0],
|
|
101
82
|
row.name,
|
|
102
|
-
|
|
83
|
+
Location.new(file, row.line).to_s,
|
|
103
84
|
source_indent(first_line_length)
|
|
104
85
|
)
|
|
105
86
|
end
|
|
106
87
|
|
|
107
88
|
def failed?
|
|
108
|
-
|
|
89
|
+
examples_array.select { |examples| examples.failed? }.any?
|
|
109
90
|
end
|
|
110
91
|
|
|
111
92
|
def to_sexp
|
|
112
|
-
init
|
|
113
93
|
sexp = [:scenario_outline, @keyword, name]
|
|
114
94
|
comment = @comment.to_sexp
|
|
115
95
|
sexp += [comment] if comment
|
|
116
96
|
tags = @tags.to_sexp
|
|
117
97
|
sexp += tags if tags.any?
|
|
118
|
-
steps
|
|
119
|
-
sexp +=
|
|
120
|
-
sexp += @examples_array.map{|e| e.to_sexp}
|
|
98
|
+
sexp += steps.to_sexp if steps.any?
|
|
99
|
+
sexp += examples_array.map{|e| e.to_sexp}
|
|
121
100
|
sexp
|
|
122
101
|
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
attr_reader :line
|
|
106
|
+
|
|
107
|
+
def examples_array
|
|
108
|
+
return @examples_array if @examples_array
|
|
109
|
+
@examples_array = @example_sections.map do |section|
|
|
110
|
+
create_examples_table(section)
|
|
111
|
+
end
|
|
112
|
+
@examples_array.extend(ExamplesArray)
|
|
113
|
+
@examples_array
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def create_examples_table(example_section_and_gherkin_examples)
|
|
117
|
+
example_section = example_section_and_gherkin_examples[0]
|
|
118
|
+
gherkin_examples = example_section_and_gherkin_examples[1]
|
|
119
|
+
|
|
120
|
+
examples_location = example_section[0]
|
|
121
|
+
examples_comment = example_section[1]
|
|
122
|
+
examples_keyword = example_section[2]
|
|
123
|
+
examples_title = example_section[3]
|
|
124
|
+
examples_description = example_section[4]
|
|
125
|
+
examples_matrix = example_section[5]
|
|
126
|
+
|
|
127
|
+
examples_table = OutlineTable.new(examples_matrix, self)
|
|
128
|
+
ex = Examples.new(examples_location, examples_comment, examples_keyword, examples_title, examples_description, examples_table)
|
|
129
|
+
ex.gherkin_statement(gherkin_examples)
|
|
130
|
+
ex
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def steps
|
|
134
|
+
@steps ||= StepCollection.new(@raw_steps)
|
|
135
|
+
end
|
|
123
136
|
end
|
|
124
137
|
end
|
|
125
138
|
end
|
data/lib/cucumber/ast/step.rb
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
require 'cucumber/core_ext/string'
|
|
2
2
|
require 'cucumber/step_match'
|
|
3
|
+
require 'cucumber/ast/location'
|
|
3
4
|
|
|
4
5
|
module Cucumber
|
|
5
6
|
module Ast
|
|
6
7
|
class Step #:nodoc:
|
|
7
|
-
|
|
8
|
+
include HasLocation
|
|
9
|
+
|
|
10
|
+
attr_reader :keyword, :name, :language
|
|
8
11
|
attr_writer :step_collection, :options
|
|
9
12
|
attr_accessor :feature_element, :exception, :multiline_arg
|
|
10
13
|
|
|
11
14
|
INDENT = 2
|
|
12
15
|
|
|
13
|
-
def initialize(
|
|
14
|
-
@
|
|
16
|
+
def initialize(language, location, keyword, name, multiline_arg=nil)
|
|
17
|
+
@language, @location, @keyword, @name, @multiline_arg = language, location, keyword, name, multiline_arg
|
|
18
|
+
@language || raise("Language is required!")
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
attr_reader :gherkin_statement
|
|
@@ -29,7 +33,7 @@ module Cucumber
|
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def step_invocation
|
|
32
|
-
StepInvocation.new(self,
|
|
36
|
+
StepInvocation.new(self, name, @multiline_arg, [])
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
def step_invocation_from_cells(cells)
|
|
@@ -50,43 +54,35 @@ module Cucumber
|
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
def visit_step_result(visitor, step_match, multiline_arg, status, exception, background)
|
|
53
|
-
visitor.visit_step_result(
|
|
57
|
+
visitor.visit_step_result(keyword, step_match, @multiline_arg, status, exception, source_indent, background, file_colon_line)
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
def first_match(visitor)
|
|
57
|
-
#
|
|
58
|
-
|
|
61
|
+
# feature_element is always a ScenarioOutline in this case
|
|
62
|
+
feature_element.each_example_row do |cells|
|
|
59
63
|
argument_hash = cells.to_hash
|
|
60
64
|
delimited_arguments = delimit_argument_names(argument_hash)
|
|
61
|
-
|
|
62
|
-
step_match = visitor.runtime.step_match(
|
|
65
|
+
name_to_match = replace_name_arguments(delimited_arguments)
|
|
66
|
+
step_match = visitor.runtime.step_match(name_to_match, name) rescue nil
|
|
63
67
|
return step_match if step_match
|
|
64
68
|
end
|
|
65
|
-
NoStepMatch.new(self,
|
|
69
|
+
NoStepMatch.new(self, name)
|
|
66
70
|
end
|
|
67
71
|
|
|
68
72
|
def to_sexp
|
|
69
|
-
[:step,
|
|
73
|
+
[:step, line, keyword, name, (@multiline_arg.nil? ? nil : @multiline_arg.to_sexp)].compact
|
|
70
74
|
end
|
|
71
75
|
|
|
72
76
|
def source_indent
|
|
73
|
-
|
|
77
|
+
feature_element.source_indent(text_length)
|
|
74
78
|
end
|
|
75
79
|
|
|
76
|
-
def text_length(name
|
|
77
|
-
INDENT + INDENT +
|
|
80
|
+
def text_length(name=name)
|
|
81
|
+
INDENT + INDENT + keyword.unpack('U*').length + name.unpack('U*').length
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def backtrace_line
|
|
81
|
-
@backtrace_line ||=
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def file_colon_line
|
|
85
|
-
@file_colon_line ||= @feature_element.file_colon_line(@line) unless @feature_element.nil?
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def language
|
|
89
|
-
@feature_element.language
|
|
85
|
+
@backtrace_line ||= feature_element.backtrace_line("#{keyword}#{name}", line) unless feature_element.nil?
|
|
90
86
|
end
|
|
91
87
|
|
|
92
88
|
def dom_id
|
|
@@ -101,7 +97,7 @@ module Cucumber
|
|
|
101
97
|
header_cell = cell.table.header_cell(col_index)
|
|
102
98
|
col_index += 1
|
|
103
99
|
delimited = delimited(header_cell.value)
|
|
104
|
-
|
|
100
|
+
name.index(delimited) || (@multiline_arg && @multiline_arg.has_text?(delimited))
|
|
105
101
|
end
|
|
106
102
|
end
|
|
107
103
|
|
|
@@ -114,10 +110,10 @@ module Cucumber
|
|
|
114
110
|
end
|
|
115
111
|
|
|
116
112
|
def replace_name_arguments(argument_hash)
|
|
117
|
-
name_with_arguments_replaced =
|
|
118
|
-
argument_hash.each do |
|
|
113
|
+
name_with_arguments_replaced = name
|
|
114
|
+
argument_hash.each do |key, value|
|
|
119
115
|
value ||= ''
|
|
120
|
-
name_with_arguments_replaced = name_with_arguments_replaced.gsub(
|
|
116
|
+
name_with_arguments_replaced = name_with_arguments_replaced.gsub(key, value)
|
|
121
117
|
end
|
|
122
118
|
name_with_arguments_replaced
|
|
123
119
|
end
|