cucumber 0.3.104 → 0.4.0.rc1

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 (81) hide show
  1. data/History.txt +50 -3
  2. data/Manifest.txt +20 -2
  3. data/Rakefile +4 -0
  4. data/config/hoe.rb +20 -14
  5. data/examples/i18n/tr/Rakefile +6 -0
  6. data/examples/i18n/tr/features/bo/314/210lme.feature +10 -0
  7. data/examples/i18n/tr/features/step_definitons/hesap_makinesi_ad/304/261mlar/304/261.rb +24 -0
  8. data/examples/i18n/tr/features/toplama.feature +18 -0
  9. data/examples/i18n/tr/lib/hesap_makinesi.rb +15 -0
  10. data/examples/python/features/step_definitions/fib_steps.py +9 -1
  11. data/examples/ruby2python/features/fibonacci.feature +19 -0
  12. data/examples/{python → ruby2python}/features/step_definitions/fib_steps.rb +0 -0
  13. data/examples/ruby2python/features/support/env.rb +21 -0
  14. data/examples/ruby2python/lib/fib.py +7 -0
  15. data/features/bug_475.feature +43 -0
  16. data/features/exception_in_before_block.feature +34 -1
  17. data/features/html_formatter.feature +1 -1
  18. data/features/language_help.feature +68 -0
  19. data/features/rake_task.feature +34 -60
  20. data/features/simplest.feature +11 -0
  21. data/features/step_definitions/simplest_steps.rb +6 -0
  22. data/features/support/env.rb +1 -1
  23. data/features/support/env.rb.simplest +7 -0
  24. data/features/table_diffing.feature +1 -1
  25. data/features/table_mapping.feature +35 -0
  26. data/features/transform.feature +133 -2
  27. data/features/usage_and_stepdefs_formatter.feature +4 -2
  28. data/gem_tasks/contributors.rake +2 -1
  29. data/lib/cucumber/ast/background.rb +17 -5
  30. data/lib/cucumber/ast/outline_table.rb +8 -1
  31. data/lib/cucumber/ast/scenario.rb +2 -1
  32. data/lib/cucumber/ast/step.rb +6 -1
  33. data/lib/cucumber/ast/step_invocation.rb +14 -1
  34. data/lib/cucumber/ast/table.rb +30 -6
  35. data/lib/cucumber/cli/configuration.rb +1 -1
  36. data/lib/cucumber/cli/language_help_formatter.rb +27 -14
  37. data/lib/cucumber/cli/options.rb +2 -1
  38. data/lib/cucumber/cli/profile_loader.rb +12 -4
  39. data/lib/cucumber/core_ext/instance_exec.rb +29 -25
  40. data/lib/cucumber/formatter/junit.rb +50 -45
  41. data/lib/cucumber/formatter/pdf.rb +16 -4
  42. data/lib/cucumber/formatter/usage.rb +2 -14
  43. data/lib/cucumber/language_support/language_methods.rb +23 -3
  44. data/lib/cucumber/languages.yml +14 -0
  45. data/lib/cucumber/parser/natural_language.rb +1 -1
  46. data/lib/cucumber/parser/table.rb +10 -7
  47. data/lib/cucumber/parser/table.tt +1 -1
  48. data/lib/cucumber/platform.rb +1 -0
  49. data/lib/cucumber/py_support/py_dsl.py +10 -8
  50. data/lib/cucumber/py_support/py_language.py +8 -0
  51. data/lib/cucumber/py_support/py_language.rb +24 -11
  52. data/lib/cucumber/rails/action_controller.rb +6 -1
  53. data/lib/cucumber/rails/active_record.rb +5 -4
  54. data/lib/cucumber/rake/task.rb +7 -82
  55. data/lib/cucumber/rb_support/rb_language.rb +0 -4
  56. data/lib/cucumber/rb_support/rb_step_definition.rb +4 -6
  57. data/lib/cucumber/rb_support/rb_transform.rb +9 -7
  58. data/lib/cucumber/step_definition_light.rb +20 -0
  59. data/lib/cucumber/step_match.rb +1 -1
  60. data/lib/cucumber/step_mother.rb +5 -1
  61. data/lib/cucumber/version.rb +3 -3
  62. data/lib/cucumber/webrat/element_locator.rb +2 -0
  63. data/rails_generators/cucumber/cucumber_generator.rb +8 -9
  64. data/rails_generators/cucumber/templates/cucumber +14 -6
  65. data/rails_generators/cucumber/templates/cucumber.rake +9 -1
  66. data/rails_generators/cucumber/templates/cucumber_environment.rb +5 -1
  67. data/rails_generators/cucumber/templates/env.rb +29 -14
  68. data/rails_generators/cucumber/templates/paths.rb +1 -1
  69. data/rails_generators/cucumber/templates/spork_env.rb +39 -17
  70. data/rails_generators/cucumber/templates/version_check.rb +29 -0
  71. data/rails_generators/cucumber/templates/webrat_steps.rb +5 -0
  72. data/spec/cucumber/ast/outline_table_spec.rb +21 -0
  73. data/spec/cucumber/ast/table_spec.rb +18 -0
  74. data/spec/cucumber/formatter/html_spec.rb +33 -69
  75. data/spec/cucumber/formatter/junit_spec.rb +73 -0
  76. data/spec/cucumber/formatter/spec_helper.rb +50 -0
  77. data/spec/cucumber/parser/table_parser_spec.rb +2 -2
  78. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +10 -1
  79. data/spec/cucumber/step_mother_spec.rb +6 -0
  80. metadata +32 -8
  81. data/examples/python/features/support/env.rb +0 -21
@@ -28,9 +28,7 @@ module Cucumber
28
28
  @testsuite << @builder.target!
29
29
  end
30
30
 
31
- basename = File.basename(feature.file)[0...-File.extname(feature.file).length]
32
- feature_filename = File.join(@reportdir, "TEST-#{basename}.xml")
33
- File.open(feature_filename, 'w') { |file| file.write(@testsuite.target!) }
31
+ write_file(feature_result_filename(feature.file), @testsuite.target!)
34
32
  end
35
33
 
36
34
  def before_background(*args)
@@ -59,69 +57,76 @@ module Cucumber
59
57
  end
60
58
 
61
59
  def after_steps(steps)
62
- return if @in_background
60
+ return if @in_background || @outline
61
+
63
62
  duration = Time.now - @steps_start
64
- unless @outline
65
- if steps.failed?
66
- steps.each { |step| @output += "#{step.keyword} #{step.name}\n" }
67
- @output += "\nMessage:\n"
68
- end
69
- build_testcase(duration, steps.status, steps.exception)
63
+ if steps.failed?
64
+ steps.each { |step| @output += "#{step.keyword} #{step.name}\n" }
65
+ @output += "\nMessage:\n"
70
66
  end
67
+ build_testcase(duration, steps.status, steps.exception)
71
68
  end
72
-
73
- def before_outline_table(outline_table)
69
+
70
+ def before_examples(*args)
74
71
  @header_row = true
75
72
  end
76
73
 
77
74
  def before_table_row(table_row)
78
- if @outline
79
- @table_start = Time.now
80
- end
81
-
82
- @header_row = false
75
+ return unless @outline
76
+
77
+ @table_start = Time.now
83
78
  end
84
79
 
85
80
  def after_table_row(table_row)
86
- if @outline
87
- duration = Time.now - @table_start
88
- unless @header_row
89
- name_suffix = " (outline example : #{table_row.name})"
90
- if table_row.failed?
91
- @output += "Example row: #{table_row.name}\n"
92
- @output += "\nMessage:\n"
93
- end
94
- build_testcase(duration, table_row.status, table_row.exception, name_suffix)
81
+ return unless @outline
82
+ duration = Time.now - @table_start
83
+ unless @header_row
84
+ name_suffix = " (outline example : #{table_row.name})"
85
+ if table_row.failed?
86
+ @output += "Example row: #{table_row.name}\n"
87
+ @output += "\nMessage:\n"
95
88
  end
89
+ build_testcase(duration, table_row.status, table_row.exception, name_suffix)
96
90
  end
97
- @header_row = false
91
+
92
+ @header_row = false if @header_row
98
93
  end
99
94
 
100
95
  private
101
96
 
102
- def build_testcase(duration, status, exception = nil, suffix = "")
103
- @time += duration
104
- classname = "#{@feature_name}.#{@scenario}"
105
- name = "#{@scenario}#{suffix}"
106
- failed = (status == :failed || (status == :pending && @options[:strict]))
107
- #puts "FAILED:!!#{failed}"
108
- if status == :passed || failed
109
- @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
110
- if failed
111
- @builder.failure(:message => "#{status.to_s} #{name}", :type => status.to_s) do
112
- @builder.text! @output
113
- @builder.text!(format_exception(exception)) if exception
114
- end
115
- @failures += 1
97
+ def build_testcase(duration, status, exception = nil, suffix = "")
98
+ @time += duration
99
+ classname = "#{@feature_name}.#{@scenario}"
100
+ name = "#{@scenario}#{suffix}"
101
+ failed = (status == :failed || (status == :pending && @options[:strict]))
102
+ #puts "FAILED:!!#{failed}"
103
+ if status == :passed || failed
104
+ @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
105
+ if failed
106
+ @builder.failure(:message => "#{status.to_s} #{name}", :type => status.to_s) do
107
+ @builder.text! @output
108
+ @builder.text!(format_exception(exception)) if exception
116
109
  end
110
+ @failures += 1
117
111
  end
118
- @tests += 1
119
112
  end
113
+ @tests += 1
120
114
  end
115
+ end
121
116
 
122
- def format_exception(exception)
123
- (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
124
- end
117
+ def format_exception(exception)
118
+ (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
119
+ end
120
+
121
+ def feature_result_filename(feature_file)
122
+ ext_length = File.extname(feature_file).length
123
+ basename = File.basename(feature_file)[0...-ext_length]
124
+ File.join(@reportdir, "TEST-#{basename}.xml")
125
+ end
126
+
127
+ def write_file(feature_filename, data)
128
+ File.open(feature_filename, 'w') { |file| file.write(data) }
129
+ end
125
130
  end
126
131
  end
127
132
  end
@@ -34,10 +34,7 @@ module Cucumber
34
34
  @indent = 0
35
35
  @buffer = []
36
36
  puts "writing to #{io.path}"
37
- begin
38
- @pdf.image open("features/support/logo.png"), :position => :center, :width => 500
39
- rescue
40
- end
37
+ load_cover_page_image
41
38
  @pdf.text "\n\n\nCucumber features", :align => :center, :size => 32
42
39
  @pdf.text "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M")}", :size => 10, :at => [0, 24]
43
40
  @pdf.text "Command: <code>cucumber #{ARGV.join(" ")}</code>", :size => 10, :at => [0,10]
@@ -53,6 +50,21 @@ module Cucumber
53
50
  end
54
51
  end
55
52
 
53
+ def load_cover_page_image()
54
+ if (!load_image("features/support/logo.png"))
55
+ load_image("features/support/logo.jpg")
56
+ end
57
+ end
58
+
59
+ def load_image(image_path)
60
+ begin
61
+ @pdf.image open(image_path, "rb"), :position => :center, :width => 500
62
+ true
63
+ rescue Errno::ENOENT
64
+ false
65
+ end
66
+ end
67
+
56
68
  def after_features(features)
57
69
  @pdf.render_file(@io.path)
58
70
  puts "\ndone"
@@ -1,25 +1,13 @@
1
1
  require 'cucumber/formatter/progress'
2
+ require 'cucumber/step_definition_light'
2
3
 
3
4
  module Cucumber
4
5
  module Formatter
5
6
  class Usage < Progress
6
7
  include Console
7
8
 
8
- class StepDefKey
9
- attr_reader :regexp_source, :file_colon_line
9
+ class StepDefKey < StepDefinitionLight
10
10
  attr_accessor :mean_duration, :status
11
-
12
- def initialize(regexp_source, file_colon_line)
13
- @regexp_source, @file_colon_line = regexp_source, file_colon_line
14
- end
15
-
16
- def eql?(o)
17
- regexp_source == o.regexp_source && file_colon_line == o.file_colon_line
18
- end
19
-
20
- def hash
21
- regexp_source.hash + 17*file_colon_line.hash
22
- end
23
11
  end
24
12
 
25
13
  def initialize(step_mother, io, options)
@@ -1,4 +1,5 @@
1
1
  require 'cucumber/step_match'
2
+ require 'cucumber/step_definition_light'
2
3
 
3
4
  module Cucumber
4
5
  module LanguageSupport
@@ -30,10 +31,9 @@ module Cucumber
30
31
  end
31
32
 
32
33
  def execute_transforms(args)
33
- transformed = nil
34
34
  args.map do |arg|
35
- transforms.detect {|t| transformed = t.invoke arg }
36
- transformed || arg
35
+ matching_transform = transforms.detect {|transform| transform.match(arg) }
36
+ matching_transform ? matching_transform.invoke(arg) : arg
37
37
  end
38
38
  end
39
39
 
@@ -51,8 +51,28 @@ module Cucumber
51
51
  hooks[phase.to_sym].select{|hook| scenario.accept_hook?(hook)}
52
52
  end
53
53
 
54
+ def unmatched_step_definitions
55
+ available_step_definition_hash.keys - invoked_step_definition_hash.keys
56
+ end
57
+
58
+ def available_step_definition(regexp_source, file_colon_line)
59
+ available_step_definition_hash[StepDefinitionLight.new(regexp_source, file_colon_line)] = nil
60
+ end
61
+
62
+ def invoked_step_definition(regexp_source, file_colon_line)
63
+ invoked_step_definition_hash[StepDefinitionLight.new(regexp_source, file_colon_line)] = nil
64
+ end
65
+
54
66
  private
55
67
 
68
+ def available_step_definition_hash
69
+ @available_step_definition_hash ||= {}
70
+ end
71
+
72
+ def invoked_step_definition_hash
73
+ @invoked_step_definition_hash ||= {}
74
+ end
75
+
56
76
  def hooks
57
77
  @hooks ||= Hash.new{|h,k| h[k] = []}
58
78
  end
@@ -500,6 +500,20 @@
500
500
  and: A
501
501
  but: Ale
502
502
  space_after_keyword: true
503
+ "tr":
504
+ name: Turkish
505
+ native: Türkçe
506
+ encoding: UTF-8
507
+ feature: Özellik
508
+ background: Geçmiş
509
+ scenario: Senaryo
510
+ scenario_outline: Senaryo taslağı
511
+ examples: Örnekler
512
+ given: Diyelim ki
513
+ when: Eğer ki
514
+ then: O zaman
515
+ and: Ve
516
+ but: Fakat|Ama
503
517
  "uz":
504
518
  name: Uzbek
505
519
  native: Узбекча
@@ -48,7 +48,7 @@ module Cucumber
48
48
  def keywords(key, raw=false)
49
49
  return @keywords[key] if raw
50
50
  return nil unless @keywords[key]
51
- values = @keywords[key].split('|')
51
+ values = @keywords[key].to_s.split('|')
52
52
  values.map{|value| "'#{value}'"}.join(" / ")
53
53
  end
54
54
 
@@ -86,7 +86,7 @@ module Cucumber
86
86
  def build
87
87
  row = cells.elements.map do |elt|
88
88
  value = elt.cell.text_value.strip
89
- value.empty? ? nil : value
89
+ value
90
90
  end
91
91
 
92
92
  class << row
@@ -265,8 +265,9 @@ module Cucumber
265
265
  s1 << r2
266
266
  if r2
267
267
  if index < input_length
268
- r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
269
- @index += 1
268
+ next_character = index + input[index..-1].match(/\A(.)/um).end(1)
269
+ r6 = instantiate_node(SyntaxNode,input, index...next_character)
270
+ @index = next_character
270
271
  else
271
272
  terminal_parse_failure("any character")
272
273
  r6 = nil
@@ -302,8 +303,9 @@ module Cucumber
302
303
  end
303
304
 
304
305
  if has_terminal?('\G[ \\t]', true, index)
305
- r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
306
- @index += 1
306
+ next_character = index + input[index..-1].match(/\A(.)/um).end(1)
307
+ r0 = instantiate_node(SyntaxNode, input, index...next_character)
308
+ @index = next_character
307
309
  else
308
310
  r0 = nil
309
311
  end
@@ -389,8 +391,9 @@ module Cucumber
389
391
 
390
392
  i0 = index
391
393
  if index < input_length
392
- r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
393
- @index += 1
394
+ next_character = index + input[index..-1].match(/\A(.)/um).end(1)
395
+ r1 = instantiate_node(SyntaxNode,input, index...next_character)
396
+ @index = next_character
394
397
  else
395
398
  terminal_parse_failure("any character")
396
399
  r1 = nil
@@ -37,7 +37,7 @@ module Cucumber
37
37
  def build
38
38
  row = cells.elements.map do |elt|
39
39
  value = elt.cell.text_value.strip
40
- value.empty? ? nil : value
40
+ value
41
41
  end
42
42
 
43
43
  class << row
@@ -15,6 +15,7 @@ module Cucumber
15
15
  RAILS = defined?(Rails)
16
16
  RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
17
17
  RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
18
+ RUBY_1_8_7 = RUBY_VERSION =~ /^1\.8\.7/
18
19
 
19
20
  class << self
20
21
  attr_accessor :use_full_backtrace
@@ -1,8 +1,10 @@
1
- def Given(s):
2
- register_rb_step_definition(s)
3
-
4
- def register_rb_step_definition(s):
5
- print "REGGED"
6
-
7
- def set_py_language(py_language):
8
- print "YAY"
1
+ import py_language
2
+
3
+ class Given(object):
4
+ def __init__(self, regexp):
5
+ self.regexp = regexp
6
+
7
+ def __call__(self, f):
8
+ py_language.register_step_def(self.regexp, f)
9
+ return f
10
+
@@ -1,2 +1,10 @@
1
1
  import py_dsl
2
2
 
3
+ step_defs = {}
4
+
5
+ def register_step_def(regexp, f):
6
+ print "Got a step def: ", regexp
7
+ step_defs[regexp] = f
8
+
9
+ def step_matches(step_name, formatted_step_name):
10
+ print "WTF: " + step_name
@@ -3,16 +3,22 @@ require 'rubypython'
3
3
  module Cucumber
4
4
  module PySupport
5
5
  class PyLanguage
6
- # include LanguageSupport::LanguageMethods
6
+ include LanguageSupport::LanguageMethods
7
7
 
8
8
  def initialize(step_mother)
9
- @python_path = ENV['PYTHONPATH'] ? ENV['PYTHONPATH'].split(':') : []
10
- add_to_python_path(File.dirname(__FILE__))
11
-
12
- RubyPython.start
13
- at_exit{RubyPython.stop}
9
+ @step_def_files = []
10
+ #
11
+ # @python_path = ENV['PYTHONPATH'] ? ENV['PYTHONPATH'].split(':') : []
12
+ # add_to_python_path(File.dirname(__FILE__))
13
+ #
14
+ # RubyPython.start
15
+ # at_exit{RubyPython.stop}
16
+ #
17
+ # import(File.dirname(__FILE__) + '/py_language.py')
18
+ end
14
19
 
15
- import(File.dirname(__FILE__) + '/py_language.py')
20
+ def load_code_file(py_file)
21
+ @step_def_files << py_file
16
22
  end
17
23
 
18
24
  def alias_adverbs(adverbs)
@@ -26,12 +32,19 @@ module Cucumber
26
32
  "python snippet: #{step_keyword}, #{step_name}"
27
33
  end
28
34
 
29
- protected
30
-
31
35
  def begin_scenario
36
+ @python_path = []
37
+ add_to_python_path(File.dirname(__FILE__))
38
+ @step_def_files.each{|f| add_to_python_path(File.dirname(f))}
39
+
40
+ RubyPython.start
41
+
42
+ @delegate = import(File.dirname(__FILE__) + '/py_language.py')
43
+ @step_def_files.each{|f| import(f)}
32
44
  end
33
45
 
34
- def end_scenario
46
+ def step_matches(step_name, formatted_step_name)
47
+ @delegate.step_matches(step_name, formatted_step_name)
35
48
  end
36
49
 
37
50
  private
@@ -41,7 +54,7 @@ module Cucumber
41
54
  begin
42
55
  mod = RubyPython.import(modname)
43
56
  rescue PythonError => e
44
- e.message << "Couldn't load #{path}\nConsider adding #{File.expand_path(File.dirname(path))} to your PYTHONPATH"
57
+ # e.message << "Couldn't load #{path}\nConsider adding #{File.expand_path(File.dirname(path))} to your PYTHONPATH"
45
58
  raise e
46
59
  end
47
60
  end
@@ -29,5 +29,10 @@ rescue NameError # Failsafe was introduced in Rails 2.3.2
29
29
  end
30
30
 
31
31
  Before('@allow-rescue') do
32
+ @__orig_allow_rescue = ActionController::Base.allow_rescue
32
33
  ActionController::Base.allow_rescue = true
33
- end
34
+ end
35
+
36
+ After('@allow-rescue') do
37
+ ActionController::Base.allow_rescue = @__orig_allow_rescue
38
+ end
@@ -1,11 +1,13 @@
1
1
  if defined?(ActiveRecord::Base)
2
+ Before do
3
+ $__cucumber_global_use_txn = !!Cucumber::Rails::World.use_transactional_fixtures if $__cucumber_global_use_txn.nil?
4
+ end
5
+
2
6
  Before('~@no-txn') do
3
- @__cucumber_use_txn = Cucumber::Rails::World.use_transactional_fixtures
4
- Cucumber::Rails::World.use_transactional_fixtures = true
7
+ Cucumber::Rails::World.use_transactional_fixtures = $__cucumber_global_use_txn
5
8
  end
6
9
 
7
10
  Before('@no-txn') do
8
- @__cucumber_use_txn = Cucumber::Rails::World.use_transactional_fixtures
9
11
  Cucumber::Rails::World.use_transactional_fixtures = false
10
12
  end
11
13
 
@@ -31,7 +33,6 @@ if defined?(ActiveRecord::Base)
31
33
  ActiveRecord::Base.__send__(:decrement_open_transactions)
32
34
  end
33
35
  end
34
- Cucumber::Rails::World.use_transactional_fixtures = @__cucumber_use_txn
35
36
  end
36
37
  else
37
38
  module Cucumber::Rails