cucumber 0.3.104 → 0.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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