cucumber 0.4.3 → 0.4.4
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/History.txt +27 -0
- data/VERSION.yml +3 -2
- data/cucumber.gemspec +11 -5
- data/examples/watir/features/support/screenshots.rb +1 -2
- data/features/call_many_steps.feature +124 -0
- data/features/default_snippets.feature +2 -2
- data/features/expand.feature +13 -2
- data/features/language_help.feature +1 -1
- data/features/report_called_undefined_steps.feature +1 -1
- data/features/snippet.feature +2 -2
- data/features/support/env.rb +3 -5
- data/features/tag_logic.feature +32 -0
- data/features/wire_protocol.feature +7 -7
- data/lib/cucumber.rb +6 -0
- data/lib/cucumber/ast/background.rb +1 -1
- data/lib/cucumber/ast/comment.rb +1 -1
- data/lib/cucumber/ast/examples.rb +1 -1
- data/lib/cucumber/ast/feature.rb +1 -1
- data/lib/cucumber/ast/feature_element.rb +2 -3
- data/lib/cucumber/ast/features.rb +1 -1
- data/lib/cucumber/ast/outline_table.rb +17 -4
- data/lib/cucumber/ast/py_string.rb +3 -1
- data/lib/cucumber/ast/scenario.rb +3 -1
- data/lib/cucumber/ast/scenario_outline.rb +2 -2
- data/lib/cucumber/ast/step.rb +1 -1
- data/lib/cucumber/ast/step_collection.rb +1 -1
- data/lib/cucumber/ast/step_invocation.rb +2 -1
- data/lib/cucumber/ast/table.rb +3 -3
- data/lib/cucumber/ast/tags.rb +18 -11
- data/lib/cucumber/ast/tree_walker.rb +16 -0
- data/lib/cucumber/cli/main.rb +3 -2
- data/lib/cucumber/cli/options.rb +4 -6
- data/lib/cucumber/cli/profile_loader.rb +4 -0
- data/lib/cucumber/filter.rb +2 -2
- data/lib/cucumber/formatter/ansicolor.rb +8 -0
- data/lib/cucumber/formatter/pretty.rb +3 -4
- data/lib/cucumber/language_support/language_methods.rb +4 -3
- data/lib/cucumber/languages.yml +1 -1
- data/lib/cucumber/parser.rb +2 -0
- data/lib/cucumber/parser/common.rb +170 -0
- data/lib/cucumber/parser/common.tt +21 -0
- data/lib/cucumber/parser/feature.rb +7 -291
- data/lib/cucumber/parser/feature.tt +7 -43
- data/lib/cucumber/parser/i18n.tt +2 -0
- data/lib/cucumber/parser/natural_language.rb +9 -0
- data/lib/cucumber/parser/py_string.rb +276 -0
- data/lib/cucumber/parser/py_string.tt +45 -0
- data/lib/cucumber/parser/table.rb +5 -120
- data/lib/cucumber/parser/table.tt +2 -13
- data/lib/cucumber/platform.rb +3 -2
- data/lib/cucumber/rails/active_record.rb +2 -21
- data/lib/cucumber/rails/world.rb +2 -1
- data/lib/cucumber/rb_support/rb_hook.rb +2 -1
- data/lib/cucumber/rb_support/rb_language.rb +8 -6
- data/lib/cucumber/rb_support/rb_step_definition.rb +4 -0
- data/lib/cucumber/rb_support/rb_world.rb +16 -37
- data/lib/cucumber/step_mother.rb +86 -2
- data/lib/cucumber/wire_support/wire_language.rb +2 -2
- data/lib/cucumber/wire_support/wire_protocol.rb +1 -1
- data/rails_generators/cucumber/cucumber_generator.rb +3 -1
- data/rails_generators/cucumber/templates/cucumber.rake +4 -2
- data/rails_generators/cucumber/templates/webrat_steps.rb +28 -28
- data/spec/cucumber/ast/background_spec.rb +2 -1
- data/spec/cucumber/ast/scenario_spec.rb +3 -1
- data/spec/cucumber/formatter/console_spec.rb +1 -1
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +14 -5
- data/spec/cucumber/step_mother_spec.rb +1 -1
- data/spec/cucumber/world/pending_spec.rb +1 -1
- metadata +8 -3
@@ -23,7 +23,7 @@ module Cucumber
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def accept(visitor)
|
26
|
-
return if
|
26
|
+
return if Cucumber.wants_to_quit
|
27
27
|
visitor.visit_comment(@comment) unless @comment.empty?
|
28
28
|
visitor.visit_background_name(@keyword, @name, file_colon_line(@line), source_indent(first_line_length))
|
29
29
|
with_visitor(hook_context, visitor) do
|
data/lib/cucumber/ast/comment.rb
CHANGED
@@ -6,7 +6,7 @@ module Cucumber
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def accept(visitor)
|
9
|
-
return if
|
9
|
+
return if Cucumber.wants_to_quit
|
10
10
|
visitor.visit_comment(@comment) unless @comment.empty?
|
11
11
|
visitor.visit_examples_name(@keyword, @name)
|
12
12
|
visitor.visit_outline_table(@outline_table)
|
data/lib/cucumber/ast/feature.rb
CHANGED
@@ -49,8 +49,7 @@ module Cucumber
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def accept_hook?(hook)
|
52
|
-
|
53
|
-
Tags.matches?(source_tag_names, parsed_hook_tag_names)
|
52
|
+
Tags.matches?(source_tag_names, hook.tag_name_lists)
|
54
53
|
end
|
55
54
|
|
56
55
|
def source_tag_names
|
@@ -62,7 +61,7 @@ module Cucumber
|
|
62
61
|
end
|
63
62
|
|
64
63
|
def language
|
65
|
-
@feature.language
|
64
|
+
@feature.language if @feature
|
66
65
|
end
|
67
66
|
end
|
68
67
|
end
|
@@ -9,7 +9,7 @@ module Cucumber
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def accept(visitor)
|
12
|
-
return if
|
12
|
+
return if Cucumber.wants_to_quit
|
13
13
|
cells_rows.each_with_index do |row, n|
|
14
14
|
if(visitor.options[:expand])
|
15
15
|
row.accept(visitor)
|
@@ -44,7 +44,11 @@ module Cucumber
|
|
44
44
|
@scenario_outline.visit_scenario_name(visitor, row)
|
45
45
|
end
|
46
46
|
|
47
|
-
|
47
|
+
def language
|
48
|
+
@scenario_outline.language
|
49
|
+
end
|
50
|
+
|
51
|
+
class ExampleRow < Cells #:nodoc:
|
48
52
|
class InvalidForHeaderRowError < NoMethodError
|
49
53
|
def initialize(*args)
|
50
54
|
super 'This is a header row and cannot pass or fail'
|
@@ -53,6 +57,11 @@ module Cucumber
|
|
53
57
|
|
54
58
|
attr_reader :scenario_outline # https://rspec.lighthouseapp.com/projects/16211/tickets/342
|
55
59
|
|
60
|
+
def initialize(table, cells)
|
61
|
+
super
|
62
|
+
@scenario_exception = nil
|
63
|
+
end
|
64
|
+
|
56
65
|
def create_step_invocations!(scenario_outline)
|
57
66
|
@scenario_outline = scenario_outline
|
58
67
|
@step_invocations = scenario_outline.step_invocations(self)
|
@@ -65,7 +74,7 @@ module Cucumber
|
|
65
74
|
end
|
66
75
|
|
67
76
|
def accept(visitor)
|
68
|
-
return if
|
77
|
+
return if Cucumber.wants_to_quit
|
69
78
|
visitor.options[:expand] ? accept_expand(visitor) : accept_plain(visitor)
|
70
79
|
end
|
71
80
|
|
@@ -141,7 +150,11 @@ module Cucumber
|
|
141
150
|
def name
|
142
151
|
"| #{@cells.collect{|c| c.value }.join(' | ')} |"
|
143
152
|
end
|
144
|
-
|
153
|
+
|
154
|
+
def language
|
155
|
+
@table.language
|
156
|
+
end
|
157
|
+
|
145
158
|
private
|
146
159
|
|
147
160
|
def header?
|
@@ -17,6 +17,8 @@ module Cucumber
|
|
17
17
|
# Note how the indentation from the source is stripped away.
|
18
18
|
#
|
19
19
|
class PyString #:nodoc:
|
20
|
+
attr_accessor :file
|
21
|
+
|
20
22
|
def self.default_arg_name
|
21
23
|
"string"
|
22
24
|
end
|
@@ -31,7 +33,7 @@ module Cucumber
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def accept(visitor)
|
34
|
-
return if
|
36
|
+
return if Cucumber.wants_to_quit
|
35
37
|
visitor.visit_py_string(to_s)
|
36
38
|
end
|
37
39
|
|
@@ -29,10 +29,12 @@ module Cucumber
|
|
29
29
|
step_invocations = steps.map{|step| step.step_invocation}
|
30
30
|
@steps = @background.step_collection(step_invocations)
|
31
31
|
@background.feature_elements << self
|
32
|
+
|
33
|
+
@exception = @executed = nil
|
32
34
|
end
|
33
35
|
|
34
36
|
def accept(visitor)
|
35
|
-
return if
|
37
|
+
return if Cucumber.wants_to_quit
|
36
38
|
|
37
39
|
with_visitor(visitor) do
|
38
40
|
visitor.visit_comment(@comment) unless @comment.empty?
|
@@ -5,7 +5,7 @@ module Cucumber
|
|
5
5
|
|
6
6
|
module ExamplesArray #:nodoc:
|
7
7
|
def accept(visitor)
|
8
|
-
return if
|
8
|
+
return if Cucumber.wants_to_quit
|
9
9
|
each do |examples|
|
10
10
|
visitor.visit_examples(examples)
|
11
11
|
end
|
@@ -39,7 +39,7 @@ module Cucumber
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def accept(visitor)
|
42
|
-
return if
|
42
|
+
return if Cucumber.wants_to_quit
|
43
43
|
visitor.visit_comment(@comment) unless @comment.empty?
|
44
44
|
visitor.visit_tags(@tags)
|
45
45
|
visitor.visit_scenario_name(@keyword, @name, file_colon_line(@line), source_indent(first_line_length))
|
data/lib/cucumber/ast/step.rb
CHANGED
@@ -38,7 +38,7 @@ module Cucumber
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def accept(visitor)
|
41
|
-
return if
|
41
|
+
return if Cucumber.wants_to_quit
|
42
42
|
# The only time a Step is visited is when it is in a ScenarioOutline.
|
43
43
|
# Otherwise it's always StepInvocation that gets visited instead.
|
44
44
|
visit_step_result(visitor, first_match(visitor), @multiline_arg, :skipped, nil, nil)
|
@@ -22,6 +22,7 @@ module Cucumber
|
|
22
22
|
def initialize(step, name, multiline_arg, matched_cells)
|
23
23
|
@step, @name, @multiline_arg, @matched_cells = step, name, multiline_arg, matched_cells
|
24
24
|
status!(:skipped)
|
25
|
+
@skip_invoke = @exception = @step_match = @different_table = @reported_exception = @background = nil
|
25
26
|
end
|
26
27
|
|
27
28
|
def background?
|
@@ -33,7 +34,7 @@ module Cucumber
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def accept(visitor)
|
36
|
-
return if
|
37
|
+
return if Cucumber.wants_to_quit
|
37
38
|
invoke(visitor.step_mother, visitor.options)
|
38
39
|
visit_step_result(visitor)
|
39
40
|
end
|
data/lib/cucumber/ast/table.rb
CHANGED
@@ -148,7 +148,7 @@ module Cucumber
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def accept(visitor) #:nodoc:
|
151
|
-
return if
|
151
|
+
return if Cucumber.wants_to_quit
|
152
152
|
cells_rows.each do |row|
|
153
153
|
visitor.visit_table_row(row)
|
154
154
|
end
|
@@ -567,7 +567,7 @@ module Cucumber
|
|
567
567
|
end
|
568
568
|
|
569
569
|
def accept(visitor)
|
570
|
-
return if
|
570
|
+
return if Cucumber.wants_to_quit
|
571
571
|
each do |cell|
|
572
572
|
visitor.visit_table_cell(cell)
|
573
573
|
end
|
@@ -623,7 +623,7 @@ module Cucumber
|
|
623
623
|
end
|
624
624
|
|
625
625
|
def accept(visitor)
|
626
|
-
return if
|
626
|
+
return if Cucumber.wants_to_quit
|
627
627
|
visitor.visit_table_cell_value(value, status)
|
628
628
|
end
|
629
629
|
|
data/lib/cucumber/ast/tags.rb
CHANGED
@@ -10,9 +10,12 @@ module Cucumber
|
|
10
10
|
# This gets stored internally as <tt>["invoice", "release_2"]</tt>
|
11
11
|
#
|
12
12
|
class Tags #:nodoc:
|
13
|
-
|
14
13
|
class And #:nodoc:
|
15
14
|
def initialize(tag_names)
|
15
|
+
if String === tag_names # They still come in as single strings on cuke4duke some times. Not sure why...
|
16
|
+
raise "Commas in tags??? #{tag_names.inspect}" if tag_names =~ /,/ # just in case...
|
17
|
+
tag_names = [tag_names]
|
18
|
+
end
|
16
19
|
@negative_tags, @positive_tags = tag_names.partition{|tag_name| Tags.exclude_tag?(tag_name)}
|
17
20
|
@negative_tags = Tags.strip_negative_char(@negative_tags)
|
18
21
|
end
|
@@ -47,9 +50,9 @@ module Cucumber
|
|
47
50
|
class << self
|
48
51
|
EXCLUDE_PATTERN = /^~/
|
49
52
|
|
50
|
-
def matches?(source_tag_names,
|
51
|
-
validate_tags(
|
52
|
-
|
53
|
+
def matches?(source_tag_names, tag_name_lists)
|
54
|
+
validate_tags(tag_name_lists)
|
55
|
+
tag_name_lists.empty? ? true : check_if_tags_match(source_tag_names, tag_name_lists)
|
53
56
|
end
|
54
57
|
|
55
58
|
def exclude_tag?(tag_name)
|
@@ -60,22 +63,26 @@ module Cucumber
|
|
60
63
|
tag_names.map{|name| name[1..-1]}
|
61
64
|
end
|
62
65
|
|
66
|
+
def parse_tags(tags_string)
|
67
|
+
tags_string.split(',')
|
68
|
+
end
|
69
|
+
|
63
70
|
private
|
64
71
|
|
65
|
-
def validate_tags(
|
66
|
-
all_tag_names =
|
72
|
+
def validate_tags(tag_name_lists)
|
73
|
+
all_tag_names = tag_name_lists.flatten
|
67
74
|
exclude_tag_names, include_tag_names = all_tag_names.partition{|tag_name| exclude_tag?(tag_name)}
|
68
75
|
exclude_tag_names = strip_negative_char(exclude_tag_names)
|
69
76
|
check_at_sign_prefix(exclude_tag_names + include_tag_names)
|
70
77
|
end
|
71
78
|
|
72
|
-
def check_if_tags_match(source_tag_names,
|
73
|
-
tag_exp = Or.new(
|
79
|
+
def check_if_tags_match(source_tag_names, tag_name_lists)
|
80
|
+
tag_exp = Or.new(tag_name_lists.map{|tag_name_list| And.new(tag_name_list) })
|
74
81
|
tag_exp.matches?(source_tag_names)
|
75
82
|
end
|
76
83
|
|
77
84
|
def check_at_sign_prefix(tag_names)
|
78
|
-
tag_names.each{|tag_name| raise "Tag names must start with an @ sign. The following tag name didn't: #{tag_name}" unless tag_name[0..0] == '@'}
|
85
|
+
tag_names.each{|tag_name| raise "Tag names must start with an @ sign. The following tag name didn't: #{tag_name.inspect}" unless tag_name[0..0] == '@'}
|
79
86
|
end
|
80
87
|
|
81
88
|
end
|
@@ -87,14 +94,14 @@ module Cucumber
|
|
87
94
|
end
|
88
95
|
|
89
96
|
def accept(visitor)
|
90
|
-
return if
|
97
|
+
return if Cucumber.wants_to_quit
|
91
98
|
@tag_names.each do |tag_name|
|
92
99
|
visitor.visit_tag_name(tag_name)
|
93
100
|
end
|
94
101
|
end
|
95
102
|
|
96
103
|
def accept_hook?(hook)
|
97
|
-
self.class.matches?(@tag_names, hook.
|
104
|
+
self.class.matches?(@tag_names, hook.tag_name_lists)
|
98
105
|
end
|
99
106
|
|
100
107
|
def count(tag)
|
@@ -75,6 +75,22 @@ 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
|
78
94
|
broadcast(keyword, name)
|
79
95
|
end
|
80
96
|
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -29,6 +29,7 @@ module Cucumber
|
|
29
29
|
@args = args
|
30
30
|
@out_stream = out_stream == STDOUT ? Formatter::ColorIO.new : out_stream
|
31
31
|
@error_stream = error_stream
|
32
|
+
@configuration = nil
|
32
33
|
end
|
33
34
|
|
34
35
|
def execute!(step_mother)
|
@@ -110,8 +111,8 @@ module Cucumber
|
|
110
111
|
|
111
112
|
def trap_interrupt
|
112
113
|
trap('INT') do
|
113
|
-
exit!(1) if
|
114
|
-
|
114
|
+
exit!(1) if Cucumber.wants_to_quit
|
115
|
+
Cucumber.wants_to_quit = true
|
115
116
|
STDERR.puts "\nExiting... Interrupt again to exit immediately."
|
116
117
|
end
|
117
118
|
end
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -48,10 +48,6 @@ module Cucumber
|
|
48
48
|
new(out_stream, error_stream, options).parse!(args)
|
49
49
|
end
|
50
50
|
|
51
|
-
def self.parse_tag_arguments(tags_string)
|
52
|
-
tags_string.split(',')
|
53
|
-
end
|
54
|
-
|
55
51
|
def initialize(out_stream = STDOUT, error_stream = STDERR, options = {})
|
56
52
|
@out_stream = out_stream
|
57
53
|
@error_stream = error_stream
|
@@ -60,7 +56,9 @@ module Cucumber
|
|
60
56
|
@skip_profile_information = options[:skip_profile_information]
|
61
57
|
@profiles = []
|
62
58
|
@overridden_paths = []
|
63
|
-
@options
|
59
|
+
@options = default_options
|
60
|
+
|
61
|
+
@quiet = @disable_profile_loading = nil
|
64
62
|
end
|
65
63
|
|
66
64
|
def [](key)
|
@@ -292,7 +290,7 @@ module Cucumber
|
|
292
290
|
end
|
293
291
|
|
294
292
|
def parse_tags(tag_string)
|
295
|
-
tag_names =
|
293
|
+
tag_names = Ast::Tags.parse_tags(tag_string)
|
296
294
|
parse_tag_limits(tag_names)
|
297
295
|
end
|
298
296
|
|
data/lib/cucumber/filter.rb
CHANGED
@@ -3,7 +3,7 @@ module Cucumber
|
|
3
3
|
class Filter #:nodoc:
|
4
4
|
def initialize(lines, options)
|
5
5
|
@lines = lines
|
6
|
-
@
|
6
|
+
@tag_name_lists = options[:tag_names] ? options[:tag_names].map{|tags_with_limit| tags_with_limit.keys } : []
|
7
7
|
@name_regexps = options[:name_regexps] || []
|
8
8
|
end
|
9
9
|
|
@@ -27,7 +27,7 @@ module Cucumber
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def matches_tags?(syntax_node)
|
30
|
-
syntax_node.matches_tags?(@
|
30
|
+
syntax_node.matches_tags?(@tag_name_lists)
|
31
31
|
end
|
32
32
|
|
33
33
|
def outline_matches_names?(syntax_node)
|
@@ -1,6 +1,14 @@
|
|
1
1
|
require 'term/ansicolor'
|
2
2
|
require 'cucumber/platform'
|
3
3
|
|
4
|
+
if Cucumber::IRONRUBY
|
5
|
+
begin
|
6
|
+
require 'iron-term-ansicolor'
|
7
|
+
rescue LoadError
|
8
|
+
STDERR.puts %{*** WARNING: You must "igem install iron-term-ansicolor" to get coloured ouput in on IronRuby}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
if Cucumber::WINDOWS_MRI
|
5
13
|
begin
|
6
14
|
require 'Win32/Console/ANSI'
|
@@ -178,13 +178,13 @@ module Cucumber
|
|
178
178
|
end
|
179
179
|
|
180
180
|
def before_table_row(table_row)
|
181
|
-
return
|
181
|
+
return if !@table || @hide_this_step
|
182
182
|
@col_index = 0
|
183
183
|
@io.print ' |'.indent(@indent-2)
|
184
184
|
end
|
185
185
|
|
186
186
|
def after_table_row(table_row)
|
187
|
-
return
|
187
|
+
return if !@table || @hide_this_step
|
188
188
|
print_table_row_announcements
|
189
189
|
@io.puts
|
190
190
|
if table_row.exception && !@exceptions.include?(table_row.exception)
|
@@ -198,7 +198,7 @@ module Cucumber
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def table_cell_value(value, status)
|
201
|
-
return
|
201
|
+
return if !@table || @hide_this_step
|
202
202
|
status ||= @status || :passed
|
203
203
|
width = @table.col_width(@col_index)
|
204
204
|
cell_text = value.to_s || ''
|
@@ -234,7 +234,6 @@ module Cucumber
|
|
234
234
|
print_passing_wip(@options)
|
235
235
|
print_tag_limit_warnings(@options)
|
236
236
|
end
|
237
|
-
|
238
237
|
end
|
239
238
|
end
|
240
239
|
end
|