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 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