cucumber 0.3.102 → 0.3.103

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.
Files changed (47) hide show
  1. data/History.txt +18 -0
  2. data/Manifest.txt +6 -2
  3. data/examples/java/README.textile +3 -3
  4. data/examples/self_test/features/sample.feature +1 -1
  5. data/examples/self_test/features/search_sample.feature +1 -1
  6. data/features/custom_formatter.feature +4 -4
  7. data/features/steps_formatter.feature +2 -1
  8. data/lib/cucumber/ast.rb +1 -0
  9. data/lib/cucumber/ast/table.rb +4 -4
  10. data/lib/cucumber/ast/tree_walker.rb +185 -0
  11. data/lib/cucumber/ast/visitor.rb +2 -106
  12. data/lib/cucumber/cli/configuration.rb +28 -28
  13. data/lib/cucumber/cli/language_help_formatter.rb +5 -7
  14. data/lib/cucumber/cli/main.rb +3 -3
  15. data/lib/cucumber/core_ext/string.rb +0 -22
  16. data/lib/cucumber/formatter/html.rb +203 -113
  17. data/lib/cucumber/formatter/junit.rb +29 -23
  18. data/lib/cucumber/formatter/pdf.rb +74 -69
  19. data/lib/cucumber/formatter/pretty.rb +93 -78
  20. data/lib/cucumber/formatter/profile.rb +2 -2
  21. data/lib/cucumber/formatter/progress.rb +16 -10
  22. data/lib/cucumber/formatter/rerun.rb +4 -5
  23. data/lib/cucumber/formatter/steps.rb +6 -7
  24. data/lib/cucumber/formatter/tag_cloud.rb +7 -6
  25. data/lib/cucumber/formatter/usage.rb +7 -10
  26. data/lib/cucumber/language_support/step_definition_methods.rb +4 -4
  27. data/lib/cucumber/rails/action_controller.rb +1 -1
  28. data/lib/cucumber/rails/active_record.rb +27 -14
  29. data/lib/cucumber/rb_support/rb_language.rb +5 -0
  30. data/lib/cucumber/rb_support/rb_step_definition.rb +9 -16
  31. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +21 -0
  32. data/lib/cucumber/step_argument.rb +9 -0
  33. data/lib/cucumber/step_match.rb +24 -5
  34. data/lib/cucumber/version.rb +1 -1
  35. data/rails_generators/cucumber/templates/env.rb +14 -0
  36. data/spec/cucumber/ast/background_spec.rb +1 -2
  37. data/spec/cucumber/ast/scenario_outline_spec.rb +3 -2
  38. data/spec/cucumber/ast/scenario_spec.rb +1 -1
  39. data/spec/cucumber/ast/tree_walker_spec.rb +18 -0
  40. data/spec/cucumber/formatter/html_spec.rb +221 -2
  41. data/spec/cucumber/formatter/progress_spec.rb +9 -4
  42. data/spec/cucumber/parser/feature_parser_spec.rb +31 -27
  43. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +18 -0
  44. data/spec/cucumber/step_match_spec.rb +40 -0
  45. metadata +8 -4
  46. data/lib/cucumber/rb_support/rb_group.rb +0 -11
  47. data/spec/cucumber/core_ext/string_spec.rb +0 -41
@@ -1,3 +1,21 @@
1
+ == 2009-09-24
2
+
3
+ This release gives you back some of the control over the Rails environment that was accidentally taken away from you in the
4
+ previous release.
5
+
6
+ Using this release on a Rails project requires a rerun of script/generate cucumber.
7
+
8
+ === New Features
9
+ * Added a new @no-txn tag to selectively turn off transactions for a particlular scenario.
10
+ * Added back a way to globally turn off transactions.
11
+ * Renamed @allow_rescue tag to @allow-rescue.
12
+
13
+ === Bugfixes
14
+ * Gracefully handle cases when optional regexp groups are not matched. Ex: /should( not)? be flashed '([^']*?)'$/ (Aslak Hellesøy)
15
+
16
+ === Changed Features
17
+ * The Formatter API has completely changed. Formatters are no longer a double-dispacth visitor - just a single-dispatch listener (#438 Matt Wynne)
18
+
1
19
  == 2009-09-22
2
20
 
3
21
  This release has some changes in the Rails support, so make sure you run "script/generate cucumber" after you upgrade.
@@ -329,6 +329,7 @@ lib/cucumber/ast/step_collection.rb
329
329
  lib/cucumber/ast/step_invocation.rb
330
330
  lib/cucumber/ast/table.rb
331
331
  lib/cucumber/ast/tags.rb
332
+ lib/cucumber/ast/tree_walker.rb
332
333
  lib/cucumber/ast/visitor.rb
333
334
  lib/cucumber/broadcaster.rb
334
335
  lib/cucumber/cli/configuration.rb
@@ -385,13 +386,14 @@ lib/cucumber/rails/test_unit.rb
385
386
  lib/cucumber/rails/world.rb
386
387
  lib/cucumber/rake/task.rb
387
388
  lib/cucumber/rb_support/rb_dsl.rb
388
- lib/cucumber/rb_support/rb_group.rb
389
389
  lib/cucumber/rb_support/rb_hook.rb
390
390
  lib/cucumber/rb_support/rb_language.rb
391
391
  lib/cucumber/rb_support/rb_step_definition.rb
392
392
  lib/cucumber/rb_support/rb_transform.rb
393
393
  lib/cucumber/rb_support/rb_world.rb
394
+ lib/cucumber/rb_support/regexp_argument_matcher.rb
394
395
  lib/cucumber/rspec_neuter.rb
396
+ lib/cucumber/step_argument.rb
395
397
  lib/cucumber/step_match.rb
396
398
  lib/cucumber/step_mother.rb
397
399
  lib/cucumber/version.rb
@@ -420,6 +422,7 @@ spec/cucumber/ast/scenario_spec.rb
420
422
  spec/cucumber/ast/step_collection_spec.rb
421
423
  spec/cucumber/ast/step_spec.rb
422
424
  spec/cucumber/ast/table_spec.rb
425
+ spec/cucumber/ast/tree_walker_spec.rb
423
426
  spec/cucumber/broadcaster_spec.rb
424
427
  spec/cucumber/cli/configuration_spec.rb
425
428
  spec/cucumber/cli/drb_client_spec.rb
@@ -427,7 +430,6 @@ spec/cucumber/cli/main_spec.rb
427
430
  spec/cucumber/cli/options_spec.rb
428
431
  spec/cucumber/cli/profile_loader_spec.rb
429
432
  spec/cucumber/core_ext/proc_spec.rb
430
- spec/cucumber/core_ext/string_spec.rb
431
433
  spec/cucumber/formatter/ansicolor_spec.rb
432
434
  spec/cucumber/formatter/color_io_spec.rb
433
435
  spec/cucumber/formatter/duration_spec.rb
@@ -436,7 +438,9 @@ spec/cucumber/formatter/progress_spec.rb
436
438
  spec/cucumber/parser/feature_parser_spec.rb
437
439
  spec/cucumber/parser/table_parser_spec.rb
438
440
  spec/cucumber/rb_support/rb_step_definition_spec.rb
441
+ spec/cucumber/rb_support/regexp_argument_matcher_spec.rb
439
442
  spec/cucumber/sell_cucumbers.feature
443
+ spec/cucumber/step_match_spec.rb
440
444
  spec/cucumber/step_mother_spec.rb
441
445
  spec/cucumber/treetop_parser/empty_feature.feature
442
446
  spec/cucumber/treetop_parser/empty_scenario.feature
@@ -11,8 +11,8 @@ h2. Running the scenarios
11
11
 
12
12
  Open a shell in this directory (java) and execute the following command:
13
13
 
14
- <pre><code>
15
- ant
16
- </code></pre>
14
+ <pre>ant</pre>
17
15
 
18
16
  There is a deliberate error. See if you can fix it!
17
+
18
+ Also see "Cuke4Duke":http://wiki.github.com/aslakhellesoy/cuke4duke for more powerful JVM and Java support for Cucumber.
@@ -12,7 +12,7 @@ Feature: Sample
12
12
  Given passing
13
13
  |a|b|
14
14
  |c|d|
15
-
15
+
16
16
  @four
17
17
  Scenario: Failing
18
18
  Given failing
@@ -20,7 +20,7 @@ Feature: search examples
20
20
  Examples:
21
21
  | state |
22
22
  | passing |
23
-
23
+
24
24
  Scenario Outline: no match in name but in examples
25
25
  Given <state> without a table
26
26
  Examples: Hantu Pisang
@@ -8,7 +8,7 @@ Feature: Custom Formatter
8
8
  | 1 | 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 | 2 | 1 |
9
9
 
10
10
  """
11
-
11
+
12
12
  Scenario: my own formatter
13
13
  Given a standard Cucumber project directory structure
14
14
  And a file named "features/f.feature" with:
@@ -25,13 +25,13 @@ Feature: Custom Formatter
25
25
  And a file named "features/support/ze/formator.rb" with:
26
26
  """
27
27
  module Ze
28
- class Formator < Cucumber::Ast::Visitor
28
+ class Formator
29
29
  def initialize(step_mother, io, options)
30
- super(step_mother)
30
+ @step_mother = step_mother
31
31
  @io = io
32
32
  end
33
33
 
34
- def visit_scenario_name(keyword, name, file_colon_line, source_indent)
34
+ def scenario_name(keyword, name, file_colon_line, source_indent)
35
35
  @io.puts "$ #{name.upcase}"
36
36
  end
37
37
  end
@@ -8,7 +8,8 @@ Feature: --formatter steps option - Steps Formatter
8
8
 
9
9
  Scenario: Printing steps
10
10
  When I run cucumber -f steps features
11
- Then it should pass with
11
+ Then STDERR should be empty
12
+ And it should pass with
12
13
  """
13
14
  features/step_definitions/steps_lib1.rb
14
15
  /^I defined a first step$/ # features/step_definitions/steps_lib1.rb:1
@@ -13,6 +13,7 @@ require 'cucumber/ast/py_string'
13
13
  require 'cucumber/ast/outline_table'
14
14
  require 'cucumber/ast/examples'
15
15
  require 'cucumber/ast/visitor'
16
+ require 'cucumber/ast/tree_walker'
16
17
 
17
18
  module Cucumber
18
19
  # Classes in this module represent the Abstract Syntax Tree (AST)
@@ -389,11 +389,11 @@ module Cucumber
389
389
 
390
390
  c = Term::ANSIColor.coloring?
391
391
  Term::ANSIColor.coloring = options[:color]
392
- f = Formatter::Pretty.new(nil, io, options)
393
- f.instance_variable_set('@indent', options[:indent])
394
- f.visit_multiline_arg(self)
392
+ formatter = Formatter::Pretty.new(nil, io, options)
393
+ formatter.instance_variable_set('@indent', options[:indent])
394
+ TreeWalker.new(nil, [formatter]).visit_multiline_arg(self)
395
+
395
396
  Term::ANSIColor.coloring = c
396
-
397
397
  io.rewind
398
398
  s = "\n" + io.read + (" " * (options[:indent] - 2))
399
399
  s
@@ -0,0 +1,185 @@
1
+ module Cucumber
2
+ module Ast
3
+ # Walks the AST, executing steps and notifying listeners
4
+ class TreeWalker
5
+ attr_accessor :options #:nodoc:
6
+ attr_reader :step_mother #:nodoc:
7
+
8
+ def initialize(step_mother, listeners = [], options = {}, io = STDOUT)
9
+ @step_mother, @listeners, @options, @io = step_mother, listeners, options, io
10
+ end
11
+
12
+ def visit_features(features)
13
+ warn "The listener(s) (#{deprecated_listeners.map{ |l| l.class }}) appear to support the legacy Ast::Visitor interface, which is no longer supported." if deprecated_listeners.any?
14
+ broadcast(features) do
15
+ features.accept(self)
16
+ end
17
+ end
18
+
19
+ def visit_feature(feature)
20
+ broadcast(feature) do
21
+ feature.accept(self)
22
+ end
23
+ end
24
+
25
+ def visit_comment(comment)
26
+ broadcast(comment) do
27
+ comment.accept(self)
28
+ end
29
+ end
30
+
31
+ def visit_comment_line(comment_line)
32
+ broadcast(comment_line)
33
+ end
34
+
35
+ def visit_tags(tags)
36
+ broadcast(tags) do
37
+ tags.accept(self)
38
+ end
39
+ end
40
+
41
+ def visit_tag_name(tag_name)
42
+ broadcast(tag_name)
43
+ end
44
+
45
+ def visit_feature_name(name)
46
+ broadcast(name)
47
+ end
48
+
49
+ # +feature_element+ is either Scenario or ScenarioOutline
50
+ def visit_feature_element(feature_element)
51
+ broadcast(feature_element) do
52
+ feature_element.accept(self)
53
+ end
54
+ end
55
+
56
+ def visit_background(background)
57
+ broadcast(background) do
58
+ background.accept(self)
59
+ end
60
+ end
61
+
62
+ def visit_background_name(keyword, name, file_colon_line, source_indent)
63
+ broadcast(keyword, name, file_colon_line, source_indent)
64
+ end
65
+
66
+ def visit_examples_array(examples_array)
67
+ broadcast(examples_array) do
68
+ examples_array.accept(self)
69
+ end
70
+ end
71
+
72
+ def visit_examples(examples)
73
+ broadcast(examples) do
74
+ examples.accept(self)
75
+ end
76
+ end
77
+
78
+ def visit_examples_name(keyword, name)
79
+ broadcast(keyword, name)
80
+ end
81
+
82
+ def visit_outline_table(outline_table)
83
+ broadcast(outline_table) do
84
+ outline_table.accept(self)
85
+ end
86
+ end
87
+
88
+ def visit_scenario_name(keyword, name, file_colon_line, source_indent)
89
+ broadcast(keyword, name, file_colon_line, source_indent)
90
+ end
91
+
92
+ def visit_steps(steps)
93
+ broadcast(steps) do
94
+ steps.accept(self)
95
+ end
96
+ end
97
+
98
+ def visit_step(step)
99
+ broadcast(step) do
100
+ step.accept(self)
101
+ end
102
+ end
103
+
104
+ def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
105
+ broadcast(keyword, step_match, multiline_arg, status, exception, source_indent, background) do
106
+ visit_step_name(keyword, step_match, status, source_indent, background)
107
+ visit_multiline_arg(multiline_arg) if multiline_arg
108
+ visit_exception(exception, status) if exception
109
+ end
110
+ end
111
+
112
+ def visit_step_name(keyword, step_match, status, source_indent, background) #:nodoc:
113
+ broadcast(keyword, step_match, status, source_indent, background)
114
+ end
115
+
116
+ def visit_multiline_arg(multiline_arg) #:nodoc:
117
+ broadcast(multiline_arg) do
118
+ multiline_arg.accept(self)
119
+ end
120
+ end
121
+
122
+ def visit_exception(exception, status) #:nodoc:
123
+ broadcast(exception, status)
124
+ end
125
+
126
+ def visit_py_string(string)
127
+ broadcast(string)
128
+ end
129
+
130
+ def visit_table_row(table_row)
131
+ broadcast(table_row) do
132
+ table_row.accept(self)
133
+ end
134
+ end
135
+
136
+ def visit_table_cell(table_cell)
137
+ broadcast(table_cell) do
138
+ table_cell.accept(self)
139
+ end
140
+ end
141
+
142
+ def visit_table_cell_value(value, status)
143
+ broadcast(value, status)
144
+ end
145
+
146
+ # Print +announcement+. This method can be called from within StepDefinitions.
147
+ def announce(announcement)
148
+ broadcast(announcement)
149
+ end
150
+
151
+ private
152
+
153
+ def broadcast(*args, &block)
154
+ message = extract_method_name_from(caller)
155
+ message.gsub!('visit_', '')
156
+
157
+ unless block_given?
158
+ send_to_all(message, *args)
159
+ return
160
+ end
161
+
162
+ send_to_all("before_#{message}", *args)
163
+ yield if block_given?
164
+ send_to_all("after_#{message}", *args)
165
+ end
166
+
167
+ def send_to_all(message, *args)
168
+ @listeners.each do |listener|
169
+ if listener.respond_to?(message)
170
+ listener.__send__(message, *args)
171
+ end
172
+ end
173
+ end
174
+
175
+ def extract_method_name_from(call_stack)
176
+ call_stack[0].match(/in `(.*)'/).captures[0]
177
+ end
178
+
179
+ def deprecated_listeners
180
+ @listeners.select{ |l| l.respond_to?(:visit_features) }
181
+ end
182
+
183
+ end
184
+ end
185
+ end
@@ -1,115 +1,11 @@
1
1
  module Cucumber
2
2
  module Ast
3
- # Base class for formatters. This class just walks the tree depth first.
4
- # Just override the methods you care about. Remember to call super if you
5
- # override a method.
6
3
  class Visitor
7
- attr_accessor :options #:nodoc:
8
- attr_reader :step_mother #:nodoc:
4
+ DEPRECATION_WARNING = "Cucumber::Ast::Visitor is deprecated and will be removed. You no longer need to inherit from this class."
9
5
 
10
6
  def initialize(step_mother)
11
- @options = {}
12
- @step_mother = step_mother
7
+ raise(DEPRECATION_WARNING)
13
8
  end
14
-
15
- def visit_features(features)
16
- features.accept(self)
17
- end
18
-
19
- def visit_feature(feature)
20
- feature.accept(self)
21
- end
22
-
23
- def visit_comment(comment)
24
- comment.accept(self)
25
- end
26
-
27
- def visit_comment_line(comment_line)
28
- end
29
-
30
- def visit_tags(tags)
31
- tags.accept(self)
32
- end
33
-
34
- def visit_tag_name(tag_name)
35
- end
36
-
37
- def visit_feature_name(name)
38
- end
39
-
40
- # +feature_element+ is either Scenario or ScenarioOutline
41
- def visit_feature_element(feature_element)
42
- feature_element.accept(self)
43
- end
44
-
45
- def visit_background(background)
46
- background.accept(self)
47
- end
48
-
49
- def visit_background_name(keyword, name, file_colon_line, source_indent)
50
- end
51
-
52
- def visit_examples_array(examples_array)
53
- examples_array.accept(self)
54
- end
55
-
56
- def visit_examples(examples)
57
- examples.accept(self)
58
- end
59
-
60
- def visit_examples_name(keyword, name)
61
- end
62
-
63
- def visit_outline_table(outline_table)
64
- @table = outline_table
65
- outline_table.accept(self)
66
- end
67
-
68
- def visit_scenario_name(keyword, name, file_colon_line, source_indent)
69
- end
70
-
71
- def visit_steps(steps)
72
- steps.accept(self)
73
- end
74
-
75
- def visit_step(step)
76
- step.accept(self)
77
- end
78
-
79
- def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
80
- visit_step_name(keyword, step_match, status, source_indent, background)
81
- visit_multiline_arg(multiline_arg) if multiline_arg
82
- visit_exception(exception, status) if exception
83
- end
84
-
85
- def visit_step_name(keyword, step_match, status, source_indent, background) #:nodoc:
86
- end
87
-
88
- def visit_multiline_arg(multiline_arg) #:nodoc:
89
- multiline_arg.accept(self)
90
- end
91
-
92
- def visit_exception(exception, status) #:nodoc:
93
- end
94
-
95
- def visit_py_string(string)
96
- end
97
-
98
- def visit_table_row(table_row)
99
- table_row.accept(self)
100
- end
101
-
102
- def visit_table_cell(table_cell)
103
- table_cell.accept(self)
104
- end
105
-
106
- def visit_table_cell_value(value, status)
107
- end
108
-
109
- # Print +announcement+. This method can be called from within StepDefinitions.
110
- def announce(announcement)
111
- end
112
-
113
9
  end
114
10
  end
115
11
  end