cucumber 0.3.96 → 0.3.97

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.
Files changed (93) hide show
  1. data/History.txt +22 -3
  2. data/License.txt +2 -0
  3. data/Manifest.txt +9 -5
  4. data/config/hoe.rb +1 -0
  5. data/examples/i18n/Rakefile +5 -3
  6. data/examples/i18n/fi/features/yhteenlasku.feature +5 -4
  7. data/examples/python/features/step_definitions/fib_steps.py +3 -0
  8. data/examples/python/features/support/env.rb +21 -21
  9. data/gem_tasks/contributors.rake +8 -0
  10. data/gem_tasks/features.rake +1 -0
  11. data/gem_tasks/sdoc.rake +7 -0
  12. data/lib/README.rdoc +12 -0
  13. data/lib/cucumber/ast/background.rb +1 -1
  14. data/lib/cucumber/ast/comment.rb +1 -1
  15. data/lib/cucumber/ast/examples.rb +9 -4
  16. data/lib/cucumber/ast/feature.rb +1 -1
  17. data/lib/cucumber/ast/feature_element.rb +1 -1
  18. data/lib/cucumber/ast/features.rb +1 -1
  19. data/lib/cucumber/ast/outline_table.rb +2 -2
  20. data/lib/cucumber/ast/py_string.rb +1 -1
  21. data/lib/cucumber/ast/scenario.rb +1 -1
  22. data/lib/cucumber/ast/scenario_outline.rb +8 -7
  23. data/lib/cucumber/ast/step.rb +1 -1
  24. data/lib/cucumber/ast/step_collection.rb +1 -1
  25. data/lib/cucumber/ast/step_invocation.rb +1 -1
  26. data/lib/cucumber/ast/table.rb +65 -45
  27. data/lib/cucumber/ast/tags.rb +2 -2
  28. data/lib/cucumber/ast/visitor.rb +6 -8
  29. data/lib/cucumber/broadcaster.rb +1 -1
  30. data/lib/cucumber/cli/language_help_formatter.rb +1 -1
  31. data/lib/cucumber/cli/main.rb +15 -52
  32. data/lib/cucumber/constantize.rb +1 -1
  33. data/lib/cucumber/core_ext/exception.rb +1 -1
  34. data/lib/cucumber/core_ext/instance_exec.rb +8 -3
  35. data/lib/cucumber/core_ext/proc.rb +1 -1
  36. data/lib/cucumber/core_ext/string.rb +1 -1
  37. data/lib/cucumber/feature_file.rb +4 -3
  38. data/lib/cucumber/filter.rb +2 -1
  39. data/lib/cucumber/formatter/ansicolor.rb +6 -5
  40. data/lib/cucumber/formatter/color_io.rb +2 -2
  41. data/lib/cucumber/formatter/console.rb +2 -0
  42. data/lib/cucumber/formatter/duration.rb +3 -0
  43. data/lib/cucumber/formatter/html.rb +1 -0
  44. data/lib/cucumber/formatter/junit.rb +1 -0
  45. data/lib/cucumber/formatter/ordered_xml_markup.rb +1 -1
  46. data/lib/cucumber/formatter/pretty.rb +18 -4
  47. data/lib/cucumber/formatter/profile.rb +1 -0
  48. data/lib/cucumber/formatter/progress.rb +1 -0
  49. data/lib/cucumber/formatter/rerun.rb +2 -0
  50. data/lib/cucumber/formatter/steps.rb +1 -0
  51. data/lib/cucumber/formatter/tag_cloud.rb +2 -1
  52. data/lib/cucumber/formatter/unicode.rb +1 -1
  53. data/lib/cucumber/formatter/usage.rb +1 -0
  54. data/lib/cucumber/language_support.rb +30 -0
  55. data/lib/cucumber/language_support/language_methods.rb +34 -12
  56. data/lib/cucumber/parser/feature.rb +81 -57
  57. data/lib/cucumber/parser/feature.tt +3 -3
  58. data/lib/cucumber/parser/natural_language.rb +1 -1
  59. data/lib/cucumber/parser/table.rb +3 -0
  60. data/lib/cucumber/parser/treetop_ext.rb +6 -5
  61. data/lib/cucumber/platform.rb +1 -2
  62. data/lib/cucumber/py_support/py_dsl.py +8 -0
  63. data/lib/cucumber/py_support/py_language.py +2 -0
  64. data/lib/cucumber/py_support/py_language.rb +68 -0
  65. data/lib/cucumber/rails/world.rb +2 -1
  66. data/lib/cucumber/rake/task.rb +13 -11
  67. data/lib/cucumber/rb_support/rb_dsl.rb +27 -15
  68. data/lib/cucumber/rb_support/rb_hook.rb +1 -2
  69. data/lib/cucumber/rb_support/rb_language.rb +57 -33
  70. data/lib/cucumber/rb_support/rb_step_definition.rb +42 -38
  71. data/lib/cucumber/rb_support/rb_world.rb +93 -0
  72. data/lib/cucumber/rspec_neuter.rb +3 -3
  73. data/lib/cucumber/step_match.rb +2 -2
  74. data/lib/cucumber/step_mother.rb +91 -65
  75. data/lib/cucumber/version.rb +1 -1
  76. data/lib/cucumber/webrat/element_locator.rb +3 -3
  77. data/rails_generators/cucumber/templates/cucumber.rake +2 -0
  78. data/rails_generators/cucumber/templates/webrat_steps.rb +4 -0
  79. data/spec/cucumber/ast/background_spec.rb +8 -1
  80. data/spec/cucumber/ast/scenario_outline_spec.rb +1 -0
  81. data/spec/cucumber/ast/table_spec.rb +10 -0
  82. data/spec/cucumber/cli/options_spec.rb +1 -1
  83. data/spec/cucumber/parser/feature_parser_spec.rb +4 -0
  84. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +114 -0
  85. data/spec/cucumber/step_mother_spec.rb +29 -10
  86. data/spec/cucumber/treetop_parser/with_comments.feature +14 -1
  87. data/spec/cucumber/world/pending_spec.rb +1 -1
  88. metadata +21 -7
  89. data/gem_tasks/yard.rake +0 -8
  90. data/lib/cucumber/language_support/hook_methods.rb +0 -9
  91. data/lib/cucumber/world.rb +0 -89
  92. data/spec/cucumber/ast/visitor_spec.rb +0 -27
  93. data/spec/cucumber/step_definition_spec.rb +0 -102
@@ -1,6 +1,25 @@
1
+ == 0.3.97 2009-08-23
2
+
3
+ The AA-FTT release. Creating a release for the AA-FTT meeting in Chicago so that we can play
4
+ with the new language API and maybe knock out some better .NET support.
5
+
6
+ === Bugfixes
7
+ * Allow comments on examples sections underneath scenario outlines (#420 Mike Sassak)
8
+ * Table.map_headers! will fail with a decent error message when 0 or 2+ headers are matched. (Aslak Hellesøy)
9
+ * Fixed an issue with comments with preceding spaces after a background causing a parse error (#401 Joseph Wilk)
10
+
11
+ === New Features
12
+ * The public API is documented and there is a new :sdoc task to generate nice searchable API docs.
13
+ * Add :default => :cucumber when setting up Rake tasks for Cucumber in Rails (Aslak Hellesøy)
14
+ * New When /^I fill in "([^\"]*)" for "([^\"]*)"$/ Webrat step for Rails (Aslak Hellesøy)
15
+
16
+ === Changed Features
17
+ * Changed the Programming Language API to support languages without "bleed through" (e.g. rubypython can't invoke ruby objs) (Aslak Hellesøy)
18
+ * The Programming Language API manages hooks on the language level instead of on the step mother level (Aslak Hellesøy)
19
+
1
20
  == 0.3.96 2009-08-15
2
21
 
3
- This release doesn't have any directly visible new features or bug fixes. But there are big
22
+ This release doesn't have any significant new features or bug fixes, but there are big
4
23
  internal changes. This release has a new API for plugging in other programming languages.
5
24
  You can read more about that here: http://groups.google.com/group/cukes/browse_thread/thread/b9db8bf1f3ec9708
6
25
 
@@ -870,8 +889,8 @@ spaces removed too.
870
889
  == 0.1.8 2008-10-18
871
890
 
872
891
  This release extends the support for tables. PLEASE NOTE THAT TABLES ARE STILL EXPERIMENTAL.
873
- In previous releases it has been possible to use tables to define "more examples" of a scenario i
874
- n a FIT-style column fixture kind of way. Now you can also use tables as arguments to steps.
892
+ In previous releases it has been possible to use tables to define "more examples" of a scenario in
893
+ a FIT-style column fixture kind of way. Now you can also use tables as arguments to steps.
875
894
 
876
895
  Tables used to define more examples after a scenario must now be prefixed. In English it looks like this:
877
896
 
@@ -1,3 +1,5 @@
1
+ The MIT License
2
+
1
3
  Copyright (c) 2008,2009 Aslak Hellesøy
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
@@ -168,6 +168,7 @@ examples/junit/features/pending.feature
168
168
  examples/junit/features/step_definitions/steps.rb
169
169
  examples/pure_java/README.textile
170
170
  examples/python/features/fibonacci.feature
171
+ examples/python/features/step_definitions/fib_steps.py
171
172
  examples/python/features/step_definitions/fib_steps.rb
172
173
  examples/python/features/support/env.rb
173
174
  examples/python/lib/fib.py
@@ -289,7 +290,8 @@ gem_tasks/flog.rake
289
290
  gem_tasks/gemspec.rake
290
291
  gem_tasks/rspec.rake
291
292
  gem_tasks/sass.rake
292
- gem_tasks/yard.rake
293
+ gem_tasks/sdoc.rake
294
+ lib/README.rdoc
293
295
  lib/autotest/cucumber.rb
294
296
  lib/autotest/cucumber_mixin.rb
295
297
  lib/autotest/cucumber_rails.rb
@@ -346,7 +348,7 @@ lib/cucumber/formatter/tag_cloud.rb
346
348
  lib/cucumber/formatter/unicode.rb
347
349
  lib/cucumber/formatter/usage.rb
348
350
  lib/cucumber/formatters/unicode.rb
349
- lib/cucumber/language_support/hook_methods.rb
351
+ lib/cucumber/language_support.rb
350
352
  lib/cucumber/language_support/language_methods.rb
351
353
  lib/cucumber/language_support/step_definition_methods.rb
352
354
  lib/cucumber/languages.yml
@@ -359,6 +361,9 @@ lib/cucumber/parser/table.rb
359
361
  lib/cucumber/parser/table.tt
360
362
  lib/cucumber/parser/treetop_ext.rb
361
363
  lib/cucumber/platform.rb
364
+ lib/cucumber/py_support/py_dsl.py
365
+ lib/cucumber/py_support/py_language.py
366
+ lib/cucumber/py_support/py_language.rb
362
367
  lib/cucumber/rails/rspec.rb
363
368
  lib/cucumber/rails/world.rb
364
369
  lib/cucumber/rake/task.rb
@@ -366,13 +371,13 @@ lib/cucumber/rb_support/rb_dsl.rb
366
371
  lib/cucumber/rb_support/rb_hook.rb
367
372
  lib/cucumber/rb_support/rb_language.rb
368
373
  lib/cucumber/rb_support/rb_step_definition.rb
374
+ lib/cucumber/rb_support/rb_world.rb
369
375
  lib/cucumber/rspec_neuter.rb
370
376
  lib/cucumber/step_match.rb
371
377
  lib/cucumber/step_mother.rb
372
378
  lib/cucumber/version.rb
373
379
  lib/cucumber/webrat/element_locator.rb
374
380
  lib/cucumber/webrat/table_locator.rb
375
- lib/cucumber/world.rb
376
381
  rails_generators/cucumber/USAGE
377
382
  rails_generators/cucumber/cucumber_generator.rb
378
383
  rails_generators/cucumber/templates/cucumber
@@ -396,7 +401,6 @@ spec/cucumber/ast/scenario_spec.rb
396
401
  spec/cucumber/ast/step_collection_spec.rb
397
402
  spec/cucumber/ast/step_spec.rb
398
403
  spec/cucumber/ast/table_spec.rb
399
- spec/cucumber/ast/visitor_spec.rb
400
404
  spec/cucumber/broadcaster_spec.rb
401
405
  spec/cucumber/cli/configuration_spec.rb
402
406
  spec/cucumber/cli/drb_client_spec.rb
@@ -415,8 +419,8 @@ spec/cucumber/parser/table_parser_spec.rb
415
419
  spec/cucumber/rails/stubs/mini_rails.rb
416
420
  spec/cucumber/rails/stubs/test_help.rb
417
421
  spec/cucumber/rails/world_spec.rb
422
+ spec/cucumber/rb_support/rb_step_definition_spec.rb
418
423
  spec/cucumber/sell_cucumbers.feature
419
- spec/cucumber/step_definition_spec.rb
420
424
  spec/cucumber/step_mother_spec.rb
421
425
  spec/cucumber/treetop_parser/empty_feature.feature
422
426
  spec/cucumber/treetop_parser/empty_scenario.feature
@@ -63,6 +63,7 @@ $hoe = Hoe.spec(GEM_NAME) do |p|
63
63
  p.extra_deps = [
64
64
  ['term-ansicolor', '>= 1.0.3'],
65
65
  ['treetop', '>= 1.3.0'],
66
+ ['polyglot', '>= 0.2.8'], # Don't really want polyglot, but it keeps breaking so we'll make people use something that works ok'ish
66
67
  ['diff-lcs', '>= 1.1.2'],
67
68
  ['builder', '>= 2.1.2']
68
69
  ]
@@ -6,7 +6,7 @@ task :i18n do
6
6
  lang = f[dir.length+1..-1]
7
7
  if examples_working?(lang)
8
8
  Dir.chdir(f) do
9
- rake("features")
9
+ rake("cucumber")
10
10
  end
11
11
  else
12
12
  STDERR.puts %{
@@ -21,10 +21,12 @@ task :i18n do
21
21
  end
22
22
  end
23
23
 
24
+ task :default => :i18n
25
+
24
26
  def examples_working?(lang)
25
- !%w{ro ko li lt}.index(lang)
27
+ !%w{ro}.index(lang)
26
28
  end
27
29
 
28
30
  def rake(args)
29
- ruby($0, args) rescue nil
31
+ ruby($0, args)
30
32
  end
@@ -1,13 +1,14 @@
1
+ # language: fi
1
2
  Ominaisuus: Yhteenlasku
2
3
  Välttyäkseni hölmöiltä virheiltä
3
4
  Koska olen laskutaidoton
4
5
  Haluan että yhteenlaskut lasketaan puolestani
5
6
 
6
7
  Tapausaihio: Kahden luvun summa
7
- Oletetaan että olen syöttänyt laskimeen luvun 50
8
- Ja että olen syöttänyt laskimeen luvun 70
9
- Kun painan "summaa"
10
- Niin laskimen ruudulla pitäisi näkyä tulos 120
8
+ Oletetaan että olen syöttänyt laskimeen luvun <luku_1>
9
+ Ja että olen syöttänyt laskimeen luvun <luku_2>
10
+ Kun painan "<nappi>"
11
+ Niin laskimen ruudulla pitäisi näkyä tulos <tulos>
11
12
 
12
13
  Tapaukset:
13
14
  | luku_1 | luku_2 | nappi | tulos |
@@ -0,0 +1,3 @@
1
+ from py_dsl import *
2
+
3
+ Given("Hello from python")
@@ -1,21 +1,21 @@
1
- require 'rubypython'
2
-
3
- ENV['PYTHONPATH'] = File.expand_path(File.dirname(__FILE__) + '/../../lib')
4
-
5
- Before do
6
- RubyPython.start
7
- @fib = RubyPython.import('fib')
8
- end
9
-
10
- After do
11
- RubyPython.stop
12
- end
13
-
14
- # RubyPython seems to expect this to exist (?)
15
- class String
16
- def end_with?(str)
17
- str = str.to_str
18
- tail = self[-str.length, str.length]
19
- tail == str
20
- end
21
- end
1
+ # require 'rubypython'
2
+ #
3
+ # ENV['PYTHONPATH'] = File.expand_path(File.dirname(__FILE__) + '/../../lib')
4
+ #
5
+ # Before do
6
+ # RubyPython.start
7
+ # @fib = RubyPython.import('fib')
8
+ # end
9
+ #
10
+ # After do
11
+ # RubyPython.stop
12
+ # end
13
+ #
14
+ # # RubyPython seems to expect this to exist (?)
15
+ # class String
16
+ # def end_with?(str)
17
+ # str = str.to_str
18
+ # tail = self[-str.length, str.length]
19
+ # tail == str
20
+ # end
21
+ # end
@@ -1,4 +1,12 @@
1
1
  task :contributors do
2
2
  contributors = `git log --pretty=short --no-merges | git shortlog -ne | egrep -ve '^ +' | egrep -ve '^$'`
3
3
  puts contributors.split("\n").length
4
+ end
5
+
6
+ task :codeswarm do
7
+ sh "code_swarm --reload" rescue nil # Fails because of encoding - which we'll fix
8
+ sh "iconv -f latin1 -t utf-8 .git/.code_swarm/log.xml > tmp.xml && mv tmp.xml .git/.code_swarm/log.xml"
9
+ sh "sed -e 's/Aslak\ Hellesøy@.BEKK.no/aslak.hellesoy@gmail.com/g' .git/.code_swarm/log.xml > tmp.xml && mv tmp.xml .git/.code_swarm/log.xml"
10
+ sh "sed -e 's/josephwilk@joesniff.co.uk/joe@josephwilk.net/g' .git/.code_swarm/log.xml > tmp.xml && mv tmp.xml .git/.code_swarm/log.xml"
11
+ sh "code_swarm"
4
12
  end
@@ -3,6 +3,7 @@ require 'cucumber/rake/task'
3
3
 
4
4
  Cucumber::Rake::Task.new do |t|
5
5
  t.cucumber_opts = %w{--format progress}
6
+ t.rcov = ENV['RCOV']
6
7
  end
7
8
 
8
9
  Cucumber::Rake::Task.new('pretty') do |t|
@@ -0,0 +1,7 @@
1
+ require 'sdoc' # and use your RDoc task the same way you used it before
2
+
3
+ Rake::RDocTask.new(:sdoc) do |rdoc|
4
+ rdoc.rdoc_dir = 'doc/sdoc'
5
+ rdoc.options += %w{--fmt shtml -N --webcvs=http://github.com/aslakhellesoy/cucumber/blob/v0.3.96/%s --title "Cucumber API" --threads 4 --main README --exclude cucumber/parser lib}
6
+ rdoc.template = 'direct' # lighter template used on railsapi.com
7
+ end
@@ -0,0 +1,12 @@
1
+ = Cucumber API
2
+
3
+ This is the public API of Cucumber. The public API includes the classes, modules
4
+ and methods you can use if you are a user of Cucumber. It also applies to you if
5
+ you're developing a 3rd party tool that integrates with Cucumber.
6
+
7
+ == Internal API
8
+
9
+ Cucumber has more classes, modules and methods than what you can see in the public
10
+ API. If you decide to dive into the source code and make use of an API that isn't
11
+ part of this documentation - beware that this API might change at any time. If you
12
+ want a particular internal API to be promoted to the public API - let us know.
@@ -2,7 +2,7 @@ require 'cucumber/ast/feature_element'
2
2
 
3
3
  module Cucumber
4
4
  module Ast
5
- class Background
5
+ class Background #:nodoc:
6
6
  include FeatureElement
7
7
  attr_reader :feature_elements
8
8
 
@@ -7,7 +7,7 @@ module Cucumber
7
7
  #
8
8
  # This gets parsed into a Comment with value <tt>"# Lorem ipsum\n# dolor sit amet\n"</tt>
9
9
  #
10
- class Comment
10
+ class Comment #:nodoc:
11
11
  def initialize(value)
12
12
  @value = value
13
13
  end
@@ -1,12 +1,13 @@
1
1
  module Cucumber
2
2
  module Ast
3
- class Examples
4
- def initialize(line, keyword, name, outline_table)
5
- @keyword, @name, @outline_table = keyword, name, outline_table
3
+ class Examples #:nodoc:
4
+ def initialize(comment, line, keyword, name, outline_table)
5
+ @comment, @keyword, @name, @outline_table = comment, keyword, name, outline_table
6
6
  end
7
7
 
8
8
  def accept(visitor)
9
9
  return if $cucumber_interrupted
10
+ visitor.visit_comment(@comment) unless @comment.empty?
10
11
  visitor.visit_examples_name(@keyword, @name)
11
12
  visitor.visit_outline_table(@outline_table)
12
13
  end
@@ -20,7 +21,11 @@ module Cucumber
20
21
  end
21
22
 
22
23
  def to_sexp
23
- [:examples, @keyword, @name, @outline_table.to_sexp]
24
+ sexp = [:examples, @keyword, @name]
25
+ comment = @comment.to_sexp
26
+ sexp += [comment] if comment
27
+ sexp += [@outline_table.to_sexp]
28
+ sexp
24
29
  end
25
30
  end
26
31
  end
@@ -1,7 +1,7 @@
1
1
  module Cucumber
2
2
  module Ast
3
3
  # Represents the root node of a parsed feature.
4
- class Feature
4
+ class Feature #:nodoc:
5
5
  attr_accessor :file, :language
6
6
  attr_writer :features
7
7
  attr_reader :name
@@ -1,7 +1,7 @@
1
1
  require 'enumerator'
2
2
 
3
3
  module Cucumber
4
- module FeatureElement
4
+ module FeatureElement #:nodoc:
5
5
  attr_writer :feature
6
6
 
7
7
  def attach_steps(steps)
@@ -1,6 +1,6 @@
1
1
  module Cucumber
2
2
  module Ast
3
- class Features
3
+ class Features #:nodoc:
4
4
  include Enumerable
5
5
 
6
6
  attr_reader :duration
@@ -1,6 +1,6 @@
1
1
  module Cucumber
2
2
  module Ast
3
- class OutlineTable < Table
3
+ class OutlineTable < Table #:nodoc:
4
4
  def initialize(raw, scenario_outline)
5
5
  super(raw)
6
6
  @scenario_outline = scenario_outline
@@ -44,7 +44,7 @@ module Cucumber
44
44
  @scenario_outline.visit_scenario_name(visitor, row)
45
45
  end
46
46
 
47
- class ExampleRow < Cells
47
+ class ExampleRow < Cells #:nodoc:
48
48
  attr_reader :scenario_outline # https://rspec.lighthouseapp.com/projects/16211/tickets/342
49
49
 
50
50
  def create_step_invocations!(scenario_outline)
@@ -16,7 +16,7 @@ module Cucumber
16
16
  #
17
17
  # Note how the indentation from the source is stripped away.
18
18
  #
19
- class PyString
19
+ class PyString #:nodoc:
20
20
  def self.default_arg_name
21
21
  "string"
22
22
  end
@@ -2,7 +2,7 @@ require 'cucumber/ast/feature_element'
2
2
 
3
3
  module Cucumber
4
4
  module Ast
5
- class Scenario
5
+ class Scenario #:nodoc:
6
6
  include FeatureElement
7
7
 
8
8
  attr_reader :name, :line
@@ -1,9 +1,9 @@
1
1
  module Cucumber
2
2
  module Ast
3
- class ScenarioOutline
3
+ class ScenarioOutline #:nodoc:
4
4
  include FeatureElement
5
5
 
6
- module ExamplesArray
6
+ module ExamplesArray #:nodoc:
7
7
  def accept(visitor)
8
8
  return if $cucumber_interrupted
9
9
  each do |examples|
@@ -24,13 +24,14 @@ module Cucumber
24
24
  @steps = StepCollection.new(steps)
25
25
 
26
26
  @examples_array = example_sections.map do |example_section|
27
- examples_line = example_section[0]
28
- examples_keyword = example_section[1]
29
- examples_name = example_section[2]
30
- examples_matrix = example_section[3]
27
+ examples_comment = example_section[0]
28
+ examples_line = example_section[1]
29
+ examples_keyword = example_section[2]
30
+ examples_name = example_section[3]
31
+ examples_matrix = example_section[4]
31
32
 
32
33
  examples_table = OutlineTable.new(examples_matrix, self)
33
- Examples.new(examples_line, examples_keyword, examples_name, examples_table)
34
+ Examples.new(examples_comment, examples_line, examples_keyword, examples_name, examples_table)
34
35
  end
35
36
  @examples_array.extend(ExamplesArray)
36
37
 
@@ -3,7 +3,7 @@ require 'cucumber/step_match'
3
3
 
4
4
  module Cucumber
5
5
  module Ast
6
- class Step
6
+ class Step #:nodoc:
7
7
  attr_reader :line, :keyword, :name, :multiline_arg
8
8
  attr_writer :step_collection, :options
9
9
  attr_accessor :feature_element, :exception
@@ -1,7 +1,7 @@
1
1
  module Cucumber
2
2
  module Ast
3
3
  # Holds an Array of Step or StepDefinition
4
- class StepCollection
4
+ class StepCollection #:nodoc:
5
5
  include Enumerable
6
6
 
7
7
  def initialize(steps)
@@ -2,7 +2,7 @@ require 'cucumber/step_match'
2
2
 
3
3
  module Cucumber
4
4
  module Ast
5
- class StepInvocation
5
+ class StepInvocation #:nodoc:
6
6
  attr_writer :step_collection, :background
7
7
  attr_reader :name, :matched_cells, :status, :reported_exception
8
8
  attr_accessor :exception
@@ -1,11 +1,23 @@
1
1
  module Cucumber
2
2
  module Ast
3
- # Holds the data of a table parsed from a feature file:
3
+ # Step Definitions that match a plain text Step with a multiline argument table
4
+ # will receive it as an instance of Table. A Table object holds the data of a
5
+ # table parsed from a feature file and lets you access and manipulate the data
6
+ # in different ways.
4
7
  #
5
- # | a | b |
6
- # | c | d |
8
+ # For example:
7
9
  #
8
- # This gets parsed into a Table holding the values <tt>[['a', 'b'], ['c', 'd']]</tt>
10
+ # Given I have:
11
+ # | a | b |
12
+ # | c | d |
13
+ #
14
+ # And a matching StepDefinition:
15
+ #
16
+ # Given /I have:/ do |table|
17
+ # data = table.raw
18
+ # end
19
+ #
20
+ # This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
9
21
  #
10
22
  class Table
11
23
  include Enumerable
@@ -14,10 +26,14 @@ module Cucumber
14
26
 
15
27
  attr_accessor :file
16
28
 
17
- def self.default_arg_name
29
+ def self.default_arg_name #:nodoc:
18
30
  "table"
19
31
  end
20
32
 
33
+ # Creates a new instance. +raw+ should be an Array of Array of String.
34
+ # You don't typically create your own Table objects - Cucumber will do
35
+ # it internally and pass them to your Step Definitions.
36
+ #
21
37
  def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
22
38
  @cells_class = Cells
23
39
  @cell_class = Cell
@@ -28,21 +44,23 @@ module Cucumber
28
44
  @conversion_procs = conversion_procs
29
45
  end
30
46
 
31
- # Creates a copy of this table, inheriting the column mappings.
47
+ # Creates a copy of this table, inheriting any column mappings.
48
+ # registered with #map_headers!
49
+ #
32
50
  def dup
33
51
  self.class.new(raw.dup, @conversion_procs.dup)
34
52
  end
35
53
 
36
54
  # Returns a new, transposed table. Example:
37
55
  #
38
- # | a | 7 | 4 |
39
- # | b | 9 | 2 |
56
+ # | a | 7 | 4 |
57
+ # | b | 9 | 2 |
40
58
  #
41
59
  # Gets converted into the following:
42
60
  #
43
- # | a | b |
44
- # | 7 | 9 |
45
- # | 4 | 2 |
61
+ # | a | b |
62
+ # | 7 | 9 |
63
+ # | 4 | 2 |
46
64
  #
47
65
  def transpose
48
66
  self.class.new(raw.transpose, @conversion_procs.dup)
@@ -109,11 +127,11 @@ module Cucumber
109
127
  raw[1..-1]
110
128
  end
111
129
 
112
- def each_cells_row(&proc)
130
+ def each_cells_row(&proc) #:nodoc:
113
131
  cells_rows.each(&proc)
114
132
  end
115
133
 
116
- def accept(visitor)
134
+ def accept(visitor) #:nodoc:
117
135
  return if $cucumber_interrupted
118
136
  cells_rows.each do |row|
119
137
  visitor.visit_table_row(row)
@@ -149,8 +167,10 @@ module Cucumber
149
167
  def map_headers!(mappings)
150
168
  header_cells = cell_matrix[0]
151
169
  mappings.each_pair do |pre, post|
152
- header_cell = header_cells.detect{|cell| pre === cell.value}
153
- header_cell.value = post
170
+ mapped_cells = header_cells.select{|cell| pre === cell.value}
171
+ raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
172
+ raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map{|c| c.value}.inspect}" if mapped_cells.length > 1
173
+ mapped_cells[0].value = post
154
174
  if @conversion_procs.has_key?(pre)
155
175
  @conversion_procs[post] = @conversion_procs.delete(pre)
156
176
  end
@@ -204,10 +224,10 @@ module Cucumber
204
224
  # Whether to raise or not raise can be changed by setting values in
205
225
  # +options+ to true or false:
206
226
  #
207
- # * <tt>missing_row</tt>: Raise on missing rows (defaults to true)
208
- # * <tt>surplus_row</tt>: Raise on surplus rows (defaults to true)
209
- # * <tt>missing_col</tt>: Raise on missing columns (defaults to true)
210
- # * <tt>surplus_col</tt>: Raise on surplus columns (defaults to false)
227
+ # * <tt>missing_row</tt> : Raise on missing rows (defaults to true)
228
+ # * <tt>surplus_row</tt> : Raise on surplus rows (defaults to true)
229
+ # * <tt>missing_col</tt> : Raise on missing columns (defaults to true)
230
+ # * <tt>surplus_col</tt> : Raise on surplus columns (defaults to false)
211
231
  #
212
232
  # The +other_table+ argument can be another Table, an Array of Array or
213
233
  # an Array of Hash (similar to the structure returned by #hashes).
@@ -296,11 +316,11 @@ module Cucumber
296
316
  cells_rows.index(cells)
297
317
  end
298
318
 
299
- def verify_column(column_name)
319
+ def verify_column(column_name) #:nodoc:
300
320
  raise %{The column named "#{column_name}" does not exist} unless raw[0].include?(column_name)
301
321
  end
302
322
 
303
- def verify_table_width(width)
323
+ def verify_table_width(width) #:nodoc:
304
324
  raise %{The table must have exactly #{width} columns} unless raw[0].size == width
305
325
  end
306
326
 
@@ -319,33 +339,33 @@ module Cucumber
319
339
  Table.new(raw_with_replaced_args)
320
340
  end
321
341
 
322
- def has_text?(text)
342
+ def has_text?(text) #:nodoc:
323
343
  raw.flatten.compact.detect{|cell_value| cell_value.index(text)}
324
344
  end
325
345
 
326
- def cells_rows
346
+ def cells_rows #:nodoc:
327
347
  @rows ||= cell_matrix.map do |cell_row|
328
348
  @cells_class.new(self, cell_row)
329
349
  end
330
350
  end
331
351
 
332
- def headers
352
+ def headers #:nodoc:
333
353
  raw.first
334
354
  end
335
355
 
336
- def header_cell(col)
356
+ def header_cell(col) #:nodoc:
337
357
  cells_rows[0][col]
338
358
  end
339
359
 
340
- def cell_matrix
360
+ def cell_matrix #:nodoc:
341
361
  @cell_matrix
342
362
  end
343
363
 
344
- def col_width(col)
364
+ def col_width(col) #:nodoc:
345
365
  columns[col].__send__(:width)
346
366
  end
347
367
 
348
- def to_s(options = {})
368
+ def to_s(options = {}) #:nodoc:
349
369
  options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
350
370
  io = StringIO.new
351
371
 
@@ -369,7 +389,7 @@ module Cucumber
369
389
 
370
390
  protected
371
391
 
372
- def inspect_rows(missing_row, inserted_row)
392
+ def inspect_rows(missing_row, inserted_row) #:nodoc:
373
393
  missing_row.each_with_index do |missing_cell, col|
374
394
  inserted_cell = inserted_row[col]
375
395
  if(missing_cell.value != inserted_cell.value && (missing_cell.value.to_s == inserted_cell.value.to_s))
@@ -379,7 +399,7 @@ module Cucumber
379
399
  end
380
400
  end
381
401
 
382
- def create_cell_matrix(raw)
402
+ def create_cell_matrix(raw) #:nodoc:
383
403
  @cell_matrix = raw.map do |raw_row|
384
404
  line = raw_row.line rescue -1
385
405
  raw_row.map do |raw_cell|
@@ -388,7 +408,7 @@ module Cucumber
388
408
  end
389
409
  end
390
410
 
391
- def convert_columns!
411
+ def convert_columns! #:nodoc:
392
412
  cell_matrix.transpose.each do |col|
393
413
  conversion_proc = @conversion_procs[col[0].value]
394
414
  col[1..-1].each do |cell|
@@ -397,7 +417,7 @@ module Cucumber
397
417
  end
398
418
  end
399
419
 
400
- def require_diff_lcs
420
+ def require_diff_lcs #:nodoc:
401
421
  begin
402
422
  require 'diff/lcs'
403
423
  rescue LoadError => e
@@ -406,23 +426,23 @@ module Cucumber
406
426
  end
407
427
  end
408
428
 
409
- def clear_cache!
429
+ def clear_cache! #:nodoc:
410
430
  @hashes = @rows_hash = @rows = @columns = nil
411
431
  end
412
432
 
413
- def columns
433
+ def columns #:nodoc:
414
434
  @columns ||= cell_matrix.transpose.map do |cell_row|
415
435
  @cells_class.new(self, cell_row)
416
436
  end.freeze
417
437
  end
418
438
 
419
- def new_cell(raw_cell, line)
439
+ def new_cell(raw_cell, line) #:nodoc:
420
440
  @cell_class.new(raw_cell, self, line)
421
441
  end
422
442
 
423
443
  # Pads our own cell_matrix and returns a cell matrix of same
424
444
  # column width that can be used for diffing
425
- def pad!(other_cell_matrix)
445
+ def pad!(other_cell_matrix) #:nodoc:
426
446
  clear_cache!
427
447
  cols = cell_matrix.transpose
428
448
  unmapped_cols = other_cell_matrix.transpose
@@ -460,38 +480,38 @@ module Cucumber
460
480
  (mapped_cols + unmapped_cols).transpose
461
481
  end
462
482
 
463
- def ensure_table(table_or_array)
483
+ def ensure_table(table_or_array) #:nodoc:
464
484
  return table_or_array if Table === table_or_array
465
485
  table_or_array = hashes_to_array(table_or_array) if Hash === table_or_array[0]
466
486
  table_or_array = enumerable_to_array(table_or_array) unless Array == table_or_array[0]
467
487
  Table.new(table_or_array)
468
488
  end
469
489
 
470
- def hashes_to_array(hashes)
490
+ def hashes_to_array(hashes) #:nodoc:
471
491
  header = hashes[0].keys
472
492
  [header] + hashes.map{|hash| header.map{|key| hash[key]}}
473
493
  end
474
494
 
475
- def enumerable_to_array(rows)
495
+ def enumerable_to_array(rows) #:nodoc:
476
496
  rows.map{|row| row.map{|cell| cell}}
477
497
  end
478
498
 
479
- def ensure_green!
499
+ def ensure_green! #:nodoc:
480
500
  each_cell{|cell| cell.status = :passed}
481
501
  end
482
502
 
483
- def each_cell(&proc)
503
+ def each_cell(&proc) #:nodoc:
484
504
  cell_matrix.each{|row| row.each(&proc)}
485
505
  end
486
506
 
487
- def mark_as_missing(col)
507
+ def mark_as_missing(col) #:nodoc:
488
508
  col.each do |cell|
489
509
  cell.status = :undefined
490
510
  end
491
511
  end
492
512
 
493
513
  # Represents a row of cells or columns of cells
494
- class Cells
514
+ class Cells #:nodoc:
495
515
  include Enumerable
496
516
  attr_reader :exception
497
517
 
@@ -547,7 +567,7 @@ module Cucumber
547
567
  end
548
568
  end
549
569
 
550
- class Cell
570
+ class Cell #:nodoc:
551
571
  attr_reader :line, :table
552
572
  attr_accessor :status, :value
553
573
 
@@ -574,7 +594,7 @@ module Cucumber
574
594
  end
575
595
  end
576
596
 
577
- class SurplusCell < Cell
597
+ class SurplusCell < Cell #:nodoc:
578
598
  def status
579
599
  :comment
580
600
  end