aslakhellesoy-cucumber 0.2.3.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/Manifest.txt +3 -0
- data/config/hoe.rb +1 -1
- data/cucumber.yml +1 -1
- data/examples/self_test/features/background/passing_background.feature +2 -2
- data/examples/self_test/features/step_definitions/sample_steps.rb +10 -0
- data/examples/tickets/features/229/tagged_hooks.feature +8 -0
- data/examples/tickets/features/229/tagged_hooks.rb +14 -0
- data/examples/tickets/features/279/py_string_indent.steps.rb +1 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +0 -7
- data/features/background.feature +1 -0
- data/features/rake_task.feature +132 -0
- data/features/step_definitions/cucumber_steps.rb +38 -19
- data/features/support/env.rb +61 -4
- data/gem_tasks/deployment.rake +1 -1
- data/lib/cucumber/ast/background.rb +11 -1
- data/lib/cucumber/ast/feature_element.rb +4 -0
- data/lib/cucumber/ast/outline_table.rb +8 -0
- data/lib/cucumber/ast/tags.rb +9 -1
- data/lib/cucumber/cli/configuration.rb +2 -2
- data/lib/cucumber/cli/main.rb +5 -1
- data/lib/cucumber/parser/feature.rb +2 -2
- data/lib/cucumber/parser/feature.tt +2 -2
- data/lib/cucumber/rake/task.rb +29 -6
- data/lib/cucumber/step_mother.rb +50 -15
- data/lib/cucumber/version.rb +3 -3
- data/spec/cucumber/cli/main_spec.rb +5 -1
- data/spec/cucumber/step_mother_spec.rb +11 -0
- metadata +5 -2
data/History.txt
CHANGED
@@ -13,7 +13,17 @@ The Visitor API (which is used for formatters) has also changed slightly. Howeve
|
|
13
13
|
do this in a backwards compatible way, so if you have custom formatters for Cucumber 0.2 they should
|
14
14
|
still work.
|
15
15
|
|
16
|
+
One of the most significant new features is Tagged Hooks: http://wiki.github.com/aslakhellesoy/cucumber/hooks
|
17
|
+
This lets you associate Before and After blocks with specific scenarios.
|
18
|
+
|
19
|
+
We are also deprecating the step_list, step_pattern, feature_list, and feature_pattern accessors on
|
20
|
+
Cucumber::Rake::Task. These accessors will be completely removed in version 0.4. For complex settings
|
21
|
+
please rely on cucumber profiles in your rake tasks:
|
22
|
+
http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles
|
23
|
+
|
16
24
|
=== New features
|
25
|
+
* Use Hooks with @tags (#229 Aslak Hellesøy)
|
26
|
+
* Rake task supports cucumber.yml profiles (#187 Ben Mabey)
|
17
27
|
* Field value steps for Webrat (Jack Chen)
|
18
28
|
* Added translation for Bulgarian (Krasimir Angelov)
|
19
29
|
* Updated translation for Polish (#273 Grzegorz Marszałek)
|
@@ -26,6 +36,7 @@ still work.
|
|
26
36
|
* Support description string for Backgrounds (#271 Joseph Wilk)
|
27
37
|
|
28
38
|
=== Bugfixes
|
39
|
+
* After methods not being executed when Background fails (#288 Luismi Cavallé)
|
29
40
|
* Fixed dependency on internal files in rspec breaks cucumber w/ rspec-1.2.4 (#291 Aslak Hellesøy)
|
30
41
|
* Fix color use when using autotest on Linux. (Hans de Graaff)
|
31
42
|
* Fixed incorrect calculation of pystring indentation (#279 Eugene Naydanov)
|
data/Manifest.txt
CHANGED
@@ -182,6 +182,8 @@ examples/tickets/features/177/1.feature
|
|
182
182
|
examples/tickets/features/177/2.feature
|
183
183
|
examples/tickets/features/177/3.feature
|
184
184
|
examples/tickets/features/180.feature
|
185
|
+
examples/tickets/features/229/tagged_hooks.feature
|
186
|
+
examples/tickets/features/229/tagged_hooks.rb
|
185
187
|
examples/tickets/features/236.feature
|
186
188
|
examples/tickets/features/241.feature
|
187
189
|
examples/tickets/features/246.feature
|
@@ -209,6 +211,7 @@ features/cucumber_cli.feature
|
|
209
211
|
features/cucumber_cli_diff_disabled.feature
|
210
212
|
features/cucumber_cli_outlines.feature
|
211
213
|
features/custom_formatter.feature
|
214
|
+
features/rake_task.feature
|
212
215
|
features/report_called_undefined_steps.feature
|
213
216
|
features/snippet.feature
|
214
217
|
features/step_definitions/cucumber_steps.rb
|
data/config/hoe.rb
CHANGED
@@ -53,7 +53,7 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
53
53
|
p.summary = DESCRIPTION
|
54
54
|
p.url = HOMEPATH
|
55
55
|
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
56
|
-
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store', '**/*.class', '**/*.jar'] #An array of file patterns to delete on clean.
|
56
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store', '**/*.class', '**/*.jar', '**/tmp'] #An array of file patterns to delete on clean.
|
57
57
|
|
58
58
|
# == Optional
|
59
59
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
data/cucumber.yml
CHANGED
@@ -1 +1 @@
|
|
1
|
-
default: --format progress features
|
1
|
+
default: --format progress features --tags ~@pending
|
@@ -68,3 +68,13 @@ end
|
|
68
68
|
|
69
69
|
Given /^another unused$/ do
|
70
70
|
end
|
71
|
+
|
72
|
+
after_file = File.dirname(__FILE__) + '/../../tmp/after.txt'
|
73
|
+
|
74
|
+
Before('@after_file') do
|
75
|
+
FileUtils.rm(after_file) if File.exist?(after_file)
|
76
|
+
end
|
77
|
+
|
78
|
+
After('@after_file') do
|
79
|
+
FileUtils.touch(after_file)
|
80
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec/expectations'
|
2
|
+
|
3
|
+
Before('@i_am_so_special') do
|
4
|
+
@something_special = 10
|
5
|
+
end
|
6
|
+
|
7
|
+
After('@i_am_so_special') do
|
8
|
+
@something_special.should == 20
|
9
|
+
end
|
10
|
+
|
11
|
+
When /special me goes to town/ do
|
12
|
+
@something_special.should == 10
|
13
|
+
@something_special = 20
|
14
|
+
end
|
data/features/background.feature
CHANGED
@@ -93,6 +93,7 @@ Feature: backgrounds
|
|
93
93
|
5 skipped steps
|
94
94
|
|
95
95
|
"""
|
96
|
+
And "examples/self_test/tmp/after.txt" should exist
|
96
97
|
|
97
98
|
Scenario: run a feature with scenario outlines that has a background that fails
|
98
99
|
When I run cucumber -q features/background/scenario_outline_failing_background.feature --require features
|
@@ -0,0 +1,132 @@
|
|
1
|
+
Feature: Rake task
|
2
|
+
In order to ease the development process
|
3
|
+
As a developer and CI server administrator
|
4
|
+
Cucumber features should be executable via Rake
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a standard Cucumber project directory structure
|
8
|
+
And a file named "features/missing_step_definitions.feature" with:
|
9
|
+
"""
|
10
|
+
Feature: Sample
|
11
|
+
|
12
|
+
Scenario: Wanted
|
13
|
+
Given I want to run this
|
14
|
+
|
15
|
+
Scenario: Unwanted
|
16
|
+
Given I don't want this ran
|
17
|
+
"""
|
18
|
+
|
19
|
+
|
20
|
+
Scenario: rake task with a defined profile
|
21
|
+
Given the following profile is defined:
|
22
|
+
"""
|
23
|
+
foo: --quiet --no-color features/missing_step_definitions.feature:3
|
24
|
+
"""
|
25
|
+
And a file named "Rakefile" with:
|
26
|
+
"""
|
27
|
+
$LOAD_PATH.unshift(CUCUMBER_LIB)
|
28
|
+
require 'cucumber/rake/task'
|
29
|
+
|
30
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
31
|
+
t.profile = "foo"
|
32
|
+
end
|
33
|
+
"""
|
34
|
+
|
35
|
+
When I run rake features
|
36
|
+
Then it should pass
|
37
|
+
And the output should contain
|
38
|
+
"""
|
39
|
+
Feature: Sample
|
40
|
+
|
41
|
+
Scenario: Wanted
|
42
|
+
Given I want to run this
|
43
|
+
|
44
|
+
1 scenario
|
45
|
+
1 undefined step
|
46
|
+
"""
|
47
|
+
|
48
|
+
Scenario: rake task with a defined profile and cucumber_opts
|
49
|
+
Given the following profile is defined:
|
50
|
+
"""
|
51
|
+
bar: features/missing_step_definitions.feature:3
|
52
|
+
"""
|
53
|
+
And a file named "Rakefile" with:
|
54
|
+
"""
|
55
|
+
$LOAD_PATH.unshift(CUCUMBER_LIB)
|
56
|
+
require 'cucumber/rake/task'
|
57
|
+
|
58
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
59
|
+
t.profile = "bar"
|
60
|
+
t.cucumber_opts = "--quiet --no-color"
|
61
|
+
end
|
62
|
+
"""
|
63
|
+
|
64
|
+
When I run rake features
|
65
|
+
Then it should pass
|
66
|
+
And the output should contain
|
67
|
+
"""
|
68
|
+
Feature: Sample
|
69
|
+
|
70
|
+
Scenario: Wanted
|
71
|
+
Given I want to run this
|
72
|
+
|
73
|
+
1 scenario
|
74
|
+
1 undefined step
|
75
|
+
"""
|
76
|
+
|
77
|
+
Scenario: rake task with a defined profile and feature list
|
78
|
+
Given a file named "features/the_one_i_want_to_run.feature" with:
|
79
|
+
"""
|
80
|
+
Feature: Desired
|
81
|
+
|
82
|
+
Scenario: Something
|
83
|
+
Given this is missing
|
84
|
+
"""
|
85
|
+
Given the following profile is defined:
|
86
|
+
"""
|
87
|
+
baz: --quiet --no-color
|
88
|
+
"""
|
89
|
+
And a file named "Rakefile" with:
|
90
|
+
"""
|
91
|
+
$LOAD_PATH.unshift(CUCUMBER_LIB)
|
92
|
+
require 'cucumber/rake/task'
|
93
|
+
|
94
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
95
|
+
t.profile = "baz"
|
96
|
+
t.feature_list = ['features/the_one_i_want_to_run.feature']
|
97
|
+
end
|
98
|
+
"""
|
99
|
+
|
100
|
+
When I run rake features
|
101
|
+
Then it should pass
|
102
|
+
And the output should contain
|
103
|
+
"""
|
104
|
+
Feature: Desired
|
105
|
+
|
106
|
+
Scenario: Something
|
107
|
+
Given this is missing
|
108
|
+
|
109
|
+
1 scenario
|
110
|
+
1 undefined step
|
111
|
+
"""
|
112
|
+
|
113
|
+
Scenario: deprecation warnings
|
114
|
+
Given a file named "Rakefile" with:
|
115
|
+
"""
|
116
|
+
$LOAD_PATH.unshift(CUCUMBER_LIB)
|
117
|
+
require 'cucumber/rake/task'
|
118
|
+
|
119
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
120
|
+
t.feature_list = ['features/missing_step_definitions.feature']
|
121
|
+
end
|
122
|
+
"""
|
123
|
+
When I run rake features
|
124
|
+
Then it should pass
|
125
|
+
And STDERR should match
|
126
|
+
"""
|
127
|
+
Cucumber::Rake::Task#feature_list is deprecated and will be removed in 0.4.0. Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles
|
128
|
+
"""
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
@@ -1,32 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Given /^I am in (.*)$/ do |dir|
|
4
|
-
@dir = dir
|
1
|
+
Given /^I am in (.*)$/ do |example_dir_relative_path|
|
2
|
+
@current_dir = examples_dir(example_dir_relative_path)
|
5
3
|
end
|
6
4
|
|
7
|
-
|
8
|
-
@
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Dir.chdir(full_dir) do
|
13
|
-
@full_cmd = "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cmd} 2> #{@stderr.path}"
|
14
|
-
@out = `#{@full_cmd}`
|
15
|
-
@status = $?.exitstatus
|
5
|
+
Given /^a standard Cucumber project directory structure$/ do
|
6
|
+
@current_dir = working_dir
|
7
|
+
in_current_dir do
|
8
|
+
FileUtils.mkdir_p 'features/support'
|
9
|
+
FileUtils.mkdir 'features/step_definitions'
|
16
10
|
end
|
17
11
|
end
|
18
12
|
|
19
|
-
|
20
|
-
|
13
|
+
Given /^a file named "([^\"]*)" with:$/ do |file_name, file_content|
|
14
|
+
create_file(file_name, file_content)
|
15
|
+
end
|
16
|
+
|
17
|
+
Given /^the following profiles? (?:are|is) defined:$/ do |profiles|
|
18
|
+
create_file('cucumber.yml', profiles)
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^I run cucumber (.*)$/ do |cucumber_opts|
|
22
|
+
run "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cucumber_opts}"
|
23
|
+
end
|
24
|
+
|
25
|
+
When /^I run rake (.*)$/ do |rake_opts|
|
26
|
+
run "rake #{rake_opts}"
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^it should (fail|pass)$/ do |success|
|
21
30
|
if success == 'fail'
|
22
|
-
|
31
|
+
last_exit_status.should_not == 0
|
23
32
|
else
|
24
|
-
|
33
|
+
last_exit_status.should == 0
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
37
|
+
Then /^it should (fail|pass) with$/ do |success, output|
|
38
|
+
last_stdout.should == output
|
39
|
+
Then("it should #{success}")
|
40
|
+
end
|
41
|
+
|
28
42
|
Then /^the output should contain$/ do |text|
|
29
|
-
|
43
|
+
last_stdout.should include(text)
|
30
44
|
end
|
31
45
|
|
32
46
|
Then /^"(.*)" should contain$/ do |file, text|
|
@@ -38,5 +52,10 @@ Then /^"(.*)" should match$/ do |file, text|
|
|
38
52
|
end
|
39
53
|
|
40
54
|
Then /^STDERR should match$/ do |text|
|
41
|
-
|
55
|
+
last_stderr.should =~ /#{text}/
|
56
|
+
end
|
57
|
+
|
58
|
+
Then /^"(.*)" should exist$/ do |file|
|
59
|
+
File.exists?(file).should be_true
|
60
|
+
FileUtils.rm(file)
|
42
61
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,8 +1,65 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'tempfile'
|
2
3
|
require 'spec/expectations'
|
3
4
|
require 'fileutils'
|
5
|
+
require 'forwardable'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
class CucumberWorld
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators CucumberWorld, :examples_dir, :self_test_dir, :working_dir, :cucumber_lib_dir
|
10
|
+
|
11
|
+
def self.examples_dir(subdir=nil)
|
12
|
+
@examples_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../examples'))
|
13
|
+
subdir ? File.join(@examples_dir, subdir) : @examples_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.self_test_dir
|
17
|
+
@self_test_dir ||= examples_dir('self_test')
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.working_dir
|
21
|
+
@working_dir ||= examples_dir('self_test/tmp')
|
22
|
+
end
|
23
|
+
|
24
|
+
def cucumber_lib_dir
|
25
|
+
@cucumber_lib_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@current_dir = self_test_dir
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
attr_reader :last_exit_status, :last_stdout, :last_stderr
|
34
|
+
|
35
|
+
def create_file(file_name, file_content)
|
36
|
+
file_content.gsub!("CUCUMBER_LIB", "'#{cucumber_lib_dir}'") # Some files, such as Rakefiles need to use the lib dir
|
37
|
+
in_current_dir do
|
38
|
+
File.open(file_name, 'w') { |f| f << file_content }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def in_current_dir(&block)
|
43
|
+
Dir.chdir(@current_dir, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def run(command)
|
47
|
+
stderr_file = Tempfile.new('cucumber')
|
48
|
+
stderr_file.close
|
49
|
+
in_current_dir do
|
50
|
+
@last_stdout = `#{command} 2> #{stderr_file.path}`
|
51
|
+
@last_exit_status = $?.exitstatus
|
52
|
+
end
|
53
|
+
@last_stderr = IO.read(stderr_file.path)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
World do
|
59
|
+
CucumberWorld.new
|
60
|
+
end
|
61
|
+
|
62
|
+
Before do
|
63
|
+
FileUtils.rm_rf CucumberWorld.working_dir
|
64
|
+
FileUtils.mkdir CucumberWorld.working_dir
|
65
|
+
end
|
data/gem_tasks/deployment.rake
CHANGED
@@ -24,9 +24,19 @@ module Cucumber
|
|
24
24
|
def accept(visitor)
|
25
25
|
visitor.visit_comment(@comment)
|
26
26
|
visitor.visit_background_name(@keyword, @name, file_colon_line(@line), source_indent(text_length))
|
27
|
-
visitor.step_mother.
|
27
|
+
visitor.step_mother.before(self)
|
28
28
|
visitor.visit_steps(@step_invocations)
|
29
29
|
@failed = @step_invocations.detect{|step_invocation| step_invocation.exception}
|
30
|
+
visitor.step_mother.after(self) if @failed
|
31
|
+
end
|
32
|
+
|
33
|
+
def accept_hook?(hook)
|
34
|
+
# TODO: When background is involved - no tag based hook filtering is occurring with
|
35
|
+
# the current implementation. All hooks will be executed. This is because of the line
|
36
|
+
# visitor.step_mother.before(self)
|
37
|
+
# in the #accept method above. Instead, we should really be passing the first scenario
|
38
|
+
# here. We currently don't have access to that, so a refactoring is in order to make that happen.
|
39
|
+
true
|
30
40
|
end
|
31
41
|
|
32
42
|
def failed?
|
@@ -15,6 +15,10 @@ module Cucumber
|
|
15
15
|
nil
|
16
16
|
end
|
17
17
|
|
18
|
+
def accept_hook?(hook)
|
19
|
+
@scenario_outline.accept_hook?(hook)
|
20
|
+
end
|
21
|
+
|
18
22
|
def skip_invoke!
|
19
23
|
example_rows.each do |cells|
|
20
24
|
cells.skip_invoke!
|
@@ -62,6 +66,10 @@ module Cucumber
|
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
69
|
+
def accept_hook?(hook)
|
70
|
+
@table.accept_hook?(hook)
|
71
|
+
end
|
72
|
+
|
65
73
|
private
|
66
74
|
|
67
75
|
def header?
|
data/lib/cucumber/ast/tags.rb
CHANGED
@@ -7,6 +7,10 @@ module Cucumber
|
|
7
7
|
# This gets stored internally as <tt>["invoice", "release_2"]</tt>
|
8
8
|
#
|
9
9
|
class Tags
|
10
|
+
def self.strip_prefix(tag_name)
|
11
|
+
tag_name =~ /^@(.*)/ ? $1 : tag_name
|
12
|
+
end
|
13
|
+
|
10
14
|
def initialize(line, tag_names)
|
11
15
|
@line, @tag_names = line, tag_names
|
12
16
|
end
|
@@ -16,7 +20,11 @@ module Cucumber
|
|
16
20
|
visitor.visit_tag_name(tag_name)
|
17
21
|
end
|
18
22
|
end
|
19
|
-
|
23
|
+
|
24
|
+
def accept_hook?(hook)
|
25
|
+
hook.matches_tag_names?(@tag_names)
|
26
|
+
end
|
27
|
+
|
20
28
|
def to_sexp
|
21
29
|
@tag_names.map{|tag_name| [:tag, tag_name]}
|
22
30
|
end
|
@@ -187,8 +187,8 @@ module Cucumber
|
|
187
187
|
excludes = excludes.map{|tag| tag[1..-1]}
|
188
188
|
|
189
189
|
# Strip @
|
190
|
-
includes = includes.map{|tag| tag
|
191
|
-
excludes = excludes.map{|tag| tag
|
190
|
+
includes = includes.map{|tag| Ast::Tags.strip_prefix(tag)}
|
191
|
+
excludes = excludes.map{|tag| Ast::Tags.strip_prefix(tag)}
|
192
192
|
[includes, excludes]
|
193
193
|
end
|
194
194
|
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -92,7 +92,11 @@ module Cucumber
|
|
92
92
|
|
93
93
|
def enable_diffing
|
94
94
|
if configuration.diff_enabled? && defined?(::Spec)
|
95
|
-
|
95
|
+
begin
|
96
|
+
require 'spec/runner/differs/default' # RSpec >=1.2.4
|
97
|
+
rescue ::LoadError
|
98
|
+
require 'spec/expectations/differs/default' # RSpec <=1.2.3
|
99
|
+
end
|
96
100
|
options = OpenStruct.new(:diff_format => :unified, :context_lines => 3)
|
97
101
|
::Spec::Expectations.differ = ::Spec::Expectations::Differs::Default.new(options)
|
98
102
|
end
|
@@ -216,7 +216,7 @@ module Cucumber
|
|
216
216
|
end
|
217
217
|
|
218
218
|
def has_tags?(tags)
|
219
|
-
tag_names
|
219
|
+
(tag_names & tags).any?
|
220
220
|
end
|
221
221
|
|
222
222
|
def build
|
@@ -224,7 +224,7 @@ module Cucumber
|
|
224
224
|
end
|
225
225
|
|
226
226
|
def tag_names
|
227
|
-
ts.elements.map{|e| e.tag.tag_name.text_value}
|
227
|
+
@tag_names ||= ts.elements.map{|e| e.tag.tag_name.text_value}
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
@@ -46,7 +46,7 @@ module Cucumber
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def has_tags?(tags)
|
49
|
-
tag_names
|
49
|
+
(tag_names & tags).any?
|
50
50
|
end
|
51
51
|
|
52
52
|
def build
|
@@ -54,7 +54,7 @@ module Cucumber
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def tag_names
|
57
|
-
ts.elements.map{|e| e.tag.tag_name.text_value}
|
57
|
+
@tag_names ||= ts.elements.map{|e| e.tag.tag_name.text_value}
|
58
58
|
end
|
59
59
|
}
|
60
60
|
end
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -27,26 +27,45 @@ module Cucumber
|
|
27
27
|
class Task
|
28
28
|
LIB = File.expand_path(File.dirname(__FILE__) + '/../..') # :nodoc:
|
29
29
|
|
30
|
+
# TODO: remove depreated accessors for 0.4.0
|
31
|
+
def self.deprecate_accessor(attribute) # :nodoc:
|
32
|
+
attr_reader attribute
|
33
|
+
class_eval <<-EOF, __FILE__, __LINE__ + 1
|
34
|
+
def #{attribute}=(value)
|
35
|
+
@#{attribute} = value
|
36
|
+
warn("Cucumber::Rake::Task##{attribute} is deprecated and will be removed in 0.4.0. Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles")
|
37
|
+
end
|
38
|
+
EOF
|
39
|
+
end
|
40
|
+
|
30
41
|
# Directories to add to the Ruby $LOAD_PATH
|
31
42
|
attr_accessor :libs
|
32
43
|
# Name of the cucumber binary to use for running features. Defaults to Cucumber::BINARY
|
33
44
|
attr_accessor :binary
|
34
45
|
# Array of paths to specific step definition files to use
|
35
|
-
|
46
|
+
deprecate_accessor :step_list
|
36
47
|
# File pattern for finding step definitions. Defaults to
|
37
48
|
# 'features/**/*.rb'.
|
38
|
-
|
49
|
+
deprecate_accessor :step_pattern
|
39
50
|
# Array of paths to specific features to run.
|
40
|
-
|
51
|
+
deprecate_accessor :feature_list
|
41
52
|
# File pattern for finding features to run. Defaults to
|
42
|
-
# 'features/**/*.feature'. Can be
|
43
|
-
|
53
|
+
# 'features/**/*.feature'. Can be overridden by the FEATURE environment variable.
|
54
|
+
deprecate_accessor :feature_pattern
|
44
55
|
# Extra options to pass to the cucumber binary. Can be overridden by the CUCUMBER_OPTS environment variable.
|
45
56
|
attr_accessor :cucumber_opts
|
46
57
|
# Run cucumber with RCov?
|
47
58
|
attr_accessor :rcov
|
48
59
|
# Extra options to pass to rcov
|
49
60
|
attr_accessor :rcov_opts
|
61
|
+
# Define what profile to be used. When used with cucumber_opts it is simply appended to it. Will be ignored when CUCUMBER_OPTS is used.
|
62
|
+
def profile=(profile)
|
63
|
+
@profile = profile
|
64
|
+
unless feature_list
|
65
|
+
@feature_list = [] # Don't use accessor to avoid deprecation warning.
|
66
|
+
end
|
67
|
+
end
|
68
|
+
attr_reader :profile
|
50
69
|
|
51
70
|
# Define a Rake
|
52
71
|
def initialize(task_name = "features", desc = "Run Features with Cucumber")
|
@@ -75,7 +94,7 @@ module Cucumber
|
|
75
94
|
def arguments_for_ruby_execution(task_args = nil) # :nodoc:
|
76
95
|
lib_args = ['"%s"' % libs.join(File::PATH_SEPARATOR)]
|
77
96
|
cucumber_bin = ['"%s"' % binary]
|
78
|
-
cuc_opts = [(ENV['CUCUMBER_OPTS'] ||
|
97
|
+
cuc_opts = [(ENV['CUCUMBER_OPTS'] || cucumber_opts_with_profile)]
|
79
98
|
|
80
99
|
step_files(task_args).each do |step_file|
|
81
100
|
cuc_opts << '--require'
|
@@ -92,6 +111,10 @@ module Cucumber
|
|
92
111
|
args
|
93
112
|
end
|
94
113
|
|
114
|
+
def cucumber_opts_with_profile # :nodoc:
|
115
|
+
@profile ? "#{cucumber_opts} --profile #{@profile}" : cucumber_opts
|
116
|
+
end
|
117
|
+
|
95
118
|
def feature_files(task_args = nil) # :nodoc:
|
96
119
|
if ENV['FEATURE']
|
97
120
|
FileList[ ENV['FEATURE'] ]
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -67,6 +67,21 @@ module Cucumber
|
|
67
67
|
# so #register_step_definition (and more interestingly - its aliases) are
|
68
68
|
# available from the top-level.
|
69
69
|
module StepMother
|
70
|
+
class Hook
|
71
|
+
def initialize(tag_names, proc)
|
72
|
+
@tag_names = tag_names.map{|tag| Ast::Tags.strip_prefix(tag)}
|
73
|
+
@proc = proc
|
74
|
+
end
|
75
|
+
|
76
|
+
def matches_tag_names?(tag_names)
|
77
|
+
@tag_names.empty? || (@tag_names & tag_names).any?
|
78
|
+
end
|
79
|
+
|
80
|
+
def execute_in(world, scenario, location)
|
81
|
+
world.cucumber_instance_exec(false, location, scenario, &@proc)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
70
85
|
class << self
|
71
86
|
def alias_adverb(adverb)
|
72
87
|
adverb = adverb.gsub(/\s/, '')
|
@@ -114,12 +129,26 @@ module Cucumber
|
|
114
129
|
|
115
130
|
# Registers a Before proc. You can call this method as many times as you
|
116
131
|
# want (typically from ruby scripts under <tt>support</tt>).
|
117
|
-
def Before(&proc)
|
118
|
-
(
|
132
|
+
def Before(*tag_names, &proc)
|
133
|
+
register_hook(:before, tag_names, proc)
|
134
|
+
end
|
135
|
+
|
136
|
+
def After(*tag_names, &proc)
|
137
|
+
register_hook(:after, tag_names, proc)
|
119
138
|
end
|
120
139
|
|
121
|
-
def
|
122
|
-
|
140
|
+
def register_hook(phase, tags, proc)
|
141
|
+
hook = Hook.new(tags, proc)
|
142
|
+
hooks[phase] << hook
|
143
|
+
hook
|
144
|
+
end
|
145
|
+
|
146
|
+
def hooks
|
147
|
+
@hooks ||= Hash.new {|hash, phase| hash[phase] = []}
|
148
|
+
end
|
149
|
+
|
150
|
+
def hooks_for(phase, scenario)
|
151
|
+
hooks[phase].select{|hook| scenario.accept_hook?(hook)}
|
123
152
|
end
|
124
153
|
|
125
154
|
# Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
|
@@ -197,16 +226,22 @@ module Cucumber
|
|
197
226
|
end
|
198
227
|
|
199
228
|
def before_and_after(scenario, skip=false)
|
200
|
-
unless
|
229
|
+
before(scenario) unless skip
|
230
|
+
yield
|
231
|
+
after(scenario) unless skip
|
232
|
+
scenario_visited(scenario)
|
233
|
+
end
|
234
|
+
|
235
|
+
def before(scenario)
|
236
|
+
unless current_world
|
201
237
|
new_world!
|
202
238
|
execute_before(scenario)
|
203
239
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def after(scenario)
|
243
|
+
execute_after(scenario)
|
244
|
+
nil_world!
|
210
245
|
end
|
211
246
|
|
212
247
|
private
|
@@ -268,14 +303,14 @@ module Cucumber
|
|
268
303
|
end
|
269
304
|
|
270
305
|
def execute_before(scenario)
|
271
|
-
(
|
272
|
-
@current_world
|
306
|
+
hooks_for(:before, scenario).each do |hook|
|
307
|
+
hook.execute_in(@current_world, scenario, 'Before')
|
273
308
|
end
|
274
309
|
end
|
275
310
|
|
276
311
|
def execute_after(scenario)
|
277
|
-
(
|
278
|
-
@current_world
|
312
|
+
hooks_for(:after, scenario).each do |hook|
|
313
|
+
hook.execute_in(@current_world, scenario, 'After')
|
279
314
|
end
|
280
315
|
end
|
281
316
|
|
data/lib/cucumber/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Cucumber #:nodoc:
|
2
2
|
class VERSION #:nodoc:
|
3
3
|
MAJOR = 0
|
4
|
-
MINOR =
|
5
|
-
TINY =
|
6
|
-
PATCH =
|
4
|
+
MINOR = 3
|
5
|
+
TINY = 0
|
6
|
+
PATCH = nil # Set to nil for official release
|
7
7
|
|
8
8
|
STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
|
9
9
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
require 'yaml'
|
3
|
-
|
3
|
+
begin
|
4
|
+
require 'spec/runner/differs/default' # RSpec >=1.2.4
|
5
|
+
rescue ::LoadError
|
6
|
+
require 'spec/expectations/differs/default' # RSpec <=1.2.3
|
7
|
+
end
|
4
8
|
|
5
9
|
module Cucumber
|
6
10
|
module Cli
|
@@ -133,5 +133,16 @@ Use Ruby modules instead to extend your worlds. See the #World RDoc.
|
|
133
133
|
|
134
134
|
})
|
135
135
|
end
|
136
|
+
|
137
|
+
it "should find before hooks" do
|
138
|
+
fish = @step_mother.Before('@fish'){}
|
139
|
+
meat = @step_mother.Before('@meat'){}
|
140
|
+
|
141
|
+
scenario = mock('Scenario')
|
142
|
+
scenario.should_receive(:accept_hook?).with(fish).and_return(true)
|
143
|
+
scenario.should_receive(:accept_hook?).with(meat).and_return(false)
|
144
|
+
|
145
|
+
@step_mother.hooks_for(:before, scenario).should == [fish]
|
146
|
+
end
|
136
147
|
end
|
137
148
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aslakhellesoy-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Aslak Helles\xC3\xB8y"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-14 00:00:00 -07:00
|
13
13
|
default_executable: cucumber
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -269,6 +269,8 @@ files:
|
|
269
269
|
- examples/tickets/features/177/2.feature
|
270
270
|
- examples/tickets/features/177/3.feature
|
271
271
|
- examples/tickets/features/180.feature
|
272
|
+
- examples/tickets/features/229/tagged_hooks.feature
|
273
|
+
- examples/tickets/features/229/tagged_hooks.rb
|
272
274
|
- examples/tickets/features/236.feature
|
273
275
|
- examples/tickets/features/241.feature
|
274
276
|
- examples/tickets/features/246.feature
|
@@ -296,6 +298,7 @@ files:
|
|
296
298
|
- features/cucumber_cli_diff_disabled.feature
|
297
299
|
- features/cucumber_cli_outlines.feature
|
298
300
|
- features/custom_formatter.feature
|
301
|
+
- features/rake_task.feature
|
299
302
|
- features/report_called_undefined_steps.feature
|
300
303
|
- features/snippet.feature
|
301
304
|
- features/step_definitions/cucumber_steps.rb
|