cucumber 0.6.2 → 0.6.3

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