cucumber 0.3.94 → 0.3.95
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +26 -1
- data/Manifest.txt +2 -0
- data/examples/cs/features/step_definitons/calculator_steps.rb +1 -1
- data/features/drb_server_integration.feature +5 -0
- data/features/support/env.rb +3 -4
- data/features/work_in_progress.feature +6 -0
- data/lib/cucumber/cli/configuration.rb +28 -28
- data/lib/cucumber/cli/main.rb +38 -15
- data/lib/cucumber/cli/options.rb +13 -12
- data/lib/cucumber/cli/profile_loader.rb +0 -2
- data/lib/cucumber/cli/rb_step_def_loader.rb +14 -0
- data/lib/cucumber/formatter/ansicolor.rb +0 -1
- data/lib/cucumber/formatter/console.rb +3 -1
- data/lib/cucumber/step_mother.rb +5 -1
- data/lib/cucumber/version.rb +1 -1
- data/lib/cucumber/webrat/element_locator.rb +87 -0
- data/lib/cucumber/webrat/table_locator.rb +1 -66
- data/lib/cucumber/world.rb +16 -0
- data/rails_generators/cucumber/templates/cucumber.rake +3 -1
- data/rails_generators/cucumber/templates/env.rb +1 -1
- data/rails_generators/cucumber/templates/spork_env.rb +1 -1
- data/rails_generators/cucumber/templates/webrat_steps.rb +4 -0
- data/spec/cucumber/cli/configuration_spec.rb +20 -80
- data/spec/cucumber/cli/main_spec.rb +1 -9
- data/spec/cucumber/cli/options_spec.rb +18 -4
- data/spec/cucumber/step_mother_spec.rb +11 -3
- metadata +4 -2
data/History.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== 0.3.95 2009-08-13
|
2
|
+
|
3
|
+
This release improves Webrat support for table-like HTML markup. Now you can easily turn the HTML
|
4
|
+
elements table, dl, ol and ul elements into a 2D array. This is particularly useful for comparing
|
5
|
+
data in your HTML with a Cucumber table using Cucumber::Ast::Table#diff!
|
6
|
+
|
7
|
+
This release also fixes several bugs related to --drb (Spork) and profiles (cucumber.yml)
|
8
|
+
|
9
|
+
=== Bug Fixes
|
10
|
+
* --guess will always prefer the longest regexp with no groups if they exist.
|
11
|
+
* Prevent delays if a NoMethodError is raise in a step definition. Define a light #inspect in World. (#374 Aslak Hellesøy)
|
12
|
+
* Restore 'features' as the default feature running path. (#412 Ben Mabey)
|
13
|
+
* --drb degrades gracefully when no drb server is running and no formatter is provided. (#410 Ben Mabey)
|
14
|
+
* --language picked up from profiles again. (#409 Ben Mabey)
|
15
|
+
* Resolved infinite loop problem when --drb was defined in a profile. (#408 Ben Mabey)
|
16
|
+
|
17
|
+
=== New Features
|
18
|
+
* The object returned by element_at (Webrat::Element) has a #to_table that works for table, dl, ol and ul. (Aslak Hellesøy)
|
19
|
+
* An explanation of why failures are ok is printed when --wip is used. (Aslak Hellesøy)
|
20
|
+
* Added cucumber alias for cucumber:ok in Rails Rake tasks. (Aslak Hellesøy)
|
21
|
+
|
22
|
+
=== Changed features
|
23
|
+
* element_at('table').to_table should be used instead of table_at('table').to_a. The old way is deprecated but still works. (Aslak Hellesøy)
|
24
|
+
* element_at (and the depracated table_at) no longer takes a DOM id, only CSS selectors. Change "my_id" to "#my_id". (Aslak Hellesøy)
|
25
|
+
|
1
26
|
== 0.3.94 2009-08-06
|
2
27
|
|
3
28
|
Kanban take II.
|
@@ -40,7 +65,7 @@ Highlights in this release: Improved profile handling (cucumber.yml) and a fix f
|
|
40
65
|
|
41
66
|
=== Bugfixes
|
42
67
|
* script/cucumber correctly loads the gem's binary if the plugin isn't installed.
|
43
|
-
* Cucumber hangs waiting for Ctrl+C if an Error is raised (#374 Aslak Hellesøy)
|
68
|
+
* Cucumber hangs waiting for Ctrl+C if an Error is raised. (#374 Aslak Hellesøy)
|
44
69
|
|
45
70
|
== 0.3.92 2009-07-29
|
46
71
|
|
data/Manifest.txt
CHANGED
@@ -321,6 +321,7 @@ lib/cucumber/cli/language_help_formatter.rb
|
|
321
321
|
lib/cucumber/cli/main.rb
|
322
322
|
lib/cucumber/cli/options.rb
|
323
323
|
lib/cucumber/cli/profile_loader.rb
|
324
|
+
lib/cucumber/cli/rb_step_def_loader.rb
|
324
325
|
lib/cucumber/core_ext/exception.rb
|
325
326
|
lib/cucumber/core_ext/instance_exec.rb
|
326
327
|
lib/cucumber/core_ext/proc.rb
|
@@ -363,6 +364,7 @@ lib/cucumber/step_definition.rb
|
|
363
364
|
lib/cucumber/step_match.rb
|
364
365
|
lib/cucumber/step_mother.rb
|
365
366
|
lib/cucumber/version.rb
|
367
|
+
lib/cucumber/webrat/element_locator.rb
|
366
368
|
lib/cucumber/webrat/table_locator.rb
|
367
369
|
lib/cucumber/world.rb
|
368
370
|
rails_generators/cucumber/USAGE
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec/expectations'
|
2
|
-
$:.unshift(File.dirname(__FILE__) + '/../../
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../../') # This line is not needed in your own project
|
3
3
|
require 'Calculator' # Calculator.dll
|
4
4
|
|
5
5
|
Before do
|
@@ -93,6 +93,11 @@ Feature: DRb Server Integration
|
|
93
93
|
I'm loading all the heavy stuff...
|
94
94
|
I'm loading the stuff just for this run...
|
95
95
|
"""
|
96
|
+
And the output should contain
|
97
|
+
"""
|
98
|
+
1 step (1 passed)
|
99
|
+
"""
|
100
|
+
|
96
101
|
|
97
102
|
Scenario: Feature Run with --drb flag *defined in a profile* with no DRb server running
|
98
103
|
|
data/features/support/env.rb
CHANGED
@@ -4,9 +4,9 @@ require 'spec/expectations'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'forwardable'
|
6
6
|
begin
|
7
|
-
|
7
|
+
require 'spork'
|
8
8
|
rescue Gem::LoadError => ex
|
9
|
-
|
9
|
+
gem 'spork', '>= 0.5.7' # Ensure correct spork version number to avoid false-negatives.
|
10
10
|
end
|
11
11
|
|
12
12
|
class CucumberWorld
|
@@ -92,8 +92,7 @@ class CucumberWorld
|
|
92
92
|
else
|
93
93
|
# STDOUT.close
|
94
94
|
# STDERR.close
|
95
|
-
|
96
|
-
cmd = "#{Cucumber::RUBY_BINARY} -I #{Cucumber::LIBDIR} #{spork} cuc"
|
95
|
+
cmd = "#{Cucumber::RUBY_BINARY} -I #{Cucumber::LIBDIR} #{Spork::BINARY} cuc"
|
97
96
|
exec cmd
|
98
97
|
end
|
99
98
|
end
|
@@ -70,6 +70,8 @@ Feature: Cucumber --work-in-progress switch
|
|
70
70
|
1 scenario (1 failed)
|
71
71
|
1 step (1 failed)
|
72
72
|
|
73
|
+
The --wip switch was used, so the failures were expected. All is good.
|
74
|
+
|
73
75
|
"""
|
74
76
|
|
75
77
|
Scenario: Pass with Undefined Scenarios
|
@@ -85,6 +87,8 @@ Feature: Cucumber --work-in-progress switch
|
|
85
87
|
1 scenario (1 undefined)
|
86
88
|
1 step (1 undefined)
|
87
89
|
|
90
|
+
The --wip switch was used, so the failures were expected. All is good.
|
91
|
+
|
88
92
|
"""
|
89
93
|
|
90
94
|
@mri186
|
@@ -104,6 +108,8 @@ Feature: Cucumber --work-in-progress switch
|
|
104
108
|
1 scenario (1 pending)
|
105
109
|
1 step (1 pending)
|
106
110
|
|
111
|
+
The --wip switch was used, so the failures were expected. All is good.
|
112
|
+
|
107
113
|
"""
|
108
114
|
|
109
115
|
Scenario: Fail with Passing Scenarios
|
@@ -18,12 +18,12 @@ module Cucumber
|
|
18
18
|
def parse!(args)
|
19
19
|
@args = args
|
20
20
|
@options.parse!(args)
|
21
|
+
arrange_formats
|
21
22
|
raise("You can't use both --strict and --wip") if strict? && wip?
|
22
23
|
|
23
24
|
return @args.replace(@options.expanded_args_without_drb) if drb?
|
24
25
|
|
25
26
|
set_environment_variables
|
26
|
-
arrange_formats
|
27
27
|
end
|
28
28
|
|
29
29
|
def verbose?
|
@@ -50,10 +50,6 @@ module Cucumber
|
|
50
50
|
@options[:drb]
|
51
51
|
end
|
52
52
|
|
53
|
-
def paths
|
54
|
-
@options[:paths]
|
55
|
-
end
|
56
|
-
|
57
53
|
def build_formatter_broadcaster(step_mother)
|
58
54
|
return Formatter::Pretty.new(step_mother, nil, @options) if @options[:autoformat]
|
59
55
|
formatters = @options[:formats].map do |format_and_out|
|
@@ -91,23 +87,23 @@ module Cucumber
|
|
91
87
|
end
|
92
88
|
end
|
93
89
|
|
94
|
-
def
|
90
|
+
def step_defs_to_load
|
95
91
|
requires = @options[:require].empty? ? require_dirs : @options[:require]
|
96
92
|
files = requires.map do |path|
|
97
93
|
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
98
94
|
path = path.gsub(/\/$/, '') # Strip trailing slash.
|
99
|
-
File.directory?(path) ? Dir["#{path}
|
95
|
+
File.directory?(path) ? Dir["#{path}/**/*"] : path
|
100
96
|
end.flatten.uniq
|
101
|
-
sorted_files = files.sort { |a,b| (b =~ %r{/support/} || -1) <=>
|
102
|
-
env_files = sorted_files.select {|f| f =~ %r{/support/env
|
103
|
-
files = env_files + sorted_files.reject {|f| f =~ %r{/support/env
|
97
|
+
sorted_files = files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
|
98
|
+
env_files = sorted_files.select {|f| f =~ %r{/support/env\..*} }
|
99
|
+
files = env_files + sorted_files.reject {|f| f =~ %r{/support/env\..*} }
|
104
100
|
remove_excluded_files_from(files)
|
105
|
-
files.reject! {|f| f =~ %r{/support/env
|
101
|
+
files.reject! {|f| f =~ %r{/support/env\..*} } if @options[:dry_run]
|
106
102
|
files
|
107
103
|
end
|
108
104
|
|
109
105
|
def feature_files
|
110
|
-
potential_feature_files =
|
106
|
+
potential_feature_files = paths.map do |path|
|
111
107
|
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
112
108
|
path = path.chomp('/')
|
113
109
|
File.directory?(path) ? Dir["#{path}/**/*.feature"] : path
|
@@ -116,8 +112,28 @@ module Cucumber
|
|
116
112
|
potential_feature_files
|
117
113
|
end
|
118
114
|
|
115
|
+
def constantize(camel_cased_word)
|
116
|
+
begin
|
117
|
+
names = camel_cased_word.split('::')
|
118
|
+
names.shift if names.empty? || names.first.empty?
|
119
|
+
|
120
|
+
constant = Object
|
121
|
+
names.each do |name|
|
122
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
123
|
+
end
|
124
|
+
constant
|
125
|
+
rescue NameError
|
126
|
+
require underscore(camel_cased_word)
|
127
|
+
retry
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
119
131
|
private
|
120
132
|
|
133
|
+
def paths
|
134
|
+
@options[:paths].empty? ? ['features'] : @options[:paths]
|
135
|
+
end
|
136
|
+
|
121
137
|
def set_environment_variables
|
122
138
|
@options[:env_vars].each do |var, value|
|
123
139
|
ENV[var] = value
|
@@ -144,22 +160,6 @@ module Cucumber
|
|
144
160
|
feature_dirs + Dir['vendor/{gems,plugins}/*/cucumber']
|
145
161
|
end
|
146
162
|
|
147
|
-
def constantize(camel_cased_word)
|
148
|
-
begin
|
149
|
-
names = camel_cased_word.split('::')
|
150
|
-
names.shift if names.empty? || names.first.empty?
|
151
|
-
|
152
|
-
constant = Object
|
153
|
-
names.each do |name|
|
154
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
155
|
-
end
|
156
|
-
constant
|
157
|
-
rescue NameError
|
158
|
-
require underscore(camel_cased_word)
|
159
|
-
retry
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
163
|
# Snagged from active_support
|
164
164
|
def underscore(camel_cased_word)
|
165
165
|
camel_cased_word.to_s.gsub(/::/, '/').
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -51,7 +51,7 @@ module Cucumber
|
|
51
51
|
# features are loaded. If we swap the order, the requires
|
52
52
|
# will fail.
|
53
53
|
features = load_plain_text_features
|
54
|
-
|
54
|
+
load_step_defs
|
55
55
|
enable_diffing
|
56
56
|
|
57
57
|
visitor = configuration.build_formatter_broadcaster(step_mother)
|
@@ -108,33 +108,56 @@ module Cucumber
|
|
108
108
|
@configuration
|
109
109
|
end
|
110
110
|
|
111
|
-
def
|
112
|
-
|
111
|
+
def verbose_log(string)
|
112
|
+
@out_stream.puts(string) if configuration.verbose?
|
113
113
|
end
|
114
114
|
|
115
115
|
private
|
116
116
|
|
117
|
-
def
|
118
|
-
|
117
|
+
def load_step_defs
|
118
|
+
step_def_files = configuration.step_defs_to_load
|
119
|
+
verbose_log("Step Definitions Files:")
|
120
|
+
step_def_files.each do |step_def_file|
|
121
|
+
load_step_def(step_def_file)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_step_def(step_def_file)
|
126
|
+
if loader = step_def_loader_for(step_def_file)
|
127
|
+
verbose_log(" * #{step_def_file}")
|
128
|
+
loader.load_step_def_file(self, step_def_file)
|
129
|
+
end
|
119
130
|
end
|
120
131
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
132
|
+
def step_def_loader_for(step_def_file)
|
133
|
+
@sted_def_loaders ||= {}
|
134
|
+
if ext = File.extname(step_def_file)[1..-1]
|
135
|
+
loader = @sted_def_loaders[ext]
|
136
|
+
return nil if loader == :missing
|
137
|
+
return loader if loader
|
138
|
+
begin
|
139
|
+
loader_class = configuration.constantize("Cucumber::Cli::#{ext.capitalize}StepDefLoader")
|
140
|
+
return @sted_def_loaders[ext] = loader_class.new
|
141
|
+
rescue LoadError
|
142
|
+
@sted_def_loaders[ext] = :missing
|
143
|
+
nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def step_def_files
|
150
|
+
main.verbose_log("Ruby files required:")
|
151
|
+
main.verbose_log(requires.map{|lib| " * #{lib}"}.join("\n"))
|
125
152
|
requires.each do |lib|
|
126
153
|
begin
|
127
|
-
|
154
|
+
require lib
|
128
155
|
rescue LoadError => e
|
129
156
|
e.message << "\nFailed to load #{lib}"
|
130
157
|
raise e
|
131
158
|
end
|
132
159
|
end
|
133
|
-
verbose_log("\n")
|
134
|
-
end
|
135
|
-
|
136
|
-
def verbose_log(string)
|
137
|
-
@out_stream.puts(string) if configuration.verbose?
|
160
|
+
main.verbose_log("\n")
|
138
161
|
end
|
139
162
|
|
140
163
|
def enable_diffing
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -28,9 +28,10 @@ module Cucumber
|
|
28
28
|
]
|
29
29
|
DRB_FLAG = '--drb'
|
30
30
|
PROFILE_SHORT_FLAG = '-p'
|
31
|
+
NO_PROFILE_SHORT_FLAG = '-P'
|
31
32
|
PROFILE_LONG_FLAG = '--profile'
|
33
|
+
NO_PROFILE_LONG_FLAG = '--no-profile'
|
32
34
|
|
33
|
-
attr_reader :paths
|
34
35
|
|
35
36
|
def self.parse(args, out_stream, error_stream, options = {})
|
36
37
|
new(out_stream, error_stream, options).parse!(args)
|
@@ -56,7 +57,8 @@ module Cucumber
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def expanded_args_without_drb
|
59
|
-
@expanded_args_without_drb
|
60
|
+
return @expanded_args_without_drb if @expanded_args_without_drb
|
61
|
+
@expanded_args_without_drb = (
|
60
62
|
previous_flag_was_profile = false
|
61
63
|
@expanded_args.reject do |arg|
|
62
64
|
if previous_flag_was_profile
|
@@ -70,6 +72,9 @@ module Cucumber
|
|
70
72
|
arg == DRB_FLAG || @overridden_paths.include?(arg)
|
71
73
|
end
|
72
74
|
)
|
75
|
+
|
76
|
+
@expanded_args_without_drb.push("--no-profile") unless @expanded_args_without_drb.include?(NO_PROFILE_LONG_FLAG) || @expanded_args_without_drb.include?(NO_PROFILE_SHORT_FLAG)
|
77
|
+
@expanded_args_without_drb
|
73
78
|
end
|
74
79
|
|
75
80
|
def parse!(args)
|
@@ -151,7 +156,7 @@ module Cucumber
|
|
151
156
|
"then only the ones from the command line are used.") do |v|
|
152
157
|
@profiles << v
|
153
158
|
end
|
154
|
-
opts.on(
|
159
|
+
opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG,
|
155
160
|
"Disables all profile laoding to avoid using the 'default' profile.") do |v|
|
156
161
|
@disable_profile_loading = true
|
157
162
|
end
|
@@ -230,7 +235,6 @@ module Cucumber
|
|
230
235
|
@options[:source] = true if @options[:source].nil?
|
231
236
|
end
|
232
237
|
|
233
|
-
|
234
238
|
extract_environment_variables
|
235
239
|
@options[:paths] = @args.dup #whatver is left over
|
236
240
|
|
@@ -240,8 +244,6 @@ module Cucumber
|
|
240
244
|
self
|
241
245
|
end
|
242
246
|
|
243
|
-
|
244
|
-
|
245
247
|
protected
|
246
248
|
|
247
249
|
attr_reader :options, :profiles, :expanded_args
|
@@ -354,19 +356,18 @@ module Cucumber
|
|
354
356
|
end
|
355
357
|
|
356
358
|
def print_profile_information
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
359
|
+
return if @skip_profile_information || @profiles.empty?
|
360
|
+
profiles_sentence = ''
|
361
|
+
profiles_sentence = @profiles.size == 1 ? @profiles.first :
|
362
|
+
"#{@profiles[0...-1].join(', ')} and #{@profiles.last}"
|
361
363
|
|
362
|
-
|
364
|
+
@out_stream.puts "Using the #{profiles_sentence} profile#{'s' if @profiles.size> 1}..."
|
363
365
|
end
|
364
366
|
|
365
367
|
def default_options
|
366
368
|
{
|
367
369
|
:strict => false,
|
368
370
|
:require => [],
|
369
|
-
:lang => nil,
|
370
371
|
:dry_run => false,
|
371
372
|
:formats => [],
|
372
373
|
:excludes => [],
|
@@ -109,8 +109,10 @@ module Cucumber
|
|
109
109
|
return unless options[:wip]
|
110
110
|
passed = step_mother.scenarios(:passed)
|
111
111
|
if passed.any?
|
112
|
-
@io.puts "\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:"
|
112
|
+
@io.puts format_string("\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:", :failed)
|
113
113
|
print_elements(passed, :passed, "scenarios")
|
114
|
+
else
|
115
|
+
@io.puts format_string("\nThe --wip switch was used, so the failures were expected. All is good.\n", :passed)
|
114
116
|
end
|
115
117
|
end
|
116
118
|
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -230,10 +230,14 @@ module Cucumber
|
|
230
230
|
end
|
231
231
|
|
232
232
|
def best_matches(step_name, step_matches)
|
233
|
+
no_groups = step_matches.select {|step_match| step_match.args.length == 0}
|
233
234
|
max_arg_length = step_matches.map {|step_match| step_match.args.length }.max
|
234
235
|
top_groups = step_matches.select {|step_match| step_match.args.length == max_arg_length }
|
235
236
|
|
236
|
-
if
|
237
|
+
if no_groups.any?
|
238
|
+
longest_regexp_length = no_groups.map {|step_match| step_match.text_length }.max
|
239
|
+
no_groups.select {|step_match| step_match.text_length == longest_regexp_length }
|
240
|
+
elsif top_groups.any?
|
237
241
|
shortest_capture_length = top_groups.map {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } }.min
|
238
242
|
top_groups.select {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } == shortest_capture_length }
|
239
243
|
else
|
data/lib/cucumber/version.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
module Webrat
|
2
|
+
class Element
|
3
|
+
# Returns an Array of Array of String where each String is the
|
4
|
+
# a "cell" in the table-like structure represented by this Element.
|
5
|
+
#
|
6
|
+
# Supported elements are table, dl, ol and ul. The return value depends
|
7
|
+
# on the type of the element:
|
8
|
+
#
|
9
|
+
# * table : Each tr is a row. The innerHTML of each tr or th becomes cells. The number
|
10
|
+
# of columns is determined by the number of cells in the first row.
|
11
|
+
# * dl : Each dt creates a row with 2 cells. The innerHTML of the dt itself and the next dd become cells.
|
12
|
+
# * ul or ol : Each ul creates a row with one cell, the innerHTML of the ul.
|
13
|
+
#
|
14
|
+
def to_table
|
15
|
+
case element.name
|
16
|
+
when 'table'
|
17
|
+
table_from_table
|
18
|
+
when 'dl'
|
19
|
+
table_from_dl
|
20
|
+
when /ul|ol/
|
21
|
+
table_from_list
|
22
|
+
else
|
23
|
+
raise "#to_table not supported for #{element.name} elements"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def table_from_table #:nodoc:
|
28
|
+
col_count = nil
|
29
|
+
Webrat::XML.css_search(element, 'tr').map do |row|
|
30
|
+
cols = Webrat::XML.css_search(row, 'th,td')
|
31
|
+
col_count ||= cols.length
|
32
|
+
cols[0...col_count].map do |col|
|
33
|
+
col.inner_html
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def table_from_dl #:nodoc:
|
39
|
+
Webrat::XML.css_search(@element, 'dt').map do |dt|
|
40
|
+
next_node = dt.next_sibling
|
41
|
+
while next_node.name != 'dd'
|
42
|
+
next_node = next_node.next_sibling
|
43
|
+
end
|
44
|
+
[dt.inner_html, next_node.inner_html]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def table_from_list #:nodoc:
|
49
|
+
Webrat::XML.css_search(@element, 'li').map do |li|
|
50
|
+
[li.inner_html]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
alias to_a to_table # Backwards compatibility with Cucumber
|
55
|
+
end
|
56
|
+
|
57
|
+
module Locators
|
58
|
+
class ElementLocator < Locator
|
59
|
+
def locate
|
60
|
+
Element.load(@session, table_element)
|
61
|
+
end
|
62
|
+
|
63
|
+
def table_element
|
64
|
+
Webrat::XML.css_search(@dom, @value)[0]
|
65
|
+
end
|
66
|
+
|
67
|
+
def error_message
|
68
|
+
"Could not find anything matching '#{@value}'"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns a Webrat DOM element located by +css_selector+.
|
73
|
+
def element_at(css_selector)
|
74
|
+
ElementLocator.new(@session, dom, css_selector).locate!
|
75
|
+
end
|
76
|
+
|
77
|
+
alias table_at element_at # Backwards compatibility with Cucumber
|
78
|
+
end
|
79
|
+
|
80
|
+
module Methods
|
81
|
+
delegate_to_session :element_at, :table_at
|
82
|
+
end
|
83
|
+
|
84
|
+
class Session
|
85
|
+
def_delegators :current_scope, :element_at, :table_at
|
86
|
+
end
|
87
|
+
end
|
@@ -1,66 +1 @@
|
|
1
|
-
|
2
|
-
class Table < Element
|
3
|
-
def self.xpath_search
|
4
|
-
".//table"
|
5
|
-
end
|
6
|
-
|
7
|
-
# Converts this Table element into an Array of Array of String where each cell
|
8
|
-
# represents the inner_html of the <td> and <th> elements. The number of columns is
|
9
|
-
# determined by the number of cells in the first row.
|
10
|
-
def to_a
|
11
|
-
col_count = nil
|
12
|
-
Webrat::XML.css_search(@element, 'tr').map do |row|
|
13
|
-
cols = Webrat::XML.css_search(row, 'th,td')
|
14
|
-
col_count ||= cols.length
|
15
|
-
cols[0...col_count].map do |col|
|
16
|
-
col.inner_html
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module Locators
|
23
|
-
class TableLocator < Locator
|
24
|
-
def locate
|
25
|
-
Table.load(@session, table_element)
|
26
|
-
end
|
27
|
-
|
28
|
-
def table_element
|
29
|
-
table_elements.detect do |table_element|
|
30
|
-
matches_id?(table_element) ||
|
31
|
-
matches_css_selector?(table_element)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def matches_id?(table_element)
|
36
|
-
Webrat::XML.attribute(table_element, "id") == @value.to_s
|
37
|
-
end
|
38
|
-
|
39
|
-
def matches_css_selector?(table_element)
|
40
|
-
Webrat::XML.css_at(@dom, @value)
|
41
|
-
end
|
42
|
-
|
43
|
-
def table_elements
|
44
|
-
Webrat::XML.xpath_search(@dom, *Table.xpath_search)
|
45
|
-
end
|
46
|
-
|
47
|
-
def error_message
|
48
|
-
"Could not find table matching '#{@value}'"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Returns a Table element located by +id_or_selector+, which can
|
53
|
-
# be a DOM id or a CSS selector.
|
54
|
-
def table_at(id_or_selector)
|
55
|
-
TableLocator.new(@session, dom, id_or_selector).locate!
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
module Methods
|
60
|
-
delegate_to_session :table_at
|
61
|
-
end
|
62
|
-
|
63
|
-
class Session
|
64
|
-
def_delegators :current_scope, :table_at
|
65
|
-
end
|
66
|
-
end
|
1
|
+
require 'cucumber/webrat/element_locator'
|
data/lib/cucumber/world.rb
CHANGED
@@ -49,5 +49,21 @@ module Cucumber
|
|
49
49
|
raise Pending.new(message)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
# The default implementation of Object#inspect recursively
|
54
|
+
# traverses all instance variables and invokes inspect.
|
55
|
+
# This can be time consuming if the object graph is large.
|
56
|
+
#
|
57
|
+
# This can cause unnecessary delays when certain exceptions
|
58
|
+
# occur. For example, MRI internally invokes #inspect on an
|
59
|
+
# object that raises a NoMethodError. (JRuby does not do this).
|
60
|
+
#
|
61
|
+
# A World object can have many references created by the user
|
62
|
+
# or frameworks (Rails), so to avoid long waiting times on
|
63
|
+
# such errors in World we define it to just return a simple String.
|
64
|
+
#
|
65
|
+
def inspect
|
66
|
+
sprintf("#<%s:0x%x>", self.class, self.object_id)
|
67
|
+
end
|
52
68
|
end
|
53
69
|
end
|
@@ -18,8 +18,10 @@ begin
|
|
18
18
|
desc 'Run all features'
|
19
19
|
task :all => [:ok, :wip]
|
20
20
|
end
|
21
|
+
desc 'Alias for cucumber:ok'
|
22
|
+
task :cucumber => 'cucumber:ok'
|
21
23
|
|
22
|
-
task :features =>
|
24
|
+
task :features => :cucumber do
|
23
25
|
STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
|
24
26
|
end
|
25
27
|
rescue LoadError
|
@@ -15,7 +15,7 @@ Cucumber::Rails.use_transactional_fixtures
|
|
15
15
|
Cucumber::Rails.bypass_rescue
|
16
16
|
|
17
17
|
require 'webrat'
|
18
|
-
require 'cucumber/webrat/
|
18
|
+
require 'cucumber/webrat/element_locator' # Lets you do table.diff!(element_at('#my_table_or_dl_or_ul_or_ol').to_table)
|
19
19
|
|
20
20
|
Webrat.configure do |config|
|
21
21
|
config.mode = :rails
|
@@ -7,7 +7,7 @@ Spork.prefork do
|
|
7
7
|
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
8
8
|
|
9
9
|
require 'webrat'
|
10
|
-
require 'cucumber/webrat/
|
10
|
+
require 'cucumber/webrat/element_locator' # Lets you do table.diff!(element_at('#my_table_or_dl_or_ul_or_ol').to_table)
|
11
11
|
|
12
12
|
Webrat.configure do |config|
|
13
13
|
config.mode = :rails
|
@@ -38,7 +38,7 @@ module Cli
|
|
38
38
|
|
39
39
|
config.parse!(%w{--require /features})
|
40
40
|
|
41
|
-
config.
|
41
|
+
config.step_defs_to_load.should == [
|
42
42
|
"/features/support/bar.rb",
|
43
43
|
"/features/step_definitions/foo.rb"
|
44
44
|
]
|
@@ -49,7 +49,7 @@ module Cli
|
|
49
49
|
|
50
50
|
config.parse!(%w{--require /features})
|
51
51
|
|
52
|
-
config.
|
52
|
+
config.step_defs_to_load.should == [
|
53
53
|
"/features/support/env.rb",
|
54
54
|
"/features/support/a_file.rb"
|
55
55
|
]
|
@@ -60,7 +60,7 @@ module Cli
|
|
60
60
|
|
61
61
|
config.parse!(%w{--require /features --dry-run})
|
62
62
|
|
63
|
-
config.
|
63
|
+
config.step_defs_to_load.should == [
|
64
64
|
"/features/support/a_file.rb"
|
65
65
|
]
|
66
66
|
end
|
@@ -71,7 +71,7 @@ module Cli
|
|
71
71
|
|
72
72
|
config.parse!(%w{--require /features})
|
73
73
|
|
74
|
-
config.
|
74
|
+
config.step_defs_to_load.should == [
|
75
75
|
"/vendor/plugins/plugin_a/cucumber/foo.rb",
|
76
76
|
"/vendor/gems/gem_a/cucumber/bar.rb"
|
77
77
|
]
|
@@ -84,7 +84,7 @@ module Cli
|
|
84
84
|
|
85
85
|
config.parse!(%w{--require /features --exclude a_file.rb})
|
86
86
|
|
87
|
-
config.
|
87
|
+
config.step_defs_to_load.should == [
|
88
88
|
"/features/support/env.rb"
|
89
89
|
]
|
90
90
|
end
|
@@ -96,7 +96,7 @@ module Cli
|
|
96
96
|
|
97
97
|
config.parse!(%w{--require /features --exclude foo[df] --exclude blah})
|
98
98
|
|
99
|
-
config.
|
99
|
+
config.step_defs_to_load.should == [
|
100
100
|
"/features/support/bar.rb",
|
101
101
|
"/features/support/fooz.rb"
|
102
102
|
]
|
@@ -114,50 +114,6 @@ module Cli
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
context '--drb' do
|
118
|
-
it "removes the --drb flag from the args" do
|
119
|
-
args = %w{features --drb}
|
120
|
-
config.parse!(args)
|
121
|
-
args.should == %w{features}
|
122
|
-
end
|
123
|
-
|
124
|
-
it "keeps all other flags intact" do
|
125
|
-
args = %w{features --drb --format profile}
|
126
|
-
config.parse!(args)
|
127
|
-
args.should == %w{features --format profile}
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
context '--drb in a profile' do
|
133
|
-
it "removes the --drb flag from the args" do
|
134
|
-
given_cucumber_yml_defined_as({'server' => '--drb features'})
|
135
|
-
|
136
|
-
args = %w{--profile server}
|
137
|
-
config.parse!(args)
|
138
|
-
args.should == %w{features}
|
139
|
-
end
|
140
|
-
|
141
|
-
it "keeps all other flags intact from all profiles involved" do
|
142
|
-
given_cucumber_yml_defined_as({'server' => '--drb features --profile nested',
|
143
|
-
'nested' => '--verbose'})
|
144
|
-
|
145
|
-
args = %w{--profile server --format profile}
|
146
|
-
config.parse!(args)
|
147
|
-
args.should == %w{--format profile features --verbose}
|
148
|
-
end
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
context '--drb in the default profile and no arguments specified' do
|
153
|
-
it "expands the profile's arguments into the args excpet for --drb" do
|
154
|
-
given_cucumber_yml_defined_as({'default' => '--drb features --format pretty'})
|
155
|
-
args = []
|
156
|
-
config.parse!(args)
|
157
|
-
args.should == %w{features --format pretty}
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
117
|
it "uses the default profile when no profile is defined" do
|
162
118
|
given_cucumber_yml_defined_as({'default' => '--require some_file'})
|
163
119
|
|
@@ -197,36 +153,10 @@ END_OF_MESSAGE
|
|
197
153
|
end
|
198
154
|
|
199
155
|
it "allows profiles to be defined in arrays" do
|
200
|
-
given_cucumber_yml_defined_as({'foo' => [
|
156
|
+
given_cucumber_yml_defined_as({'foo' => ['-f','progress']})
|
201
157
|
|
202
158
|
config.parse!(%w{--profile foo})
|
203
|
-
config.
|
204
|
-
end
|
205
|
-
|
206
|
-
it "notifies the user that an individual profile is being used" do
|
207
|
-
given_cucumber_yml_defined_as({'foo' => [1,2,3]})
|
208
|
-
|
209
|
-
config.parse!(%w{--profile foo})
|
210
|
-
out.string.should =~ /Using the foo profile...\n/
|
211
|
-
end
|
212
|
-
|
213
|
-
it "notifies the user when multiple profiles are being used" do
|
214
|
-
given_cucumber_yml_defined_as({'foo' => [1,2,3], 'bar' => ['v'], 'dog' => ['v']})
|
215
|
-
|
216
|
-
config.parse!(%w{--profile foo --profile bar})
|
217
|
-
out.string.should =~ /Using the foo and bar profiles...\n/
|
218
|
-
|
219
|
-
reset_config
|
220
|
-
|
221
|
-
config.parse!(%w{--profile foo --profile bar --profile dog})
|
222
|
-
out.string.should =~ /Using the foo, bar and dog profiles...\n/
|
223
|
-
end
|
224
|
-
|
225
|
-
it "disregards paths in profiles when other paths are passed in (via cmd line)" do
|
226
|
-
given_cucumber_yml_defined_as({'foo' => %w[-v features]})
|
227
|
-
|
228
|
-
config.parse!(%w{--profile foo features/specific.feature --format pretty})
|
229
|
-
config.paths.should == ['features/specific.feature']
|
159
|
+
config.options[:formats].should == [['progress', out]]
|
230
160
|
end
|
231
161
|
|
232
162
|
it "disregards default STDOUT formatter defined in profile when another is passed in (via cmd line)" do
|
@@ -422,17 +352,27 @@ END_OF_MESSAGE
|
|
422
352
|
config.feature_files.should == ["cucumber.feature"]
|
423
353
|
end
|
424
354
|
|
355
|
+
it "defaults to the features directory when no feature file are provided" do
|
356
|
+
File.stub!(:directory?).and_return(true)
|
357
|
+
Dir.should_receive(:[]).with("features/**/*.feature").
|
358
|
+
any_number_of_times.and_return(["cucumber.feature"])
|
359
|
+
|
360
|
+
config.parse!(%w{})
|
361
|
+
|
362
|
+
config.feature_files.should == ["cucumber.feature"]
|
363
|
+
end
|
364
|
+
|
425
365
|
it "should allow specifying environment variables on the command line" do
|
426
366
|
config.parse!(["foo=bar"])
|
427
367
|
ENV["foo"].should == "bar"
|
428
|
-
config.feature_files.
|
368
|
+
config.feature_files.should_not include('foo=bar')
|
429
369
|
end
|
430
370
|
|
431
371
|
it "should allow specifying environment variables in profiles" do
|
432
372
|
given_cucumber_yml_defined_as({'selenium' => 'RAILS_ENV=selenium'})
|
433
373
|
config.parse!(["--profile", "selenium"])
|
434
374
|
ENV["RAILS_ENV"].should == "selenium"
|
435
|
-
config.feature_files.
|
375
|
+
config.feature_files.should_not include('RAILS_ENV=selenium')
|
436
376
|
end
|
437
377
|
|
438
378
|
end
|
@@ -14,6 +14,7 @@ module Cucumber
|
|
14
14
|
@err = StringIO.new
|
15
15
|
Kernel.stub!(:exit).and_return(nil)
|
16
16
|
File.stub!(:exist?).and_return(false) # When Configuration checks for cucumber.yml
|
17
|
+
Dir.stub!(:[]).and_return([]) # to prevent cucumber's features dir to being laoded
|
17
18
|
end
|
18
19
|
|
19
20
|
describe "verbose mode" do
|
@@ -22,15 +23,6 @@ module Cucumber
|
|
22
23
|
@empty_feature = Ast::Feature.new(nil, Ast::Comment.new(''), Ast::Tags.new(2, []), "Feature", [])
|
23
24
|
end
|
24
25
|
|
25
|
-
it "should show ruby files required" do
|
26
|
-
@cli = Main.new(%w{--verbose --require example.rb}, @out)
|
27
|
-
@cli.stub!(:require)
|
28
|
-
|
29
|
-
@cli.execute!(Object.new.extend(StepMother))
|
30
|
-
|
31
|
-
@out.string.should include('example.rb')
|
32
|
-
end
|
33
|
-
|
34
26
|
it "should show feature files parsed" do
|
35
27
|
@cli = Main.new(%w{--verbose example.feature}, @out)
|
36
28
|
@cli.stub!(:require)
|
@@ -209,6 +209,10 @@ module Cli
|
|
209
209
|
options[:source].should be_false
|
210
210
|
end
|
211
211
|
|
212
|
+
it "uses the language from profile when none is specified on the command line" do
|
213
|
+
given_cucumber_yml_defined_as({'foo' => '--language fr'})
|
214
|
+
after_parsing('-p foo') {options[:lang].should == 'fr'}
|
215
|
+
end
|
212
216
|
end
|
213
217
|
|
214
218
|
context '-P or --no-profile' do
|
@@ -278,28 +282,38 @@ module Cli
|
|
278
282
|
'baz' => '-r some_file.rb')
|
279
283
|
options.parse!(%w[features -p foo --profile bar])
|
280
284
|
|
281
|
-
options.expanded_args_without_drb.should == %w[features -v --wip -r some_file.rb]
|
285
|
+
options.expanded_args_without_drb.should == %w[features -v --wip -r some_file.rb --no-profile]
|
282
286
|
end
|
283
287
|
|
284
288
|
it "removes the --drb flag so that the args can be safely passed to the drb server" do
|
285
289
|
given_cucumber_yml_defined_as('default' => 'features -f pretty --drb')
|
286
290
|
options.parse!(%w[--profile default])
|
287
291
|
|
288
|
-
options.expanded_args_without_drb.should == %w[features -f pretty]
|
292
|
+
options.expanded_args_without_drb.should == %w[features -f pretty --no-profile]
|
289
293
|
end
|
290
294
|
|
291
295
|
it "contains the environment variables" do
|
292
296
|
options.parse!(%w[features FOO=bar])
|
293
|
-
options.expanded_args_without_drb.should == %w[features FOO=bar]
|
297
|
+
options.expanded_args_without_drb.should == %w[features FOO=bar --no-profile]
|
294
298
|
end
|
295
299
|
|
296
300
|
it "ignores the paths from the profiles if one was specified on the command line" do
|
297
301
|
given_cucumber_yml_defined_as('foo' => 'features --drb')
|
298
302
|
options.parse!(%w[some_feature.feature -p foo])
|
299
|
-
options.expanded_args_without_drb.should == %w[some_feature.feature]
|
303
|
+
options.expanded_args_without_drb.should == %w[some_feature.feature --no-profile]
|
300
304
|
end
|
301
305
|
|
302
306
|
|
307
|
+
it "appends the --no-profile flag so that the DRb server doesn't reload the profiles" do
|
308
|
+
given_cucumber_yml_defined_as('foo' => 'features --drb')
|
309
|
+
options.parse!(%w[some_feature.feature -p foo])
|
310
|
+
options.expanded_args_without_drb.should == %w[some_feature.feature --no-profile]
|
311
|
+
end
|
312
|
+
|
313
|
+
it "does not append --no-profile if already present" do
|
314
|
+
options.parse!(%w[some_feature.feature -P])
|
315
|
+
options.expanded_args_without_drb.should == %w[some_feature.feature -P]
|
316
|
+
end
|
303
317
|
|
304
318
|
|
305
319
|
end
|
@@ -72,6 +72,14 @@ spec/cucumber/step_mother_spec.rb:40:in `/Three cute (.*)/'
|
|
72
72
|
wrong = @step_mother.Given(/Three (.*)/) {|animal|}
|
73
73
|
@step_mother.step_match("Three blind mice ran far").step_definition.should == right
|
74
74
|
end
|
75
|
+
|
76
|
+
it "should pick most specific step definition when --guess is enabled and unequal number of capture groups" do
|
77
|
+
@step_mother.options = {:guess => true}
|
78
|
+
general = @step_mother.Given(/Three (.*) mice ran (.*)/) {|disability|}
|
79
|
+
specific = @step_mother.Given(/Three blind mice ran far/) {}
|
80
|
+
more_specific = @step_mother.Given(/^Three blind mice ran far$/) {}
|
81
|
+
@step_mother.step_match("Three blind mice ran far").step_definition.should == more_specific
|
82
|
+
end
|
75
83
|
|
76
84
|
it "should raise Undefined error when no step definitions match" do
|
77
85
|
lambda do
|
@@ -101,7 +109,7 @@ spec/cucumber/step_mother_spec.rb:40:in `/Three cute (.*)/'
|
|
101
109
|
raise "Should fail"
|
102
110
|
rescue NilWorld => e
|
103
111
|
e.message.should == "World procs should never return nil"
|
104
|
-
e.backtrace.should == ["spec/cucumber/step_mother_spec.rb:
|
112
|
+
e.backtrace.should == ["spec/cucumber/step_mother_spec.rb:104:in `World'"]
|
105
113
|
end
|
106
114
|
end
|
107
115
|
|
@@ -132,8 +140,8 @@ spec/cucumber/step_mother_spec.rb:40:in `/Three cute (.*)/'
|
|
132
140
|
end.should raise_error(MultipleWorld, %{You can only pass a proc to #World once, but it's happening
|
133
141
|
in 2 places:
|
134
142
|
|
135
|
-
spec/cucumber/step_mother_spec.rb:
|
136
|
-
spec/cucumber/step_mother_spec.rb:
|
143
|
+
spec/cucumber/step_mother_spec.rb:137:in `World'
|
144
|
+
spec/cucumber/step_mother_spec.rb:139:in `World'
|
137
145
|
|
138
146
|
Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc
|
139
147
|
or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.95
|
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-08-
|
12
|
+
date: 2009-08-13 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -388,6 +388,7 @@ files:
|
|
388
388
|
- lib/cucumber/cli/main.rb
|
389
389
|
- lib/cucumber/cli/options.rb
|
390
390
|
- lib/cucumber/cli/profile_loader.rb
|
391
|
+
- lib/cucumber/cli/rb_step_def_loader.rb
|
391
392
|
- lib/cucumber/core_ext/exception.rb
|
392
393
|
- lib/cucumber/core_ext/instance_exec.rb
|
393
394
|
- lib/cucumber/core_ext/proc.rb
|
@@ -430,6 +431,7 @@ files:
|
|
430
431
|
- lib/cucumber/step_match.rb
|
431
432
|
- lib/cucumber/step_mother.rb
|
432
433
|
- lib/cucumber/version.rb
|
434
|
+
- lib/cucumber/webrat/element_locator.rb
|
433
435
|
- lib/cucumber/webrat/table_locator.rb
|
434
436
|
- lib/cucumber/world.rb
|
435
437
|
- rails_generators/cucumber/USAGE
|