opal-rspec-cj 0.4.4
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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.gitmodules +15 -0
- data/.travis.yml +13 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +8 -0
- data/README.md +147 -0
- data/Rakefile +26 -0
- data/config.ru +10 -0
- data/example/Gemfile +4 -0
- data/example/README.md +13 -0
- data/example/Rakefile +8 -0
- data/example/opal/user.rb +11 -0
- data/example/spec/user_spec.rb +15 -0
- data/lib/opal-rspec.rb +2 -0
- data/lib/opal/rspec.rb +20 -0
- data/lib/opal/rspec/rake_task.rb +63 -0
- data/lib/opal/rspec/version.rb +5 -0
- data/opal-rspec.gemspec +21 -0
- data/opal/opal-rspec.rb +1 -0
- data/opal/opal/rspec.rb +25 -0
- data/opal/opal/rspec/async.rb +289 -0
- data/opal/opal/rspec/browser_formatter.rb +188 -0
- data/opal/opal/rspec/fixes.rb +116 -0
- data/opal/opal/rspec/requires.rb +45 -0
- data/opal/opal/rspec/runner.rb +69 -0
- data/opal/opal/rspec/sprockets_runner.rb.erb +11 -0
- data/opal/opal/rspec/text_formatter.rb +74 -0
- data/spec/async_spec.rb +38 -0
- data/spec/example_spec.rb +163 -0
- data/spec/matchers_spec.rb +201 -0
- data/spec/mock_spec.rb +63 -0
- data/spec/named_subject_spec.rb +11 -0
- data/spec/should_syntax_spec.rb +17 -0
- data/vendor/spec_runner.js +50 -0
- data/vendor_lib/rspec-expectations.rb +1 -0
- data/vendor_lib/rspec.rb +3 -0
- data/vendor_lib/rspec/autorun.rb +2 -0
- data/vendor_lib/rspec/core.rb +203 -0
- data/vendor_lib/rspec/core/backport_random.rb +302 -0
- data/vendor_lib/rspec/core/backtrace_formatter.rb +65 -0
- data/vendor_lib/rspec/core/command_line.rb +36 -0
- data/vendor_lib/rspec/core/configuration.rb +1129 -0
- data/vendor_lib/rspec/core/configuration_options.rb +143 -0
- data/vendor_lib/rspec/core/drb_command_line.rb +26 -0
- data/vendor_lib/rspec/core/drb_options.rb +87 -0
- data/vendor_lib/rspec/core/dsl.rb +26 -0
- data/vendor_lib/rspec/core/example.rb +312 -0
- data/vendor_lib/rspec/core/example_group.rb +540 -0
- data/vendor_lib/rspec/core/filter_manager.rb +224 -0
- data/vendor_lib/rspec/core/flat_map.rb +17 -0
- data/vendor_lib/rspec/core/formatters.rb +54 -0
- data/vendor_lib/rspec/core/formatters/base_formatter.rb +291 -0
- data/vendor_lib/rspec/core/formatters/base_text_formatter.rb +307 -0
- data/vendor_lib/rspec/core/formatters/deprecation_formatter.rb +193 -0
- data/vendor_lib/rspec/core/formatters/documentation_formatter.rb +67 -0
- data/vendor_lib/rspec/core/formatters/helpers.rb +82 -0
- data/vendor_lib/rspec/core/formatters/html_formatter.rb +155 -0
- data/vendor_lib/rspec/core/formatters/html_printer.rb +408 -0
- data/vendor_lib/rspec/core/formatters/json_formatter.rb +99 -0
- data/vendor_lib/rspec/core/formatters/progress_formatter.rb +32 -0
- data/vendor_lib/rspec/core/formatters/snippet_extractor.rb +101 -0
- data/vendor_lib/rspec/core/hooks.rb +535 -0
- data/vendor_lib/rspec/core/memoized_helpers.rb +431 -0
- data/vendor_lib/rspec/core/metadata.rb +313 -0
- data/vendor_lib/rspec/core/mocking/with_absolutely_nothing.rb +11 -0
- data/vendor_lib/rspec/core/mocking/with_flexmock.rb +27 -0
- data/vendor_lib/rspec/core/mocking/with_mocha.rb +52 -0
- data/vendor_lib/rspec/core/mocking/with_rr.rb +27 -0
- data/vendor_lib/rspec/core/mocking/with_rspec.rb +27 -0
- data/vendor_lib/rspec/core/option_parser.rb +234 -0
- data/vendor_lib/rspec/core/ordering.rb +154 -0
- data/vendor_lib/rspec/core/pending.rb +110 -0
- data/vendor_lib/rspec/core/project_initializer.rb +88 -0
- data/vendor_lib/rspec/core/rake_task.rb +128 -0
- data/vendor_lib/rspec/core/reporter.rb +132 -0
- data/vendor_lib/rspec/core/ruby_project.rb +44 -0
- data/vendor_lib/rspec/core/runner.rb +97 -0
- data/vendor_lib/rspec/core/shared_context.rb +53 -0
- data/vendor_lib/rspec/core/shared_example_group.rb +146 -0
- data/vendor_lib/rspec/core/shared_example_group/collection.rb +27 -0
- data/vendor_lib/rspec/core/version.rb +7 -0
- data/vendor_lib/rspec/core/warnings.rb +22 -0
- data/vendor_lib/rspec/core/world.rb +131 -0
- data/vendor_lib/rspec/expectations.rb +75 -0
- data/vendor_lib/rspec/expectations/differ.rb +154 -0
- data/vendor_lib/rspec/expectations/errors.rb +9 -0
- data/vendor_lib/rspec/expectations/expectation_target.rb +87 -0
- data/vendor_lib/rspec/expectations/extensions.rb +1 -0
- data/vendor_lib/rspec/expectations/extensions/object.rb +29 -0
- data/vendor_lib/rspec/expectations/fail_with.rb +79 -0
- data/vendor_lib/rspec/expectations/handler.rb +68 -0
- data/vendor_lib/rspec/expectations/syntax.rb +182 -0
- data/vendor_lib/rspec/expectations/version.rb +8 -0
- data/vendor_lib/rspec/matchers.rb +633 -0
- data/vendor_lib/rspec/matchers/built_in.rb +39 -0
- data/vendor_lib/rspec/matchers/built_in/base_matcher.rb +68 -0
- data/vendor_lib/rspec/matchers/built_in/be.rb +213 -0
- data/vendor_lib/rspec/matchers/built_in/be_instance_of.rb +15 -0
- data/vendor_lib/rspec/matchers/built_in/be_kind_of.rb +11 -0
- data/vendor_lib/rspec/matchers/built_in/be_within.rb +55 -0
- data/vendor_lib/rspec/matchers/built_in/change.rb +141 -0
- data/vendor_lib/rspec/matchers/built_in/cover.rb +21 -0
- data/vendor_lib/rspec/matchers/built_in/eq.rb +22 -0
- data/vendor_lib/rspec/matchers/built_in/eql.rb +23 -0
- data/vendor_lib/rspec/matchers/built_in/equal.rb +48 -0
- data/vendor_lib/rspec/matchers/built_in/exist.rb +26 -0
- data/vendor_lib/rspec/matchers/built_in/has.rb +48 -0
- data/vendor_lib/rspec/matchers/built_in/include.rb +61 -0
- data/vendor_lib/rspec/matchers/built_in/match.rb +17 -0
- data/vendor_lib/rspec/matchers/built_in/match_array.rb +51 -0
- data/vendor_lib/rspec/matchers/built_in/raise_error.rb +154 -0
- data/vendor_lib/rspec/matchers/built_in/respond_to.rb +74 -0
- data/vendor_lib/rspec/matchers/built_in/satisfy.rb +30 -0
- data/vendor_lib/rspec/matchers/built_in/start_and_end_with.rb +48 -0
- data/vendor_lib/rspec/matchers/built_in/throw_symbol.rb +94 -0
- data/vendor_lib/rspec/matchers/built_in/yield.rb +297 -0
- data/vendor_lib/rspec/matchers/compatibility.rb +14 -0
- data/vendor_lib/rspec/matchers/configuration.rb +113 -0
- data/vendor_lib/rspec/matchers/dsl.rb +23 -0
- data/vendor_lib/rspec/matchers/generated_descriptions.rb +35 -0
- data/vendor_lib/rspec/matchers/matcher.rb +301 -0
- data/vendor_lib/rspec/matchers/method_missing.rb +12 -0
- data/vendor_lib/rspec/matchers/operator_matcher.rb +99 -0
- data/vendor_lib/rspec/matchers/pretty.rb +70 -0
- data/vendor_lib/rspec/matchers/test_unit_integration.rb +11 -0
- data/vendor_lib/rspec/mocks.rb +100 -0
- data/vendor_lib/rspec/mocks/any_instance/chain.rb +92 -0
- data/vendor_lib/rspec/mocks/any_instance/expectation_chain.rb +47 -0
- data/vendor_lib/rspec/mocks/any_instance/message_chains.rb +75 -0
- data/vendor_lib/rspec/mocks/any_instance/recorder.rb +200 -0
- data/vendor_lib/rspec/mocks/any_instance/stub_chain.rb +45 -0
- data/vendor_lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
- data/vendor_lib/rspec/mocks/argument_list_matcher.rb +104 -0
- data/vendor_lib/rspec/mocks/argument_matchers.rb +264 -0
- data/vendor_lib/rspec/mocks/arity_calculator.rb +66 -0
- data/vendor_lib/rspec/mocks/configuration.rb +111 -0
- data/vendor_lib/rspec/mocks/error_generator.rb +203 -0
- data/vendor_lib/rspec/mocks/errors.rb +12 -0
- data/vendor_lib/rspec/mocks/example_methods.rb +201 -0
- data/vendor_lib/rspec/mocks/extensions/marshal.rb +17 -0
- data/vendor_lib/rspec/mocks/framework.rb +36 -0
- data/vendor_lib/rspec/mocks/instance_method_stasher.rb +112 -0
- data/vendor_lib/rspec/mocks/matchers/have_received.rb +99 -0
- data/vendor_lib/rspec/mocks/matchers/receive.rb +112 -0
- data/vendor_lib/rspec/mocks/matchers/receive_messages.rb +72 -0
- data/vendor_lib/rspec/mocks/message_expectation.rb +643 -0
- data/vendor_lib/rspec/mocks/method_double.rb +209 -0
- data/vendor_lib/rspec/mocks/method_reference.rb +95 -0
- data/vendor_lib/rspec/mocks/mock.rb +7 -0
- data/vendor_lib/rspec/mocks/mutate_const.rb +406 -0
- data/vendor_lib/rspec/mocks/object_reference.rb +90 -0
- data/vendor_lib/rspec/mocks/order_group.rb +82 -0
- data/vendor_lib/rspec/mocks/proxy.rb +269 -0
- data/vendor_lib/rspec/mocks/proxy_for_nil.rb +37 -0
- data/vendor_lib/rspec/mocks/space.rb +95 -0
- data/vendor_lib/rspec/mocks/standalone.rb +3 -0
- data/vendor_lib/rspec/mocks/stub_chain.rb +51 -0
- data/vendor_lib/rspec/mocks/syntax.rb +374 -0
- data/vendor_lib/rspec/mocks/targets.rb +90 -0
- data/vendor_lib/rspec/mocks/test_double.rb +109 -0
- data/vendor_lib/rspec/mocks/verifying_double.rb +77 -0
- data/vendor_lib/rspec/mocks/verifying_message_expecation.rb +60 -0
- data/vendor_lib/rspec/mocks/verifying_proxy.rb +151 -0
- data/vendor_lib/rspec/mocks/version.rb +7 -0
- data/vendor_lib/rspec/support.rb +6 -0
- data/vendor_lib/rspec/support/caller_filter.rb +56 -0
- data/vendor_lib/rspec/support/spec.rb +14 -0
- data/vendor_lib/rspec/support/spec/deprecation_helpers.rb +29 -0
- data/vendor_lib/rspec/support/spec/in_sub_process.rb +40 -0
- data/vendor_lib/rspec/support/spec/stderr_splitter.rb +50 -0
- data/vendor_lib/rspec/support/version.rb +7 -0
- data/vendor_lib/rspec/support/warnings.rb +41 -0
- data/vendor_lib/rspec/version.rb +5 -0
- metadata +268 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
require 'rspec/core/formatters/base_formatter'
|
|
2
|
+
require 'set'
|
|
3
|
+
|
|
4
|
+
module RSpec
|
|
5
|
+
module Core
|
|
6
|
+
module Formatters
|
|
7
|
+
|
|
8
|
+
# Base for all of RSpec's built-in formatters. See RSpec::Core::Formatters::BaseFormatter
|
|
9
|
+
# to learn more about all of the methods called by the reporter.
|
|
10
|
+
#
|
|
11
|
+
# @see RSpec::Core::Formatters::BaseFormatter
|
|
12
|
+
# @see RSpec::Core::Reporter
|
|
13
|
+
class BaseTextFormatter < BaseFormatter
|
|
14
|
+
def message(message)
|
|
15
|
+
output.puts message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def dump_failures
|
|
19
|
+
return if failed_examples.empty?
|
|
20
|
+
output.puts
|
|
21
|
+
output.puts "Failures:"
|
|
22
|
+
failed_examples.each_with_index do |example, index|
|
|
23
|
+
output.puts
|
|
24
|
+
pending_fixed?(example) ? dump_pending_fixed(example, index) : dump_failure(example, index)
|
|
25
|
+
dump_backtrace(example)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @api public
|
|
30
|
+
#
|
|
31
|
+
# Colorizes the output red for failure, yellow for
|
|
32
|
+
# pending, and green otherwise.
|
|
33
|
+
#
|
|
34
|
+
# @param [String] string
|
|
35
|
+
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)
|
|
40
|
+
else
|
|
41
|
+
color(summary, RSpec.configuration.success_color)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
|
46
|
+
super(duration, example_count, failure_count, pending_count)
|
|
47
|
+
dump_profile unless mute_profile_output?(failure_count)
|
|
48
|
+
output.puts "\nFinished in #{format_duration(duration)}\n"
|
|
49
|
+
output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
|
|
50
|
+
dump_commands_to_rerun_failed_examples
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @api public
|
|
54
|
+
#
|
|
55
|
+
# Outputs commands which can be used to re-run failed examples.
|
|
56
|
+
#
|
|
57
|
+
def dump_commands_to_rerun_failed_examples
|
|
58
|
+
return if failed_examples.empty?
|
|
59
|
+
output.puts
|
|
60
|
+
output.puts("Failed examples:")
|
|
61
|
+
output.puts
|
|
62
|
+
|
|
63
|
+
failed_examples.each do |example|
|
|
64
|
+
output.puts(failure_color("rspec #{RSpec::Core::Metadata::relative_path(example.location)}") + " " + detail_color("# #{example.full_description}"))
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @api public
|
|
69
|
+
#
|
|
70
|
+
# Outputs the slowest examples and example groups in a report when using `--profile COUNT` (default 10).
|
|
71
|
+
#
|
|
72
|
+
def dump_profile
|
|
73
|
+
dump_profile_slowest_examples
|
|
74
|
+
dump_profile_slowest_example_groups
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def dump_profile_slowest_examples
|
|
78
|
+
sorted_examples = slowest_examples
|
|
79
|
+
|
|
80
|
+
time_taken = sorted_examples[:slows] / sorted_examples[:total]
|
|
81
|
+
percentage = '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100)
|
|
82
|
+
|
|
83
|
+
output.puts "\nTop #{sorted_examples[:examples].size} slowest examples (#{format_seconds(sorted_examples[:slows])} seconds, #{percentage}% of total time):\n"
|
|
84
|
+
|
|
85
|
+
sorted_examples[:examples].each do |example|
|
|
86
|
+
output.puts " #{example.full_description}"
|
|
87
|
+
output.puts " #{bold(format_seconds(example.execution_result[:run_time]))} #{bold("seconds")} #{format_caller(example.location)}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def dump_profile_slowest_example_groups
|
|
92
|
+
|
|
93
|
+
sorted_groups = slowest_groups
|
|
94
|
+
return if sorted_groups.empty?
|
|
95
|
+
|
|
96
|
+
output.puts "\nTop #{sorted_groups.size} slowest example groups:"
|
|
97
|
+
slowest_groups.each do |loc, hash|
|
|
98
|
+
average = "#{bold(format_seconds(hash[:average]))} #{bold("seconds")} average"
|
|
99
|
+
total = "#{format_seconds(hash[:total_time])} seconds"
|
|
100
|
+
count = pluralize(hash[:count], "example")
|
|
101
|
+
output.puts " #{hash[:description]}"
|
|
102
|
+
output.puts " #{average} (#{total} / #{count}) #{loc}"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @api public
|
|
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
|
|
118
|
+
unless pending_examples.empty?
|
|
119
|
+
output.puts
|
|
120
|
+
output.puts "Pending:"
|
|
121
|
+
pending_examples.each do |pending_example|
|
|
122
|
+
output.puts pending_color(" #{pending_example.full_description}")
|
|
123
|
+
output.puts detail_color(" # #{pending_example.execution_result[:pending_message]}")
|
|
124
|
+
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
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def seed(number)
|
|
135
|
+
output.puts
|
|
136
|
+
output.puts "Randomized with seed #{number}"
|
|
137
|
+
output.puts
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def close
|
|
141
|
+
output.close if IO === output && output != $stdout
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
VT100_COLORS = {
|
|
145
|
+
:black => 30,
|
|
146
|
+
:red => 31,
|
|
147
|
+
:green => 32,
|
|
148
|
+
:yellow => 33,
|
|
149
|
+
:blue => 34,
|
|
150
|
+
:magenta => 35,
|
|
151
|
+
:cyan => 36,
|
|
152
|
+
:white => 37
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
VT100_COLOR_CODES = VT100_COLORS.values.to_set
|
|
156
|
+
|
|
157
|
+
def color_code_for(code_or_symbol)
|
|
158
|
+
if VT100_COLOR_CODES.include?(code_or_symbol)
|
|
159
|
+
code_or_symbol
|
|
160
|
+
else
|
|
161
|
+
VT100_COLORS.fetch(code_or_symbol) do
|
|
162
|
+
color_code_for(:white)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def colorize(text, code_or_symbol)
|
|
168
|
+
"\e[#{color_code_for(code_or_symbol)}m#{text}\e[0m"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
protected
|
|
172
|
+
|
|
173
|
+
def bold(text)
|
|
174
|
+
color_enabled? ? "\e[1m#{text}\e[0m" : text
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def color(text, color_code)
|
|
178
|
+
color_enabled? ? colorize(text, color_code) : text
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def failure_color(text)
|
|
182
|
+
color(text, RSpec.configuration.failure_color)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def success_color(text)
|
|
186
|
+
color(text, RSpec.configuration.success_color)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def pending_color(text)
|
|
190
|
+
color(text, RSpec.configuration.pending_color)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def fixed_color(text)
|
|
194
|
+
color(text, RSpec.configuration.fixed_color)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def detail_color(text)
|
|
198
|
+
color(text, RSpec.configuration.detail_color)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def default_color(text)
|
|
202
|
+
color(text, RSpec.configuration.default_color)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def red(text)
|
|
206
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#red", :replacement => "#failure_color")
|
|
207
|
+
color(text, :red)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def green(text)
|
|
211
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#green", :replacement => "#success_color")
|
|
212
|
+
color(text, :green)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def yellow(text)
|
|
216
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#yellow", :replacement => "#pending_color")
|
|
217
|
+
color(text, :yellow)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def blue(text)
|
|
221
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#blue", :replacement => "#fixed_color")
|
|
222
|
+
color(text, :blue)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def magenta(text)
|
|
226
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#magenta")
|
|
227
|
+
color(text, :magenta)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def cyan(text)
|
|
231
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#cyan", :replacement => "#detail_color")
|
|
232
|
+
color(text, :cyan)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def white(text)
|
|
236
|
+
RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#white", :replacement => "#default_color")
|
|
237
|
+
color(text, :white)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def short_padding
|
|
241
|
+
' '
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def long_padding
|
|
245
|
+
' '
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
private
|
|
249
|
+
|
|
250
|
+
def format_caller(caller_info)
|
|
251
|
+
configuration.backtrace_formatter.backtrace_line(caller_info.to_s.split(':in `block').first)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def dump_backtrace(example)
|
|
255
|
+
format_backtrace(example.execution_result[:exception].backtrace, example).each do |backtrace_info|
|
|
256
|
+
output.puts detail_color("#{long_padding}# #{backtrace_info}")
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def dump_pending_fixed(example, index)
|
|
261
|
+
output.puts "#{short_padding}#{index.next}) #{example.full_description} FIXED"
|
|
262
|
+
output.puts fixed_color("#{long_padding}Expected pending '#{example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised.")
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def pending_fixed?(example)
|
|
266
|
+
example.execution_result[:pending_fixed]
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def dump_failure(example, index)
|
|
270
|
+
output.puts "#{short_padding}#{index.next}) #{example.full_description}"
|
|
271
|
+
dump_failure_info(example)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def dump_failure_info(example)
|
|
275
|
+
exception = example.execution_result[:exception]
|
|
276
|
+
exception_class_name = exception_class_name_for(exception)
|
|
277
|
+
output.puts "#{long_padding}#{failure_color("Failure/Error:")} #{failure_color(read_failed_line(exception, example).strip)}"
|
|
278
|
+
output.puts "#{long_padding}#{failure_color(exception_class_name)}:" unless exception_class_name =~ /RSpec/
|
|
279
|
+
exception.message.to_s.split("\n").each { |line| output.puts "#{long_padding} #{failure_color(line)}" } if exception.message
|
|
280
|
+
|
|
281
|
+
if shared_group = find_shared_group(example)
|
|
282
|
+
dump_shared_failure_info(shared_group)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def exception_class_name_for(exception)
|
|
287
|
+
name = exception.class.name.to_s
|
|
288
|
+
name ="(anonymous error class)" if name == ''
|
|
289
|
+
name
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def dump_shared_failure_info(group)
|
|
293
|
+
output.puts "#{long_padding}Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " +
|
|
294
|
+
"#{configuration.backtrace_formatter.backtrace_line(group.metadata[:example_group][:location])}"
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def find_shared_group(example)
|
|
298
|
+
group_and_parent_groups(example).find {|group| group.metadata[:shared_group_name]}
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def group_and_parent_groups(example)
|
|
302
|
+
example.example_group.parent_groups + [example.example_group]
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require 'rspec/core/formatters/helpers'
|
|
2
|
+
require 'set'
|
|
3
|
+
|
|
4
|
+
module RSpec
|
|
5
|
+
module Core
|
|
6
|
+
module Formatters
|
|
7
|
+
class DeprecationFormatter
|
|
8
|
+
attr_reader :count, :deprecation_stream, :summary_stream
|
|
9
|
+
|
|
10
|
+
def initialize(deprecation_stream, summary_stream)
|
|
11
|
+
@deprecation_stream = deprecation_stream
|
|
12
|
+
@summary_stream = summary_stream
|
|
13
|
+
@seen_deprecations = Set.new
|
|
14
|
+
@count = 0
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def printer
|
|
18
|
+
@printer ||= case deprecation_stream
|
|
19
|
+
when File, RaiseErrorStream
|
|
20
|
+
ImmediatePrinter.new(deprecation_stream, summary_stream, self)
|
|
21
|
+
else
|
|
22
|
+
DelayedPrinter.new(deprecation_stream, summary_stream, self)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def deprecation(data)
|
|
27
|
+
return if @seen_deprecations.include?(data)
|
|
28
|
+
|
|
29
|
+
@count += 1
|
|
30
|
+
printer.print_deprecation_message data
|
|
31
|
+
@seen_deprecations << data
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def deprecation_summary
|
|
35
|
+
printer.deprecation_summary
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def deprecation_message_for(data)
|
|
39
|
+
if data[:message]
|
|
40
|
+
SpecifiedDeprecationMessage.new(data)
|
|
41
|
+
else
|
|
42
|
+
GeneratedDeprecationMessage.new(data)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
RAISE_ERROR_CONFIG_NOTICE = <<-EOS.gsub(/^\s+\|/, '')
|
|
47
|
+
|
|
|
48
|
+
|If you need more of the backtrace for any of these deprecations to
|
|
49
|
+
|identify where to make the necessary changes, you can configure
|
|
50
|
+
|`config.raise_errors_for_deprecations!`, and it will turn the
|
|
51
|
+
|deprecation warnings into errors, giving you the full backtrace.
|
|
52
|
+
EOS
|
|
53
|
+
|
|
54
|
+
SpecifiedDeprecationMessage = Struct.new(:type) do
|
|
55
|
+
def initialize(data)
|
|
56
|
+
@message = data[:message]
|
|
57
|
+
super deprecation_type_for(data)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def to_s
|
|
61
|
+
@message
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def too_many_warnings_message
|
|
65
|
+
msg = "Too many similar deprecation messages reported, disregarding further reports."
|
|
66
|
+
msg << " Set config.deprecation_stream to a File for full output."
|
|
67
|
+
msg
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def deprecation_type_for(data)
|
|
73
|
+
data[:message].gsub(/(\w+\/)+\w+\.rb:\d+/, '')
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
GeneratedDeprecationMessage = Struct.new(:type) do
|
|
78
|
+
def initialize(data)
|
|
79
|
+
@data = data
|
|
80
|
+
super data[:deprecated]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def to_s
|
|
84
|
+
msg = "#{@data[:deprecated]} is deprecated."
|
|
85
|
+
msg << " Use #{@data[:replacement]} instead." if @data[:replacement]
|
|
86
|
+
msg << " Called from #{@data[:call_site]}." if @data[:call_site]
|
|
87
|
+
msg
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def too_many_warnings_message
|
|
91
|
+
msg = "Too many uses of deprecated '#{type}'."
|
|
92
|
+
msg << " Set config.deprecation_stream to a File for full output."
|
|
93
|
+
msg
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class ImmediatePrinter
|
|
98
|
+
include ::RSpec::Core::Formatters::Helpers
|
|
99
|
+
|
|
100
|
+
attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter
|
|
101
|
+
|
|
102
|
+
def initialize(deprecation_stream, summary_stream, deprecation_formatter)
|
|
103
|
+
@deprecation_stream = deprecation_stream
|
|
104
|
+
|
|
105
|
+
# In one of my test suites, I got lots of duplicate output in the
|
|
106
|
+
# deprecation file (e.g. 200 of the same deprecation, even though
|
|
107
|
+
# the `puts` below was only called 6 times). Setting `sync = true`
|
|
108
|
+
# fixes this (but we really have no idea why!).
|
|
109
|
+
@deprecation_stream.sync = true
|
|
110
|
+
|
|
111
|
+
@summary_stream = summary_stream
|
|
112
|
+
@deprecation_formatter = deprecation_formatter
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def print_deprecation_message(data)
|
|
116
|
+
deprecation_message = deprecation_formatter.deprecation_message_for(data)
|
|
117
|
+
deprecation_stream.puts deprecation_message.to_s
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def deprecation_summary
|
|
121
|
+
if deprecation_formatter.count > 0
|
|
122
|
+
summary_stream.puts "\n#{pluralize(deprecation_formatter.count, 'deprecation')} logged to #{deprecation_stream.path}"
|
|
123
|
+
deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
class DelayedPrinter
|
|
129
|
+
TOO_MANY_USES_LIMIT = 4
|
|
130
|
+
|
|
131
|
+
include ::RSpec::Core::Formatters::Helpers
|
|
132
|
+
|
|
133
|
+
attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter
|
|
134
|
+
|
|
135
|
+
def initialize(deprecation_stream, summary_stream, deprecation_formatter)
|
|
136
|
+
@deprecation_stream = deprecation_stream
|
|
137
|
+
@summary_stream = summary_stream
|
|
138
|
+
@deprecation_formatter = deprecation_formatter
|
|
139
|
+
@seen_deprecations = Hash.new { 0 }
|
|
140
|
+
@deprecation_messages = Hash.new { |h, k| h[k] = [] }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def print_deprecation_message(data)
|
|
144
|
+
deprecation_message = deprecation_formatter.deprecation_message_for(data)
|
|
145
|
+
@seen_deprecations[deprecation_message] += 1
|
|
146
|
+
|
|
147
|
+
stash_deprecation_message(deprecation_message)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def stash_deprecation_message(deprecation_message)
|
|
151
|
+
if @seen_deprecations[deprecation_message] < TOO_MANY_USES_LIMIT
|
|
152
|
+
@deprecation_messages[deprecation_message] << deprecation_message.to_s
|
|
153
|
+
elsif @seen_deprecations[deprecation_message] == TOO_MANY_USES_LIMIT
|
|
154
|
+
@deprecation_messages[deprecation_message] << deprecation_message.too_many_warnings_message
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def deprecation_summary
|
|
159
|
+
return unless @deprecation_messages.any?
|
|
160
|
+
|
|
161
|
+
print_deferred_deprecation_warnings
|
|
162
|
+
deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE
|
|
163
|
+
|
|
164
|
+
summary_stream.puts "\n#{pluralize(deprecation_formatter.count, 'deprecation warning')} total"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def print_deferred_deprecation_warnings
|
|
168
|
+
deprecation_stream.puts "\nDeprecation Warnings:\n\n"
|
|
169
|
+
@deprecation_messages.keys.sort_by(&:type).each do |deprecation|
|
|
170
|
+
messages = @deprecation_messages[deprecation]
|
|
171
|
+
messages.each { |msg| deprecation_stream.puts msg }
|
|
172
|
+
deprecation_stream.puts
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Not really a stream, but is usable in place of one.
|
|
178
|
+
class RaiseErrorStream
|
|
179
|
+
def puts(message)
|
|
180
|
+
raise DeprecationError, message
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def sync=(value)
|
|
184
|
+
# no-op
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
DeprecationError = Class.new(StandardError)
|
|
192
|
+
end
|
|
193
|
+
end
|