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