aslakhellesoy-cucumber 0.2.3.4 → 0.3.0
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 +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
|