cucumber 0.6.2 → 0.6.3

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 (87) hide show
  1. data/History.txt +19 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -5
  4. data/VERSION.yml +1 -1
  5. data/cucumber.gemspec +12 -4
  6. data/examples/i18n/de/features/addition.feature +1 -1
  7. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +3 -3
  8. data/examples/self_test/features/step_definitions/sample_steps.rb +22 -22
  9. data/examples/tickets/features/half_manual.feature +11 -0
  10. data/examples/tickets/features/step_definitons/half_manual_steps.rb +11 -0
  11. data/features/announce.feature +97 -97
  12. data/features/background.feature +1 -4
  13. data/features/bug_475.feature +1 -2
  14. data/features/call_many_steps.feature +4 -6
  15. data/features/exception_in_after_block.feature +2 -3
  16. data/features/exception_in_after_step_block.feature +2 -3
  17. data/features/exception_in_before_block.feature +1 -2
  18. data/features/html_formatter/a.html +50 -40
  19. data/features/negative_tagged_hooks.feature +2 -3
  20. data/features/profiles.feature +2 -2
  21. data/features/report_called_undefined_steps.feature +2 -2
  22. data/features/rerun_formatter.feature +45 -0
  23. data/features/table_diffing.feature +1 -1
  24. data/features/table_mapping.feature +2 -3
  25. data/features/wire_protocol_table_diffing.feature +25 -0
  26. data/features/wire_protocol_tags.feature +47 -0
  27. data/lib/cucumber/ast/table.rb +2 -2
  28. data/lib/cucumber/cli/configuration.rb +1 -1
  29. data/lib/cucumber/cli/drb_client.rb +27 -16
  30. data/lib/cucumber/cli/profile_loader.rb +3 -2
  31. data/lib/cucumber/core_ext/proc.rb +1 -2
  32. data/lib/cucumber/formatter/console.rb +6 -4
  33. data/lib/cucumber/formatter/cucumber.css +10 -0
  34. data/lib/cucumber/formatter/cucumber.sass +10 -0
  35. data/lib/cucumber/formatter/html.rb +197 -186
  36. data/lib/cucumber/formatter/pdf.rb +24 -7
  37. data/lib/cucumber/formatter/rerun.rb +6 -3
  38. data/lib/cucumber/formatter/unicode.rb +1 -1
  39. data/lib/cucumber/languages.yml +7 -7
  40. data/lib/cucumber/parser/natural_language.rb +7 -0
  41. data/lib/cucumber/parser/treetop_ext.rb +1 -0
  42. data/lib/cucumber/rb_support/rb_world.rb +5 -0
  43. data/lib/cucumber/step_match.rb +4 -2
  44. data/lib/cucumber/step_mother.rb +53 -4
  45. data/lib/cucumber/wire_support/configuration.rb +11 -1
  46. data/lib/cucumber/wire_support/wire_language.rb +6 -3
  47. data/lib/cucumber/wire_support/wire_protocol.rb +2 -2
  48. data/lib/cucumber/wire_support/wire_protocol/requests.rb +26 -4
  49. data/spec/cucumber/ast/background_spec.rb +3 -3
  50. data/spec/cucumber/ast/feature_element_spec.rb +2 -2
  51. data/spec/cucumber/ast/feature_spec.rb +5 -5
  52. data/spec/cucumber/ast/outline_table_spec.rb +1 -1
  53. data/spec/cucumber/ast/py_string_spec.rb +1 -1
  54. data/spec/cucumber/ast/scenario_outline_spec.rb +3 -3
  55. data/spec/cucumber/ast/scenario_spec.rb +3 -3
  56. data/spec/cucumber/ast/step_collection_spec.rb +3 -3
  57. data/spec/cucumber/ast/step_spec.rb +1 -1
  58. data/spec/cucumber/ast/table_spec.rb +23 -3
  59. data/spec/cucumber/ast/tree_walker_spec.rb +1 -1
  60. data/spec/cucumber/broadcaster_spec.rb +1 -1
  61. data/spec/cucumber/cli/configuration_spec.rb +16 -6
  62. data/spec/cucumber/cli/drb_client_spec.rb +1 -1
  63. data/spec/cucumber/cli/main_spec.rb +13 -14
  64. data/spec/cucumber/cli/options_spec.rb +1 -1
  65. data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
  66. data/spec/cucumber/core_ext/proc_spec.rb +1 -1
  67. data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
  68. data/spec/cucumber/formatter/color_io_spec.rb +1 -1
  69. data/spec/cucumber/formatter/duration_spec.rb +1 -1
  70. data/spec/cucumber/formatter/html_spec.rb +2 -2
  71. data/spec/cucumber/formatter/junit_spec.rb +2 -2
  72. data/spec/cucumber/formatter/progress_spec.rb +3 -3
  73. data/spec/cucumber/parser/feature_parser_spec.rb +5 -5
  74. data/spec/cucumber/parser/table_parser_spec.rb +3 -3
  75. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +7 -7
  76. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
  77. data/spec/cucumber/step_match_spec.rb +6 -1
  78. data/spec/cucumber/step_mother_spec.rb +18 -10
  79. data/spec/cucumber/tag_expression_spec.rb +88 -90
  80. data/spec/cucumber/wire_support/configuration_spec.rb +29 -12
  81. data/spec/cucumber/wire_support/connection_spec.rb +1 -1
  82. data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
  83. data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
  84. data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
  85. data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
  86. data/spec/cucumber/world/pending_spec.rb +5 -5
  87. metadata +128 -54
@@ -429,8 +429,8 @@ module Cucumber
429
429
  private
430
430
 
431
431
  TO_S_PREFIXES = Hash.new(' ')
432
- TO_S_PREFIXES[:comment] = ['(+) ']
433
- TO_S_PREFIXES[:undefined] = ['(-) ']
432
+ TO_S_PREFIXES[:comment] = '(+) '
433
+ TO_S_PREFIXES[:undefined] = '(-) '
434
434
 
435
435
  protected
436
436
 
@@ -83,7 +83,7 @@ module Cucumber
83
83
  files.reject! {|f| !File.file?(f)}
84
84
  files.reject! {|f| File.extname(f) == '.feature' }
85
85
  files.reject! {|f| f =~ /^http/}
86
- files
86
+ files.sort
87
87
  end
88
88
 
89
89
  def step_defs_to_load
@@ -9,24 +9,35 @@ module Cucumber
9
9
  class DRbClient
10
10
  DEFAULT_PORT = 8990
11
11
 
12
- def self.run(args, error_stream, out_stream, port = nil)
13
- port ||= ENV["CUCUMBER_DRB"] || DEFAULT_PORT
14
-
15
- # See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0
16
- begin
17
- DRb.start_service("druby://localhost:0")
18
- rescue SocketError
19
- # Ruby-1.8.7 on snow leopard doesn't like localhost:0 - but just :0
20
- # seems to work just fine
21
- DRb.start_service("druby://:0")
12
+ class << self
13
+
14
+ def run(args, error_stream, out_stream, port = nil)
15
+ port ||= ENV["CUCUMBER_DRB"] || DEFAULT_PORT
16
+
17
+ setup_support_for_io_streams_over_drb
18
+
19
+ feature_server = DRbObject.new_with_uri("druby://127.0.0.1:#{port}")
20
+ cloned_args = [] # I have no idea why this is needed, but if the regular args are sent then DRb magically transforms it into a DRb object - not an array
21
+ args.each { |arg| cloned_args << arg }
22
+ feature_server.run(cloned_args, error_stream, out_stream)
23
+ rescue DRb::DRbConnError => e
24
+ raise DRbClientError, "No DRb server is running."
22
25
  end
23
- feature_server = DRbObject.new_with_uri("druby://127.0.0.1:#{port}")
24
- cloned_args = [] # I have no idea why this is needed, but if the regular args are sent then DRb magically transforms it into a DRb object - not an array
25
- args.each { |arg| cloned_args << arg }
26
- feature_server.run(cloned_args, error_stream, out_stream)
27
- rescue DRb::DRbConnError => e
28
- raise DRbClientError, "No DRb server is running."
26
+
27
+ private
28
+ def setup_support_for_io_streams_over_drb
29
+ # See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0
30
+ begin
31
+ DRb.start_service("druby://localhost:0")
32
+ rescue SocketError
33
+ # Ruby-1.8.7 on snow leopard doesn't like localhost:0 - but just :0
34
+ # seems to work just fine
35
+ DRb.start_service("druby://:0")
36
+ end
37
+ end
38
+
29
39
  end
40
+
30
41
  end
31
42
  end
32
43
  end
@@ -22,7 +22,8 @@ Defined profiles in cucumber.yml:
22
22
  case(args_from_yml)
23
23
  when String
24
24
  raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was blank. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml =~ /^\s*$/
25
- args_from_yml = args_from_yml.split(' ')
25
+ require 'shellwords'
26
+ args_from_yml = Shellwords.shellwords(args_from_yml)
26
27
  when Array
27
28
  raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was empty. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml.empty?
28
29
  else
@@ -51,7 +52,7 @@ Defined profiles in cucumber.yml:
51
52
  require 'erb'
52
53
  require 'yaml'
53
54
  begin
54
- @cucumber_erb = ERB.new(IO.read(cucumber_file)).result
55
+ @cucumber_erb = ERB.new(IO.read(cucumber_file)).result(binding)
55
56
  rescue Exception => e
56
57
  raise(YmlLoadError,"cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage.\n#{$!.inspect}")
57
58
  end
@@ -1,6 +1,6 @@
1
1
  # Proc extension to get more location info out of a proc
2
2
  class Proc #:nodoc:
3
- PROC_PATTERN = /[\d\w]+@(.*):(.*)>/
3
+ PROC_PATTERN = /[\d\w]+@(.+):(\d+).*>/
4
4
 
5
5
  def to_comment_line
6
6
  "# #{file_colon_line}"
@@ -13,7 +13,6 @@ class Proc #:nodoc:
13
13
  if Proc.new{}.to_s =~ PROC_PATTERN
14
14
  def file_colon_line
15
15
  path, line = *to_s.match(PROC_PATTERN)[1..2]
16
- line = line.to_i - 1 if Cucumber::RUBY_1_9
17
16
  path = File.expand_path(path)
18
17
  pwd = Dir.pwd
19
18
  path = path[pwd.length+1..-1]
@@ -68,7 +68,7 @@ module Cucumber
68
68
  if !@failures.empty?
69
69
  @io.puts format_string("Failing Scenarios:", :failed)
70
70
  @failures.each do |failure|
71
- profiles_string = (profiles.map{|profile| "-p #{profile} " }).flatten unless profiles.empty?
71
+ profiles_string = profiles.empty? ? '' : (profiles.map{|profile| "-p #{profile}" }).join(' ') + ' '
72
72
  @io.puts format_string("cucumber #{profiles_string}" + failure.file_colon_line, :failed) +
73
73
  format_string(" # Scenario: " + failure.name, :comment)
74
74
  end
@@ -145,9 +145,11 @@ module Cucumber
145
145
  if @delayed_announcements
146
146
  @delayed_announcements << announcement
147
147
  else
148
- @io.puts
149
- @io.puts(format_string(announcement, :tag))
150
- @io.flush
148
+ if @io
149
+ @io.puts
150
+ @io.puts(format_string(announcement, :tag))
151
+ @io.flush
152
+ end
151
153
  end
152
154
  end
153
155
 
@@ -48,6 +48,16 @@ body {
48
48
  .cucumber .summary ul.features li, td .summary ul.features li, th .summary ul.features li {
49
49
  display: inline;
50
50
  }
51
+ .cucumber .step_name, td .step_name, th .step_name {
52
+ float: left;
53
+ }
54
+ .cucumber .step_file, td .step_file, th .step_file {
55
+ text-align: right;
56
+ color: #999999;
57
+ }
58
+ .cucumber .step_file a, td .step_file a, th .step_file a {
59
+ color: #999999;
60
+ }
51
61
  .cucumber .tag, td .tag, th .tag {
52
62
  font-weight: bold;
53
63
  color: #246AC1;
@@ -73,6 +73,16 @@ body
73
73
  ul.features
74
74
  li
75
75
  :display inline
76
+
77
+ .step_name
78
+ :float left
79
+
80
+ .step_file
81
+ :text-align right
82
+ :color #999999
83
+ a
84
+ :color #999999
85
+
76
86
 
77
87
  .tag
78
88
  :font-weight bold
@@ -328,124 +328,137 @@ module Cucumber
328
328
 
329
329
  protected
330
330
 
331
- def build_exception_detail(exception)
332
- backtrace = Array.new
333
- @builder.div(:class => 'message') do
334
- message = exception.message
335
- if defined?(RAILS_ROOT) && message.include?('Exception caught')
336
- matches = message.match(/Showing <i>(.+)<\/i>(?:.+)#(\d+)/)
337
- backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"]
338
- message = message.match(/<code>([^(\/)]+)<\//m)[1]
339
- end
340
- @builder.pre do
341
- @builder.text!(message)
342
- end
331
+ def build_exception_detail(exception)
332
+ backtrace = Array.new
333
+ @builder.div(:class => 'message') do
334
+ message = exception.message
335
+ if defined?(RAILS_ROOT) && message.include?('Exception caught')
336
+ matches = message.match(/Showing <i>(.+)<\/i>(?:.+)#(\d+)/)
337
+ backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"]
338
+ message = message.match(/<code>([^(\/)]+)<\//m)[1]
343
339
  end
344
- @builder.div(:class => 'backtrace') do
345
- @builder.pre do
346
- backtrace = exception.backtrace
347
- backtrace.delete_if { |x| x =~ /\/gems\/(cucumber|rspec)/ }
348
- @builder << backtrace_line(backtrace.join("\n"))
349
- end
340
+ @builder.pre do
341
+ @builder.text!(message)
350
342
  end
351
- extra = extra_failure_content(backtrace)
352
- @builder << extra unless extra == ""
353
343
  end
354
-
355
- def set_scenario_color(status)
356
- if status == :undefined
357
- set_scenario_color_pending
358
- end
359
- if status == :failed
360
- set_scenario_color_failed
344
+ @builder.div(:class => 'backtrace') do
345
+ @builder.pre do
346
+ backtrace = exception.backtrace
347
+ backtrace.delete_if { |x| x =~ /\/gems\/(cucumber|rspec)/ }
348
+ @builder << backtrace_line(backtrace.join("\n"))
361
349
  end
362
350
  end
363
-
364
- def set_scenario_color_failed
365
- @builder.script do
366
- @builder.text!("makeRed('cucumber-header');") unless @header_red
367
- @header_red = true
368
- @builder.text!("makeRed('scenario_#{@scenario_number}');") unless @scenario_red
369
- @scenario_red = true
370
- end
351
+ extra = extra_failure_content(backtrace)
352
+ @builder << extra unless extra == ""
353
+ end
354
+
355
+ def set_scenario_color(status)
356
+ if status == :undefined
357
+ set_scenario_color_pending
371
358
  end
372
-
373
- def set_scenario_color_pending
374
- @builder.script do
375
- @builder.text!("makeYellow('cucumber-header');") unless @header_red
376
- @builder.text!("makeYellow('scenario_#{@scenario_number}');") unless @scenario_red
377
- end
378
- end
379
-
380
- def get_step_count(features)
381
- count = 0
382
- features = features.instance_variable_get("@features")
383
- features.each do |feature|
384
- #get background steps
385
- if feature.instance_variable_get("@background")
386
- background = feature.instance_variable_get("@background").instance_variable_get("@steps").instance_variable_get("@steps")
387
- count += background.size
388
- end
389
- #get scenarios
390
- feature.instance_variable_get("@feature_elements").each do |scenario|
391
- #get steps
392
- steps = scenario.instance_variable_get("@steps").instance_variable_get("@steps")
393
- count += steps.size
394
-
395
- #get example table
396
- examples = scenario.instance_variable_get("@examples_array")
397
- unless examples.nil?
398
- examples.each do |example|
399
- example_matrix = example.instance_variable_get("@outline_table").instance_variable_get("@cell_matrix")
400
- count += example_matrix.size
401
- end
359
+ if status == :failed
360
+ set_scenario_color_failed
361
+ end
362
+ end
363
+
364
+ def set_scenario_color_failed
365
+ @builder.script do
366
+ @builder.text!("makeRed('cucumber-header');") unless @header_red
367
+ @header_red = true
368
+ @builder.text!("makeRed('scenario_#{@scenario_number}');") unless @scenario_red
369
+ @scenario_red = true
370
+ end
371
+ end
372
+
373
+ def set_scenario_color_pending
374
+ @builder.script do
375
+ @builder.text!("makeYellow('cucumber-header');") unless @header_red
376
+ @builder.text!("makeYellow('scenario_#{@scenario_number}');") unless @scenario_red
377
+ end
378
+ end
379
+
380
+ def get_step_count(features)
381
+ count = 0
382
+ features = features.instance_variable_get("@features")
383
+ features.each do |feature|
384
+ #get background steps
385
+ if feature.instance_variable_get("@background")
386
+ background = feature.instance_variable_get("@background").instance_variable_get("@steps").instance_variable_get("@steps")
387
+ count += background.size
388
+ end
389
+ #get scenarios
390
+ feature.instance_variable_get("@feature_elements").each do |scenario|
391
+ #get steps
392
+ steps = scenario.instance_variable_get("@steps").instance_variable_get("@steps")
393
+ count += steps.size
394
+
395
+ #get example table
396
+ examples = scenario.instance_variable_get("@examples_array")
397
+ unless examples.nil?
398
+ examples.each do |example|
399
+ example_matrix = example.instance_variable_get("@outline_table").instance_variable_get("@cell_matrix")
400
+ count += example_matrix.size
402
401
  end
402
+ end
403
403
 
404
- #get multiline step tables
405
- steps.each do |step|
406
- multi_arg = step.instance_variable_get("@multiline_arg")
407
- next if multi_arg.nil?
408
- matrix = multi_arg.instance_variable_get("@cell_matrix")
409
- count += matrix.size unless matrix.nil?
410
- end
404
+ #get multiline step tables
405
+ steps.each do |step|
406
+ multi_arg = step.instance_variable_get("@multiline_arg")
407
+ next if multi_arg.nil?
408
+ matrix = multi_arg.instance_variable_get("@cell_matrix")
409
+ count += matrix.size unless matrix.nil?
411
410
  end
412
411
  end
413
- return count
414
412
  end
413
+ return count
414
+ end
415
415
 
416
- def build_step(keyword, step_match, status)
417
- step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
418
- @builder.div do |div|
419
- @builder.span(keyword, :class => 'keyword')
420
- @builder.text!(' ')
421
- @builder.span(:class => 'step val') do |name|
422
- name << h(step_name).gsub(/&lt;span class=&quot;(.*?)&quot;&gt;/, '<span class="\1">').gsub(/&lt;\/span&gt;/, '</span>')
423
- end
416
+ def build_step(keyword, step_match, status)
417
+ step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
418
+ @builder.div(:class => 'step_name') do |div|
419
+ @builder.span(keyword, :class => 'keyword')
420
+ @builder.text!(' ')
421
+ @builder.span(:class => 'step val') do |name|
422
+ name << h(step_name).gsub(/&lt;span class=&quot;(.*?)&quot;&gt;/, '<span class="\1">').gsub(/&lt;\/span&gt;/, '</span>')
423
+ end
424
+ end
425
+
426
+ step_file = step_match.file_colon_line
427
+ step_file.gsub(/^([^:]*\.rb):(\d*)/) do
428
+ if ENV['TM_PROJECT_DIRECTORY']
429
+ step_file = "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
424
430
  end
425
431
  end
426
-
427
- def build_cell(cell_type, value, attributes)
428
- @builder.__send__(cell_type, attributes) do
429
- @builder.div do
430
- @builder.span(value,:class => 'step param')
431
- end
432
+
433
+ @builder.div(:class => 'step_file') do |div|
434
+ @builder.span do
435
+ @builder << step_file
432
436
  end
433
437
  end
438
+ end
434
439
 
435
- def inline_css
436
- @builder.style(:type => 'text/css') do
437
- @builder << File.read(File.dirname(__FILE__) + '/cucumber.css')
440
+ def build_cell(cell_type, value, attributes)
441
+ @builder.__send__(cell_type, attributes) do
442
+ @builder.div do
443
+ @builder.span(value,:class => 'step param')
438
444
  end
439
445
  end
446
+ end
440
447
 
441
- def inline_js
442
- @builder.script(:type => 'text/javascript') do
443
- @builder << inline_js_content
444
- end
448
+ def inline_css
449
+ @builder.style(:type => 'text/css') do
450
+ @builder << File.read(File.dirname(__FILE__) + '/cucumber.css')
445
451
  end
452
+ end
453
+
454
+ def inline_js
455
+ @builder.script(:type => 'text/javascript') do
456
+ @builder << inline_js_content
457
+ end
458
+ end
446
459
 
447
- def inline_js_content
448
- <<-EOF
460
+ def inline_js_content
461
+ <<-EOF
449
462
  function moveProgressBar(percentDone) {
450
463
  document.getElementById("cucumber-header").style.width = percentDone +"%";
451
464
  }
@@ -459,113 +472,111 @@ module Cucumber
459
472
  document.getElementById(element_id).style.color = '#000000';
460
473
  }
461
474
  EOF
462
- end
475
+ end
463
476
 
464
- def move_progress
465
- @builder << " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
466
- end
477
+ def move_progress
478
+ @builder << " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
479
+ end
467
480
 
468
- def percent_done
469
- result = 100.0
470
- if @step_count != 0
471
- result = ((@step_number).to_f / @step_count.to_f * 1000).to_i / 10.0
472
- end
473
- result
481
+ def percent_done
482
+ result = 100.0
483
+ if @step_count != 0
484
+ result = ((@step_number).to_f / @step_count.to_f * 1000).to_i / 10.0
474
485
  end
486
+ result
487
+ end
475
488
 
476
- def format_exception(exception)
477
- (["#{exception.message}"] + exception.backtrace).join("\n")
478
- end
489
+ def format_exception(exception)
490
+ (["#{exception.message}"] + exception.backtrace).join("\n")
491
+ end
479
492
 
480
- def backtrace_line(line)
481
- line.gsub(/^([^:]*\.(?:rb|feature|haml)):(\d*)/) do
482
- if ENV['TM_PROJECT_DIRECTORY']
483
- "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
484
- else
485
- line
486
- end
493
+ def backtrace_line(line)
494
+ line.gsub(/^([^:]*\.(?:rb|feature|haml)):(\d*)/) do
495
+ if ENV['TM_PROJECT_DIRECTORY']
496
+ "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
497
+ else
498
+ line
487
499
  end
488
500
  end
501
+ end
489
502
 
490
- def print_stats(features)
491
- @builder << "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{format_duration(features.duration)} seconds</strong>\";</script>"
492
- @builder << "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{print_stat_string(features)}\";</script>"
493
- end
503
+ def print_stats(features)
504
+ @builder << "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{format_duration(features.duration)} seconds</strong>\";</script>"
505
+ @builder << "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{print_stat_string(features)}\";</script>"
506
+ end
494
507
 
495
- def print_stat_string(features)
496
- string = String.new
497
- string << dump_count(@step_mother.scenarios.length, "scenario")
498
- scenario_count = print_status_counts{|status| @step_mother.scenarios(status)}
499
- string << scenario_count if scenario_count
500
- string << "<br />"
501
- string << dump_count(@step_mother.steps.length, "step")
502
- step_count = print_status_counts{|status| @step_mother.steps(status)}
503
- string << step_count if step_count
504
- end
508
+ def print_stat_string(features)
509
+ string = String.new
510
+ string << dump_count(@step_mother.scenarios.length, "scenario")
511
+ scenario_count = print_status_counts{|status| @step_mother.scenarios(status)}
512
+ string << scenario_count if scenario_count
513
+ string << "<br />"
514
+ string << dump_count(@step_mother.steps.length, "step")
515
+ step_count = print_status_counts{|status| @step_mother.steps(status)}
516
+ string << step_count if step_count
517
+ end
505
518
 
506
- def print_status_counts
507
- counts = [:failed, :skipped, :undefined, :pending, :passed].map do |status|
508
- elements = yield status
509
- elements.any? ? "#{elements.length} #{status.to_s}" : nil
510
- end.compact
511
- return " (#{counts.join(', ')})" if counts.any?
512
- end
519
+ def print_status_counts
520
+ counts = [:failed, :skipped, :undefined, :pending, :passed].map do |status|
521
+ elements = yield status
522
+ elements.any? ? "#{elements.length} #{status.to_s}" : nil
523
+ end.compact
524
+ return " (#{counts.join(', ')})" if counts.any?
525
+ end
513
526
 
514
- def dump_count(count, what, state=nil)
515
- [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(" ")
516
- end
527
+ def dump_count(count, what, state=nil)
528
+ [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(" ")
529
+ end
517
530
 
518
- def create_builder(io)
519
- OrderedXmlMarkup.new(:target => io, :indent => 0)
520
- end
521
- end
522
- end
523
- end
531
+ def create_builder(io)
532
+ OrderedXmlMarkup.new(:target => io, :indent => 0)
533
+ end
524
534
 
535
+ class SnippetExtractor #:nodoc:
536
+ class NullConverter; def convert(code, pre); code; end; end #:nodoc:
537
+ begin; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
525
538
 
526
- class SnippetExtractor #:nodoc:
527
- class NullConverter; def convert(code, pre); code; end; end #:nodoc:
528
- begin; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
539
+ def snippet(error)
540
+ raw_code, line = snippet_for(error[0])
541
+ highlighted = @@converter.convert(raw_code, false)
542
+ highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
543
+ post_process(highlighted, line)
544
+ end
529
545
 
530
- def snippet(error)
531
- raw_code, line = snippet_for(error[0])
532
- highlighted = @@converter.convert(raw_code, false)
533
- highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
534
- post_process(highlighted, line)
535
- end
546
+ def snippet_for(error_line)
547
+ if error_line =~ /(.*):(\d+)/
548
+ file = $1
549
+ line = $2.to_i
550
+ [lines_around(file, line), line]
551
+ else
552
+ ["# Couldn't get snippet for #{error_line}", 1]
553
+ end
554
+ end
536
555
 
537
- def snippet_for(error_line)
538
- if error_line =~ /(.*):(\d+)/
539
- file = $1
540
- line = $2.to_i
541
- [lines_around(file, line), line]
542
- else
543
- return snippet_for()
544
- ["# Couldn't get snippet for #{error_line}", 1]
545
- end
546
- end
556
+ def lines_around(file, line)
557
+ if File.file?(file)
558
+ lines = File.open(file).read.split("\n")
559
+ min = [0, line-3].max
560
+ max = [line+1, lines.length-1].min
561
+ selected_lines = []
562
+ selected_lines.join("\n")
563
+ lines[min..max].join("\n")
564
+ else
565
+ "# Couldn't get snippet for #{file}"
566
+ end
567
+ end
547
568
 
548
- def lines_around(file, line)
549
- if File.file?(file)
550
- lines = File.open(file).read.split("\n")
551
- min = [0, line-3].max
552
- max = [line+1, lines.length-1].min
553
- selected_lines = []
554
- selected_lines.join("\n")
555
- lines[min..max].join("\n")
556
- else
557
- "# Couldn't get snippet for #{file}"
558
- end
559
- end
569
+ def post_process(highlighted, offending_line)
570
+ new_lines = []
571
+ highlighted.split("\n").each_with_index do |line, i|
572
+ new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
573
+ new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
574
+ new_lines << new_line
575
+ end
576
+ new_lines.join("\n")
577
+ end
560
578
 
561
- def post_process(highlighted, offending_line)
562
- new_lines = []
563
- highlighted.split("\n").each_with_index do |line, i|
564
- new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
565
- new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
566
- new_lines << new_line
579
+ end
567
580
  end
568
- new_lines.join("\n")
569
581
  end
570
-
571
- end
582
+ end