rspec-core 2.11.1 → 2.12.0

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 (116) hide show
  1. data/Changelog.md +59 -0
  2. data/README.md +22 -0
  3. data/features/command_line/example_name_option.feature +5 -5
  4. data/features/command_line/exit_status.feature +6 -6
  5. data/features/command_line/format_option.feature +2 -2
  6. data/features/command_line/line_number_appended_to_path.feature +2 -2
  7. data/features/command_line/line_number_option.feature +2 -2
  8. data/features/command_line/pattern_option.feature +2 -2
  9. data/features/command_line/rake_task.feature +62 -8
  10. data/features/command_line/ruby.feature +1 -1
  11. data/features/command_line/tag.feature +1 -1
  12. data/features/configuration/alias_example_to.feature +2 -2
  13. data/features/configuration/custom_settings.feature +3 -3
  14. data/features/configuration/default_path.feature +3 -3
  15. data/features/configuration/fail_fast.feature +5 -5
  16. data/features/configuration/read_options_from_file.feature +4 -4
  17. data/features/example_groups/basic_structure.feature +2 -2
  18. data/features/example_groups/shared_context.feature +3 -3
  19. data/features/example_groups/shared_examples.feature +25 -7
  20. data/features/expectation_framework_integration/configure_expectation_framework.feature +6 -6
  21. data/features/filtering/exclusion_filters.feature +5 -5
  22. data/features/filtering/if_and_unless.feature +5 -5
  23. data/features/filtering/inclusion_filters.feature +5 -5
  24. data/features/filtering/run_all_when_everything_filtered.feature +3 -3
  25. data/features/formatters/custom_formatter.feature +2 -2
  26. data/features/formatters/json_formatter.feature +30 -0
  27. data/features/formatters/text_formatter.feature +5 -5
  28. data/features/helper_methods/arbitrary_methods.feature +2 -2
  29. data/features/helper_methods/let.feature +2 -2
  30. data/features/helper_methods/modules.feature +6 -6
  31. data/features/hooks/around_hooks.feature +11 -11
  32. data/features/hooks/before_and_after_hooks.feature +15 -11
  33. data/features/hooks/filtering.feature +6 -6
  34. data/features/metadata/current_example.feature +1 -1
  35. data/features/metadata/described_class.feature +1 -1
  36. data/features/metadata/user_defined.feature +4 -4
  37. data/features/mock_framework_integration/use_any_framework.feature +6 -6
  38. data/features/mock_framework_integration/use_flexmock.feature +5 -5
  39. data/features/mock_framework_integration/use_mocha.feature +5 -5
  40. data/features/mock_framework_integration/use_rr.feature +5 -5
  41. data/features/mock_framework_integration/use_rspec.feature +5 -5
  42. data/features/pending/pending_examples.feature +11 -11
  43. data/features/spec_files/arbitrary_file_suffix.feature +1 -1
  44. data/features/step_definitions/additional_cli_steps.rb +2 -0
  45. data/features/subject/attribute_of_subject.feature +5 -5
  46. data/features/subject/explicit_subject.feature +5 -5
  47. data/features/subject/implicit_receiver.feature +2 -2
  48. data/features/subject/implicit_subject.feature +3 -3
  49. data/lib/autotest/rspec2.rb +1 -1
  50. data/lib/rspec/core.rb +53 -32
  51. data/lib/rspec/core/configuration.rb +123 -15
  52. data/lib/rspec/core/configuration_options.rb +17 -2
  53. data/lib/rspec/core/example.rb +5 -4
  54. data/lib/rspec/core/example_group.rb +19 -9
  55. data/lib/rspec/core/extensions/ordered.rb +12 -6
  56. data/lib/rspec/core/formatters.rb +55 -0
  57. data/lib/rspec/core/formatters/base_formatter.rb +43 -38
  58. data/lib/rspec/core/formatters/base_text_formatter.rb +9 -5
  59. data/lib/rspec/core/formatters/documentation_formatter.rb +1 -1
  60. data/lib/rspec/core/formatters/helpers.rb +30 -5
  61. data/lib/rspec/core/formatters/html_formatter.rb +58 -368
  62. data/lib/rspec/core/formatters/html_printer.rb +407 -0
  63. data/lib/rspec/core/formatters/json_formatter.rb +73 -0
  64. data/lib/rspec/core/formatters/snippet_extractor.rb +3 -1
  65. data/lib/rspec/core/hooks.rb +4 -4
  66. data/lib/rspec/core/metadata.rb +14 -6
  67. data/lib/rspec/core/mocking/with_mocha.rb +25 -2
  68. data/lib/rspec/core/mocking/with_rspec.rb +6 -2
  69. data/lib/rspec/core/option_parser.rb +28 -7
  70. data/lib/rspec/core/project_initializer.rb +0 -1
  71. data/lib/rspec/core/rake_task.rb +49 -38
  72. data/lib/rspec/core/reporter.rb +2 -2
  73. data/lib/rspec/core/shared_example_group.rb +89 -41
  74. data/lib/rspec/core/subject.rb +6 -2
  75. data/lib/rspec/core/version.rb +1 -1
  76. data/lib/rspec/core/world.rb +2 -2
  77. data/spec/autotest/rspec_spec.rb +6 -1
  78. data/spec/command_line/order_spec.rb +67 -0
  79. data/spec/rspec/core/configuration_options_spec.rb +45 -38
  80. data/spec/rspec/core/configuration_spec.rb +219 -44
  81. data/spec/rspec/core/deprecations_spec.rb +9 -0
  82. data/spec/rspec/core/drb_command_line_spec.rb +1 -7
  83. data/spec/rspec/core/drb_options_spec.rb +1 -1
  84. data/spec/rspec/core/dsl_spec.rb +17 -9
  85. data/spec/rspec/core/example_group_spec.rb +51 -5
  86. data/spec/rspec/core/example_spec.rb +39 -7
  87. data/spec/rspec/core/filter_manager_spec.rb +20 -30
  88. data/spec/rspec/core/formatters/base_formatter_spec.rb +29 -1
  89. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +6 -2
  90. data/spec/rspec/core/formatters/helpers_spec.rb +12 -0
  91. data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +462 -0
  92. data/spec/rspec/core/formatters/html_formatted-1.9.2-jruby.html +410 -0
  93. data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +462 -0
  94. data/spec/rspec/core/formatters/html_formatter_spec.rb +11 -3
  95. data/spec/rspec/core/formatters/json_formatter_spec.rb +110 -0
  96. data/spec/rspec/core/formatters/snippet_extractor_spec.rb +8 -0
  97. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-rbx.html +462 -0
  98. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2-jruby.html +410 -0
  99. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-rbx.html +462 -0
  100. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +11 -3
  101. data/spec/rspec/core/hooks_filtering_spec.rb +6 -6
  102. data/spec/rspec/core/metadata_spec.rb +29 -0
  103. data/spec/rspec/core/option_parser_spec.rb +42 -0
  104. data/spec/rspec/core/project_initializer_spec.rb +2 -2
  105. data/spec/rspec/core/rake_task_spec.rb +60 -17
  106. data/spec/rspec/core/reporter_spec.rb +17 -0
  107. data/spec/rspec/core/runner_spec.rb +1 -0
  108. data/spec/rspec/core/shared_example_group_spec.rb +17 -5
  109. data/spec/rspec/core/subject_spec.rb +11 -0
  110. data/spec/spec_helper.rb +32 -2
  111. data/spec/support/config_options_helper.rb +1 -10
  112. data/spec/support/helper_methods.rb +13 -0
  113. data/spec/support/isolated_directory.rb +10 -0
  114. data/spec/support/isolated_home_directory.rb +16 -0
  115. metadata +145 -148
  116. data/lib/rspec/core/extensions.rb +0 -4
@@ -4,7 +4,12 @@ require 'stringio'
4
4
  module RSpec
5
5
  module Core
6
6
  module Formatters
7
-
7
+ # RSpec's built-in formatters are all subclasses of RSpec::Core::Formatters::BaseTextFormatter,
8
+ # but the BaseTextFormatter documents all of the methods needed to be implemented by a formatter,
9
+ # as they are called from the reporter.
10
+ #
11
+ # @see RSpec::Core::Formatters::BaseTextFormatter
12
+ # @see RSpec::Core::Reporter
8
13
  class BaseFormatter
9
14
  include Helpers
10
15
  attr_accessor :example_group
@@ -21,54 +26,68 @@ module RSpec
21
26
  @example_group = nil
22
27
  end
23
28
 
24
- # This method is invoked before any examples are run, right after
25
- # they have all been collected. This can be useful for special
26
- # formatters that need to provide progress on feedback (graphical ones)
29
+ # Invoked before any examples are run, right after they have all
30
+ # been collected. This can be useful for formatters that provide
31
+ # feedback on progress through a suite.
27
32
  #
28
- # This will only be invoked once, and the next one to be invoked
29
- # is #example_group_started
33
+ # @param example_count
30
34
  def start(example_count)
31
35
  start_sync_output
32
36
  @example_count = example_count
33
37
  end
34
38
 
35
- # This method is invoked at the beginning of the execution of each example group.
36
- # +example_group+ is the example_group.
39
+ # Invoked at the beginning of the execution of each example
40
+ # group.
37
41
  #
38
- # The next method to be invoked after this is +example_passed+,
39
- # +example_pending+, or +example_finished+
42
+ # @param example_group subclass of `RSpec::Core::ExampleGroup`
40
43
  def example_group_started(example_group)
41
44
  @example_group = example_group
42
45
  end
43
46
 
44
- # This method is invoked at the end of the execution of each example group.
45
- # +example_group+ is the example_group.
47
+ # Invoked at the end of the execution of each example group.
48
+ #
49
+ # @param example_group subclass of `RSpec::Core::ExampleGroup`
46
50
  def example_group_finished(example_group)
47
51
  end
48
52
 
53
+
54
+ # Invoked at the beginning of the execution of each example.
55
+ #
56
+ # @param example instance of subclass of `RSpec::Core::ExampleGroup`
49
57
  def example_started(example)
50
58
  examples << example
51
59
  end
52
60
 
61
+ # Invoked when an example passes.
62
+ #
63
+ # @param example instance of subclass of `RSpec::Core::ExampleGroup`
53
64
  def example_passed(example)
54
65
  end
55
66
 
67
+ # Invoked when an example is pending.
68
+ #
69
+ # @param example instance of subclass of `RSpec::Core::ExampleGroup`
56
70
  def example_pending(example)
57
71
  @pending_examples << example
58
72
  end
59
73
 
74
+ # Invoked when an example fails.
75
+ #
76
+ # @param example instance of subclass of `RSpec::Core::ExampleGroup`
60
77
  def example_failed(example)
61
78
  @failed_examples << example
62
79
  end
63
80
 
81
+ # Used by the reporter to send messages to the output stream.
82
+ # @param [String] message
64
83
  def message(message)
65
84
  end
66
85
 
86
+ # Invoked after all examples have executed, before dumping post-run reports.
67
87
  def stop
68
88
  end
69
89
 
70
- # This method is invoked after all of the examples have executed. The next method
71
- # to be invoked after this one is #dump_failure (once for each failed example),
90
+ # Invoked after all of the examples have executed (after `stop`).
72
91
  def start_dump
73
92
  end
74
93
 
@@ -76,7 +95,7 @@ module RSpec
76
95
  def dump_failures
77
96
  end
78
97
 
79
- # This method is invoked after the dumping of examples and failures.
98
+ # Invoked after the dumping of examples and failures.
80
99
  def dump_summary(duration, example_count, failure_count, pending_count)
81
100
  @duration = duration
82
101
  @example_count = example_count
@@ -84,41 +103,26 @@ module RSpec
84
103
  @pending_count = pending_count
85
104
  end
86
105
 
87
- # This gets invoked after the summary if option is set to do so.
106
+ # Invoked after the summary if option is set to do so.
88
107
  def dump_pending
89
108
  end
90
109
 
110
+ # @private not intended for use outside RSpec.
91
111
  def seed(number)
92
112
  end
93
113
 
94
- # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
114
+ # Invoked at the very end, `close` allows the formatter to clean
115
+ # up resources, e.g. open streams, etc.
95
116
  def close
96
117
  restore_sync_output
97
118
  end
98
119
 
99
- def format_backtrace(backtrace, example)
100
- return "" unless backtrace
101
- return backtrace if example.metadata[:full_backtrace] == true
102
-
103
- if at_exit_index = backtrace.index(RSpec::Core::Runner::AT_EXIT_HOOK_BACKTRACE_LINE)
104
- backtrace = backtrace[0, at_exit_index]
105
- end
106
-
107
- cleansed = backtrace.map { |line| backtrace_line(line) }.compact
108
- cleansed.empty? ? backtrace : cleansed
109
- end
110
-
111
120
  protected
112
121
 
113
122
  def configuration
114
123
  RSpec.configuration
115
124
  end
116
125
 
117
- def backtrace_line(line)
118
- return nil if configuration.cleaned_from_backtrace?(line)
119
- RSpec::Core::Metadata::relative_path(line)
120
- end
121
-
122
126
  def read_failed_line(exception, example)
123
127
  unless matching_line = find_failed_line(exception.backtrace, example.file_path)
124
128
  return "Unable to find matching line from backtrace"
@@ -127,10 +131,13 @@ module RSpec
127
131
  file_path, line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)[1..2]
128
132
 
129
133
  if File.exist?(file_path)
130
- File.readlines(file_path)[line_number.to_i - 1]
134
+ File.readlines(file_path)[line_number.to_i - 1] ||
135
+ "Unable to find matching line in #{file_path}"
131
136
  else
132
137
  "Unable to find #{file_path} to read failed line"
133
138
  end
139
+ rescue SecurityError
140
+ "Unable to read failed line"
134
141
  end
135
142
 
136
143
  def find_failed_line(backtrace, path)
@@ -158,11 +165,9 @@ module RSpec
158
165
  end
159
166
 
160
167
  def color_enabled?
161
- configuration.color_enabled?
168
+ configuration.color_enabled?(output)
162
169
  end
163
-
164
170
  end
165
-
166
171
  end
167
172
  end
168
173
  end
@@ -4,8 +4,12 @@ module RSpec
4
4
  module Core
5
5
  module Formatters
6
6
 
7
+ # Base for all of RSpec's built-in formatters. See RSpec::Core::Formatters::BaseFormatter
8
+ # to learn more about all of the methods called by the reporter.
9
+ #
10
+ # @see RSpec::Core::Formatters::BaseFormatter
11
+ # @see RSpec::Core::Reporter
7
12
  class BaseTextFormatter < BaseFormatter
8
-
9
13
  def message(message)
10
14
  output.puts message
11
15
  end
@@ -156,7 +160,7 @@ module RSpec
156
160
  end
157
161
 
158
162
  def dump_backtrace(example)
159
- format_backtrace(example.execution_result[:exception].backtrace, example).each do |backtrace_info|
163
+ format_backtrace(example.execution_result[:exception].backtrace, example.metadata).each do |backtrace_info|
160
164
  output.puts cyan("#{long_padding}# #{backtrace_info}")
161
165
  end
162
166
  end
@@ -191,11 +195,11 @@ module RSpec
191
195
  end
192
196
 
193
197
  def find_shared_group(example)
194
- group_and_ancestors(example).find {|group| group.metadata[:shared_group_name]}
198
+ group_and_parent_groups(example).find {|group| group.metadata[:shared_group_name]}
195
199
  end
196
200
 
197
- def group_and_ancestors(example)
198
- example.example_group.ancestors + [example.example_group]
201
+ def group_and_parent_groups(example)
202
+ example.example_group.parent_groups + [example.example_group]
199
203
  end
200
204
  end
201
205
  end
@@ -59,7 +59,7 @@ module RSpec
59
59
  end
60
60
 
61
61
  def example_group_chain
62
- example_group.ancestors.reverse
62
+ example_group.parent_groups.reverse
63
63
  end
64
64
  end
65
65
  end
@@ -1,8 +1,34 @@
1
1
  module RSpec
2
2
  module Core
3
- module Formatters
3
+ module BacktraceFormatter
4
+ extend self
5
+
6
+ def format_backtrace(backtrace, options = {})
7
+ return "" unless backtrace
8
+ return backtrace if options[:full_backtrace] == true
9
+
10
+ if at_exit_index = backtrace.index(RSpec::Core::Runner::AT_EXIT_HOOK_BACKTRACE_LINE)
11
+ backtrace = backtrace[0, at_exit_index]
12
+ end
13
+
14
+ cleansed = backtrace.map { |line| backtrace_line(line) }.compact
15
+ cleansed.empty? ? backtrace : cleansed
16
+ end
17
+
18
+ protected
4
19
 
20
+ def backtrace_line(line)
21
+ return nil if RSpec.configuration.cleaned_from_backtrace?(line)
22
+ RSpec::Core::Metadata::relative_path(line)
23
+ rescue SecurityError
24
+ nil
25
+ end
26
+ end
27
+
28
+ module Formatters
5
29
  module Helpers
30
+ include BacktraceFormatter
31
+
6
32
  SUB_SECOND_PRECISION = 5
7
33
  DEFAULT_PRECISION = 2
8
34
 
@@ -11,9 +37,9 @@ module RSpec
11
37
  minutes = duration.to_i / 60
12
38
  seconds = duration - minutes * 60
13
39
 
14
- "#{pluralize(minutes, 'minute')} #{format_seconds(seconds)} seconds"
40
+ "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds), 'second')}"
15
41
  else
16
- "#{format_seconds(duration)} seconds"
42
+ pluralize(format_seconds(duration), 'second')
17
43
  end
18
44
  end
19
45
 
@@ -29,9 +55,8 @@ module RSpec
29
55
  end
30
56
 
31
57
  def pluralize(count, string)
32
- "#{count} #{string}#{'s' unless count == 1}"
58
+ "#{count} #{string}#{'s' unless count.to_f == 1}"
33
59
  end
34
-
35
60
  end
36
61
 
37
62
  end
@@ -1,17 +1,17 @@
1
- require 'erb'
2
1
  require 'rspec/core/formatters/base_text_formatter'
2
+ require 'rspec/core/formatters/html_printer'
3
3
 
4
4
  module RSpec
5
5
  module Core
6
6
  module Formatters
7
7
  class HtmlFormatter < BaseTextFormatter
8
- include ERB::Util # for the #h method
9
8
 
10
9
  def initialize(output)
11
10
  super(output)
12
11
  @example_group_number = 0
13
12
  @example_number = 0
14
13
  @header_red = nil
14
+ @printer = HtmlPrinter.new(output)
15
15
  end
16
16
 
17
17
  private
@@ -35,29 +35,25 @@ module RSpec
35
35
 
36
36
  def start(example_count)
37
37
  super(example_count)
38
- @output.puts html_header
39
- @output.puts report_header
40
- @output.flush
38
+ @printer.print_html_start
39
+ @printer.flush
41
40
  end
42
41
 
43
42
  def example_group_started(example_group)
44
43
  super(example_group)
45
44
  @example_group_red = false
46
45
  @example_group_number += 1
46
+
47
47
  unless example_group_number == 1
48
- @output.puts " </dl>"
49
- @output.puts "</div>"
48
+ @printer.print_example_group_end
50
49
  end
51
- @output.puts "<div id=\"div_group_#{example_group_number}\" class=\"example_group passed\">"
52
- @output.puts " <dl #{current_indentation}>"
53
- @output.puts " <dt id=\"example_group_#{example_group_number}\" class=\"passed\">#{h(example_group.description)}</dt>"
54
- @output.flush
50
+ @printer.print_example_group_start( example_group_number, example_group.description, example_group.parent_groups.size )
51
+ @printer.flush
55
52
  end
56
53
 
57
54
  def start_dump
58
- @output.puts " </dl>"
59
- @output.puts "</div>"
60
- @output.flush
55
+ @printer.print_example_group_end
56
+ @printer.flush
61
57
  end
62
58
 
63
59
  def example_started(example)
@@ -66,41 +62,55 @@ module RSpec
66
62
  end
67
63
 
68
64
  def example_passed(example)
69
- move_progress
70
- @output.puts " <dd class=\"example passed\"><span class=\"passed_spec_name\">#{h(example.description)}</span><span class='duration'>#{sprintf("%.5f", example.execution_result[:run_time])}s</span></dd>"
71
- @output.flush
65
+ @printer.move_progress(percent_done)
66
+ @printer.print_example_passed( example.description, example.execution_result[:run_time] )
67
+ @printer.flush
72
68
  end
73
69
 
74
70
  def example_failed(example)
75
71
  super(example)
72
+
73
+ unless @header_red
74
+ @header_red = true
75
+ @printer.make_header_red
76
+ end
77
+
78
+ unless @example_group_red
79
+ @example_group_red = true
80
+ @printer.make_example_group_header_red(example_group_number)
81
+ end
82
+
83
+ @printer.move_progress(percent_done)
84
+
76
85
  exception = example.metadata[:execution_result][:exception]
86
+ exception_details = if exception
87
+ {
88
+ :message => exception.message,
89
+ :backtrace => format_backtrace(exception.backtrace, example.metadata).join("\n")
90
+ }
91
+ else
92
+ false
93
+ end
77
94
  extra = extra_failure_content(exception)
78
- @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red
79
- @header_red = true
80
- @output.puts " <script type=\"text/javascript\">makeRed('div_group_#{example_group_number}');</script>" unless @example_group_red
81
- @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{example_group_number}');</script>" unless @example_group_red
82
- @example_group_red = true
83
- move_progress
84
- @output.puts " <dd class=\"example #{exception.pending_fixed? ? 'pending_fixed' : 'failed'}\">"
85
- @output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>"
86
- @output.puts " <span class=\"duration\">#{sprintf('%.5f', example.execution_result[:run_time])}s</span>"
87
- @output.puts " <div class=\"failure\" id=\"failure_#{@failed_examples.size}\">"
88
- @output.puts " <div class=\"message\"><pre>#{h(exception.message)}</pre></div>" unless exception.nil?
89
- @output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(exception.backtrace, example).join("\n")}</pre></div>" if exception
90
- @output.puts extra unless extra == ""
91
- @output.puts " </div>"
92
- @output.puts " </dd>"
93
- @output.flush
95
+
96
+ @printer.print_example_failed(
97
+ exception.pending_fixed?,
98
+ example.description,
99
+ example.execution_result[:run_time],
100
+ @failed_examples.size,
101
+ exception_details,
102
+ (extra == "") ? false : extra
103
+ )
104
+ @printer.flush
94
105
  end
95
106
 
96
107
  def example_pending(example)
97
- message = example.metadata[:execution_result][:pending_message]
98
- @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
99
- @output.puts " <script type=\"text/javascript\">makeYellow('div_group_#{example_group_number}');</script>" unless @example_group_red
100
- @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{example_group_number}');</script>" unless @example_group_red
101
- move_progress
102
- @output.puts " <dd class=\"example not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>"
103
- @output.flush
108
+
109
+ @printer.make_header_yellow unless @header_red
110
+ @printer.make_example_group_header_yellow(example_group_number) unless @example_group_red
111
+ @printer.move_progress(percent_done)
112
+ @printer.print_example_pending( example.description, example.metadata[:execution_result][:pending_message] )
113
+ @printer.flush
104
114
  end
105
115
 
106
116
  # Override this method if you wish to output extra HTML for a failed spec. For example, you
@@ -114,11 +124,6 @@ module RSpec
114
124
  " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
115
125
  end
116
126
 
117
- def move_progress
118
- @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
119
- @output.flush
120
- end
121
-
122
127
  def percent_done
123
128
  result = 100.0
124
129
  if @example_count > 0
@@ -134,329 +139,14 @@ module RSpec
134
139
  end
135
140
 
136
141
  def dump_summary(duration, example_count, failure_count, pending_count)
137
- # TODO - kill dry_run?
138
- if dry_run?
139
- totals = "This was a dry-run"
140
- else
141
- totals = "#{example_count} example#{'s' unless example_count == 1}, "
142
- totals << "#{failure_count} failure#{'s' unless failure_count == 1}"
143
- totals << ", #{pending_count} pending" if pending_count > 0
144
- end
145
- @output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{sprintf("%.5f", duration)} seconds</strong>\";</script>"
146
- @output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
147
- @output.puts "</div>"
148
- @output.puts "</div>"
149
- @output.puts "</body>"
150
- @output.puts "</html>"
151
- @output.flush
152
- end
153
-
154
- def current_indentation
155
- "style=\"margin-left: #{(example_group.ancestors.size - 1) * 15}px;\""
156
- end
157
-
158
- def html_header
159
- <<-EOF
160
- <?xml version="1.0" encoding="UTF-8"?>
161
- <!DOCTYPE html
162
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
163
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
164
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
165
- <head>
166
- <title>RSpec results</title>
167
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
168
- <meta http-equiv="Expires" content="-1" />
169
- <meta http-equiv="Pragma" content="no-cache" />
170
- <style type="text/css">
171
- body {
172
- margin: 0;
173
- padding: 0;
174
- background: #fff;
175
- font-size: 80%;
176
- }
177
- </style>
178
- <script type="text/javascript">
179
- // <![CDATA[
180
- #{global_scripts}
181
- // ]]>
182
- </script>
183
- <style type="text/css">
184
- #{global_styles}
185
- </style>
186
- </head>
187
- <body>
188
- EOF
189
- end
190
-
191
- def report_header
192
- <<-EOF
193
- <div class="rspec-report">
194
-
195
- <div id="rspec-header">
196
- <div id="label">
197
- <h1>RSpec Code Examples</h1>
198
- </div>
199
-
200
- <div id="display-filters">
201
- <input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked onchange="apply_filters()" value="1"> <label for="passed_checkbox">Passed</label>
202
- <input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked onchange="apply_filters()" value="2"> <label for="failed_checkbox">Failed</label>
203
- <input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked onchange="apply_filters()" value="3"> <label for="pending_checkbox">Pending</label>
204
- </div>
205
-
206
- <div id="summary">
207
- <p id="totals">&nbsp;</p>
208
- <p id="duration">&nbsp;</p>
209
- </div>
210
- </div>
211
-
212
-
213
- <div class="results">
214
- EOF
215
- end
216
-
217
- def global_scripts
218
- <<-EOF
219
-
220
- function addClass(element_id, classname) {
221
- document.getElementById(element_id).className += (" " + classname);
222
- }
223
-
224
- function removeClass(element_id, classname) {
225
- var elem = document.getElementById(element_id);
226
- var classlist = elem.className.replace(classname,'');
227
- elem.className = classlist;
228
- }
229
-
230
- function moveProgressBar(percentDone) {
231
- document.getElementById("rspec-header").style.width = percentDone +"%";
232
- }
233
-
234
- function makeRed(element_id) {
235
- removeClass(element_id, 'passed');
236
- removeClass(element_id, 'not_implemented');
237
- addClass(element_id,'failed');
238
- }
239
-
240
- function makeYellow(element_id) {
241
- var elem = document.getElementById(element_id);
242
- if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed
243
- if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
244
- removeClass(element_id, 'passed');
245
- addClass(element_id,'not_implemented');
246
- }
247
- }
248
- }
249
-
250
- function apply_filters() {
251
- var passed_filter = document.getElementById('passed_checkbox').checked;
252
- var failed_filter = document.getElementById('failed_checkbox').checked;
253
- var pending_filter = document.getElementById('pending_checkbox').checked;
254
-
255
- assign_display_style("example passed", passed_filter);
256
- assign_display_style("example failed", failed_filter);
257
- assign_display_style("example not_implemented", pending_filter);
258
-
259
- assign_display_style_for_group("example_group passed", passed_filter);
260
- assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
261
- assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
262
- }
263
-
264
- function get_display_style(display_flag) {
265
- var style_mode = 'none';
266
- if (display_flag == true) {
267
- style_mode = 'block';
268
- }
269
- return style_mode;
270
- }
271
-
272
- function assign_display_style(classname, display_flag) {
273
- var style_mode = get_display_style(display_flag);
274
- var elems = document.getElementsByClassName(classname)
275
- for (var i=0; i<elems.length;i++) {
276
- elems[i].style.display = style_mode;
277
- }
278
- }
279
-
280
- function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
281
- var display_style_mode = get_display_style(display_flag);
282
- var subgroup_style_mode = get_display_style(subgroup_flag);
283
- var elems = document.getElementsByClassName(classname)
284
- for (var i=0; i<elems.length;i++) {
285
- var style_mode = display_style_mode;
286
- if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
287
- elems[i].style.display = subgroup_style_mode;
288
- } else {
289
- elems[i].style.display = display_style_mode;
290
- }
291
- }
292
- }
293
- EOF
294
- end
295
-
296
- def global_styles
297
- <<-EOF
298
- #rspec-header {
299
- background: #65C400; color: #fff; height: 4em;
300
- }
301
-
302
- .rspec-report h1 {
303
- margin: 0px 10px 0px 10px;
304
- padding: 10px;
305
- font-family: "Lucida Grande", Helvetica, sans-serif;
306
- font-size: 1.8em;
307
- position: absolute;
308
- }
309
-
310
- #label {
311
- float:left;
312
- }
313
-
314
- #display-filters {
315
- float:left;
316
- padding: 28px 0 0 40%;
317
- font-family: "Lucida Grande", Helvetica, sans-serif;
318
- }
319
-
320
- #summary {
321
- float:right;
322
- padding: 5px 10px;
323
- font-family: "Lucida Grande", Helvetica, sans-serif;
324
- text-align: right;
325
- }
326
-
327
- #summary p {
328
- margin: 0 0 0 2px;
329
- }
330
-
331
- #summary #totals {
332
- font-size: 1.2em;
333
- }
334
-
335
- .example_group {
336
- margin: 0 10px 5px;
337
- background: #fff;
338
- }
339
-
340
- dl {
341
- margin: 0; padding: 0 0 5px;
342
- font: normal 11px "Lucida Grande", Helvetica, sans-serif;
343
- }
344
-
345
- dt {
346
- padding: 3px;
347
- background: #65C400;
348
- color: #fff;
349
- font-weight: bold;
350
- }
351
-
352
- dd {
353
- margin: 5px 0 5px 5px;
354
- padding: 3px 3px 3px 18px;
355
- }
356
-
357
- dd .duration {
358
- padding-left: 5px;
359
- text-align: right;
360
- right: 0px;
361
- float:right;
362
- }
363
-
364
- dd.example.passed {
365
- border-left: 5px solid #65C400;
366
- border-bottom: 1px solid #65C400;
367
- background: #DBFFB4; color: #3D7700;
368
- }
369
-
370
- dd.example.not_implemented {
371
- border-left: 5px solid #FAF834;
372
- border-bottom: 1px solid #FAF834;
373
- background: #FCFB98; color: #131313;
374
- }
375
-
376
- dd.example.pending_fixed {
377
- border-left: 5px solid #0000C2;
378
- border-bottom: 1px solid #0000C2;
379
- color: #0000C2; background: #D3FBFF;
380
- }
381
-
382
- dd.example.failed {
383
- border-left: 5px solid #C20000;
384
- border-bottom: 1px solid #C20000;
385
- color: #C20000; background: #FFFBD3;
386
- }
387
-
388
-
389
- dt.not_implemented {
390
- color: #000000; background: #FAF834;
391
- }
392
-
393
- dt.pending_fixed {
394
- color: #FFFFFF; background: #C40D0D;
395
- }
396
-
397
- dt.failed {
398
- color: #FFFFFF; background: #C40D0D;
399
- }
400
-
401
-
402
- #rspec-header.not_implemented {
403
- color: #000000; background: #FAF834;
404
- }
405
-
406
- #rspec-header.pending_fixed {
407
- color: #FFFFFF; background: #C40D0D;
408
- }
409
-
410
- #rspec-header.failed {
411
- color: #FFFFFF; background: #C40D0D;
412
- }
413
-
414
-
415
- .backtrace {
416
- color: #000;
417
- font-size: 12px;
418
- }
419
-
420
- a {
421
- color: #BE5C00;
422
- }
423
-
424
- /* Ruby code, style similar to vibrant ink */
425
- .ruby {
426
- font-size: 12px;
427
- font-family: monospace;
428
- color: white;
429
- background-color: black;
430
- padding: 0.1em 0 0.2em 0;
431
- }
432
-
433
- .ruby .keyword { color: #FF6600; }
434
- .ruby .constant { color: #339999; }
435
- .ruby .attribute { color: white; }
436
- .ruby .global { color: white; }
437
- .ruby .module { color: white; }
438
- .ruby .class { color: white; }
439
- .ruby .string { color: #66FF00; }
440
- .ruby .ident { color: white; }
441
- .ruby .method { color: #FFCC00; }
442
- .ruby .number { color: white; }
443
- .ruby .char { color: white; }
444
- .ruby .comment { color: #9933CC; }
445
- .ruby .symbol { color: white; }
446
- .ruby .regex { color: #44B4CC; }
447
- .ruby .punct { color: white; }
448
- .ruby .escape { color: white; }
449
- .ruby .interp { color: white; }
450
- .ruby .expr { color: white; }
451
-
452
- .ruby .offending { background-color: gray; }
453
- .ruby .linenum {
454
- width: 75px;
455
- padding: 0.1em 1em 0.2em 0;
456
- color: #000000;
457
- background-color: #FFFBD3;
458
- }
459
- EOF
142
+ @printer.print_summary(
143
+ dry_run?,
144
+ duration,
145
+ example_count,
146
+ failure_count,
147
+ pending_count
148
+ )
149
+ @printer.flush
460
150
  end
461
151
  end
462
152
  end