rspec-core 3.0.0.beta1 → 3.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/Changelog.md +137 -0
- data/README.md +2 -2
- data/exe/rspec +2 -23
- data/features/README.md +1 -5
- data/features/command_line/README.md +7 -10
- data/features/command_line/exit_status.feature +1 -1
- data/features/command_line/format_option.feature +1 -1
- data/features/command_line/init.feature +40 -1
- data/features/command_line/line_number_option.feature +2 -2
- data/features/command_line/ruby.feature +5 -4
- data/features/configuration/enable_global_dsl.feature +54 -0
- data/features/example_groups/aliasing.feature +48 -0
- data/features/example_groups/basic_structure.feature +1 -1
- data/features/expectation_framework_integration/configure_expectation_framework.feature +1 -1
- data/features/filtering/if_and_unless.feature +0 -30
- data/features/formatters/custom_formatter.feature +32 -0
- data/features/formatters/regression_tests.feature +95 -0
- data/features/hooks/around_hooks.feature +1 -0
- data/features/hooks/before_and_after_hooks.feature +2 -2
- data/features/mock_framework_integration/use_flexmock.feature +11 -13
- data/features/mock_framework_integration/use_mocha.feature +11 -13
- data/features/mock_framework_integration/use_rr.feature +11 -13
- data/features/mock_framework_integration/use_rspec.feature +11 -13
- data/features/pending_and_skipped_examples/README.md +3 -0
- data/features/pending_and_skipped_examples/pending_examples.feature +118 -0
- data/features/pending_and_skipped_examples/skipped_examples.feature +106 -0
- data/features/step_definitions/additional_cli_steps.rb +34 -0
- data/features/subject/explicit_subject.feature +1 -1
- data/features/subject/one_liner_syntax.feature +71 -0
- data/lib/rspec/core.rb +6 -14
- data/lib/rspec/core/backtrace_formatter.rb +16 -4
- data/lib/rspec/core/command_line.rb +2 -3
- data/lib/rspec/core/configuration.rb +114 -125
- data/lib/rspec/core/configuration_options.rb +32 -18
- data/lib/rspec/core/dsl.rb +80 -18
- data/lib/rspec/core/example.rb +84 -33
- data/lib/rspec/core/example_group.rb +95 -43
- data/lib/rspec/core/filter_manager.rb +31 -40
- data/lib/rspec/core/formatters.rb +137 -0
- data/lib/rspec/core/formatters/base_formatter.rb +28 -41
- data/lib/rspec/core/formatters/base_text_formatter.rb +26 -37
- data/lib/rspec/core/formatters/deprecation_formatter.rb +48 -27
- data/lib/rspec/core/formatters/documentation_formatter.rb +27 -22
- data/lib/rspec/core/formatters/html_formatter.rb +48 -56
- data/lib/rspec/core/formatters/html_printer.rb +11 -18
- data/lib/rspec/core/formatters/json_formatter.rb +18 -22
- data/lib/rspec/core/formatters/legacy_formatter.rb +227 -0
- data/lib/rspec/core/formatters/progress_formatter.rb +7 -10
- data/lib/rspec/core/hooks.rb +250 -217
- data/lib/rspec/core/memoized_helpers.rb +43 -9
- data/lib/rspec/core/mocking_adapters/flexmock.rb +29 -0
- data/lib/rspec/core/{mocking/with_mocha.rb → mocking_adapters/mocha.rb} +19 -16
- data/lib/rspec/core/mocking_adapters/null.rb +12 -0
- data/lib/rspec/core/mocking_adapters/rr.rb +28 -0
- data/lib/rspec/core/mocking_adapters/rspec.rb +30 -0
- data/lib/rspec/core/notifications.rb +100 -0
- data/lib/rspec/core/option_parser.rb +11 -18
- data/lib/rspec/core/pending.rb +78 -47
- data/lib/rspec/core/project_initializer.rb +2 -49
- data/lib/rspec/core/project_initializer/dot_rspec +3 -0
- data/lib/rspec/core/project_initializer/spec_helper.rb +82 -0
- data/lib/rspec/core/rake_task.rb +5 -14
- data/lib/rspec/core/reporter.rb +24 -32
- data/lib/rspec/core/ruby_project.rb +1 -1
- data/lib/rspec/core/runner.rb +14 -4
- data/lib/rspec/core/shared_example_group.rb +40 -13
- data/lib/rspec/core/version.rb +1 -1
- data/spec/command_line/order_spec.rb +15 -15
- data/spec/rspec/core/backtrace_formatter_spec.rb +15 -1
- data/spec/rspec/core/command_line_spec.rb +18 -17
- data/spec/rspec/core/configuration_options_spec.rb +57 -34
- data/spec/rspec/core/configuration_spec.rb +162 -184
- data/spec/rspec/core/drb_command_line_spec.rb +5 -7
- data/spec/rspec/core/drb_options_spec.rb +2 -2
- data/spec/rspec/core/dsl_spec.rb +79 -15
- data/spec/rspec/core/example_group_spec.rb +253 -39
- data/spec/rspec/core/example_spec.rb +149 -33
- data/spec/rspec/core/filter_manager_spec.rb +9 -26
- data/spec/rspec/core/formatters/base_formatter_spec.rb +2 -5
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +42 -145
- data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +64 -34
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +15 -28
- data/spec/rspec/core/formatters/helpers_spec.rb +2 -2
- data/spec/rspec/core/formatters/{html_formatted-1.8.7.html → html_formatted-2.1.0.html} +22 -44
- data/spec/rspec/core/formatters/{html_formatted-1.8.7-jruby.html → html_formatted.html} +30 -49
- data/spec/rspec/core/formatters/html_formatter_spec.rb +35 -19
- data/spec/rspec/core/formatters/json_formatter_spec.rb +42 -40
- data/spec/rspec/core/formatters/legacy_formatter_spec.rb +137 -0
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +38 -25
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +1 -1
- data/spec/rspec/core/formatters_spec.rb +120 -0
- data/spec/rspec/core/hooks_filtering_spec.rb +1 -1
- data/spec/rspec/core/hooks_spec.rb +13 -2
- data/spec/rspec/core/memoized_helpers_spec.rb +17 -8
- data/spec/rspec/core/metadata_spec.rb +3 -3
- data/spec/rspec/core/option_parser_spec.rb +53 -46
- data/spec/rspec/core/ordering_spec.rb +4 -4
- data/spec/rspec/core/pending_example_spec.rb +23 -126
- data/spec/rspec/core/pending_spec.rb +8 -0
- data/spec/rspec/core/project_initializer_spec.rb +8 -41
- data/spec/rspec/core/rake_task_spec.rb +15 -4
- data/spec/rspec/core/random_spec.rb +1 -1
- data/spec/rspec/core/reporter_spec.rb +50 -37
- data/spec/rspec/core/resources/formatter_specs.rb +9 -11
- data/spec/rspec/core/rspec_matchers_spec.rb +1 -1
- data/spec/rspec/core/ruby_project_spec.rb +3 -3
- data/spec/rspec/core/runner_spec.rb +65 -23
- data/spec/rspec/core/shared_context_spec.rb +4 -4
- data/spec/rspec/core/shared_example_group/collection_spec.rb +1 -1
- data/spec/rspec/core/shared_example_group_spec.rb +20 -11
- data/spec/rspec/core/warnings_spec.rb +1 -1
- data/spec/rspec/core/world_spec.rb +10 -10
- data/spec/rspec/core_spec.rb +2 -2
- data/spec/spec_helper.rb +12 -24
- data/spec/support/config_options_helper.rb +1 -3
- data/spec/support/formatter_support.rb +83 -0
- data/spec/support/isolate_load_path_mutation.rb +1 -2
- data/spec/support/isolated_directory.rb +1 -1
- data/spec/support/isolated_home_directory.rb +1 -1
- data/spec/support/legacy_formatter_using_sub_classing_example.rb +87 -0
- data/spec/support/matchers.rb +20 -0
- data/spec/support/mathn_integration_support.rb +2 -2
- data/spec/support/old_style_formatter_example.rb +69 -0
- data/spec/support/shared_example_groups.rb +1 -1
- data/spec/support/spec_files.rb +3 -3
- metadata +192 -69
- metadata.gz.sig +3 -1
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -2
- data/features/configuration/show_failures_in_pending_blocks.feature +0 -61
- data/features/pending/pending_examples.feature +0 -229
- data/features/subject/implicit_receiver.feature +0 -29
- data/lib/rspec/core/mocking/with_absolutely_nothing.rb +0 -11
- data/lib/rspec/core/mocking/with_flexmock.rb +0 -27
- data/lib/rspec/core/mocking/with_rr.rb +0 -27
- data/lib/rspec/core/mocking/with_rspec.rb +0 -27
- data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +0 -477
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +0 -425
- data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +0 -416
- data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +0 -477
- data/spec/rspec/core/formatters/html_formatted-1.9.3.html +0 -419
- data/spec/rspec/core/formatters/html_formatted-2.0.0.html +0 -425
- data/spec/support/in_sub_process.rb +0 -37
- data/spec/support/sandboxed_mock_space.rb +0 -100
@@ -102,34 +102,16 @@ module RSpec
|
|
102
102
|
|
103
103
|
private
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
def reverse_merge(orig, opposite, *updates)
|
117
|
-
_warn_deprecated_keys(updates.last)
|
118
|
-
super
|
119
|
-
end
|
120
|
-
|
121
|
-
# Supports a use case that probably doesn't exist: overriding the
|
122
|
-
# if/unless procs.
|
123
|
-
def _warn_deprecated_keys(updates)
|
124
|
-
_warn_deprecated_key(:unless, updates) if updates.has_key?(:unless)
|
125
|
-
_warn_deprecated_key(:if, updates) if updates.has_key?(:if)
|
126
|
-
end
|
127
|
-
|
128
|
-
# Emits a deprecation warning for keys that will not be supported in
|
129
|
-
# the future.
|
130
|
-
def _warn_deprecated_key(key, updates)
|
131
|
-
RSpec.deprecate("FilterManager#exclude(#{key.inspect} => #{updates[key].inspect})")
|
132
|
-
@exclusions[key] = updates.delete(key)
|
105
|
+
if RUBY_VERSION.to_f < 2.1
|
106
|
+
def without_conditional_filters
|
107
|
+
# On 1.8.7, Hash#reject returns a hash but Hash#select returns an array.
|
108
|
+
reject {|k,v| CONDITIONAL_FILTERS[k] == v}
|
109
|
+
end
|
110
|
+
else
|
111
|
+
def without_conditional_filters
|
112
|
+
# On ruby 2.1 #reject on a subclass of Hash emits warnings, but #select does not.
|
113
|
+
select {|k,v| CONDITIONAL_FILTERS[k] != v}
|
114
|
+
end
|
133
115
|
end
|
134
116
|
end
|
135
117
|
|
@@ -138,7 +120,6 @@ module RSpec
|
|
138
120
|
def initialize
|
139
121
|
@exclusions = ExclusionFilterHash.new
|
140
122
|
@inclusions = InclusionFilterHash.new
|
141
|
-
extend(BackwardCompatibility)
|
142
123
|
end
|
143
124
|
|
144
125
|
def add_location(file_path, line_numbers)
|
@@ -147,8 +128,8 @@ module RSpec
|
|
147
128
|
# { "path/to/file.rb" => [37, 42] }
|
148
129
|
locations = @inclusions.delete(:locations) || Hash.new {|h,k| h[k] = []}
|
149
130
|
locations[File.expand_path(file_path)].push(*line_numbers)
|
150
|
-
|
151
|
-
|
131
|
+
|
132
|
+
replace_filters :locations => locations
|
152
133
|
end
|
153
134
|
|
154
135
|
def empty?
|
@@ -175,26 +156,36 @@ module RSpec
|
|
175
156
|
@exclusions.empty? ? false : example.any_apply?(@exclusions)
|
176
157
|
end
|
177
158
|
|
178
|
-
def include(*
|
179
|
-
|
159
|
+
def include(*filters)
|
160
|
+
set_standalone_filter(*filters) || merge(@inclusions, @exclusions, *filters)
|
180
161
|
end
|
181
162
|
|
182
|
-
def include!(*
|
183
|
-
|
163
|
+
def include!(*filters)
|
164
|
+
set_standalone_filter(*filters) || replace(@inclusions, @exclusions, *filters)
|
184
165
|
end
|
185
166
|
|
186
|
-
def include_with_low_priority(*
|
187
|
-
|
167
|
+
def include_with_low_priority(*filters)
|
168
|
+
set_standalone_filter(*filters) || reverse_merge(@inclusions, @exclusions, *filters)
|
188
169
|
end
|
189
170
|
|
190
171
|
def include?(example)
|
191
172
|
@inclusions.empty? ? true : example.any_apply?(@inclusions)
|
192
173
|
end
|
193
174
|
|
194
|
-
|
175
|
+
private
|
195
176
|
|
196
|
-
def
|
197
|
-
|
177
|
+
def set_standalone_filter(*args)
|
178
|
+
if already_set_standalone_filter?
|
179
|
+
true
|
180
|
+
elsif is_standalone_filter?(args.last)
|
181
|
+
replace_filters(args.last)
|
182
|
+
true
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def replace_filters(rule)
|
187
|
+
@inclusions.replace(rule)
|
188
|
+
@exclusions.clear
|
198
189
|
end
|
199
190
|
|
200
191
|
def merge(orig, opposite, *updates)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rspec/core/formatters/legacy_formatter'
|
2
|
+
|
1
3
|
# ## Built-in Formatters
|
2
4
|
#
|
3
5
|
# * progress (default) - prints dots for passing examples, `F` for failures, `*` for pending
|
@@ -51,4 +53,139 @@
|
|
51
53
|
# @see RSpec::Core::Formatters::BaseTextFormatter
|
52
54
|
# @see RSpec::Core::Reporter
|
53
55
|
module RSpec::Core::Formatters
|
56
|
+
autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
|
57
|
+
autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
|
58
|
+
autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
|
59
|
+
autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
|
60
|
+
|
61
|
+
def self.register(formatter_class, *notifications)
|
62
|
+
Loader.formatters[formatter_class] = notifications
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
#
|
67
|
+
# `RSpec::Core::Formatters::Loader` is an internal class for
|
68
|
+
# managing formatters used by a particular configuration. It is
|
69
|
+
# not expected to be used directly, but only through the configuration
|
70
|
+
# interface.
|
71
|
+
class Loader
|
72
|
+
# @api private
|
73
|
+
#
|
74
|
+
# Internal formatters are stored here when loaded
|
75
|
+
def self.formatters
|
76
|
+
@formatters ||= {}
|
77
|
+
end
|
78
|
+
|
79
|
+
# @api private
|
80
|
+
def initialize(reporter)
|
81
|
+
@formatters = []
|
82
|
+
@reporter = reporter
|
83
|
+
end
|
84
|
+
attr_reader :formatters, :reporter
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
def setup_default(output_stream, deprecation_stream)
|
88
|
+
if @formatters.empty?
|
89
|
+
add 'progress', output_stream
|
90
|
+
end
|
91
|
+
unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
|
92
|
+
add DeprecationFormatter, deprecation_stream, output_stream
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# @api private
|
97
|
+
def add(formatter_to_use, *paths)
|
98
|
+
formatter_class = find_formatter(formatter_to_use)
|
99
|
+
|
100
|
+
args = paths.map { |p| String === p ? file_at(p) : p }
|
101
|
+
|
102
|
+
if !Loader.formatters[formatter_class].nil?
|
103
|
+
formatter = formatter_class.new(*args)
|
104
|
+
@reporter.register_listener formatter, *notifications_for(formatter_class)
|
105
|
+
else
|
106
|
+
formatter = LegacyFormatter.new(formatter_class, *args)
|
107
|
+
@reporter.register_listener formatter, *formatter.notifications
|
108
|
+
end
|
109
|
+
|
110
|
+
@formatters << formatter unless duplicate_formatter_exists?(formatter)
|
111
|
+
if formatter.is_a?(LegacyFormatter)
|
112
|
+
RSpec.warn_deprecation "The #{formatter_class} formatter uses the deprecated formatter interface.\n Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}"
|
113
|
+
end
|
114
|
+
|
115
|
+
formatter
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def find_formatter(formatter_to_use)
|
121
|
+
built_in_formatter(formatter_to_use) ||
|
122
|
+
custom_formatter(formatter_to_use) ||
|
123
|
+
(raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
|
124
|
+
end
|
125
|
+
|
126
|
+
def duplicate_formatter_exists?(new_formatter)
|
127
|
+
@formatters.any? do |formatter|
|
128
|
+
formatter.class === new_formatter && formatter.output == new_formatter.output
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def built_in_formatter(key)
|
133
|
+
case key.to_s
|
134
|
+
when 'd', 'doc', 'documentation'
|
135
|
+
DocumentationFormatter
|
136
|
+
when 'h', 'html'
|
137
|
+
HtmlFormatter
|
138
|
+
when 'p', 'progress'
|
139
|
+
ProgressFormatter
|
140
|
+
when 'j', 'json'
|
141
|
+
JsonFormatter
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def notifications_for(formatter_class)
|
146
|
+
formatter_class.ancestors.inject(Set.new) do |notifications, klass|
|
147
|
+
notifications + Loader.formatters.fetch(klass) { Set.new }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def custom_formatter(formatter_ref)
|
152
|
+
if Class === formatter_ref
|
153
|
+
formatter_ref
|
154
|
+
elsif string_const?(formatter_ref)
|
155
|
+
begin
|
156
|
+
formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
|
157
|
+
rescue NameError
|
158
|
+
require( path_for(formatter_ref) ) ? retry : raise
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def string_const?(str)
|
164
|
+
str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
|
165
|
+
end
|
166
|
+
|
167
|
+
def path_for(const_ref)
|
168
|
+
underscore_with_fix_for_non_standard_rspec_naming(const_ref)
|
169
|
+
end
|
170
|
+
|
171
|
+
def underscore_with_fix_for_non_standard_rspec_naming(string)
|
172
|
+
underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
|
173
|
+
end
|
174
|
+
|
175
|
+
# activesupport/lib/active_support/inflector/methods.rb, line 48
|
176
|
+
def underscore(camel_cased_word)
|
177
|
+
word = camel_cased_word.to_s.dup
|
178
|
+
word.gsub!(/::/, '/')
|
179
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
180
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
181
|
+
word.tr!("-", "_")
|
182
|
+
word.downcase!
|
183
|
+
word
|
184
|
+
end
|
185
|
+
|
186
|
+
def file_at(path)
|
187
|
+
FileUtils.mkdir_p(File.dirname(path))
|
188
|
+
File.new(path, 'w')
|
189
|
+
end
|
190
|
+
end
|
54
191
|
end
|
@@ -5,16 +5,20 @@ 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
|
9
|
-
#
|
8
|
+
# but the BaseTextFormatter documents all of the notifications implemented as part of the standard
|
9
|
+
# interface. The reporter will issue these during a normal test suite run, but a formatter will
|
10
|
+
# only receive those notifications it has registered itself to receive.
|
10
11
|
#
|
11
12
|
# @see RSpec::Core::Formatters::BaseTextFormatter
|
12
13
|
# @see RSpec::Core::Reporter
|
13
14
|
class BaseFormatter
|
15
|
+
|
16
|
+
# all formatters inheriting from this formatter will receive these notifications
|
17
|
+
Formatters.register self, :start, :example_group_started, :example_started,
|
18
|
+
:example_pending, :example_failed, :close
|
14
19
|
include Helpers
|
15
20
|
attr_accessor :example_group
|
16
|
-
attr_reader :
|
17
|
-
attr_reader :example_count, :pending_count, :failure_count
|
21
|
+
attr_reader :examples, :output
|
18
22
|
attr_reader :failed_examples, :pending_examples
|
19
23
|
|
20
24
|
# @api public
|
@@ -39,9 +43,9 @@ module RSpec
|
|
39
43
|
# is {#example_group_started}.
|
40
44
|
#
|
41
45
|
# @param example_count
|
42
|
-
def start(
|
46
|
+
def start(notification)
|
43
47
|
start_sync_output
|
44
|
-
@example_count =
|
48
|
+
@example_count = notification.count
|
45
49
|
end
|
46
50
|
|
47
51
|
# @api public
|
@@ -54,17 +58,16 @@ module RSpec
|
|
54
58
|
# {#example_pending}, or {#example_group_finished}.
|
55
59
|
#
|
56
60
|
# @param example_group
|
57
|
-
def example_group_started(
|
58
|
-
@example_group =
|
61
|
+
def example_group_started(notification)
|
62
|
+
@example_group = notification.group
|
59
63
|
end
|
60
64
|
|
65
|
+
# @method example_group_finished
|
61
66
|
# @api public
|
62
67
|
#
|
63
68
|
# Invoked at the end of the execution of each example group.
|
64
69
|
#
|
65
70
|
# @param example_group subclass of `RSpec::Core::ExampleGroup`
|
66
|
-
def example_group_finished(example_group)
|
67
|
-
end
|
68
71
|
|
69
72
|
# @api public
|
70
73
|
#
|
@@ -72,24 +75,23 @@ module RSpec
|
|
72
75
|
#
|
73
76
|
# @param example instance of subclass of `RSpec::Core::ExampleGroup`
|
74
77
|
# @return [Array]
|
75
|
-
def example_started(
|
76
|
-
examples << example
|
78
|
+
def example_started(notification)
|
79
|
+
examples << notification.example
|
77
80
|
end
|
78
81
|
|
82
|
+
# @method example_passed
|
79
83
|
# @api public
|
80
84
|
#
|
81
85
|
# Invoked when an example passes.
|
82
86
|
#
|
83
87
|
# @param example instance of subclass of `RSpec::Core::ExampleGroup`
|
84
|
-
def example_passed(example)
|
85
|
-
end
|
86
88
|
|
87
89
|
# Invoked when an example is pending.
|
88
90
|
#
|
89
91
|
# @param example instance of subclass of `RSpec::Core::ExampleGroup`
|
90
92
|
# @return [Array]
|
91
|
-
def example_pending(
|
92
|
-
@pending_examples << example
|
93
|
+
def example_pending(notification)
|
94
|
+
@pending_examples << notification.example
|
93
95
|
end
|
94
96
|
|
95
97
|
# @api public
|
@@ -98,26 +100,25 @@ module RSpec
|
|
98
100
|
#
|
99
101
|
# @param example instance of subclass of `RSpec::Core::ExampleGroup`
|
100
102
|
# @return [Array]
|
101
|
-
def example_failed(
|
102
|
-
@failed_examples << example
|
103
|
+
def example_failed(notification)
|
104
|
+
@failed_examples << notification.example
|
103
105
|
end
|
104
106
|
|
107
|
+
# @method message
|
105
108
|
# @api public
|
106
109
|
#
|
107
110
|
# Used by the reporter to send messages to the output stream.
|
108
111
|
#
|
109
112
|
# @param [String] message
|
110
|
-
def message(message)
|
111
|
-
end
|
112
113
|
|
114
|
+
# @method stop
|
113
115
|
# @api public
|
114
116
|
#
|
115
117
|
# Invoked after all examples have executed, before dumping post-run reports.
|
116
118
|
#
|
117
119
|
# @return [nil]
|
118
|
-
def stop
|
119
|
-
end
|
120
120
|
|
121
|
+
# @method start_dump
|
121
122
|
# @api public
|
122
123
|
#
|
123
124
|
# This method is invoked after all of the examples have executed. The next method
|
@@ -125,17 +126,15 @@ module RSpec
|
|
125
126
|
# (BaseTextFormatter then calls {#dump_failure} once for each failed example.)
|
126
127
|
#
|
127
128
|
# @return [nil]
|
128
|
-
def start_dump
|
129
|
-
end
|
130
129
|
|
130
|
+
# @method dump_failures
|
131
131
|
# @api public
|
132
132
|
#
|
133
133
|
# Dumps detailed information about each example failure.
|
134
134
|
#
|
135
135
|
# @return [nil]
|
136
|
-
def dump_failures
|
137
|
-
end
|
138
136
|
|
137
|
+
# @method dump_summary
|
139
138
|
# @api public
|
140
139
|
#
|
141
140
|
# This method is invoked after the dumping of examples and failures. Each parameter
|
@@ -145,40 +144,28 @@ module RSpec
|
|
145
144
|
# @param example_count
|
146
145
|
# @param failure_count
|
147
146
|
# @param pending_count
|
148
|
-
def dump_summary(duration, example_count, failure_count, pending_count)
|
149
|
-
@duration = duration
|
150
|
-
@example_count = example_count
|
151
|
-
@failure_count = failure_count
|
152
|
-
@pending_count = pending_count
|
153
|
-
end
|
154
147
|
|
148
|
+
# @method dump_pending
|
155
149
|
# @api public
|
156
150
|
#
|
157
151
|
# Outputs a report of pending examples. This gets invoked
|
158
152
|
# after the summary if option is set to do so.
|
159
153
|
#
|
160
154
|
# @return [nil]
|
161
|
-
def dump_pending
|
162
|
-
end
|
163
155
|
|
156
|
+
# @method dump_profile
|
164
157
|
# @api public
|
165
158
|
#
|
166
159
|
# This methods is invoked form formatters to show slowest examples and example groups
|
167
160
|
# when using `--profile COUNT` (default 10).
|
168
161
|
#
|
169
162
|
# @return [nil]
|
170
|
-
def dump_profile
|
171
|
-
end
|
172
|
-
|
173
|
-
# @private not intended for use outside RSpec.
|
174
|
-
def seed(number)
|
175
|
-
end
|
176
163
|
|
177
164
|
# @api public
|
178
165
|
#
|
179
166
|
# Invoked at the very end, `close` allows the formatter to clean
|
180
167
|
# up resources, e.g. open streams, etc.
|
181
|
-
def close
|
168
|
+
def close(notification)
|
182
169
|
restore_sync_output
|
183
170
|
end
|
184
171
|
|
@@ -11,11 +11,14 @@ module RSpec
|
|
11
11
|
# @see RSpec::Core::Formatters::BaseFormatter
|
12
12
|
# @see RSpec::Core::Reporter
|
13
13
|
class BaseTextFormatter < BaseFormatter
|
14
|
-
|
15
|
-
|
14
|
+
Formatters.register self, :message, :dump_summary, :dump_failures,
|
15
|
+
:dump_profile, :dump_pending, :seed
|
16
|
+
|
17
|
+
def message(notification)
|
18
|
+
output.puts notification.message
|
16
19
|
end
|
17
20
|
|
18
|
-
def dump_failures
|
21
|
+
def dump_failures(notification)
|
19
22
|
return if failed_examples.empty?
|
20
23
|
output.puts
|
21
24
|
output.puts "Failures:"
|
@@ -33,20 +36,19 @@ module RSpec
|
|
33
36
|
#
|
34
37
|
# @param [String] string
|
35
38
|
def colorise_summary(summary)
|
36
|
-
if failure_count > 0
|
37
|
-
color(summary, RSpec.configuration.failure_color)
|
38
|
-
elsif pending_count > 0
|
39
|
-
color(summary, RSpec.configuration.pending_color)
|
39
|
+
if summary.failure_count > 0
|
40
|
+
color(summary.summary_line, RSpec.configuration.failure_color)
|
41
|
+
elsif summary.pending_count > 0
|
42
|
+
color(summary.summary_line, RSpec.configuration.pending_color)
|
40
43
|
else
|
41
|
-
color(summary, RSpec.configuration.success_color)
|
44
|
+
color(summary.summary_line, RSpec.configuration.success_color)
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
def dump_summary(
|
46
|
-
|
47
|
-
|
48
|
-
output.puts
|
49
|
-
output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
|
48
|
+
def dump_summary(summary)
|
49
|
+
dump_profile unless mute_profile_output?(summary.failure_count)
|
50
|
+
output.puts "\nFinished in #{format_duration(summary.duration)}\n"
|
51
|
+
output.puts colorise_summary(summary)
|
50
52
|
dump_commands_to_rerun_failed_examples
|
51
53
|
end
|
52
54
|
|
@@ -74,6 +76,7 @@ module RSpec
|
|
74
76
|
dump_profile_slowest_example_groups
|
75
77
|
end
|
76
78
|
|
79
|
+
# @api private
|
77
80
|
def dump_profile_slowest_examples
|
78
81
|
sorted_examples = slowest_examples
|
79
82
|
|
@@ -88,6 +91,7 @@ module RSpec
|
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
94
|
+
# @api private
|
91
95
|
def dump_profile_slowest_example_groups
|
92
96
|
|
93
97
|
sorted_groups = slowest_groups
|
@@ -103,18 +107,7 @@ module RSpec
|
|
103
107
|
end
|
104
108
|
end
|
105
109
|
|
106
|
-
|
107
|
-
#
|
108
|
-
# Outputs summary with number of examples, failures and pending.
|
109
|
-
#
|
110
|
-
def summary_line(example_count, failure_count, pending_count)
|
111
|
-
summary = pluralize(example_count, "example")
|
112
|
-
summary << ", " << pluralize(failure_count, "failure")
|
113
|
-
summary << ", #{pending_count} pending" if pending_count > 0
|
114
|
-
summary
|
115
|
-
end
|
116
|
-
|
117
|
-
def dump_pending
|
110
|
+
def dump_pending(notification)
|
118
111
|
unless pending_examples.empty?
|
119
112
|
output.puts
|
120
113
|
output.puts "Pending:"
|
@@ -122,22 +115,18 @@ module RSpec
|
|
122
115
|
output.puts pending_color(" #{pending_example.full_description}")
|
123
116
|
output.puts detail_color(" # #{pending_example.execution_result[:pending_message]}")
|
124
117
|
output.puts detail_color(" # #{format_caller(pending_example.location)}")
|
125
|
-
if pending_example.execution_result[:exception] \
|
126
|
-
&& RSpec.configuration.show_failures_in_pending_blocks?
|
127
|
-
dump_failure_info(pending_example)
|
128
|
-
dump_backtrace(pending_example)
|
129
|
-
end
|
130
118
|
end
|
131
119
|
end
|
132
120
|
end
|
133
121
|
|
134
|
-
def seed(
|
122
|
+
def seed(notification)
|
123
|
+
return unless notification.seed_used?
|
135
124
|
output.puts
|
136
|
-
output.puts "Randomized with seed #{
|
125
|
+
output.puts "Randomized with seed #{notification.seed}"
|
137
126
|
output.puts
|
138
127
|
end
|
139
128
|
|
140
|
-
def close
|
129
|
+
def close(notification)
|
141
130
|
output.close if IO === output && output != $stdout
|
142
131
|
end
|
143
132
|
|
@@ -251,8 +240,8 @@ module RSpec
|
|
251
240
|
configuration.backtrace_formatter.backtrace_line(caller_info.to_s.split(':in `block').first)
|
252
241
|
end
|
253
242
|
|
254
|
-
def dump_backtrace(example)
|
255
|
-
format_backtrace(example.execution_result[
|
243
|
+
def dump_backtrace(example, key = :exception)
|
244
|
+
format_backtrace(example.execution_result[key].backtrace, example).each do |backtrace_info|
|
256
245
|
output.puts detail_color("#{long_padding}# #{backtrace_info}")
|
257
246
|
end
|
258
247
|
end
|
@@ -271,8 +260,8 @@ module RSpec
|
|
271
260
|
dump_failure_info(example)
|
272
261
|
end
|
273
262
|
|
274
|
-
def dump_failure_info(example)
|
275
|
-
exception = example.execution_result[
|
263
|
+
def dump_failure_info(example, key = :exception)
|
264
|
+
exception = example.execution_result[key]
|
276
265
|
exception_class_name = exception_class_name_for(exception)
|
277
266
|
output.puts "#{long_padding}#{failure_color("Failure/Error:")} #{failure_color(read_failed_line(exception, example).strip)}"
|
278
267
|
output.puts "#{long_padding}#{failure_color(exception_class_name)}:" unless exception_class_name =~ /RSpec/
|