cucumber 0.7.2 → 0.7.3

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.
@@ -1,3 +1,9 @@
1
+ == 0.7.3
2
+
3
+ === New Features
4
+ * Table cells can now contain escaped bars - \| and escaped backslashes - \\. (Gregory Hnatiuk, Aslak Hellesøy)
5
+ * Added support for Around hooks. (#605 John Firebaugh)
6
+
1
7
  == 0.7.2 (2010-05-03)
2
8
 
3
9
  === Bugfixes
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ begin
16
16
  gem.homepage = "http://cukes.info"
17
17
  gem.authors = ["Aslak Hellesøy"]
18
18
 
19
- gem.add_dependency 'gherkin', '>= 1.0.24'
19
+ gem.add_dependency 'gherkin', '>= 1.0.27'
20
20
  gem.add_dependency 'term-ansicolor', '>= 1.0.4'
21
21
  gem.add_dependency 'builder', '>= 2.1.2'
22
22
  gem.add_dependency 'diff-lcs', '>= 1.1.2'
@@ -1,5 +1,5 @@
1
1
  ---
2
- :patch: 2
2
+ :patch: 3
3
3
  :build:
4
4
  :major: 0
5
5
  :minor: 7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cucumber}
8
- s.version = "0.7.2"
8
+ s.version = "0.7.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Aslak Helles\303\270y"]
12
- s.date = %q{2010-05-04}
12
+ s.date = %q{2010-05-18}
13
13
  s.default_executable = %q{cucumber}
14
14
  s.description = %q{Behaviour Driven Development with elegance and joy}
15
15
  s.email = %q{cukes@googlegroups.com}
@@ -342,6 +342,7 @@ Gem::Specification.new do |s|
342
342
  "examples/webrat/features/step_definitions/kvasir_steps.rb",
343
343
  "examples/webrat/features/support/env.rb",
344
344
  "features/announce.feature",
345
+ "features/around_hooks.feature",
345
346
  "features/background.feature",
346
347
  "features/bug_371.feature",
347
348
  "features/bug_464.feature",
@@ -541,7 +542,7 @@ Gem::Specification.new do |s|
541
542
 
542
543
  (::) U P G R A D I N G (::)
543
544
 
544
- Thank you for installing cucumber-0.7.2.
545
+ Thank you for installing cucumber-0.7.3.
545
546
  Please be sure to read http://wiki.github.com/aslakhellesoy/cucumber/upgrading
546
547
  for important information about this release. Happy cuking!
547
548
 
@@ -681,6 +682,7 @@ for important information about this release. Happy cuking!
681
682
  "examples/ruby2python/features/support/env.rb",
682
683
  "examples/self_test/features/step_definitions/sample_steps.rb",
683
684
  "examples/self_test/features/support/env.rb",
685
+ "examples/self_test/tmp/features/step_definitions/steps.rb",
684
686
  "examples/sinatra/app.rb",
685
687
  "examples/sinatra/features/step_definitions/add_steps.rb",
686
688
  "examples/sinatra/features/support/env.rb",
@@ -713,7 +715,7 @@ for important information about this release. Happy cuking!
713
715
  s.specification_version = 3
714
716
 
715
717
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
716
- s.add_runtime_dependency(%q<gherkin>, [">= 1.0.24"])
718
+ s.add_runtime_dependency(%q<gherkin>, [">= 1.0.27"])
717
719
  s.add_runtime_dependency(%q<term-ansicolor>, [">= 1.0.4"])
718
720
  s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
719
721
  s.add_runtime_dependency(%q<diff-lcs>, [">= 1.1.2"])
@@ -726,7 +728,7 @@ for important information about this release. Happy cuking!
726
728
  s.add_development_dependency(%q<syntax>, [">= 1.0.0"])
727
729
  s.add_development_dependency(%q<spork>, [">= 0.8.3"])
728
730
  else
729
- s.add_dependency(%q<gherkin>, [">= 1.0.24"])
731
+ s.add_dependency(%q<gherkin>, [">= 1.0.27"])
730
732
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.4"])
731
733
  s.add_dependency(%q<builder>, [">= 2.1.2"])
732
734
  s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
@@ -740,7 +742,7 @@ for important information about this release. Happy cuking!
740
742
  s.add_dependency(%q<spork>, [">= 0.8.3"])
741
743
  end
742
744
  else
743
- s.add_dependency(%q<gherkin>, [">= 1.0.24"])
745
+ s.add_dependency(%q<gherkin>, [">= 1.0.27"])
744
746
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.4"])
745
747
  s.add_dependency(%q<builder>, [">= 2.1.2"])
746
748
  s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
@@ -37,5 +37,10 @@ Feature: Fibonacci
37
37
  Scenario: Single series with Before hook with a tag label
38
38
  Then it should give me [1, 1, 2]
39
39
 
40
+ @another-do-fibonnacci-in-before-hook
41
+ Scenario: Single series with Before hook with a tag label
42
+ Then it should give me [1, 1, 2]
43
+
44
+
40
45
  Scenario: Single series by calling a step from within a step
41
46
  Then it should give me [1, 1] via calling another step definition
@@ -2,7 +2,7 @@ Before(function(){
2
2
  fibResult = 0;
3
3
  });
4
4
 
5
- Before('@do-fibonnacci-in-before-hook', function(){
5
+ Before(['@another-do-fibonnacci-in-before-hook,@do-fibonnacci-in-before-hook'], function(){
6
6
  fibResult = fibonacciSeries(3);
7
7
  });
8
8
 
@@ -38,7 +38,6 @@ Then(/^it should contain:$/, function(table){
38
38
  assertMatches(hashes[0]['cell 2'], fibResult);
39
39
  });
40
40
 
41
-
42
41
  Then(/^it should give me (\[.*\]) via calling another step definition$/, function(expectedResult){
43
42
  Given("I ask Javascript to calculate fibonacci up to 2");
44
43
  assertEqual(expectedResult, fibResult);
@@ -0,0 +1,188 @@
1
+ Feature: Around hooks
2
+ In order to support transactional scenarios for database libraries
3
+ that provide only a block syntax for transactions, Cucumber should
4
+ permit definition of Around hooks.
5
+
6
+ Scenario: A single Around hook
7
+ Given a standard Cucumber project directory structure
8
+ And a file named "features/step_definitions/steps.rb" with:
9
+ """
10
+ Then /^the hook is called$/ do
11
+ $hook_called.should == true
12
+ end
13
+ """
14
+ And a file named "features/support/hooks.rb" with:
15
+ """
16
+ Around do |scenario, block|
17
+ $hook_called = true
18
+ block.call
19
+ end
20
+ """
21
+ And a file named "features/f.feature" with:
22
+ """
23
+ Feature: Around hooks
24
+ Scenario: using hook
25
+ Then the hook is called
26
+ """
27
+ When I run cucumber features/f.feature
28
+ Then it should pass with
29
+ """
30
+ Feature: Around hooks
31
+
32
+ Scenario: using hook # features/f.feature:2
33
+ Then the hook is called # features/step_definitions/steps.rb:1
34
+
35
+ 1 scenario (1 passed)
36
+ 1 step (1 passed)
37
+
38
+ """
39
+
40
+ Scenario: Multiple Around hooks
41
+ Given a standard Cucumber project directory structure
42
+ And a file named "features/step_definitions/steps.rb" with:
43
+ """
44
+ Then /^the hooks are called in the correct order$/ do
45
+ $hooks_called.should == ['A', 'B', 'C']
46
+ end
47
+ """
48
+ And a file named "features/support/hooks.rb" with:
49
+ """
50
+ Around do |scenario, block|
51
+ $hooks_called ||= []
52
+ $hooks_called << 'A'
53
+ block.call
54
+ end
55
+
56
+ Around do |scenario, block|
57
+ $hooks_called ||= []
58
+ $hooks_called << 'B'
59
+ block.call
60
+ end
61
+
62
+ Around do |scenario, block|
63
+ $hooks_called ||= []
64
+ $hooks_called << 'C'
65
+ block.call
66
+ end
67
+ """
68
+ And a file named "features/f.feature" with:
69
+ """
70
+ Feature: Around hooks
71
+ Scenario: using multiple hooks
72
+ Then the hooks are called in the correct order
73
+ """
74
+ When I run cucumber features/f.feature
75
+ Then it should pass with
76
+ """
77
+ Feature: Around hooks
78
+
79
+ Scenario: using multiple hooks # features/f.feature:2
80
+ Then the hooks are called in the correct order # features/step_definitions/steps.rb:1
81
+
82
+ 1 scenario (1 passed)
83
+ 1 step (1 passed)
84
+
85
+ """
86
+
87
+ Scenario: Mixing Around, Before, and After hooks
88
+ Given a standard Cucumber project directory structure
89
+ And a file named "features/step_definitions/steps.rb" with:
90
+ """
91
+ Then /^the Around hook is called around Before and After hooks$/ do
92
+ $hooks_called.should == ['Around', 'Before']
93
+ end
94
+ """
95
+ And a file named "features/support/hooks.rb" with:
96
+ """
97
+ Around do |scenario, block|
98
+ $hooks_called ||= []
99
+ $hooks_called << 'Around'
100
+ block.call
101
+ $hooks_called << 'Around'
102
+ $hooks_called.should == ['Around', 'Before', 'After', 'Around']
103
+ end
104
+
105
+ Before do |scenario|
106
+ $hooks_called ||= []
107
+ $hooks_called << 'Before'
108
+ end
109
+
110
+ After do |scenario|
111
+ $hooks_called ||= []
112
+ $hooks_called << 'After'
113
+ $hooks_called.should == ['Around', 'Before', 'After']
114
+ end
115
+ """
116
+ And a file named "features/f.feature" with:
117
+ """
118
+ Feature: Around hooks
119
+ Scenario: Mixing Around, Before, and After hooks
120
+ Then the Around hook is called around Before and After hooks
121
+ """
122
+ When I run cucumber features/f.feature
123
+ Then it should pass with
124
+ """
125
+ Feature: Around hooks
126
+
127
+ Scenario: Mixing Around, Before, and After hooks # features/f.feature:2
128
+ Then the Around hook is called around Before and After hooks # features/step_definitions/steps.rb:1
129
+
130
+ 1 scenario (1 passed)
131
+ 1 step (1 passed)
132
+
133
+ """
134
+
135
+ Scenario: Around hooks with tags
136
+ Given a standard Cucumber project directory structure
137
+ And a file named "features/step_definitions/steps.rb" with:
138
+ """
139
+ Then /^the Around hooks with matching tags are called$/ do
140
+ $hooks_called.should == ['one', 'one or two']
141
+ end
142
+ """
143
+ And a file named "features/support/hooks.rb" with:
144
+ """
145
+ Around('@one') do |scenario, block|
146
+ $hooks_called ||= []
147
+ $hooks_called << 'one'
148
+ block.call
149
+ end
150
+
151
+ Around('@one,@two') do |scenario, block|
152
+ $hooks_called ||= []
153
+ $hooks_called << 'one or two'
154
+ block.call
155
+ end
156
+
157
+ Around('@one', '@two') do |scenario, block|
158
+ $hooks_called ||= []
159
+ $hooks_called << 'one and two'
160
+ block.call
161
+ end
162
+
163
+ Around('@two') do |scenario, block|
164
+ $hooks_called ||= []
165
+ $hooks_called << 'two'
166
+ block.call
167
+ end
168
+ """
169
+ And a file named "features/f.feature" with:
170
+ """
171
+ Feature: Around hooks
172
+ @one
173
+ Scenario: Around hooks with tags
174
+ Then the Around hooks with matching tags are called
175
+ """
176
+ When I run cucumber -q -t @one features/f.feature
177
+ Then it should pass with
178
+ """
179
+ Feature: Around hooks
180
+
181
+ @one
182
+ Scenario: Around hooks with tags
183
+ Then the Around hooks with matching tags are called
184
+
185
+ 1 scenario (1 passed)
186
+ 1 step (1 passed)
187
+
188
+ """
@@ -54,6 +54,7 @@ Feature: Language help
54
54
  | ja | Japanese | 日本語 |
55
55
  | ko | Korean | 한국어 |
56
56
  | lt | Lithuanian | lietuvių kalba |
57
+ | lu | Luxemburgish | Lëtzebuergesch |
57
58
  | lv | Latvian | latviešu |
58
59
  | nl | Dutch | Nederlands |
59
60
  | no | Norwegian | norsk |
@@ -28,13 +28,13 @@ module Cucumber
28
28
 
29
29
  def name_line_lengths
30
30
  if @name.strip.empty?
31
- [Ast::Step::INDENT + @keyword.jlength + ': '.jlength]
31
+ [Ast::Step::INDENT + @keyword.unpack('U*').length + ': '.length]
32
32
  else
33
33
  @name.split("\n").enum_for(:each_with_index).map do |line, line_number|
34
34
  if line_number == 0
35
- Ast::Step::INDENT + @keyword.jlength + ': '.jlength + line.jlength
35
+ Ast::Step::INDENT + @keyword.unpack('U*').length + ': '.length + line.unpack('U*').length
36
36
  else
37
- Ast::Step::INDENT + Ast::Step::INDENT + line.jlength
37
+ Ast::Step::INDENT + Ast::Step::INDENT + line.unpack('U*').length
38
38
  end
39
39
  end
40
40
  end
@@ -48,9 +48,11 @@ module Cucumber
48
48
  visitor.visit_scenario_name(@keyword, @name, file_colon_line(@line), source_indent(first_line_length))
49
49
 
50
50
  skip_invoke! if @background.failed?
51
- visitor.step_mother.before_and_after(self, skip_hooks?) do
52
- skip_invoke! if failed?
53
- visitor.visit_steps(@steps)
51
+ visitor.step_mother.around(self, skip_hooks?) do
52
+ visitor.step_mother.before_and_after(self, skip_hooks?) do
53
+ skip_invoke! if failed?
54
+ visitor.visit_steps(@steps)
55
+ end
54
56
  end
55
57
  @executed = true
56
58
  end
@@ -69,7 +69,7 @@ module Cucumber
69
69
  end
70
70
 
71
71
  def text_length(name=@name)
72
- INDENT + INDENT + @keyword.jlength + name.jlength
72
+ INDENT + INDENT + @keyword.unpack('U*').length + name.unpack('U*').length
73
73
  end
74
74
 
75
75
  def backtrace_line
@@ -1,4 +1,5 @@
1
1
  require 'gherkin/rubify'
2
+ require 'gherkin/formatter/escaping'
2
3
 
3
4
  module Cucumber
4
5
  module Ast
@@ -585,6 +586,8 @@ module Cucumber
585
586
  # Represents a row of cells or columns of cells
586
587
  class Cells #:nodoc:
587
588
  include Enumerable
589
+ include Gherkin::Formatter::Escaping
590
+
588
591
  attr_reader :exception
589
592
 
590
593
  def initialize(table, cells)
@@ -631,7 +634,7 @@ module Cucumber
631
634
  end
632
635
 
633
636
  def width
634
- map{|cell| cell.value ? cell.value.to_s.jlength : 0}.max
637
+ map{|cell| cell.value ? escape_cell(cell.value.to_s).unpack('U*').length : 0}.max
635
638
  end
636
639
 
637
640
  def each(&proc)
@@ -6,11 +6,4 @@ class String #:nodoc:
6
6
  gsub(/^ {0,#{-n}}/, "")
7
7
  end
8
8
  end
9
-
10
- if (Cucumber::JRUBY && Cucumber::RAILS) || Cucumber::RUBY_1_9
11
- # Workaround for http://tinyurl.com/55uu3u
12
- alias jlength length
13
- else
14
- require 'jcode'
15
- end
16
9
  end
@@ -32,7 +32,8 @@ module Cucumber
32
32
  lexer = Gherkin::I18nLexer.new(parser, false)
33
33
 
34
34
  begin
35
- lexer.scan(source)
35
+ s = ENV['FILTER_PML_CALLOUT'] ? source.gsub(C_CALLOUT, '') : source
36
+ lexer.scan(s)
36
37
  ast = builder.ast
37
38
  return nil if ast.nil? # Filter caused nothing to match
38
39
  ast.language = lexer.i18n_language
@@ -59,14 +60,10 @@ module Cucumber
59
60
  end
60
61
  end
61
62
 
62
- def lang
63
- # TODO: Gherkin has logic for this. Remove.
64
- line_one = source.split(/\n/)[0]
65
- if line_one =~ LANGUAGE_PATTERN
66
- $1.strip
67
- else
68
- nil
69
- end
70
- end
63
+ private
64
+
65
+ # Special PML markup that we want to filter out.
66
+ CO = %{\\s*<(label|callout)\s+id=".*?"\s*/>\\s*}
67
+ C_CALLOUT = %r{/\*#{CO}\*/|//#{CO}}o
71
68
  end
72
69
  end
@@ -1,6 +1,7 @@
1
+ require 'fileutils'
1
2
  require 'cucumber/formatter/console'
2
3
  require 'cucumber/formatter/io'
3
- require 'fileutils'
4
+ require 'gherkin/formatter/escaping'
4
5
 
5
6
  module Cucumber
6
7
  module Formatter
@@ -15,6 +16,7 @@ module Cucumber
15
16
  include FileUtils
16
17
  include Console
17
18
  include Io
19
+ include Gherkin::Formatter::Escaping
18
20
  attr_writer :indent
19
21
  attr_reader :step_mother
20
22
 
@@ -198,8 +200,8 @@ module Cucumber
198
200
  return if !@table || @hide_this_step
199
201
  status ||= @status || :passed
200
202
  width = @table.col_width(@col_index)
201
- cell_text = value.to_s || ''
202
- padded = cell_text + (' ' * (width - cell_text.jlength))
203
+ cell_text = escape_cell(value.to_s || '')
204
+ padded = cell_text + (' ' * (width - cell_text.unpack('U*').length))
203
205
  prefix = cell_prefix(status)
204
206
  @io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Term::ANSIColor.reset(" |"))
205
207
  @io.flush
@@ -24,7 +24,7 @@ module Cucumber
24
24
  source_indent = source_indent(sources)
25
25
  sources.sort.each do |file_colon_line, regexp_source|
26
26
  @io.print regexp_source.indent(2)
27
- @io.print " # #{file_colon_line}".indent(source_indent - regexp_source.jlength)
27
+ @io.print " # #{file_colon_line}".indent(source_indent - regexp_source.unpack('U*').length)
28
28
  @io.puts
29
29
  end
30
30
  @io.puts
@@ -68,7 +68,7 @@ module Cucumber
68
68
  @io.print format_string(sprintf("%.7f", stepdef_key.mean_duration), :skipped) + " " unless @options[:dry_run]
69
69
  @io.print format_string(stepdef_key.regexp_source, stepdef_key.status)
70
70
  if @options[:source]
71
- indent = max_length - stepdef_key.regexp_source.jlength
71
+ indent = max_length - stepdef_key.regexp_source.unpack('U*').length
72
72
  line_comment = " # #{stepdef_key.file_colon_line}".indent(indent)
73
73
  @io.print(format_string(line_comment, :comment))
74
74
  end
@@ -81,7 +81,7 @@ module Cucumber
81
81
  @io.print format_string(sprintf("%.7f", step[:duration]), :skipped) + " " unless @options[:dry_run]
82
82
  @io.print format_step(step[:keyword], step[:step_match], step[:status], nil)
83
83
  if @options[:source]
84
- indent = max_length - (step[:keyword].jlength + step[:step_match].format_args.jlength)
84
+ indent = max_length - (step[:keyword].unpack('U*').length + step[:step_match].format_args.unpack('U*').length)
85
85
  line_comment = " # #{step[:file_colon_line]}".indent(indent)
86
86
  @io.print(format_string(line_comment, :comment))
87
87
  end
@@ -94,12 +94,12 @@ module Cucumber
94
94
  end
95
95
 
96
96
  def max_stepdef_length
97
- @stepdef_to_match.keys.flatten.map{|key| key.regexp_source.jlength}.max
97
+ @stepdef_to_match.keys.flatten.map{|key| key.regexp_source.unpack('U*').length}.max
98
98
  end
99
99
 
100
100
  def max_step_length
101
101
  @stepdef_to_match.values.to_a.flatten.map do |step|
102
- step[:keyword].jlength + step[:step_match].format_args.jlength
102
+ step[:keyword].unpack('U*').length + step[:step_match].format_args.unpack('U*').length
103
103
  end.max
104
104
  end
105
105
 
@@ -12,28 +12,27 @@ var CucumberJsDsl = {
12
12
  jsLanguage.registerJsTransform(regexp, func);
13
13
  },
14
14
 
15
- beforeHook: function(tag_or_func, func){
16
- CucumberJsDsl.__registerJsHook('before', tag_or_func, func);
15
+ beforeHook: function(tag_expressions_or_func, func){
16
+ CucumberJsDsl.__registerJsHook('before', tag_expressions_or_func, func);
17
17
  },
18
18
 
19
- afterHook: function(tag_or_func, func){
20
- CucumberJsDsl.__registerJsHook('after', tag_or_func, func);
19
+ afterHook: function(tag_expressions_or_func, func){
20
+ CucumberJsDsl.__registerJsHook('after', tag_expressions_or_func, func);
21
21
  },
22
22
 
23
23
  Table: function(raw_table){
24
24
  this.raw = raw_table;
25
25
  },
26
26
 
27
- __registerJsHook: function(label, tag_or_func, func){
27
+ __registerJsHook: function(label, tag_expressions_or_func, func){
28
28
  if(func != null){
29
29
  var hook_func = func;
30
- var tag = tag_or_func;
30
+ var tag_expressions = tag_expressions_or_func;
31
+ } else {
32
+ var hook_func = tag_expressions_or_func;
33
+ var tag_expressions = [];
31
34
  }
32
- else{
33
- var hook_func = tag_or_func;
34
- var tag = null;
35
- }
36
- jsLanguage.registerJsHook(label, hook_func, tag);
35
+ jsLanguage.registerJsHook(label, tag_expressions, hook_func);
37
36
  }
38
37
  }
39
38
 
@@ -58,12 +58,12 @@ module Cucumber
58
58
  end
59
59
 
60
60
  class JsHook
61
- def initialize(js_language, tag_names, js_function)
62
- @js_language, @tag_names, @js_function = js_language, tag_names, js_function
61
+ def initialize(js_language, tag_expressions, js_function)
62
+ @js_language, @tag_expressions, @js_function = js_language, tag_expressions, js_function
63
63
  end
64
64
 
65
65
  def tag_expressions
66
- @tag_names
66
+ @tag_expressions
67
67
  end
68
68
 
69
69
  def invoke(location, scenario)
@@ -145,10 +145,8 @@ module Cucumber
145
145
  @step_mother.step_match(name).invoke(multiline_argument)
146
146
  end
147
147
 
148
- #TODO: support multiple tag_names
149
- def register_js_hook(phase, js_function, tag_name = nil)
150
- tag_names = tag_name ? [tag_name] : []
151
- add_hook(phase, JsHook.new(self, tag_names, js_function))
148
+ def register_js_hook(phase, tag_expressions, js_function)
149
+ add_hook(phase, JsHook.new(self, tag_expressions, js_function))
152
150
  end
153
151
 
154
152
  def register_js_transform(regexp, js_function)
@@ -8,6 +8,12 @@ module Cucumber
8
8
  StepMatch.new(step_definition, step_name, name_to_report, step_arguments)
9
9
  end
10
10
 
11
+ def around(scenario)
12
+ execute_around(scenario) do
13
+ yield
14
+ end
15
+ end
16
+
11
17
  def before(scenario)
12
18
  begin_scenario(scenario)
13
19
  execute_before(scenario)
@@ -85,6 +91,16 @@ module Cucumber
85
91
  @transforms ||= []
86
92
  end
87
93
 
94
+ def execute_around(scenario, &block)
95
+ hooks_for(:around, scenario).reverse.inject(block) do |blk, hook|
96
+ proc do
97
+ invoke(hook, 'Around', scenario, true) do
98
+ blk.call(scenario)
99
+ end
100
+ end
101
+ end.call
102
+ end
103
+
88
104
  def execute_before(scenario)
89
105
  hooks_for(:before, scenario).each do |hook|
90
106
  invoke(hook, 'Before', scenario, true)
@@ -97,9 +113,9 @@ module Cucumber
97
113
  end
98
114
  end
99
115
 
100
- def invoke(hook, location, scenario, exception_fails_scenario)
116
+ def invoke(hook, location, scenario, exception_fails_scenario, &block)
101
117
  begin
102
- hook.invoke(location, scenario)
118
+ hook.invoke(location, scenario, &block)
103
119
  rescue Exception => exception
104
120
  if exception_fails_scenario
105
121
  scenario.fail!(exception)
@@ -50,18 +50,27 @@ module Cucumber
50
50
  RbDsl.build_rb_world_factory(world_modules, proc)
51
51
  end
52
52
 
53
- # Registers a proc that will run before each Scenario. You can register as
53
+ # Registers a proc that will run before each Scenario. You can register as many
54
54
  # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
55
55
  def Before(*tag_expressions, &proc)
56
56
  RbDsl.register_rb_hook('before', tag_expressions, proc)
57
57
  end
58
58
 
59
- # Registers a proc that will run after each Scenario. You can register as
59
+ # Registers a proc that will run after each Scenario. You can register as many
60
60
  # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
61
61
  def After(*tag_expressions, &proc)
62
62
  RbDsl.register_rb_hook('after', tag_expressions, proc)
63
63
  end
64
64
 
65
+ # Registers a proc that will be wrapped around each scenario. The proc
66
+ # should accept two arguments: two arguments: the scenario and a "block"
67
+ # argument (but passed as a regular argument, since blocks cannot accept
68
+ # blocks in 1.8), on which it should call the .call method. You can register
69
+ # as many as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
70
+ def Around(*tag_expressions, &proc)
71
+ RbDsl.register_rb_hook('around', tag_expressions, proc)
72
+ end
73
+
65
74
  # Registers a proc that will run after each Step. You can register as
66
75
  # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
67
76
  def AfterStep(*tag_expressions, &proc)
@@ -10,8 +10,8 @@ module Cucumber
10
10
  @proc = proc
11
11
  end
12
12
 
13
- def invoke(location, argument)
14
- @rb_language.current_world.cucumber_instance_exec(false, location, argument, &@proc)
13
+ def invoke(location, argument, &block)
14
+ @rb_language.current_world.cucumber_instance_exec(false, location, *[argument, block].compact, &@proc)
15
15
  end
16
16
  end
17
17
  end
@@ -92,8 +92,8 @@ module Cucumber
92
92
  connect_world(scenario)
93
93
  end
94
94
 
95
- def register_rb_hook(phase, tag_names, proc)
96
- add_hook(phase, RbHook.new(self, tag_names, proc))
95
+ def register_rb_hook(phase, tag_expressions, proc)
96
+ add_hook(phase, RbHook.new(self, tag_expressions, proc))
97
97
  end
98
98
 
99
99
  def register_rb_transform(regexp, proc)
@@ -54,7 +54,7 @@ module Cucumber
54
54
  end
55
55
 
56
56
  def text_length
57
- @step_definition.regexp_source.jlength
57
+ @step_definition.regexp_source.unpack('U*').length
58
58
  end
59
59
 
60
60
  def replace_arguments(string, step_arguments, format, &proc)
@@ -72,7 +72,7 @@ module Cucumber
72
72
  end
73
73
 
74
74
  s[step_argument.byte_offset + offset, step_argument.val.length] = replacement
75
- offset += replacement.jlength - step_argument.val.jlength
75
+ offset += replacement.unpack('U*').length - step_argument.val.unpack('U*').length
76
76
  past_offset = step_argument.byte_offset + step_argument.val.length
77
77
  end
78
78
  s
@@ -311,6 +311,20 @@ module Cucumber
311
311
  @programming_languages.empty?
312
312
  end
313
313
 
314
+ def around(scenario, skip_hooks=false, &block) #:nodoc:
315
+ unless skip_hooks
316
+ @programming_languages.reverse.inject(block) do |blk, programming_language|
317
+ proc do
318
+ programming_language.around(scenario) do
319
+ blk.call(scenario)
320
+ end
321
+ end
322
+ end.call
323
+ else
324
+ yield
325
+ end
326
+ end
327
+
314
328
  def before_and_after(scenario, skip_hooks=false) #:nodoc:
315
329
  before(scenario) unless skip_hooks
316
330
  yield scenario
@@ -171,6 +171,20 @@ or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.
171
171
 
172
172
  @rb.hooks_for(:before, scenario).should == [fish]
173
173
  end
174
+
175
+ it "should find around hooks" do
176
+ a = @dsl.Around do |scenario, block|
177
+ end
178
+
179
+ b = @dsl.Around('@tag') do |scenario, block|
180
+ end
181
+
182
+ scenario = mock('Scenario')
183
+ scenario.should_receive(:accept_hook?).with(a).and_return(true)
184
+ scenario.should_receive(:accept_hook?).with(b).and_return(false)
185
+
186
+ @rb.hooks_for(:around, scenario).should == [a]
187
+ end
174
188
  end
175
189
 
176
190
  describe StepMother, "step argument transformations" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 2
9
- version: 0.7.2
8
+ - 3
9
+ version: 0.7.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - "Aslak Helles\xC3\xB8y"
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-04 00:00:00 +02:00
17
+ date: 2010-05-18 00:00:00 +02:00
18
18
  default_executable: cucumber
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,8 +27,8 @@ dependencies:
27
27
  segments:
28
28
  - 1
29
29
  - 0
30
- - 24
31
- version: 1.0.24
30
+ - 27
31
+ version: 1.0.27
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
@@ -518,6 +518,7 @@ files:
518
518
  - examples/webrat/features/step_definitions/kvasir_steps.rb
519
519
  - examples/webrat/features/support/env.rb
520
520
  - features/announce.feature
521
+ - features/around_hooks.feature
521
522
  - features/background.feature
522
523
  - features/bug_371.feature
523
524
  - features/bug_464.feature
@@ -720,7 +721,7 @@ post_install_message: |+
720
721
 
721
722
  (::) U P G R A D I N G (::)
722
723
 
723
- Thank you for installing cucumber-0.7.2.
724
+ Thank you for installing cucumber-0.7.3.
724
725
  Please be sure to read http://wiki.github.com/aslakhellesoy/cucumber/upgrading
725
726
  for important information about this release. Happy cuking!
726
727
 
@@ -880,6 +881,7 @@ test_files:
880
881
  - examples/ruby2python/features/support/env.rb
881
882
  - examples/self_test/features/step_definitions/sample_steps.rb
882
883
  - examples/self_test/features/support/env.rb
884
+ - examples/self_test/tmp/features/step_definitions/steps.rb
883
885
  - examples/sinatra/app.rb
884
886
  - examples/sinatra/features/step_definitions/add_steps.rb
885
887
  - examples/sinatra/features/support/env.rb