cucumber 0.8.6 → 0.8.7
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.
- data/.rspec +1 -1
- data/Caliper.yml +4 -0
- data/History.txt +1557 -0
- data/LICENSE +1 -1
- data/README.rdoc +26 -0
- data/Rakefile +51 -5
- data/VERSION.yml +5 -0
- data/bin/cucumber +1 -7
- data/cucumber.gemspec +77 -3
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +7 -4
- data/examples/i18n/ro/features/suma.feature +11 -0
- data/examples/i18n/ru/features/division.feature +2 -2
- data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +3 -3
- data/examples/sinatra/features/support/env.rb +5 -2
- data/examples/v8/features/fibonacci.feature +1 -1
- data/examples/watir/features/step_definitions/search_steps.rb +1 -1
- data/features/announce.feature +164 -0
- data/features/around_hooks.feature +232 -0
- data/features/background.feature +95 -284
- data/features/bug_371.feature +32 -0
- data/features/bug_464.feature +16 -0
- data/features/bug_475.feature +42 -0
- data/features/bug_585_tab_indentation.feature +22 -0
- data/features/bug_600.feature +67 -0
- data/features/call_steps_from_stepdefs.feature +154 -0
- data/features/cucumber_cli.feature +591 -0
- data/features/cucumber_cli_outlines.feature +117 -0
- data/features/custom_formatter.feature +73 -3
- data/features/default_snippets.feature +42 -0
- data/features/diffing.feature +25 -0
- data/features/drb_server_integration.feature +174 -0
- data/features/exception_in_after_block.feature +127 -0
- data/features/exception_in_after_step_block.feature +104 -0
- data/features/exception_in_before_block.feature +98 -0
- data/features/exclude_files.feature +20 -0
- data/features/expand.feature +60 -0
- data/features/html_formatter.feature +8 -0
- data/features/html_formatter/a.html +582 -0
- data/features/json_formatter.feature +245 -160
- data/features/junit_formatter.feature +88 -0
- data/features/language_from_header.feature +30 -0
- data/features/language_help.feature +78 -0
- data/features/listener_debugger_formatter.feature +42 -0
- data/features/multiline_names.feature +44 -0
- data/features/negative_tagged_hooks.feature +60 -0
- data/features/post_configuration_hook.feature +37 -0
- data/features/profiles.feature +126 -0
- data/features/rake_task.feature +152 -0
- data/features/report_called_undefined_steps.feature +34 -0
- data/features/rerun_formatter.feature +45 -0
- data/features/simplest.feature +11 -0
- data/features/snippet.feature +23 -0
- data/features/snippets_when_using_star_keyword.feature +36 -0
- data/features/step_definitions/cucumber_steps.rb +153 -7
- data/features/step_definitions/extra_steps.rb +2 -0
- data/features/step_definitions/simplest_steps.rb +3 -0
- data/features/step_definitions/wire_steps.rb +32 -0
- data/features/support/env.rb +140 -18
- data/features/support/env.rb.simplest +7 -0
- data/features/support/fake_wire_server.rb +77 -0
- data/features/table_diffing.feature +45 -0
- data/features/table_mapping.feature +34 -0
- data/features/tag_logic.feature +258 -0
- data/features/transform.feature +245 -0
- data/features/unicode_table.feature +35 -0
- data/features/usage_and_stepdefs_formatter.feature +169 -0
- data/features/wire_protocol.feature +332 -0
- data/features/wire_protocol_table_diffing.feature +119 -0
- data/features/wire_protocol_tags.feature +87 -0
- data/features/wire_protocol_timeouts.feature +63 -0
- data/features/work_in_progress.feature +156 -0
- data/fixtures/json/features/pystring.feature +8 -0
- data/fixtures/junit/features/pending.feature +1 -3
- data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +12 -0
- data/fixtures/self_test/features/background/background_with_name.feature +7 -0
- data/fixtures/self_test/features/background/failing_background.feature +12 -0
- data/fixtures/self_test/features/background/failing_background_after_success.feature +11 -0
- data/fixtures/self_test/features/background/multiline_args_background.feature +32 -0
- data/fixtures/self_test/features/background/passing_background.feature +10 -0
- data/fixtures/self_test/features/background/pending_background.feature +10 -0
- data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +16 -0
- data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +16 -0
- data/fixtures/self_test/features/support/env.rb +0 -8
- data/fixtures/tickets/features.html +1 -1
- data/gem_tasks/examples.rake +1 -1
- data/gem_tasks/features.rake +14 -0
- data/gem_tasks/sdoc.rake +12 -0
- data/lib/cucumber.rb +0 -12
- data/lib/cucumber/ast.rb +1 -1
- data/lib/cucumber/ast/background.rb +5 -21
- data/lib/cucumber/ast/examples.rb +4 -12
- data/lib/cucumber/ast/feature.rb +5 -13
- data/lib/cucumber/ast/feature_element.rb +4 -9
- data/lib/cucumber/ast/outline_table.rb +4 -4
- data/lib/cucumber/ast/py_string.rb +80 -0
- data/lib/cucumber/ast/scenario.rb +5 -7
- data/lib/cucumber/ast/scenario_outline.rb +15 -23
- data/lib/cucumber/ast/step.rb +0 -5
- data/lib/cucumber/ast/step_invocation.rb +15 -21
- data/lib/cucumber/ast/table.rb +8 -14
- data/lib/cucumber/ast/tree_walker.rb +48 -10
- data/lib/cucumber/cli/configuration.rb +8 -33
- data/lib/cucumber/cli/main.rb +35 -20
- data/lib/cucumber/cli/options.rb +7 -8
- data/lib/cucumber/cli/profile_loader.rb +0 -2
- data/lib/cucumber/core_ext/proc.rb +1 -2
- data/lib/cucumber/feature_file.rb +15 -47
- data/lib/cucumber/formatter/ansicolor.rb +5 -3
- data/lib/cucumber/formatter/color_io.rb +23 -0
- data/lib/cucumber/formatter/console.rb +23 -27
- data/lib/cucumber/formatter/cucumber.css +17 -34
- data/lib/cucumber/formatter/cucumber.sass +182 -173
- data/lib/cucumber/formatter/html.rb +11 -46
- data/lib/cucumber/formatter/io.rb +4 -2
- data/lib/cucumber/formatter/json.rb +152 -15
- data/lib/cucumber/formatter/json_pretty.rb +6 -5
- data/lib/cucumber/formatter/junit.rb +22 -28
- data/lib/cucumber/formatter/pdf.rb +6 -6
- data/lib/cucumber/formatter/pretty.rb +5 -5
- data/lib/cucumber/formatter/rerun.rb +11 -22
- data/lib/cucumber/formatter/tag_cloud.rb +35 -0
- data/lib/cucumber/formatter/unicode.rb +20 -41
- data/lib/cucumber/js_support/js_dsl.js +4 -4
- data/lib/cucumber/js_support/js_language.rb +5 -9
- data/lib/cucumber/js_support/js_snippets.rb +2 -2
- data/lib/cucumber/language_support.rb +2 -2
- data/lib/cucumber/parser/gherkin_builder.rb +30 -35
- data/lib/cucumber/platform.rb +8 -8
- data/lib/cucumber/py_support/py_language.rb +2 -2
- data/lib/cucumber/rake/task.rb +31 -74
- data/lib/cucumber/rb_support/rb_dsl.rb +0 -1
- data/lib/cucumber/rb_support/rb_language.rb +8 -10
- data/lib/cucumber/rb_support/rb_step_definition.rb +0 -8
- data/lib/cucumber/rb_support/rb_transform.rb +0 -17
- data/lib/cucumber/rb_support/rb_world.rb +18 -26
- data/lib/cucumber/rspec/doubles.rb +3 -3
- data/lib/cucumber/step_match.rb +2 -6
- data/lib/cucumber/step_mother.rb +427 -6
- data/lib/cucumber/wire_support/configuration.rb +1 -4
- data/lib/cucumber/wire_support/wire_language.rb +10 -3
- data/spec/cucumber/ast/background_spec.rb +6 -68
- data/spec/cucumber/ast/feature_factory.rb +4 -5
- data/spec/cucumber/ast/feature_spec.rb +4 -4
- data/spec/cucumber/ast/outline_table_spec.rb +1 -1
- data/spec/cucumber/ast/py_string_spec.rb +40 -0
- data/spec/cucumber/ast/scenario_outline_spec.rb +11 -15
- data/spec/cucumber/ast/scenario_spec.rb +4 -4
- data/spec/cucumber/ast/step_spec.rb +3 -3
- data/spec/cucumber/ast/table_spec.rb +2 -38
- data/spec/cucumber/ast/tree_walker_spec.rb +2 -2
- data/spec/cucumber/broadcaster_spec.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +6 -32
- data/spec/cucumber/cli/drb_client_spec.rb +3 -2
- data/spec/cucumber/cli/main_spec.rb +43 -43
- data/spec/cucumber/cli/options_spec.rb +1 -28
- data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
- data/spec/cucumber/core_ext/proc_spec.rb +1 -1
- data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
- data/spec/cucumber/formatter/color_io_spec.rb +29 -0
- data/spec/cucumber/formatter/duration_spec.rb +1 -1
- data/spec/cucumber/formatter/html_spec.rb +5 -3
- data/spec/cucumber/formatter/junit_spec.rb +2 -16
- data/spec/cucumber/formatter/progress_spec.rb +1 -1
- data/spec/cucumber/formatter/spec_helper.rb +12 -11
- data/spec/cucumber/rb_support/rb_language_spec.rb +28 -241
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +28 -33
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
- data/spec/cucumber/step_match_spec.rb +9 -11
- data/spec/cucumber/step_mother_spec.rb +302 -0
- data/spec/cucumber/wire_support/configuration_spec.rb +1 -1
- data/spec/cucumber/wire_support/connection_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
- data/spec/cucumber/world/pending_spec.rb +2 -2
- data/spec/spec_helper.rb +20 -13
- metadata +78 -4
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
require 'cucumber/ast/feature_element'
|
|
2
|
-
require 'cucumber/ast/names'
|
|
3
|
-
|
|
4
1
|
module Cucumber
|
|
5
2
|
module Ast
|
|
6
3
|
class ScenarioOutline #:nodoc:
|
|
7
4
|
include FeatureElement
|
|
8
|
-
include Names
|
|
9
5
|
|
|
6
|
+
attr_reader :name
|
|
7
|
+
|
|
10
8
|
module ExamplesArray #:nodoc:
|
|
11
9
|
def accept(visitor)
|
|
12
10
|
return if Cucumber.wants_to_quit
|
|
@@ -22,12 +20,12 @@ module Cucumber
|
|
|
22
20
|
# * Examples keyword
|
|
23
21
|
# * Examples section name
|
|
24
22
|
# * Raw matrix
|
|
25
|
-
def initialize(background, comment, tags, line, keyword,
|
|
26
|
-
@background, @comment, @tags, @line, @keyword, @
|
|
23
|
+
def initialize(background, comment, tags, line, keyword, name, raw_steps, example_sections)
|
|
24
|
+
@background, @comment, @tags, @line, @keyword, @name, @raw_steps, @example_sections = background, comment, tags, line, keyword, name, raw_steps, example_sections
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
def add_examples(example_section
|
|
30
|
-
@example_sections <<
|
|
27
|
+
def add_examples(example_section)
|
|
28
|
+
@example_sections << example_section
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def init
|
|
@@ -35,21 +33,15 @@ module Cucumber
|
|
|
35
33
|
attach_steps(@raw_steps)
|
|
36
34
|
@steps = StepCollection.new(@raw_steps)
|
|
37
35
|
|
|
38
|
-
@examples_array = @example_sections.map do |
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
examples_keyword = example_section[2]
|
|
45
|
-
examples_title = example_section[3]
|
|
46
|
-
examples_description = example_section[4]
|
|
47
|
-
examples_matrix = example_section[5]
|
|
36
|
+
@examples_array = @example_sections.map do |example_section|
|
|
37
|
+
examples_comment = example_section[0]
|
|
38
|
+
examples_line = example_section[1]
|
|
39
|
+
examples_keyword = example_section[2]
|
|
40
|
+
examples_name = example_section[3]
|
|
41
|
+
examples_matrix = example_section[4]
|
|
48
42
|
|
|
49
43
|
examples_table = OutlineTable.new(examples_matrix, self)
|
|
50
|
-
|
|
51
|
-
ex.gherkin_statement(gherkin_examples)
|
|
52
|
-
ex
|
|
44
|
+
Examples.new(examples_comment, examples_line, examples_keyword, examples_name, examples_table)
|
|
53
45
|
end
|
|
54
46
|
|
|
55
47
|
@examples_array.extend(ExamplesArray)
|
|
@@ -61,7 +53,7 @@ module Cucumber
|
|
|
61
53
|
return if Cucumber.wants_to_quit
|
|
62
54
|
visitor.visit_comment(@comment) unless @comment.empty?
|
|
63
55
|
visitor.visit_tags(@tags)
|
|
64
|
-
visitor.visit_scenario_name(@keyword, name, file_colon_line(@line), source_indent(first_line_length))
|
|
56
|
+
visitor.visit_scenario_name(@keyword, @name, file_colon_line(@line), source_indent(first_line_length))
|
|
65
57
|
visitor.visit_steps(@steps)
|
|
66
58
|
|
|
67
59
|
skip_invoke! if @background && @background.failed?
|
|
@@ -110,7 +102,7 @@ module Cucumber
|
|
|
110
102
|
|
|
111
103
|
def to_sexp
|
|
112
104
|
init
|
|
113
|
-
sexp = [:scenario_outline, @keyword, name]
|
|
105
|
+
sexp = [:scenario_outline, @keyword, @name]
|
|
114
106
|
comment = @comment.to_sexp
|
|
115
107
|
sexp += [comment] if comment
|
|
116
108
|
tags = @tags.to_sexp
|
data/lib/cucumber/ast/step.rb
CHANGED
|
@@ -14,11 +14,6 @@ module Cucumber
|
|
|
14
14
|
@line, @keyword, @name, @multiline_arg = line, keyword, name, multiline_arg
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
attr_reader :gherkin_statement
|
|
18
|
-
def gherkin_statement(statement=nil)
|
|
19
|
-
@gherkin_statement ||= statement
|
|
20
|
-
end
|
|
21
|
-
|
|
22
17
|
def background?
|
|
23
18
|
false
|
|
24
19
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'cucumber/errors'
|
|
2
1
|
require 'cucumber/step_match'
|
|
3
2
|
require 'cucumber/ast/table'
|
|
4
3
|
require 'gherkin/rubify'
|
|
@@ -39,7 +38,7 @@ module Cucumber
|
|
|
39
38
|
|
|
40
39
|
def accept(visitor)
|
|
41
40
|
return if Cucumber.wants_to_quit
|
|
42
|
-
invoke(visitor.step_mother, visitor.
|
|
41
|
+
invoke(visitor.step_mother, visitor.options)
|
|
43
42
|
visit_step_result(visitor)
|
|
44
43
|
end
|
|
45
44
|
|
|
@@ -55,64 +54,63 @@ module Cucumber
|
|
|
55
54
|
)
|
|
56
55
|
end
|
|
57
56
|
|
|
58
|
-
def invoke(step_mother,
|
|
59
|
-
find_step_match!(step_mother
|
|
60
|
-
unless @skip_invoke ||
|
|
57
|
+
def invoke(step_mother, options)
|
|
58
|
+
find_step_match!(step_mother)
|
|
59
|
+
unless @skip_invoke || options[:dry_run] || @exception || @step_collection.exception
|
|
61
60
|
@skip_invoke = true
|
|
62
61
|
begin
|
|
63
62
|
@step_match.invoke(@multiline_arg)
|
|
64
63
|
step_mother.after_step
|
|
65
64
|
status!(:passed)
|
|
66
65
|
rescue Pending => e
|
|
67
|
-
failed(
|
|
66
|
+
failed(options, e, false)
|
|
68
67
|
status!(:pending)
|
|
69
68
|
rescue Undefined => e
|
|
70
|
-
failed(
|
|
69
|
+
failed(options, e, false)
|
|
71
70
|
status!(:undefined)
|
|
72
71
|
rescue Cucumber::Ast::Table::Different => e
|
|
73
72
|
@different_table = e.table
|
|
74
|
-
failed(
|
|
73
|
+
failed(options, e, false)
|
|
75
74
|
status!(:failed)
|
|
76
75
|
rescue Exception => e
|
|
77
|
-
failed(
|
|
76
|
+
failed(options, e, false)
|
|
78
77
|
status!(:failed)
|
|
79
78
|
end
|
|
80
79
|
end
|
|
81
80
|
end
|
|
82
81
|
|
|
83
|
-
def find_step_match!(step_mother
|
|
82
|
+
def find_step_match!(step_mother)
|
|
84
83
|
return if @step_match
|
|
85
84
|
begin
|
|
86
85
|
@step_match = step_mother.step_match(@name)
|
|
87
86
|
rescue Undefined => e
|
|
88
|
-
failed(
|
|
87
|
+
failed(step_mother.options, e, true)
|
|
89
88
|
status!(:undefined)
|
|
90
89
|
@step_match = NoStepMatch.new(@step, @name)
|
|
91
90
|
rescue Ambiguous => e
|
|
92
|
-
failed(
|
|
91
|
+
failed(step_mother.options, e, false)
|
|
93
92
|
status!(:failed)
|
|
94
93
|
@step_match = NoStepMatch.new(@step, @name)
|
|
95
94
|
end
|
|
96
95
|
step_mother.step_visited(self)
|
|
97
96
|
end
|
|
98
97
|
|
|
99
|
-
def failed(
|
|
98
|
+
def failed(options, e, clear_backtrace)
|
|
100
99
|
e = filter_backtrace(e)
|
|
101
100
|
e.set_backtrace([]) if clear_backtrace
|
|
102
101
|
e.backtrace << @step.backtrace_line unless @step.backtrace_line.nil?
|
|
103
102
|
@exception = e
|
|
104
|
-
if(
|
|
103
|
+
if(options[:strict] || !(Undefined === e) || e.nested?)
|
|
105
104
|
@reported_exception = e
|
|
106
105
|
else
|
|
107
106
|
@reported_exception = nil
|
|
108
107
|
end
|
|
109
108
|
end
|
|
110
109
|
|
|
111
|
-
PWD_PATTERN = /#{Regexp.escape(Dir.pwd)}\//m
|
|
112
|
-
|
|
113
110
|
def filter_backtrace(e)
|
|
114
111
|
return e if Cucumber.use_full_backtrace
|
|
115
|
-
|
|
112
|
+
pwd = /#{Regexp.escape(Dir.pwd)}\//m
|
|
113
|
+
(e.backtrace || []).each{|line| line.gsub!(pwd, "./")}
|
|
116
114
|
|
|
117
115
|
filtered = (e.backtrace || []).reject do |line|
|
|
118
116
|
BACKTRACE_FILTER_PATTERNS.detect { |p| line =~ p }
|
|
@@ -187,10 +185,6 @@ module Cucumber
|
|
|
187
185
|
@step.language
|
|
188
186
|
end
|
|
189
187
|
|
|
190
|
-
def gherkin_statement
|
|
191
|
-
@step.gherkin_statement
|
|
192
|
-
end
|
|
193
|
-
|
|
194
188
|
def to_sexp
|
|
195
189
|
[:step_invocation, @step.line, @step.keyword, @name, (@multiline_arg.nil? ? nil : @multiline_arg.to_sexp)].compact
|
|
196
190
|
end
|
data/lib/cucumber/ast/table.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'gherkin/rubify'
|
|
2
|
-
require 'gherkin/lexer/i18n_lexer'
|
|
3
2
|
require 'gherkin/formatter/escaping'
|
|
4
3
|
|
|
5
4
|
module Cucumber
|
|
@@ -61,7 +60,7 @@ module Cucumber
|
|
|
61
60
|
|
|
62
61
|
def self.parse(text, uri, offset)
|
|
63
62
|
builder = Builder.new
|
|
64
|
-
lexer = Gherkin::
|
|
63
|
+
lexer = Gherkin::I18nLexer.new(builder)
|
|
65
64
|
lexer.scan(text)
|
|
66
65
|
new(builder.rows)
|
|
67
66
|
end
|
|
@@ -74,6 +73,7 @@ module Cucumber
|
|
|
74
73
|
def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
|
|
75
74
|
@cells_class = Cells
|
|
76
75
|
@cell_class = Cell
|
|
76
|
+
|
|
77
77
|
raw = ensure_array_of_array(rubify(raw))
|
|
78
78
|
# Verify that it's square
|
|
79
79
|
transposed = raw.transpose
|
|
@@ -153,7 +153,7 @@ module Cucumber
|
|
|
153
153
|
#
|
|
154
154
|
# gets converted into the following:
|
|
155
155
|
#
|
|
156
|
-
# [['a', 'b
|
|
156
|
+
# [['a', 'b], ['c', 'd']]
|
|
157
157
|
#
|
|
158
158
|
def raw
|
|
159
159
|
cell_matrix.map do |row|
|
|
@@ -163,14 +163,9 @@ module Cucumber
|
|
|
163
163
|
end
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
@col_names ||= cell_matrix[0].map { |cell| cell.value }
|
|
168
|
-
end
|
|
169
|
-
|
|
166
|
+
# Same as #raw, but skips the first (header) row
|
|
170
167
|
def rows
|
|
171
|
-
|
|
172
|
-
hash.values_at *headers
|
|
173
|
-
end
|
|
168
|
+
raw[1..-1]
|
|
174
169
|
end
|
|
175
170
|
|
|
176
171
|
def each_cells_row(&proc) #:nodoc:
|
|
@@ -276,9 +271,8 @@ module Cucumber
|
|
|
276
271
|
# end
|
|
277
272
|
#
|
|
278
273
|
def map_column!(column_name, strict=true, &conversion_proc)
|
|
279
|
-
verify_column(column_name
|
|
280
|
-
@conversion_procs[column_name
|
|
281
|
-
self
|
|
274
|
+
verify_column(column_name) if strict
|
|
275
|
+
@conversion_procs[column_name] = conversion_proc
|
|
282
276
|
end
|
|
283
277
|
|
|
284
278
|
# Compares +other_table+ to self. If +other_table+ contains columns
|
|
@@ -385,7 +379,7 @@ module Cucumber
|
|
|
385
379
|
hash = Hash.new do |hash, key|
|
|
386
380
|
hash[key.to_s] if key.is_a?(Symbol)
|
|
387
381
|
end
|
|
388
|
-
|
|
382
|
+
raw[0].each_with_index do |column_name, column_index|
|
|
389
383
|
value = @conversion_procs[column_name].call(cells.value(column_index))
|
|
390
384
|
hash[column_name] = value
|
|
391
385
|
end
|
|
@@ -2,11 +2,11 @@ module Cucumber
|
|
|
2
2
|
module Ast
|
|
3
3
|
# Walks the AST, executing steps and notifying listeners
|
|
4
4
|
class TreeWalker
|
|
5
|
-
attr_accessor :
|
|
5
|
+
attr_accessor :options #:nodoc:
|
|
6
6
|
attr_reader :step_mother #:nodoc:
|
|
7
7
|
|
|
8
|
-
def initialize(step_mother, listeners = [],
|
|
9
|
-
@step_mother, @listeners, @
|
|
8
|
+
def initialize(step_mother, listeners = [], options = {}, io = STDOUT)
|
|
9
|
+
@step_mother, @listeners, @options, @io = step_mother, listeners, options, io
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def visit_features(features)
|
|
@@ -122,7 +122,7 @@ module Cucumber
|
|
|
122
122
|
broadcast(exception, status)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
def
|
|
125
|
+
def visit_py_string(string)
|
|
126
126
|
broadcast(string)
|
|
127
127
|
end
|
|
128
128
|
|
|
@@ -142,15 +142,15 @@ module Cucumber
|
|
|
142
142
|
broadcast(value, status)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
# Print +
|
|
146
|
-
def
|
|
147
|
-
broadcast(
|
|
145
|
+
# Print +announcement+. This method can be called from within StepDefinitions.
|
|
146
|
+
def announce(announcement)
|
|
147
|
+
broadcast(announcement)
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# Embed +file+ of +mime_type+ in the formatter. This method can be called from within StepDefinitions.
|
|
151
151
|
# For most formatters this is a no-op.
|
|
152
|
-
def embed(file, mime_type
|
|
153
|
-
broadcast(file, mime_type
|
|
152
|
+
def embed(file, mime_type)
|
|
153
|
+
broadcast(file, mime_type)
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
private
|
|
@@ -171,10 +171,48 @@ module Cucumber
|
|
|
171
171
|
def send_to_all(message, *args)
|
|
172
172
|
@listeners.each do |listener|
|
|
173
173
|
if listener.respond_to?(message)
|
|
174
|
-
listener
|
|
174
|
+
if legacy_listener?(listener)
|
|
175
|
+
warn_legacy(listener)
|
|
176
|
+
legacy_invoke(listener, message, *args)
|
|
177
|
+
else
|
|
178
|
+
listener.__send__(message, *args)
|
|
179
|
+
end
|
|
175
180
|
end
|
|
176
181
|
end
|
|
177
182
|
end
|
|
183
|
+
|
|
184
|
+
def legacy_listener?(listener)
|
|
185
|
+
listener.respond_to?(:feature_name) &&
|
|
186
|
+
(listener.method(:feature_name) rescue false) &&
|
|
187
|
+
listener.method(:feature_name).arity == 1
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def warn_legacy(listener)
|
|
191
|
+
@warned_listeners ||= []
|
|
192
|
+
unless @warned_listeners.index(listener)
|
|
193
|
+
warn("#{listener.class} is using a deprecated formatter API. Starting with Cucumber 0.7.0 the signatures\n" +
|
|
194
|
+
"that have changed are:\n" +
|
|
195
|
+
" feature_name(keyword, name) # Two arguments. The keyword argument will not contain a colon.\n" +
|
|
196
|
+
" scenario_name(keyword, name, file_colon_line, source_indent) # The keyword argument will not contain a colon.\n" +
|
|
197
|
+
" examples_name(keyword, name) # The keyword argument will not contain a colon.\n"
|
|
198
|
+
)
|
|
199
|
+
end
|
|
200
|
+
@warned_listeners << listener
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def legacy_invoke(listener, message, *args)
|
|
204
|
+
case message.to_sym
|
|
205
|
+
when :feature_name
|
|
206
|
+
listener.feature_name("#{args[0]}: #{args[1]}")
|
|
207
|
+
when :scenario_name, :examples_name
|
|
208
|
+
args_with_colon = args.dup
|
|
209
|
+
args_with_colon[0] += ':'
|
|
210
|
+
listener.__send__(message, *args_with_colon)
|
|
211
|
+
else
|
|
212
|
+
listener.__send__(message, *args)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
178
216
|
def extract_method_name_from(call_stack)
|
|
179
217
|
call_stack[0].match(/in `(.*)'/).captures[0]
|
|
180
218
|
end
|
|
@@ -12,7 +12,7 @@ module Cucumber
|
|
|
12
12
|
class Configuration
|
|
13
13
|
include Constantize
|
|
14
14
|
|
|
15
|
-
attr_reader :out_stream
|
|
15
|
+
attr_reader :options, :out_stream
|
|
16
16
|
|
|
17
17
|
def initialize(out_stream = STDOUT, error_stream = STDERR)
|
|
18
18
|
@out_stream = out_stream
|
|
@@ -56,16 +56,8 @@ module Cucumber
|
|
|
56
56
|
@options[:drb_port].to_i if @options[:drb_port]
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
def
|
|
60
|
-
@options
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def expand?
|
|
64
|
-
@options[:expand]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def build_tree_walker(step_mother)
|
|
68
|
-
Ast::TreeWalker.new(step_mother, formatters(step_mother), self)
|
|
59
|
+
def build_runner(step_mother, io)
|
|
60
|
+
Ast::TreeWalker.new(step_mother, formatters(step_mother), @options, io)
|
|
69
61
|
end
|
|
70
62
|
|
|
71
63
|
def formatter_class(format)
|
|
@@ -106,7 +98,7 @@ module Cucumber
|
|
|
106
98
|
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
|
107
99
|
path = path.chomp('/')
|
|
108
100
|
if File.directory?(path)
|
|
109
|
-
Dir["#{path}/**/*.feature"]
|
|
101
|
+
Dir["#{path}/**/*.feature"]
|
|
110
102
|
elsif path[0..0] == '@' and # @listfile.txt
|
|
111
103
|
File.file?(path[1..-1]) # listfile.txt is a file
|
|
112
104
|
IO.read(path[1..-1]).split
|
|
@@ -129,27 +121,7 @@ module Cucumber
|
|
|
129
121
|
logger.level = Logger::DEBUG if self.verbose?
|
|
130
122
|
logger
|
|
131
123
|
end
|
|
132
|
-
|
|
133
|
-
def tag_expression
|
|
134
|
-
Gherkin::TagExpression.new(@options[:tag_expressions])
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def filters
|
|
138
|
-
@options.filters
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def formats
|
|
142
|
-
@options[:formats]
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def options
|
|
146
|
-
warn("Deprecated: Configuration#options will be removed from the next release of Cucumber. Please use the configuration object directly instead.")
|
|
147
|
-
@options
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def paths
|
|
151
|
-
@options[:paths].empty? ? ['features'] : @options[:paths]
|
|
152
|
-
end
|
|
124
|
+
|
|
153
125
|
private
|
|
154
126
|
|
|
155
127
|
def formatters(step_mother)
|
|
@@ -179,6 +151,9 @@ module Cucumber
|
|
|
179
151
|
end
|
|
180
152
|
end
|
|
181
153
|
|
|
154
|
+
def paths
|
|
155
|
+
@options[:paths].empty? ? ['features'] : @options[:paths]
|
|
156
|
+
end
|
|
182
157
|
|
|
183
158
|
def set_environment_variables
|
|
184
159
|
@options[:env_vars].each do |var, value|
|
data/lib/cucumber/cli/main.rb
CHANGED
|
@@ -9,6 +9,7 @@ require 'cucumber'
|
|
|
9
9
|
require 'logger'
|
|
10
10
|
require 'cucumber/parser'
|
|
11
11
|
require 'cucumber/feature_file'
|
|
12
|
+
require 'cucumber/formatter/color_io'
|
|
12
13
|
require 'cucumber/cli/configuration'
|
|
13
14
|
require 'cucumber/cli/drb_client'
|
|
14
15
|
|
|
@@ -16,32 +17,55 @@ module Cucumber
|
|
|
16
17
|
module Cli
|
|
17
18
|
class Main
|
|
18
19
|
class << self
|
|
20
|
+
def step_mother
|
|
21
|
+
@step_mother ||= StepMother.new
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
def execute(args)
|
|
20
|
-
new(args).execute!
|
|
25
|
+
new(args).execute!(step_mother)
|
|
21
26
|
end
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
def initialize(args, out_stream = STDOUT, error_stream = STDERR)
|
|
25
30
|
@args = args
|
|
26
|
-
|
|
31
|
+
if Cucumber::WINDOWS_MRI
|
|
32
|
+
@out_stream = out_stream == STDOUT ? Formatter::ColorIO.new(Kernel, STDOUT) : out_stream
|
|
33
|
+
else
|
|
34
|
+
@out_stream = out_stream
|
|
35
|
+
end
|
|
27
36
|
|
|
28
37
|
@error_stream = error_stream
|
|
29
38
|
@configuration = nil
|
|
30
39
|
end
|
|
31
40
|
|
|
32
|
-
def execute!(
|
|
41
|
+
def execute!(step_mother)
|
|
33
42
|
trap_interrupt
|
|
34
|
-
|
|
43
|
+
if configuration.drb?
|
|
44
|
+
begin
|
|
45
|
+
return DRbClient.run(@args, @error_stream, @out_stream, configuration.drb_port)
|
|
46
|
+
rescue DRbClientError => e
|
|
47
|
+
@error_stream.puts "WARNING: #{e.message} Running features locally:"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
step_mother.options = configuration.options
|
|
51
|
+
step_mother.log = configuration.log
|
|
52
|
+
|
|
53
|
+
step_mother.load_code_files(configuration.support_to_load)
|
|
54
|
+
step_mother.after_configuration(configuration)
|
|
55
|
+
features = step_mother.load_plain_text_features(configuration.feature_files)
|
|
56
|
+
step_mother.load_code_files(configuration.step_defs_to_load)
|
|
57
|
+
|
|
58
|
+
runner = configuration.build_runner(step_mother, @out_stream)
|
|
59
|
+
step_mother.visitor = runner # Needed to support World#announce
|
|
35
60
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
runner.visit_features(features)
|
|
62
|
+
|
|
63
|
+
failure = if configuration.wip?
|
|
64
|
+
step_mother.scenarios(:passed).any?
|
|
39
65
|
else
|
|
40
|
-
|
|
66
|
+
step_mother.scenarios(:failed).any? ||
|
|
67
|
+
(configuration.strict? && (step_mother.steps(:undefined).any? || step_mother.steps(:pending).any?))
|
|
41
68
|
end
|
|
42
|
-
|
|
43
|
-
runtime.run!
|
|
44
|
-
runtime.results.failure?
|
|
45
69
|
rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e
|
|
46
70
|
@error_stream.puts e.message
|
|
47
71
|
true
|
|
@@ -52,19 +76,10 @@ module Cucumber
|
|
|
52
76
|
|
|
53
77
|
@configuration = Configuration.new(@out_stream, @error_stream)
|
|
54
78
|
@configuration.parse!(@args)
|
|
55
|
-
Cucumber.logger = @configuration.log
|
|
56
79
|
@configuration
|
|
57
80
|
end
|
|
58
81
|
|
|
59
82
|
private
|
|
60
|
-
|
|
61
|
-
def run_drb_client
|
|
62
|
-
return false unless configuration.drb?
|
|
63
|
-
@drb_output = DRbClient.run(@args, @error_stream, @out_stream, configuration.drb_port)
|
|
64
|
-
true
|
|
65
|
-
rescue DRbClientError => e
|
|
66
|
-
@error_stream.puts "WARNING: #{e.message} Running features locally:"
|
|
67
|
-
end
|
|
68
83
|
|
|
69
84
|
def trap_interrupt
|
|
70
85
|
trap('INT') do
|