casecumber 1.0.2.1 → 1.2.1.cb2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/.rvmrc +1 -1
  2. data/.travis.yml +13 -6
  3. data/Gemfile +2 -0
  4. data/History.md +139 -0
  5. data/LICENSE +1 -1
  6. data/README.md +19 -4
  7. data/cucumber.gemspec +16 -29
  8. data/cucumber.yml +3 -3
  9. data/examples/i18n/README.textile +1 -16
  10. data/features/.cucumber/stepdefs.json +612 -0
  11. data/features/backtraces.feature +36 -0
  12. data/features/doc_strings.feature +73 -0
  13. data/features/drb_server_integration.feature +63 -0
  14. data/features/formatter_step_file_colon_line.feature +46 -0
  15. data/features/json_formatter.feature +137 -137
  16. data/features/nested_steps.feature +60 -0
  17. data/features/rerun_formatter.feature +35 -0
  18. data/features/run_specific_scenarios.feature +47 -0
  19. data/features/step_definitions/cucumber-features/cucumber_ruby_mappings.rb +32 -3
  20. data/features/step_definitions/cucumber_steps.rb +15 -0
  21. data/features/step_definitions/drb_steps.rb +3 -0
  22. data/features/support/env.rb +4 -0
  23. data/features/support/feature_factory.rb +50 -0
  24. data/gem_tasks/cucumber.rake +15 -8
  25. data/gem_tasks/yard.rake +18 -0
  26. data/legacy_features/call_steps_from_stepdefs.feature +1 -1
  27. data/legacy_features/cucumber_cli.feature +0 -7
  28. data/legacy_features/default_snippets.feature +3 -2
  29. data/legacy_features/junit_formatter.feature +60 -10
  30. data/legacy_features/language_help.feature +17 -15
  31. data/legacy_features/snippets_when_using_star_keyword.feature +3 -2
  32. data/legacy_features/step_definitions/cucumber_steps.rb +1 -1
  33. data/legacy_features/support/env.rb +1 -1
  34. data/legacy_features/wire_protocol.feature +1 -1
  35. data/lib/cucumber/ast/background.rb +11 -0
  36. data/lib/cucumber/ast/doc_string.rb +10 -29
  37. data/lib/cucumber/ast/feature.rb +6 -2
  38. data/lib/cucumber/ast/feature_element.rb +7 -3
  39. data/lib/cucumber/ast/multiline_argument.rb +30 -0
  40. data/lib/cucumber/ast/outline_table.rb +20 -12
  41. data/lib/cucumber/ast/step.rb +1 -1
  42. data/lib/cucumber/ast/step_invocation.rb +2 -15
  43. data/lib/cucumber/ast/table.rb +67 -38
  44. data/lib/cucumber/ast/tags.rb +7 -7
  45. data/lib/cucumber/ast/tree_walker.rb +5 -5
  46. data/lib/cucumber/cli/configuration.rb +4 -0
  47. data/lib/cucumber/cli/main.rb +1 -0
  48. data/lib/cucumber/cli/options.rb +29 -10
  49. data/lib/cucumber/constantize.rb +1 -1
  50. data/lib/cucumber/core_ext/disable_mini_and_test_unit_autorun.rb +24 -10
  51. data/lib/cucumber/formatter/ansicolor.rb +8 -13
  52. data/lib/cucumber/formatter/console.rb +3 -2
  53. data/lib/cucumber/formatter/cucumber.css +7 -1
  54. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +6 -2
  55. data/lib/cucumber/formatter/html.rb +14 -8
  56. data/lib/cucumber/formatter/interceptor.rb +62 -0
  57. data/lib/cucumber/formatter/json.rb +0 -12
  58. data/lib/cucumber/formatter/junit.rb +31 -15
  59. data/lib/cucumber/formatter/pretty.rb +3 -3
  60. data/lib/cucumber/formatter/progress.rb +1 -1
  61. data/lib/cucumber/formatter/rerun.rb +31 -8
  62. data/lib/cucumber/formatter/usage.rb +1 -1
  63. data/lib/cucumber/js_support/js_language.rb +1 -1
  64. data/lib/cucumber/js_support/js_snippets.rb +1 -1
  65. data/lib/cucumber/language_support/language_methods.rb +0 -4
  66. data/lib/cucumber/parser/gherkin_builder.rb +13 -14
  67. data/lib/cucumber/platform.rb +1 -1
  68. data/lib/cucumber/py_support/py_language.rb +3 -7
  69. data/lib/cucumber/rb_support/rb_dsl.rb +15 -8
  70. data/lib/cucumber/rb_support/rb_language.rb +3 -17
  71. data/lib/cucumber/rb_support/rb_step_definition.rb +17 -5
  72. data/lib/cucumber/rb_support/rb_transform.rb +5 -2
  73. data/lib/cucumber/rb_support/rb_world.rb +9 -5
  74. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +3 -3
  75. data/lib/cucumber/runtime/results.rb +2 -2
  76. data/lib/cucumber/runtime/support_code.rb +14 -19
  77. data/lib/cucumber/runtime.rb +40 -2
  78. data/lib/cucumber/step_match.rb +3 -4
  79. data/lib/cucumber/term/ansicolor.rb +118 -0
  80. data/lib/cucumber/wire_support/wire_protocol/requests.rb +7 -5
  81. data/lib/cucumber/wire_support/wire_protocol.rb +0 -1
  82. data/lib/cucumber.rb +2 -1
  83. data/spec/cucumber/ast/doc_string_spec.rb +2 -2
  84. data/spec/cucumber/ast/feature_factory.rb +4 -3
  85. data/spec/cucumber/ast/scenario_outline_spec.rb +1 -2
  86. data/spec/cucumber/ast/step_spec.rb +1 -1
  87. data/spec/cucumber/ast/table_spec.rb +61 -27
  88. data/spec/cucumber/cli/configuration_spec.rb +12 -6
  89. data/spec/cucumber/cli/main_spec.rb +2 -2
  90. data/spec/cucumber/cli/options_spec.rb +9 -3
  91. data/spec/cucumber/constantize_spec.rb +16 -0
  92. data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
  93. data/spec/cucumber/formatter/html_spec.rb +4 -3
  94. data/spec/cucumber/formatter/interceptor_spec.rb +111 -0
  95. data/spec/cucumber/formatter/junit_spec.rb +36 -20
  96. data/spec/cucumber/formatter/progress_spec.rb +2 -2
  97. data/spec/cucumber/rb_support/rb_language_spec.rb +5 -5
  98. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +20 -4
  99. data/spec/cucumber/rb_support/rb_transform_spec.rb +6 -2
  100. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +7 -3
  101. data/spec/cucumber/runtime/results_spec.rb +81 -0
  102. data/spec/cucumber/step_match_spec.rb +8 -4
  103. data/spec/spec_helper.rb +15 -1
  104. metadata +68 -128
  105. data/.gitignore +0 -26
  106. data/.gitmodules +0 -3
  107. data/.yardopts +0 -0
  108. data/Gemfile.lock +0 -115
  109. data/examples/i18n/de/.gitignore +0 -1
  110. data/examples/i18n/en/.gitignore +0 -1
  111. data/examples/i18n/eo/.gitignore +0 -1
  112. data/examples/i18n/fi/.gitignore +0 -1
  113. data/examples/i18n/hu/.gitignore +0 -1
  114. data/examples/i18n/id/.gitignore +0 -1
  115. data/examples/i18n/ja/.gitignore +0 -1
  116. data/examples/i18n/ko/.gitignore +0 -1
  117. data/examples/i18n/lt/.gitignore +0 -1
  118. data/examples/i18n/pl/.gitignore +0 -1
  119. data/examples/i18n/sk/.gitignore +0 -1
  120. data/examples/i18n/tr/.gitignore +0 -1
  121. data/examples/i18n/zh-TW/.gitignore +0 -1
  122. data/examples/python/lib/.gitignore +0 -1
  123. data/examples/ruby2python/lib/.gitignore +0 -1
  124. data/examples/watir/.gitignore +0 -2
  125. data/fixtures/self_test/.gitignore +0 -1
  126. data/lib/cucumber/formatter/pdf.rb +0 -244
  127. data/lib/cucumber/step_argument.rb +0 -9
@@ -33,9 +33,13 @@ module Cucumber
33
33
  def accept_hook?(hook)
34
34
  @scenario_outline.accept_hook?(hook)
35
35
  end
36
-
36
+
37
+ def source_tags
38
+ @scenario_outline.source_tags
39
+ end
40
+
37
41
  def source_tag_names
38
- @scenario_outline.source_tag_names
42
+ source_tags.map { |tag| tag.name }
39
43
  end
40
44
 
41
45
  def skip_invoke!
@@ -52,7 +56,7 @@ module Cucumber
52
56
  cells.create_step_invocations!(scenario_outline)
53
57
  end
54
58
  end
55
-
59
+
56
60
  def example_rows
57
61
  cells_rows[1..-1]
58
62
  end
@@ -65,29 +69,33 @@ module Cucumber
65
69
  @scenario_outline.language
66
70
  end
67
71
 
68
- class ExampleRow < Cells #:nodoc:
72
+ class ExampleRow < Cells #:nodoc:
69
73
  class InvalidForHeaderRowError < NoMethodError
70
74
  def initialize(*args)
71
75
  super 'This is a header row and cannot pass or fail'
72
76
  end
73
77
  end
74
-
78
+
75
79
  attr_reader :scenario_outline # https://rspec.lighthouseapp.com/projects/16211/tickets/342
76
80
 
77
81
  def initialize(table, cells)
78
82
  super
79
83
  @scenario_exception = nil
80
84
  end
81
-
85
+
82
86
  def source_tag_names
83
- @table.source_tag_names
87
+ source_tags.map { |tag| tag.name }
88
+ end
89
+
90
+ def source_tags
91
+ @table.source_tags
84
92
  end
85
93
 
86
94
  def create_step_invocations!(scenario_outline)
87
95
  @scenario_outline = scenario_outline
88
96
  @step_invocations = scenario_outline.step_invocations(self)
89
97
  end
90
-
98
+
91
99
  def skip_invoke!
92
100
  @step_invocations.each do |step_invocation|
93
101
  step_invocation.skip_invoke!
@@ -115,7 +123,7 @@ module Cucumber
115
123
  @cells.each do |cell|
116
124
  visitor.visit_table_cell(cell)
117
125
  end
118
-
126
+
119
127
  visitor.visit_exception(@scenario_exception, :failed) if @scenario_exception
120
128
  end
121
129
  end
@@ -138,15 +146,15 @@ module Cucumber
138
146
  def accept_hook?(hook)
139
147
  @table.accept_hook?(hook)
140
148
  end
141
-
149
+
142
150
  def exception
143
151
  @exception || @scenario_exception
144
152
  end
145
-
153
+
146
154
  def fail!(exception)
147
155
  @scenario_exception = exception
148
156
  end
149
-
157
+
150
158
  # Returns true if one or more steps failed
151
159
  def failed?
152
160
  raise InvalidForHeaderRowError if header?
@@ -50,7 +50,7 @@ module Cucumber
50
50
  end
51
51
 
52
52
  def visit_step_result(visitor, step_match, multiline_arg, status, exception, background)
53
- visitor.visit_step_result(@keyword, step_match, @multiline_arg, status, exception, source_indent, background)
53
+ visitor.visit_step_result(@keyword, step_match, @multiline_arg, status, exception, source_indent, background, file_colon_line)
54
54
  end
55
55
 
56
56
  def first_match(visitor)
@@ -47,7 +47,8 @@ module Cucumber
47
47
  @status,
48
48
  @reported_exception,
49
49
  source_indent,
50
- @background
50
+ @background,
51
+ file_colon_line
51
52
  )
52
53
  end
53
54
 
@@ -93,20 +94,6 @@ module Cucumber
93
94
  end
94
95
 
95
96
  def failed(configuration, e, clear_backtrace)
96
- if Cucumber::JRUBY && e.class.name == 'NativeException'
97
- # JRuby's NativeException ignores #set_backtrace.
98
- # We're fixing it.
99
- e.instance_eval do
100
- def set_backtrace(backtrace)
101
- @backtrace = backtrace
102
- end
103
-
104
- def backtrace
105
- @backtrace
106
- end
107
- end
108
- end
109
-
110
97
  e.set_backtrace([]) if e.backtrace.nil? || clear_backtrace
111
98
  e.backtrace << @step.backtrace_line unless @step.backtrace_line.nil?
112
99
  e = filter_backtrace(e)
@@ -51,7 +51,7 @@ module Cucumber
51
51
  include Enumerable
52
52
  include Gherkin::Rubify
53
53
 
54
- NULL_CONVERSIONS = Hash.new(lambda{ |cell_value| cell_value }).freeze
54
+ NULL_CONVERSIONS = Hash.new({ :strict => false, :proc => lambda{ |cell_value| cell_value } }).freeze
55
55
 
56
56
  attr_accessor :file
57
57
 
@@ -71,7 +71,7 @@ module Cucumber
71
71
  # You don't typically create your own Table objects - Cucumber will do
72
72
  # it internally and pass them to your Step Definitions.
73
73
  #
74
- def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
74
+ def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup, header_mappings = {}, header_conversion_proc = nil)
75
75
  @cells_class = Cells
76
76
  @cell_class = Cell
77
77
  raw = ensure_array_of_array(rubify(raw))
@@ -79,17 +79,19 @@ module Cucumber
79
79
  transposed = raw.transpose
80
80
  create_cell_matrix(raw)
81
81
  @conversion_procs = conversion_procs
82
+ @header_mappings = header_mappings
83
+ @header_conversion_proc = header_conversion_proc
82
84
  end
83
85
 
84
86
  def to_step_definition_arg
85
87
  dup
86
88
  end
87
89
 
88
- # Creates a copy of this table, inheriting any column mappings.
89
- # registered with #map_headers!
90
+ # Creates a copy of this table, inheriting any column and header mappings
91
+ # registered with #map_column! and #map_headers!.
90
92
  #
91
93
  def dup
92
- self.class.new(raw.dup, @conversion_procs.dup)
94
+ self.class.new(raw.dup, @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
93
95
  end
94
96
 
95
97
  # Returns a new, transposed table. Example:
@@ -104,9 +106,9 @@ module Cucumber
104
106
  # | 4 | 2 |
105
107
  #
106
108
  def transpose
107
- self.class.new(raw.transpose, @conversion_procs.dup)
109
+ self.class.new(raw.transpose, @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
108
110
  end
109
-
111
+
110
112
  # Converts this table into an Array of Hash where the keys of each
111
113
  # Hash are the headers in the table. For example, a Table built from
112
114
  # the following plain text:
@@ -122,9 +124,7 @@ module Cucumber
122
124
  # Use #map_column! to specify how values in a column are converted.
123
125
  #
124
126
  def hashes
125
- @hashes ||= cells_rows[1..-1].map do |row|
126
- row.to_hash
127
- end
127
+ @hashes ||= build_hashes
128
128
  end
129
129
 
130
130
  # Converts this table into a Hash where the first column is
@@ -238,22 +238,8 @@ module Cucumber
238
238
  # # => ['phone number', 'ADDRESS']
239
239
  #
240
240
  def map_headers!(mappings={}, &block)
241
- header_cells = cell_matrix[0]
242
-
243
- if block_given?
244
- header_values = header_cells.map { |cell| cell.value } - mappings.keys
245
- mappings = mappings.merge(Hash[*header_values.zip(header_values.map(&block)).flatten])
246
- end
247
-
248
- mappings.each_pair do |pre, post|
249
- mapped_cells = header_cells.select{|cell| pre === cell.value}
250
- raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
251
- raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map{|c| c.value}.inspect}" if mapped_cells.length > 1
252
- mapped_cells[0].value = post
253
- if @conversion_procs.has_key?(pre)
254
- @conversion_procs[post] = @conversion_procs.delete(pre)
255
- end
256
- end
241
+ @header_mappings = mappings
242
+ @header_conversion_proc = block
257
243
  end
258
244
 
259
245
  # Returns a new Table where the headers are redefined. See #map_headers!
@@ -276,8 +262,7 @@ module Cucumber
276
262
  # end
277
263
  #
278
264
  def map_column!(column_name, strict=true, &conversion_proc)
279
- verify_column(column_name.to_s) if strict
280
- @conversion_procs[column_name.to_s] = conversion_proc
265
+ @conversion_procs[column_name.to_s] = { :strict => strict, :proc => conversion_proc }
281
266
  self
282
267
  end
283
268
 
@@ -300,7 +285,8 @@ module Cucumber
300
285
  # #diff!. You can use #map_column! on either of the tables.
301
286
  #
302
287
  # A Different error is raised if there are missing rows or columns, or
303
- # surplus rows. An error is <em>not</em> raised for surplus columns.
288
+ # surplus rows. An error is <em>not</em> raised for surplus columns. An
289
+ # error is <em>not</em> raised for misplaced (out of sequence) columns.
304
290
  # Whether to raise or not raise can be changed by setting values in
305
291
  # +options+ to true or false:
306
292
  #
@@ -308,6 +294,7 @@ module Cucumber
308
294
  # * <tt>surplus_row</tt> : Raise on surplus rows (defaults to true)
309
295
  # * <tt>missing_col</tt> : Raise on missing columns (defaults to true)
310
296
  # * <tt>surplus_col</tt> : Raise on surplus columns (defaults to false)
297
+ # * <tt>misplaced_col</tt> : Raise on misplaced columns (defaults to false)
311
298
  #
312
299
  # The +other_table+ argument can be another Table, an Array of Array or
313
300
  # an Array of Hash (similar to the structure returned by #hashes).
@@ -316,11 +303,21 @@ module Cucumber
316
303
  # a Table argument, if you want to compare that table to some actual values.
317
304
  #
318
305
  def diff!(other_table, options={})
319
- options = {:missing_row => true, :surplus_row => true, :missing_col => true, :surplus_col => false}.merge(options)
306
+ options = {
307
+ :missing_row => true,
308
+ :surplus_row => true,
309
+ :missing_col => true,
310
+ :surplus_col => false,
311
+ :misplaced_col => false
312
+ }.merge(options)
320
313
 
321
314
  other_table = ensure_table(other_table)
315
+ other_table.convert_headers!
322
316
  other_table.convert_columns!
323
317
  ensure_green!
318
+
319
+ convert_headers!
320
+ convert_columns!
324
321
 
325
322
  original_width = cell_matrix[0].length
326
323
  other_table_cell_matrix = pad!(other_table.cell_matrix)
@@ -328,10 +325,10 @@ module Cucumber
328
325
 
329
326
  missing_col = cell_matrix[0].detect{|cell| cell.status == :undefined}
330
327
  surplus_col = padded_width > original_width
328
+ misplaced_col = cell_matrix[0] != other_table.cell_matrix[0]
331
329
 
332
330
  require_diff_lcs
333
331
  cell_matrix.extend(Diff::LCS)
334
- convert_columns!
335
332
  changes = cell_matrix.diff(other_table_cell_matrix).flatten
336
333
 
337
334
  inserted = 0
@@ -377,7 +374,8 @@ module Cucumber
377
374
  missing_row_pos && options[:missing_row] ||
378
375
  insert_row_pos && options[:surplus_row] ||
379
376
  missing_col && options[:missing_col] ||
380
- surplus_col && options[:surplus_col]
377
+ surplus_col && options[:surplus_col] ||
378
+ misplaced_col && options[:misplaced_col]
381
379
  raise Different.new(self) if should_raise
382
380
  end
383
381
 
@@ -386,8 +384,7 @@ module Cucumber
386
384
  hash[key.to_s] if key.is_a?(Symbol)
387
385
  end
388
386
  column_names.each_with_index do |column_name, column_index|
389
- value = @conversion_procs[column_name].call(cells.value(column_index))
390
- hash[column_name] = value
387
+ hash[column_name] = cells.value(column_index)
391
388
  end
392
389
  hash
393
390
  end
@@ -450,13 +447,13 @@ module Cucumber
450
447
  options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
451
448
  io = StringIO.new
452
449
 
453
- c = Term::ANSIColor.coloring?
454
- Term::ANSIColor.coloring = options[:color]
450
+ c = Cucumber::Term::ANSIColor.coloring?
451
+ Cucumber::Term::ANSIColor.coloring = options[:color]
455
452
  formatter = Formatter::Pretty.new(nil, io, options)
456
453
  formatter.instance_variable_set('@indent', options[:indent])
457
454
  TreeWalker.new(nil, [formatter]).visit_multiline_arg(self)
458
455
 
459
- Term::ANSIColor.coloring = c
456
+ Cucumber::Term::ANSIColor.coloring = c
460
457
  io.rewind
461
458
  s = "\n" + io.read + (" " * (options[:indent] - 2))
462
459
  s
@@ -470,6 +467,14 @@ module Cucumber
470
467
 
471
468
  protected
472
469
 
470
+ def build_hashes
471
+ convert_headers!
472
+ convert_columns!
473
+ cells_rows[1..-1].map do |row|
474
+ row.to_hash
475
+ end
476
+ end
477
+
473
478
  def inspect_rows(missing_row, inserted_row) #:nodoc:
474
479
  missing_row.each_with_index do |missing_cell, col|
475
480
  inserted_cell = inserted_row[col]
@@ -490,14 +495,38 @@ module Cucumber
490
495
  end
491
496
 
492
497
  def convert_columns! #:nodoc:
498
+ @conversion_procs.each do |column_name, conversion_proc|
499
+ verify_column(column_name) if conversion_proc[:strict]
500
+ end
501
+
493
502
  cell_matrix.transpose.each do |col|
494
- conversion_proc = @conversion_procs[col[0].value]
503
+ column_name = col[0].value
504
+ conversion_proc = @conversion_procs[column_name][:proc]
495
505
  col[1..-1].each do |cell|
496
506
  cell.value = conversion_proc.call(cell.value)
497
507
  end
498
508
  end
499
509
  end
500
510
 
511
+ def convert_headers! #:nodoc:
512
+ header_cells = cell_matrix[0]
513
+
514
+ if @header_conversion_proc
515
+ header_values = header_cells.map { |cell| cell.value } - @header_mappings.keys
516
+ @header_mappings = @header_mappings.merge(Hash[*header_values.zip(header_values.map(&@header_conversion_proc)).flatten])
517
+ end
518
+
519
+ @header_mappings.each_pair do |pre, post|
520
+ mapped_cells = header_cells.select { |cell| pre === cell.value }
521
+ raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
522
+ raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map { |c| c.value }.inspect}" if mapped_cells.length > 1
523
+ mapped_cells[0].value = post
524
+ if @conversion_procs.has_key?(pre)
525
+ @conversion_procs[post] = @conversion_procs.delete(pre)
526
+ end
527
+ end
528
+ end
529
+
501
530
  def require_diff_lcs #:nodoc:
502
531
  begin
503
532
  require 'diff/lcs'
@@ -3,25 +3,25 @@ require 'gherkin/tag_expression'
3
3
  module Cucumber
4
4
  module Ast
5
5
  class Tags #:nodoc:
6
- attr_reader :tag_names
6
+ attr_reader :tags
7
7
 
8
- def initialize(line, tag_names)
9
- @line, @tag_names = line, tag_names
8
+ def initialize(line, tags)
9
+ @line, @tags = line, tags
10
10
  end
11
11
 
12
12
  def accept(visitor)
13
13
  return if Cucumber.wants_to_quit
14
- @tag_names.each do |tag_name|
15
- visitor.visit_tag_name(tag_name)
14
+ @tags.each do |tag|
15
+ visitor.visit_tag_name(tag.name)
16
16
  end
17
17
  end
18
18
 
19
19
  def accept_hook?(hook)
20
- Gherkin::TagExpression.new(hook.tag_expressions).eval(@tag_names)
20
+ Gherkin::TagExpression.new(hook.tag_expressions).eval(@tags)
21
21
  end
22
22
 
23
23
  def to_sexp
24
- @tag_names.map{|tag_name| [:tag, tag_name]}
24
+ @tags.map{|tag| [:tag, tag.name]}
25
25
  end
26
26
  end
27
27
  end
@@ -100,16 +100,16 @@ module Cucumber
100
100
  end
101
101
  end
102
102
 
103
- def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
104
- broadcast(keyword, step_match, multiline_arg, status, exception, source_indent, background) do
105
- visit_step_name(keyword, step_match, status, source_indent, background)
103
+ def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
104
+ broadcast(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line) do
105
+ visit_step_name(keyword, step_match, status, source_indent, background, file_colon_line)
106
106
  visit_multiline_arg(multiline_arg) if multiline_arg
107
107
  visit_exception(exception, status) if exception
108
108
  end
109
109
  end
110
110
 
111
- def visit_step_name(keyword, step_match, status, source_indent, background) #:nodoc:
112
- broadcast(keyword, step_match, status, source_indent, background)
111
+ def visit_step_name(keyword, step_match, status, source_indent, background, file_colon_line) #:nodoc:
112
+ broadcast(keyword, step_match, status, source_indent, background, file_colon_line)
113
113
  end
114
114
 
115
115
  def visit_multiline_arg(multiline_arg) #:nodoc:
@@ -64,6 +64,10 @@ module Cucumber
64
64
  @options[:expand]
65
65
  end
66
66
 
67
+ def dotcucumber
68
+ @options[:dotcucumber]
69
+ end
70
+
67
71
  def build_tree_walker(step_mother)
68
72
  Ast::TreeWalker.new(step_mother, formatters(step_mother), self)
69
73
  end
@@ -41,6 +41,7 @@ module Cucumber
41
41
  end
42
42
 
43
43
  runtime.run!
44
+ runtime.write_stepdefs_json
44
45
  runtime.results.failure?
45
46
  rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e
46
47
  @error_stream.puts e.message
@@ -9,10 +9,6 @@ module Cucumber
9
9
  BUILTIN_FORMATS = {
10
10
  'html' => ['Cucumber::Formatter::Html', 'Generates a nice looking HTML report.'],
11
11
  'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
12
- 'pdf' => ['Cucumber::Formatter::Pdf', "Generates a PDF report. You need to have the\n" +
13
- "#{INDENT}prawn gem installed. Will pick up logo from\n" +
14
- "#{INDENT}features/support/logo.png or\n" +
15
- "#{INDENT}features/support/logo.jpg if present."],
16
12
  'progress' => ['Cucumber::Formatter::Progress', 'Prints one character per scenario.'],
17
13
  'rerun' => ['Cucumber::Formatter::Rerun', 'Prints failing files with line numbers.'],
18
14
  'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" +
@@ -42,11 +38,15 @@ module Cucumber
42
38
  "on Ruby's LOAD_PATH, for example in a Ruby gem."
43
39
  ]
44
40
  DRB_FLAG = '--drb'
41
+ DRB_OPTIONAL_FLAG = '--[no-]drb'
45
42
  PROFILE_SHORT_FLAG = '-p'
46
43
  NO_PROFILE_SHORT_FLAG = '-P'
47
44
  PROFILE_LONG_FLAG = '--profile'
48
45
  NO_PROFILE_LONG_FLAG = '--no-profile'
49
-
46
+ OPTIONS_WITH_ARGS = ['-r', '--require', '--i18n', '-f', '--format', '-o', '--out',
47
+ '-t', '--tags', '-n', '--name', '-e', '--exclude',
48
+ PROFILE_SHORT_FLAG, PROFILE_LONG_FLAG,
49
+ '-a', '--autoformat', '-l', '--lines', '--port']
50
50
 
51
51
  def self.parse(args, out_stream, error_stream, options = {})
52
52
  new(out_stream, error_stream, options).parse!(args)
@@ -77,7 +77,10 @@ module Cucumber
77
77
  return @expanded_args_without_drb if @expanded_args_without_drb
78
78
  @expanded_args_without_drb = (
79
79
  previous_flag_was_profile = false
80
+ previous_flag_requires_arg = false
81
+
80
82
  @expanded_args.reject do |arg|
83
+ # ignore profiles
81
84
  if previous_flag_was_profile
82
85
  previous_flag_was_profile = false
83
86
  next true
@@ -86,6 +89,19 @@ module Cucumber
86
89
  previous_flag_was_profile = true
87
90
  next true
88
91
  end
92
+
93
+ # accept all options which requires arguments
94
+ # and don't try to look @overridden_paths in it's arguments!
95
+ if previous_flag_requires_arg
96
+ previous_flag_requires_arg = false
97
+ next false
98
+ end
99
+ if OPTIONS_WITH_ARGS.include?(arg)
100
+ previous_flag_requires_arg = true
101
+ next false
102
+ end
103
+
104
+ # ignore --drb flag and overridden features paths
89
105
  arg == DRB_FLAG || @overridden_paths.include?(arg)
90
106
  end
91
107
  )
@@ -195,7 +211,7 @@ module Cucumber
195
211
  opts.on("-c", "--[no-]color",
196
212
  "Whether or not to use ANSI color in the output. Cucumber decides",
197
213
  "based on your platform and the output destination if not specified.") do |v|
198
- Term::ANSIColor.coloring = v
214
+ Cucumber::Term::ANSIColor.coloring = v
199
215
  end
200
216
  opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.",
201
217
  "This also omits the loading of your support/env.rb file if it exists.") do
@@ -204,9 +220,9 @@ module Cucumber
204
220
  opts.on("-a", "--autoformat DIR",
205
221
  "Reformats (pretty prints) feature files and write them to DIRECTORY.",
206
222
  "Be careful if you choose to overwrite the originals.",
207
- "Implies --dry-run --formatter pretty.") do |directory|
223
+ "Implies --dry-run --format pretty.") do |directory|
208
224
  @options[:autoformat] = directory
209
- Term::ANSIColor.coloring = false
225
+ Cucumber::Term::ANSIColor.coloring = false
210
226
  @options[:dry_run] = true
211
227
  @quiet = true
212
228
  end
@@ -246,12 +262,15 @@ module Cucumber
246
262
  opts.on("-x", "--expand", "Expand Scenario Outline Tables in output.") do
247
263
  @options[:expand] = true
248
264
  end
249
- opts.on(DRB_FLAG, "Run features against a DRb server. (i.e. with the spork gem)") do
250
- @options[:drb] = true
265
+ opts.on(DRB_OPTIONAL_FLAG, "Run features against a DRb server. (i.e. with the spork gem)") do |drb|
266
+ @options[:drb] = drb
251
267
  end
252
268
  opts.on("--port PORT", "Specify DRb port. Ignored without --drb") do |port|
253
269
  @options[:drb_port] = port
254
270
  end
271
+ opts.on("--dotcucumber DIR", "Write metadata to DIR") do |dir|
272
+ @options[:dotcucumber] = dir
273
+ end
255
274
  opts.on_tail("--version", "Show version.") do
256
275
  @out_stream.puts Cucumber::VERSION
257
276
  Kernel.exit(0)
@@ -7,7 +7,7 @@ module Cucumber
7
7
  names = camel_cased_word.split('::')
8
8
  names.shift if names.empty? || names.first.empty?
9
9
 
10
- constant = Object
10
+ constant = ::Object
11
11
  names.each do |name|
12
12
  constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
13
13
  end
@@ -1,13 +1,20 @@
1
1
  # Why: http://groups.google.com/group/cukes/browse_thread/thread/5682d41436e235d7
2
2
  begin
3
3
  require 'minitest/unit'
4
- class MiniTest::Unit
5
- class << self
6
- @@installed_at_exit = true
7
- end
4
+ # Don't attempt to monkeypatch if the require succeeded but didn't
5
+ # define the actual module.
6
+ #
7
+ # https://github.com/cucumber/cucumber/pull/93
8
+ # http://youtrack.jetbrains.net/issue/TW-17414
9
+ if defined?(MiniTest::Unit)
10
+ class MiniTest::Unit
11
+ class << self
12
+ @@installed_at_exit = true
13
+ end
8
14
 
9
- def run(*)
10
- 0
15
+ def run(*)
16
+ 0
17
+ end
11
18
  end
12
19
  end
13
20
  rescue LoadError => ignore
@@ -15,10 +22,17 @@ end
15
22
 
16
23
  # Do the same for Test::Unit
17
24
  begin
18
- require 'test/unit'
19
- module Test::Unit
20
- def self.run?
21
- true
25
+ require 'test/unit'
26
+ # Don't attempt to monkeypatch if the require succeeded but didn't
27
+ # define the actual module.
28
+ #
29
+ # https://github.com/cucumber/cucumber/pull/93
30
+ # http://youtrack.jetbrains.net/issue/TW-17414
31
+ if defined?(Test::Unit)
32
+ module Test::Unit
33
+ def self.run?
34
+ true
35
+ end
22
36
  end
23
37
  end
24
38
  rescue LoadError => ignore
@@ -1,10 +1,5 @@
1
- begin
2
- require 'term/ansicolor'
3
- rescue LoadError
4
- require 'rubygems'
5
- require 'term/ansicolor'
6
- end
7
1
  require 'cucumber/platform'
2
+ require 'cucumber/term/ansicolor'
8
3
 
9
4
  if Cucumber::IRONRUBY
10
5
  begin
@@ -16,12 +11,12 @@ end
16
11
 
17
12
  if Cucumber::WINDOWS_MRI
18
13
  unless ENV['ANSICON']
19
- STDERR.puts %{*** WARNING: You must use ANSICON 1.31 or higher (http://adoxa.110mb.com/ansicon) to get coloured output on Windows}
20
- Term::ANSIColor.coloring = false
14
+ STDERR.puts %{*** WARNING: You must use ANSICON 1.31 or higher (https://github.com/adoxa/ansicon/) to get coloured output on Windows}
15
+ Cucumber::Term::ANSIColor.coloring = false
21
16
  end
22
17
  end
23
18
 
24
- Term::ANSIColor.coloring = false if !STDOUT.tty? && !ENV.has_key?('AUTOTEST')
19
+ Cucumber::Term::ANSIColor.coloring = false if !STDOUT.tty? && !ENV.has_key?("AUTOTEST")
25
20
 
26
21
  module Cucumber
27
22
  module Formatter
@@ -57,11 +52,11 @@ module Cucumber
57
52
  # (If you're on Windows, use SET instead of export).
58
53
  # To see what colours and effects are available, just run this in your shell:
59
54
  #
60
- # ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Term::ANSIColor.attributes"
55
+ # ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Cucumber::Term::ANSIColor.attributes"
61
56
  #
62
57
  # Although not listed, you can also use <tt>grey</tt>
63
58
  module ANSIColor
64
- include Term::ANSIColor
59
+ include Cucumber::Term::ANSIColor
65
60
 
66
61
  ALIASES = Hash.new do |h,k|
67
62
  if k.to_s =~ /(.*)_param/
@@ -108,7 +103,7 @@ module Cucumber
108
103
  when 0
109
104
  raise "Your terminal doesn't support colours"
110
105
  when 1
111
- ::Term::ANSIColor.coloring = false
106
+ ::Cucumber::Term::ANSIColor.coloring = false
112
107
  alias grey white
113
108
  when 2..8
114
109
  alias grey white
@@ -130,7 +125,7 @@ module Cucumber
130
125
 
131
126
  def self.define_real_grey #:nodoc:
132
127
  def grey(m) #:nodoc:
133
- if ::Term::ANSIColor.coloring?
128
+ if ::Cucumber::Term::ANSIColor.coloring?
134
129
  "\e[90m#{m}\e[0m"
135
130
  else
136
131
  m
@@ -114,8 +114,9 @@ module Cucumber
114
114
  @io.puts format_string(text, :undefined)
115
115
 
116
116
  if unknown_programming_language
117
- @io.puts format_string("\nIf you want snippets in a different programming language, just make sure a file\n" +
118
- "with the appropriate file extension exists where cucumber looks for step definitions.", :failed)
117
+ @io.puts format_string("\nIf you want snippets in a different programming language,\n" +
118
+ "just make sure a file with the appropriate file extension\n" +
119
+ "exists where cucumber looks for step definitions.", :failed)
119
120
  end
120
121
 
121
122
  @io.puts