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.
- data/Changelog.md +59 -0
- data/README.md +22 -0
- data/features/command_line/example_name_option.feature +5 -5
- data/features/command_line/exit_status.feature +6 -6
- data/features/command_line/format_option.feature +2 -2
- data/features/command_line/line_number_appended_to_path.feature +2 -2
- data/features/command_line/line_number_option.feature +2 -2
- data/features/command_line/pattern_option.feature +2 -2
- data/features/command_line/rake_task.feature +62 -8
- data/features/command_line/ruby.feature +1 -1
- data/features/command_line/tag.feature +1 -1
- data/features/configuration/alias_example_to.feature +2 -2
- data/features/configuration/custom_settings.feature +3 -3
- data/features/configuration/default_path.feature +3 -3
- data/features/configuration/fail_fast.feature +5 -5
- data/features/configuration/read_options_from_file.feature +4 -4
- data/features/example_groups/basic_structure.feature +2 -2
- data/features/example_groups/shared_context.feature +3 -3
- data/features/example_groups/shared_examples.feature +25 -7
- data/features/expectation_framework_integration/configure_expectation_framework.feature +6 -6
- data/features/filtering/exclusion_filters.feature +5 -5
- data/features/filtering/if_and_unless.feature +5 -5
- data/features/filtering/inclusion_filters.feature +5 -5
- data/features/filtering/run_all_when_everything_filtered.feature +3 -3
- data/features/formatters/custom_formatter.feature +2 -2
- data/features/formatters/json_formatter.feature +30 -0
- data/features/formatters/text_formatter.feature +5 -5
- data/features/helper_methods/arbitrary_methods.feature +2 -2
- data/features/helper_methods/let.feature +2 -2
- data/features/helper_methods/modules.feature +6 -6
- data/features/hooks/around_hooks.feature +11 -11
- data/features/hooks/before_and_after_hooks.feature +15 -11
- data/features/hooks/filtering.feature +6 -6
- data/features/metadata/current_example.feature +1 -1
- data/features/metadata/described_class.feature +1 -1
- data/features/metadata/user_defined.feature +4 -4
- data/features/mock_framework_integration/use_any_framework.feature +6 -6
- data/features/mock_framework_integration/use_flexmock.feature +5 -5
- data/features/mock_framework_integration/use_mocha.feature +5 -5
- data/features/mock_framework_integration/use_rr.feature +5 -5
- data/features/mock_framework_integration/use_rspec.feature +5 -5
- data/features/pending/pending_examples.feature +11 -11
- data/features/spec_files/arbitrary_file_suffix.feature +1 -1
- data/features/step_definitions/additional_cli_steps.rb +2 -0
- data/features/subject/attribute_of_subject.feature +5 -5
- data/features/subject/explicit_subject.feature +5 -5
- data/features/subject/implicit_receiver.feature +2 -2
- data/features/subject/implicit_subject.feature +3 -3
- data/lib/autotest/rspec2.rb +1 -1
- data/lib/rspec/core.rb +53 -32
- data/lib/rspec/core/configuration.rb +123 -15
- data/lib/rspec/core/configuration_options.rb +17 -2
- data/lib/rspec/core/example.rb +5 -4
- data/lib/rspec/core/example_group.rb +19 -9
- data/lib/rspec/core/extensions/ordered.rb +12 -6
- data/lib/rspec/core/formatters.rb +55 -0
- data/lib/rspec/core/formatters/base_formatter.rb +43 -38
- data/lib/rspec/core/formatters/base_text_formatter.rb +9 -5
- data/lib/rspec/core/formatters/documentation_formatter.rb +1 -1
- data/lib/rspec/core/formatters/helpers.rb +30 -5
- data/lib/rspec/core/formatters/html_formatter.rb +58 -368
- data/lib/rspec/core/formatters/html_printer.rb +407 -0
- data/lib/rspec/core/formatters/json_formatter.rb +73 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +3 -1
- data/lib/rspec/core/hooks.rb +4 -4
- data/lib/rspec/core/metadata.rb +14 -6
- data/lib/rspec/core/mocking/with_mocha.rb +25 -2
- data/lib/rspec/core/mocking/with_rspec.rb +6 -2
- data/lib/rspec/core/option_parser.rb +28 -7
- data/lib/rspec/core/project_initializer.rb +0 -1
- data/lib/rspec/core/rake_task.rb +49 -38
- data/lib/rspec/core/reporter.rb +2 -2
- data/lib/rspec/core/shared_example_group.rb +89 -41
- data/lib/rspec/core/subject.rb +6 -2
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +2 -2
- data/spec/autotest/rspec_spec.rb +6 -1
- data/spec/command_line/order_spec.rb +67 -0
- data/spec/rspec/core/configuration_options_spec.rb +45 -38
- data/spec/rspec/core/configuration_spec.rb +219 -44
- data/spec/rspec/core/deprecations_spec.rb +9 -0
- data/spec/rspec/core/drb_command_line_spec.rb +1 -7
- data/spec/rspec/core/drb_options_spec.rb +1 -1
- data/spec/rspec/core/dsl_spec.rb +17 -9
- data/spec/rspec/core/example_group_spec.rb +51 -5
- data/spec/rspec/core/example_spec.rb +39 -7
- data/spec/rspec/core/filter_manager_spec.rb +20 -30
- data/spec/rspec/core/formatters/base_formatter_spec.rb +29 -1
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +6 -2
- data/spec/rspec/core/formatters/helpers_spec.rb +12 -0
- data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +462 -0
- data/spec/rspec/core/formatters/html_formatted-1.9.2-jruby.html +410 -0
- data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +462 -0
- data/spec/rspec/core/formatters/html_formatter_spec.rb +11 -3
- data/spec/rspec/core/formatters/json_formatter_spec.rb +110 -0
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +8 -0
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-rbx.html +462 -0
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.2-jruby.html +410 -0
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-rbx.html +462 -0
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +11 -3
- data/spec/rspec/core/hooks_filtering_spec.rb +6 -6
- data/spec/rspec/core/metadata_spec.rb +29 -0
- data/spec/rspec/core/option_parser_spec.rb +42 -0
- data/spec/rspec/core/project_initializer_spec.rb +2 -2
- data/spec/rspec/core/rake_task_spec.rb +60 -17
- data/spec/rspec/core/reporter_spec.rb +17 -0
- data/spec/rspec/core/runner_spec.rb +1 -0
- data/spec/rspec/core/shared_example_group_spec.rb +17 -5
- data/spec/rspec/core/subject_spec.rb +11 -0
- data/spec/spec_helper.rb +32 -2
- data/spec/support/config_options_helper.rb +1 -10
- data/spec/support/helper_methods.rb +13 -0
- data/spec/support/isolated_directory.rb +10 -0
- data/spec/support/isolated_home_directory.rb +16 -0
- metadata +145 -148
- 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
|
-
#
|
25
|
-
#
|
26
|
-
#
|
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
|
-
#
|
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
|
-
#
|
36
|
-
#
|
39
|
+
# Invoked at the beginning of the execution of each example
|
40
|
+
# group.
|
37
41
|
#
|
38
|
-
#
|
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
|
-
#
|
45
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
198
|
+
group_and_parent_groups(example).find {|group| group.metadata[:shared_group_name]}
|
195
199
|
end
|
196
200
|
|
197
|
-
def
|
198
|
-
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
|
@@ -1,8 +1,34 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
|
-
module
|
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)}
|
40
|
+
"#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds), 'second')}"
|
15
41
|
else
|
16
|
-
|
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
|
-
@
|
39
|
-
@
|
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
|
-
@
|
49
|
-
@output.puts "</div>"
|
48
|
+
@printer.print_example_group_end
|
50
49
|
end
|
51
|
-
@
|
52
|
-
@
|
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
|
-
@
|
59
|
-
@
|
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
|
-
@
|
71
|
-
@
|
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
|
-
|
79
|
-
@
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
@
|
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
|
-
|
98
|
-
@
|
99
|
-
@
|
100
|
-
@
|
101
|
-
|
102
|
-
@
|
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
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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"> </p>
|
208
|
-
<p id="duration"> </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
|