aslakhellesoy-cucumber 0.3.9.4 → 0.3.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -5
- data/Manifest.txt +4 -0
- data/cucumber.yml +1 -1
- data/features/drb_server_integration.feature +86 -0
- data/features/html_formatter/a.html +208 -169
- data/features/step_definitions/cucumber_steps.rb +9 -0
- data/features/support/env.rb +35 -1
- data/lib/cucumber/cli/configuration.rb +32 -8
- data/lib/cucumber/cli/drb_client.rb +21 -0
- data/lib/cucumber/cli/main.rb +10 -1
- data/lib/cucumber/formatter/html.rb +14 -3
- data/lib/cucumber/rake/task.rb +1 -1
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/cucumber_generator.rb +12 -2
- data/rails_generators/cucumber/templates/cucumber.rake +1 -1
- data/rails_generators/cucumber/templates/env.rb +10 -3
- data/rails_generators/cucumber/templates/spork_env.rb +36 -0
- data/spec/cucumber/cli/configuration_spec.rb +56 -1
- data/spec/cucumber/cli/drb_client_spec.rb +42 -0
- data/spec/cucumber/cli/main_spec.rb +64 -19
- metadata +6 -2
@@ -31,6 +31,15 @@ Given /^the following profiles? (?:are|is) defined:$/ do |profiles|
|
|
31
31
|
create_file('cucumber.yml', profiles)
|
32
32
|
end
|
33
33
|
|
34
|
+
Given /^I am running "([^\"]*)" in the background$/ do |command|
|
35
|
+
run_in_background command
|
36
|
+
end
|
37
|
+
|
38
|
+
Given /^I am not running (?:.*) in the background$/ do
|
39
|
+
# no-op
|
40
|
+
end
|
41
|
+
|
42
|
+
|
34
43
|
When /^I run cucumber (.*)$/ do |cucumber_opts|
|
35
44
|
run "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cucumber_opts}"
|
36
45
|
end
|
data/features/support/env.rb
CHANGED
@@ -3,6 +3,11 @@ require 'tempfile'
|
|
3
3
|
require 'spec/expectations'
|
4
4
|
require 'fileutils'
|
5
5
|
require 'forwardable'
|
6
|
+
begin
|
7
|
+
require 'spork'
|
8
|
+
rescue Gem::LoadError => ex
|
9
|
+
warn "WARNING: #{ex.message} You need to have the spork gem installed to run the DRb feature properly!"
|
10
|
+
end
|
6
11
|
|
7
12
|
class CucumberWorld
|
8
13
|
extend Forwardable
|
@@ -52,6 +57,10 @@ class CucumberWorld
|
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
60
|
+
def background_jobs
|
61
|
+
@background_jobs ||= []
|
62
|
+
end
|
63
|
+
|
55
64
|
def in_current_dir(&block)
|
56
65
|
Dir.chdir(@current_dir, &block)
|
57
66
|
end
|
@@ -66,6 +75,27 @@ class CucumberWorld
|
|
66
75
|
@last_stderr = IO.read(stderr_file.path)
|
67
76
|
end
|
68
77
|
|
78
|
+
def run_in_background(command)
|
79
|
+
pid = fork
|
80
|
+
in_current_dir do
|
81
|
+
if pid
|
82
|
+
background_jobs << pid
|
83
|
+
else
|
84
|
+
#STDOUT.close
|
85
|
+
#STDERR.close
|
86
|
+
exec command
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def terminate_background_jobs
|
92
|
+
if @background_jobs
|
93
|
+
@background_jobs.each do |pid|
|
94
|
+
Process.kill(Signal.list['TERM'], pid)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
69
99
|
end
|
70
100
|
|
71
101
|
World do
|
@@ -77,7 +107,11 @@ Before do
|
|
77
107
|
FileUtils.mkdir CucumberWorld.working_dir
|
78
108
|
end
|
79
109
|
|
110
|
+
After do
|
111
|
+
terminate_background_jobs
|
112
|
+
end
|
113
|
+
|
80
114
|
Before('@diffxml') do
|
81
115
|
`diffxml --version`
|
82
116
|
raise "Please install diffxml from http://diffxml.sourceforge.net/" if $? != 0
|
83
|
-
end
|
117
|
+
end
|
@@ -13,6 +13,9 @@ module Cucumber
|
|
13
13
|
'junit' => 'Cucumber::Formatter::Junit'
|
14
14
|
}
|
15
15
|
DEFAULT_FORMAT = 'pretty'
|
16
|
+
DRB_FLAG = '--drb'
|
17
|
+
PROFILE_SHORT_FLAG = '-p'
|
18
|
+
PROFILE_LONG_FLAG = '--profile'
|
16
19
|
|
17
20
|
attr_reader :paths
|
18
21
|
attr_reader :options
|
@@ -28,8 +31,10 @@ module Cucumber
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def parse!(args)
|
31
|
-
@args = args
|
32
|
-
|
34
|
+
@args = args.empty? ? args_from_profile('default') : args
|
35
|
+
expand_profiles_into_args
|
36
|
+
return if parse_drb
|
37
|
+
|
33
38
|
@args.extend(::OptionParser::Arguable)
|
34
39
|
|
35
40
|
@args.options do |opts|
|
@@ -100,8 +105,8 @@ module Cucumber
|
|
100
105
|
opts.on("-e", "--exclude PATTERN", "Don't run feature files or require ruby files matching PATTERN") do |v|
|
101
106
|
@options[:excludes] << Regexp.new(v)
|
102
107
|
end
|
103
|
-
opts.on(
|
104
|
-
|
108
|
+
opts.on(PROFILE_SHORT_FLAG, "#{PROFILE_LONG_FLAG} PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
|
109
|
+
# Processing of this is done previsouly so that the DRb flag can be detected within profiles.
|
105
110
|
end
|
106
111
|
opts.on("-c", "--[no-]color",
|
107
112
|
"Whether or not to use ANSI color in the output. Cucumber decides",
|
@@ -158,6 +163,9 @@ module Cucumber
|
|
158
163
|
opts.on("--no-diff", "Disable diff output on failing expectations.") do
|
159
164
|
@options[:diff_enabled] = false
|
160
165
|
end
|
166
|
+
opts.on(DRB_FLAG, "Run features against a DRb server. (i.e. with the spork gem)") do
|
167
|
+
# Processing of this is done previsouly in order to short circuit args from being lost.
|
168
|
+
end
|
161
169
|
opts.on_tail("--version", "Show version.") do
|
162
170
|
@out_stream.puts VERSION::STRING
|
163
171
|
Kernel.exit
|
@@ -176,7 +184,7 @@ module Cucumber
|
|
176
184
|
raise("You can't use both --strict and --wip") if @options[:strict] && @options[:wip]
|
177
185
|
|
178
186
|
# Whatever is left after option parsing is the FILE arguments
|
179
|
-
@paths += args
|
187
|
+
@paths += @args
|
180
188
|
end
|
181
189
|
|
182
190
|
def verbose?
|
@@ -199,6 +207,10 @@ module Cucumber
|
|
199
207
|
@options[:diff_enabled]
|
200
208
|
end
|
201
209
|
|
210
|
+
def drb?
|
211
|
+
@drb
|
212
|
+
end
|
213
|
+
|
202
214
|
def load_language
|
203
215
|
if Cucumber.language_incomplete?(@options[:lang])
|
204
216
|
list_keywords_and_exit(@options[:lang])
|
@@ -313,7 +325,15 @@ module Cucumber
|
|
313
325
|
downcase
|
314
326
|
end
|
315
327
|
|
316
|
-
def
|
328
|
+
def expand_profiles_into_args
|
329
|
+
while (profile_index = @args.index(PROFILE_SHORT_FLAG) || @args.index(PROFILE_LONG_FLAG)) do
|
330
|
+
@args.delete_at(profile_index)
|
331
|
+
@args[profile_index] = args_from_profile(@args[profile_index])
|
332
|
+
@args.flatten!
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def args_from_profile(profile)
|
317
337
|
unless cucumber_yml.has_key?(profile)
|
318
338
|
raise(<<-END_OF_ERROR)
|
319
339
|
Could not find profile: '#{profile}'
|
@@ -334,7 +354,7 @@ Defined profiles in cucumber.yml:
|
|
334
354
|
else
|
335
355
|
raise "The '#{profile}' profile in cucumber.yml was a #{args_from_yml.class}. It must be a String or Array"
|
336
356
|
end
|
337
|
-
|
357
|
+
args_from_yml
|
338
358
|
end
|
339
359
|
|
340
360
|
def cucumber_yml
|
@@ -346,7 +366,7 @@ Defined profiles in cucumber.yml:
|
|
346
366
|
require 'yaml'
|
347
367
|
begin
|
348
368
|
@cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
349
|
-
rescue
|
369
|
+
rescue StandardError => e
|
350
370
|
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
|
351
371
|
end
|
352
372
|
|
@@ -370,6 +390,10 @@ Defined profiles in cucumber.yml:
|
|
370
390
|
Kernel.exit
|
371
391
|
end
|
372
392
|
|
393
|
+
def parse_drb
|
394
|
+
@drb = @args.delete(DRB_FLAG) ? true : false
|
395
|
+
end
|
396
|
+
|
373
397
|
def default_options
|
374
398
|
{
|
375
399
|
:strict => false,
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "drb/drb"
|
2
|
+
# This code was taken from the RSpec project and slightly modified.
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Cli
|
6
|
+
# Runs features on a DRB server, originally created with Spork compatibility in mind.
|
7
|
+
class DRbClient
|
8
|
+
def self.run(args, error_stream, out_stream)
|
9
|
+
begin
|
10
|
+
# See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0
|
11
|
+
DRb.start_service("druby://localhost:0")
|
12
|
+
feature_server = DRbObject.new_with_uri("druby://127.0.0.1:8990")
|
13
|
+
feature_server.run(args, error_stream, out_stream)
|
14
|
+
true
|
15
|
+
rescue DRb::DRbConnError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -5,6 +5,7 @@ require 'cucumber/parser'
|
|
5
5
|
require 'cucumber/formatter/color_io'
|
6
6
|
require 'cucumber/cli/language_help_formatter'
|
7
7
|
require 'cucumber/cli/configuration'
|
8
|
+
require 'cucumber/cli/drb_client'
|
8
9
|
|
9
10
|
module Cucumber
|
10
11
|
module Cli
|
@@ -27,11 +28,19 @@ module Cucumber
|
|
27
28
|
|
28
29
|
def initialize(args, out_stream = STDOUT, error_stream = STDERR)
|
29
30
|
@args = args
|
30
|
-
@out_stream = out_stream
|
31
|
+
@out_stream = out_stream #== STDOUT ? Formatter::ColorIO.new : out_stream
|
31
32
|
@error_stream = error_stream
|
32
33
|
end
|
33
34
|
|
34
35
|
def execute!(step_mother)
|
36
|
+
if configuration.drb?
|
37
|
+
if DRbClient.run(@args, @error_stream, @out_stream)
|
38
|
+
return false
|
39
|
+
else
|
40
|
+
@out_stream.puts "No DRb server is running. Running features locally:"
|
41
|
+
configuration.parse!(@args)
|
42
|
+
end
|
43
|
+
end
|
35
44
|
configuration.load_language
|
36
45
|
step_mother.options = configuration.options
|
37
46
|
|
@@ -16,7 +16,11 @@ module Cucumber
|
|
16
16
|
def initialize(step_mother, io, options)
|
17
17
|
super(step_mother)
|
18
18
|
@options = options
|
19
|
-
@builder =
|
19
|
+
@builder = create_builder(io)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_builder(io)
|
23
|
+
Builder::XmlMarkup.new(:target => io, :indent => 2)
|
20
24
|
end
|
21
25
|
|
22
26
|
def visit_features(features)
|
@@ -89,6 +93,7 @@ module Cucumber
|
|
89
93
|
@listing_background = true
|
90
94
|
@builder.h3 do |h3|
|
91
95
|
@builder.span(keyword, :class => 'keyword')
|
96
|
+
@builder.text!(' ')
|
92
97
|
@builder.span(name, :class => 'val')
|
93
98
|
end
|
94
99
|
end
|
@@ -108,6 +113,7 @@ module Cucumber
|
|
108
113
|
@listing_background = false
|
109
114
|
@builder.h3 do
|
110
115
|
@builder.span(keyword, :class => 'keyword')
|
116
|
+
@builder.text!(' ')
|
111
117
|
@builder.span(name, :class => 'val')
|
112
118
|
end
|
113
119
|
end
|
@@ -127,7 +133,11 @@ module Cucumber
|
|
127
133
|
end
|
128
134
|
|
129
135
|
def visit_examples_name(keyword, name)
|
130
|
-
@builder.h4
|
136
|
+
@builder.h4 do
|
137
|
+
@builder.span(keyword, :class => 'keyword')
|
138
|
+
@builder.text!(' ')
|
139
|
+
@builder.span(name, :class => 'val')
|
140
|
+
end
|
131
141
|
end
|
132
142
|
|
133
143
|
def visit_steps(steps)
|
@@ -181,7 +191,7 @@ module Cucumber
|
|
181
191
|
|
182
192
|
def visit_py_string(string)
|
183
193
|
@builder.pre(:class => 'val') do |pre|
|
184
|
-
|
194
|
+
@builder.text!(string)
|
185
195
|
end
|
186
196
|
end
|
187
197
|
|
@@ -221,6 +231,7 @@ module Cucumber
|
|
221
231
|
step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
|
222
232
|
@builder.div do |div|
|
223
233
|
@builder.span(keyword, :class => 'keyword')
|
234
|
+
@builder.text!(' ')
|
224
235
|
@builder.span(:class => 'step val') do |name|
|
225
236
|
name << h(step_name).gsub(/<span class="(.*?)">/, '<span class="\1">').gsub(/<\/span>/, '</span>')
|
226
237
|
end
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -90,7 +90,7 @@ module Cucumber
|
|
90
90
|
class_eval <<-EOF, __FILE__, __LINE__ + 1
|
91
91
|
def #{attribute}=(value)
|
92
92
|
@#{attribute} = value
|
93
|
-
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")
|
93
|
+
warn("\nWARNING: 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\n")
|
94
94
|
end
|
95
95
|
EOF
|
96
96
|
end
|
data/lib/cucumber/version.rb
CHANGED
@@ -19,11 +19,17 @@ class CucumberGenerator < Rails::Generator::Base
|
|
19
19
|
m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *TEST"
|
20
20
|
|
21
21
|
m.directory 'features/support'
|
22
|
-
|
22
|
+
|
23
|
+
if options[:spork]
|
24
|
+
m.template 'spork_env.rb', 'features/support/env.rb'
|
25
|
+
else
|
26
|
+
m.template 'env.rb', 'features/support/env.rb'
|
27
|
+
end
|
28
|
+
|
23
29
|
m.file 'paths.rb', 'features/support/paths.rb'
|
24
30
|
|
25
31
|
m.directory 'lib/tasks'
|
26
|
-
m.
|
32
|
+
m.template 'cucumber.rake', 'lib/tasks/cucumber.rake'
|
27
33
|
|
28
34
|
m.file 'cucumber', 'script/cucumber', {
|
29
35
|
:chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
|
@@ -51,6 +57,10 @@ protected
|
|
51
57
|
opt.on('--testunit', 'Setup cucumber for use with test/unit') do |value|
|
52
58
|
options[:framework] = :testunit
|
53
59
|
end
|
60
|
+
|
61
|
+
opt.on('--spork', 'Setup cucumber for use with Spork') do |value|
|
62
|
+
options[:spork] = true
|
63
|
+
end
|
54
64
|
end
|
55
65
|
|
56
66
|
end
|
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
|
6
6
|
Cucumber::Rake::Task.new(:features) do |t|
|
7
7
|
t.fork = true
|
8
|
-
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
|
8
|
+
t.cucumber_opts = [<%= options[:spork] ? "'--drb', " : "" %>'--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
|
9
9
|
end
|
10
10
|
task :features => 'db:test:prepare'
|
11
11
|
rescue LoadError
|
@@ -2,10 +2,17 @@
|
|
2
2
|
ENV["RAILS_ENV"] ||= "cucumber"
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
4
4
|
require 'cucumber/rails/world'
|
5
|
-
|
5
|
+
|
6
|
+
# Comment out the next line if you don't want Cucumber Unicode support
|
7
|
+
require 'cucumber/formatter/unicode'
|
8
|
+
|
9
|
+
# Comment out the next line if you don't want transactions to
|
10
|
+
# open/roll back around each scenario
|
6
11
|
Cucumber::Rails.use_transactional_fixtures
|
7
|
-
|
8
|
-
|
12
|
+
|
13
|
+
# Comment out the next line if you want Rails' own error handling
|
14
|
+
# (e.g. rescue_action_in_public / rescue_responses / rescue_from)
|
15
|
+
Cucumber::Rails.bypass_rescue
|
9
16
|
|
10
17
|
require 'webrat'
|
11
18
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spork'
|
3
|
+
|
4
|
+
Spork.prefork do
|
5
|
+
# Sets up the Rails environment for Cucumber
|
6
|
+
ENV["RAILS_ENV"] ||= "cucumber"
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
8
|
+
|
9
|
+
require 'webrat'
|
10
|
+
|
11
|
+
Webrat.configure do |config|
|
12
|
+
config.mode = :rails
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'webrat/core/matchers'
|
16
|
+
require 'cucumber'
|
17
|
+
|
18
|
+
# Comment out the next line if you don't want Cucumber Unicode support
|
19
|
+
require 'cucumber/formatter/unicode'
|
20
|
+
|
21
|
+
require 'spec/rails'
|
22
|
+
require 'cucumber/rails/rspec'
|
23
|
+
end
|
24
|
+
|
25
|
+
Spork.each_run do
|
26
|
+
# This code will be run each time you run your specs.
|
27
|
+
require 'cucumber/rails/world'
|
28
|
+
|
29
|
+
# Comment out the next line if you don't want transactions to
|
30
|
+
# open/roll back around each scenario
|
31
|
+
Cucumber::Rails.use_transactional_fixtures
|
32
|
+
|
33
|
+
# Comment out the next line if you want Rails' own error handling
|
34
|
+
# (e.g. rescue_action_in_public / rescue_responses / rescue_from)
|
35
|
+
Cucumber::Rails.bypass_rescue
|
36
|
+
end
|
@@ -83,6 +83,61 @@ module Cli
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
describe '#drb?' do
|
87
|
+
it "indicates whether the --drb flag was passed in or not" do
|
88
|
+
config = Configuration.new(StringIO.new)
|
89
|
+
|
90
|
+
config.parse!(%w{features})
|
91
|
+
config.drb?.should == false
|
92
|
+
|
93
|
+
|
94
|
+
config.parse!(%w{features --drb})
|
95
|
+
config.drb?.should == true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context '--drb' do
|
100
|
+
it "removes the --drb flag from the args" do
|
101
|
+
config = Configuration.new(StringIO.new)
|
102
|
+
|
103
|
+
args = %w{features --drb}
|
104
|
+
config.parse!(args)
|
105
|
+
args.should == %w{features}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "keeps all other flags intact" do
|
109
|
+
config = Configuration.new(StringIO.new)
|
110
|
+
|
111
|
+
args = %w{features --drb --format profile}
|
112
|
+
config.parse!(args)
|
113
|
+
args.should == %w{features --format profile}
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
context '--drb in a profile' do
|
119
|
+
it "removes the --drb flag from the args" do
|
120
|
+
given_cucumber_yml_defined_as({'server' => '--drb features'})
|
121
|
+
config = Configuration.new(StringIO.new)
|
122
|
+
|
123
|
+
args = %w{--profile server}
|
124
|
+
config.parse!(args)
|
125
|
+
args.should == %w{features}
|
126
|
+
end
|
127
|
+
|
128
|
+
it "keeps all other flags intact from all profiles involved" do
|
129
|
+
given_cucumber_yml_defined_as({'server' => '--drb features --profile nested',
|
130
|
+
'nested' => '--verbose'})
|
131
|
+
|
132
|
+
config = Configuration.new(StringIO.new)
|
133
|
+
|
134
|
+
args = %w{--profile server --format profile}
|
135
|
+
config.parse!(args)
|
136
|
+
args.should == %w{features --verbose --format profile}
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
86
141
|
it "should expand args from YAML file" do
|
87
142
|
given_cucumber_yml_defined_as({'bongo' => '--require from/yml'})
|
88
143
|
|
@@ -156,7 +211,7 @@ END_OF_MESSAGE
|
|
156
211
|
expected_error_message = /cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage./
|
157
212
|
|
158
213
|
given_cucumber_yml_defined_as("input that causes an exception in YAML loading")
|
159
|
-
YAML.should_receive(:load).and_raise
|
214
|
+
YAML.should_receive(:load).and_raise ArgumentError
|
160
215
|
|
161
216
|
config = Configuration.new(StringIO.new, error = StringIO.new)
|
162
217
|
lambda{config.parse!([])}.should raise_error(expected_error_message)
|