cucumber 0.3.94 → 0.3.95

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 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__) + '/../../lib') # This line is not needed in your own project
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
 
@@ -4,9 +4,9 @@ require 'spec/expectations'
4
4
  require 'fileutils'
5
5
  require 'forwardable'
6
6
  begin
7
- gem "spork", ">= 0.5.1" # Ensure correct spork version number to avoid false-negatives.
7
+ require 'spork'
8
8
  rescue Gem::LoadError => ex
9
- warn "WARNING: #{ex.message} You need to have the spork gem installed to run the DRb feature properly!"
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
- spork = `which spork`.strip
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 files_to_require
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}/**/*.rb"] : path
95
+ File.directory?(path) ? Dir["#{path}/**/*"] : path
100
96
  end.flatten.uniq
101
- sorted_files = files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
102
- env_files = sorted_files.select {|f| f =~ %r{/support/env.rb} }
103
- files = env_files + sorted_files.reject {|f| f =~ %r{/support/env.rb} }
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.rb} } if @options[:dry_run]
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 = @options[:paths].map do |path|
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(/::/, '/').
@@ -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
- require_files
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 load_files
112
- each_lib{|lib| load(lib)}
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 require_files
118
- each_lib{|lib| require lib}
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 each_lib
122
- requires = configuration.files_to_require
123
- verbose_log("Ruby files required:")
124
- verbose_log(requires.map{|lib| " * #{lib}"}.join("\n"))
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
- yield lib
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
@@ -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('-P', '--no-profile',
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
- return if @skip_profile_information || @profiles.empty?
358
- profiles_sentence = ''
359
- profiles_sentence = @profiles.size == 1 ? @profiles.first :
360
- "#{@profiles[0...-1].join(', ')} and #{@profiles.last}"
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
- @out_stream.puts "Using the #{profiles_sentence} profile#{'s' if @profiles.size> 1}..."
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 => [],
@@ -57,8 +57,6 @@ Defined profiles in cucumber.yml:
57
57
  return @cucumber_yml
58
58
  end
59
59
 
60
-
61
-
62
60
  end
63
61
  end
64
62
  end
@@ -0,0 +1,14 @@
1
+ module Cucumber
2
+ module Cli
3
+ class RbStepDefLoader
4
+ def load_step_def_file(main, step_def_file)
5
+ begin
6
+ require step_def_file
7
+ rescue LoadError => e
8
+ e.message << "\nFailed to load #{step_def_file}"
9
+ raise e
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -101,7 +101,6 @@ module Cucumber
101
101
  begin
102
102
  gem 'genki-ruby-terminfo'
103
103
  require 'terminfo'
104
- puts TermInfo.default_object.tigetnum("colors")
105
104
  case TermInfo.default_object.tigetnum("colors")
106
105
  when 0
107
106
  raise "Your terminal doesn't support colours"
@@ -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
 
@@ -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 top_groups.length > 1
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
@@ -2,7 +2,7 @@ module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
- TINY = 94
5
+ TINY = 95
6
6
  PATCH = nil # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
@@ -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
- module Webrat
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'
@@ -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 => 'cucumber:ok' do
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/table_locator' # Lets you do table.diff!(table_at('#my_table').to_a)
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/table_locator' # Lets you do table.diff!(table_at('#my_table').to_a)
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
@@ -167,3 +167,7 @@ Then /^I should be on (.+)$/ do |page_name|
167
167
  assert_equal path_to(page_name), URI.parse(current_url).path
168
168
  <% end -%>
169
169
  end
170
+
171
+ Then /^show me the page$/ do
172
+ save_and_open_page
173
+ end
@@ -38,7 +38,7 @@ module Cli
38
38
 
39
39
  config.parse!(%w{--require /features})
40
40
 
41
- config.files_to_require.should == [
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.files_to_require.should == [
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.files_to_require.should == [
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.files_to_require.should == [
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.files_to_require.should == [
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.files_to_require.should == [
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' => [1,2,3]})
156
+ given_cucumber_yml_defined_as({'foo' => ['-f','progress']})
201
157
 
202
158
  config.parse!(%w{--profile foo})
203
- config.paths.should == [1,2,3]
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.should == []
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.should == []
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:96:in `World'"]
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:129:in `World'
136
- spec/cucumber/step_mother_spec.rb:131:in `World'
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.94
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-06 00:00:00 +02:00
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