rspec-support 3.0.4 → 3.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +322 -0
- data/{LICENSE.txt → LICENSE.md} +3 -2
- data/README.md +29 -6
- data/lib/rspec/support/caller_filter.rb +35 -16
- data/lib/rspec/support/comparable_version.rb +46 -0
- data/lib/rspec/support/differ.rb +51 -41
- data/lib/rspec/support/directory_maker.rb +63 -0
- data/lib/rspec/support/encoded_string.rb +110 -15
- data/lib/rspec/support/fuzzy_matcher.rb +5 -6
- data/lib/rspec/support/hunk_generator.rb +0 -1
- data/lib/rspec/support/matcher_definition.rb +42 -0
- data/lib/rspec/support/method_signature_verifier.rb +287 -54
- data/lib/rspec/support/mutex.rb +73 -0
- data/lib/rspec/support/object_formatter.rb +275 -0
- data/lib/rspec/support/recursive_const_methods.rb +76 -0
- data/lib/rspec/support/reentrant_mutex.rb +78 -0
- data/lib/rspec/support/ruby_features.rb +177 -14
- data/lib/rspec/support/source/location.rb +21 -0
- data/lib/rspec/support/source/node.rb +110 -0
- data/lib/rspec/support/source/token.rb +94 -0
- data/lib/rspec/support/source.rb +85 -0
- data/lib/rspec/support/spec/deprecation_helpers.rb +19 -32
- data/lib/rspec/support/spec/diff_helpers.rb +31 -0
- data/lib/rspec/support/spec/in_sub_process.rb +43 -16
- data/lib/rspec/support/spec/library_wide_checks.rb +150 -0
- data/lib/rspec/support/spec/shell_out.rb +108 -0
- data/lib/rspec/support/spec/stderr_splitter.rb +31 -9
- data/lib/rspec/support/spec/string_matcher.rb +45 -0
- data/lib/rspec/support/spec/with_isolated_directory.rb +13 -0
- data/lib/rspec/support/spec/with_isolated_stderr.rb +0 -2
- data/lib/rspec/support/spec.rb +46 -26
- data/lib/rspec/support/version.rb +1 -1
- data/lib/rspec/support/warnings.rb +6 -6
- data/lib/rspec/support/with_keywords_when_needed.rb +33 -0
- data/lib/rspec/support.rb +87 -3
- data.tar.gz.sig +0 -0
- metadata +70 -52
- metadata.gz.sig +0 -0
- data/lib/rspec/support/version_checker.rb +0 -53
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'rake/file_utils'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Support
|
7
|
+
module ShellOut
|
8
|
+
def with_env(vars)
|
9
|
+
original = ENV.to_hash
|
10
|
+
vars.each { |k, v| ENV[k] = v }
|
11
|
+
|
12
|
+
begin
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
ENV.replace(original)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if Open3.respond_to?(:capture3) # 1.9+
|
20
|
+
def shell_out(*command)
|
21
|
+
stdout, stderr, status = Open3.capture3(*command)
|
22
|
+
return stdout, filter(stderr), status
|
23
|
+
end
|
24
|
+
else # 1.8.7
|
25
|
+
# popen3 doesn't provide the exit status so we fake it out.
|
26
|
+
FakeProcessStatus = Struct.new(:exitstatus)
|
27
|
+
|
28
|
+
def shell_out(*command)
|
29
|
+
stdout = stderr = nil
|
30
|
+
|
31
|
+
Open3.popen3(*command) do |_in, out, err|
|
32
|
+
stdout = out.read
|
33
|
+
stderr = err.read
|
34
|
+
end
|
35
|
+
|
36
|
+
status = FakeProcessStatus.new(0)
|
37
|
+
return stdout, filter(stderr), status
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def run_ruby_with_current_load_path(ruby_command, *flags)
|
42
|
+
command = [
|
43
|
+
FileUtils::RUBY,
|
44
|
+
"-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}",
|
45
|
+
"-e", ruby_command, *flags
|
46
|
+
]
|
47
|
+
|
48
|
+
# Unset these env vars because `ruby -w` will issue warnings whenever
|
49
|
+
# they are set to non-default values.
|
50
|
+
with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil,
|
51
|
+
'RUBY_FREE_MIN' => nil do
|
52
|
+
shell_out(*command)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
LINES_TO_IGNORE =
|
57
|
+
[
|
58
|
+
# Ignore bundler warning.
|
59
|
+
%r{bundler/source/rubygems},
|
60
|
+
# Ignore bundler + rubygems warning.
|
61
|
+
%r{site_ruby/\d\.\d\.\d/rubygems},
|
62
|
+
%r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/rubygems},
|
63
|
+
# This is required for windows for some reason
|
64
|
+
%r{lib/bundler/rubygems},
|
65
|
+
# This is a JRuby file that generates warnings on 9.0.3.0
|
66
|
+
%r{lib/ruby/stdlib/jar},
|
67
|
+
# This is a JRuby file that generates warnings on 9.1.7.0
|
68
|
+
%r{org/jruby/RubyKernel\.java},
|
69
|
+
# This is a JRuby gem that generates warnings on 9.1.7.0
|
70
|
+
%r{ffi-1\.13\.\d+-java},
|
71
|
+
%r{uninitialized constant FFI},
|
72
|
+
# These are related to the above, there is a warning about io from FFI
|
73
|
+
%r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/io},
|
74
|
+
%r{io/console on JRuby shells out to stty for most operations},
|
75
|
+
# This is a JRuby 9.1.17.0 error on Github Actions
|
76
|
+
%r{io/console not supported; tty will not be manipulated},
|
77
|
+
# This is a JRuby 9.2.1.x error
|
78
|
+
%r{jruby/kernel/gem_prelude},
|
79
|
+
%r{lib/jruby\.jar!/jruby/preludes},
|
80
|
+
# Ignore some JRuby errors for gems
|
81
|
+
%r{jruby/\d\.\d(\.\d)?/gems/aruba},
|
82
|
+
%r{jruby/\d\.\d(\.\d)?/gems/ffi},
|
83
|
+
]
|
84
|
+
|
85
|
+
def strip_known_warnings(input)
|
86
|
+
input.split("\n").reject do |l|
|
87
|
+
LINES_TO_IGNORE.any? { |to_ignore| l =~ to_ignore } ||
|
88
|
+
# Remove blank lines
|
89
|
+
l == "" || l.nil?
|
90
|
+
end.join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
if Ruby.jruby?
|
96
|
+
def filter(output)
|
97
|
+
output.each_line.reject do |line|
|
98
|
+
line.include?("lib/ruby/shared/rubygems")
|
99
|
+
end.join($/)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
def filter(output)
|
103
|
+
output
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -6,15 +6,16 @@ module RSpec
|
|
6
6
|
def initialize(original)
|
7
7
|
@orig_stderr = original
|
8
8
|
@output_tracker = ::StringIO.new
|
9
|
+
@last_line = nil
|
9
10
|
end
|
10
11
|
|
11
12
|
respond_to_name = (::RUBY_VERSION.to_f < 1.9) ? :respond_to? : :respond_to_missing?
|
12
13
|
define_method respond_to_name do |*args|
|
13
|
-
@orig_stderr.respond_to?(*args) || super
|
14
|
+
@orig_stderr.respond_to?(*args) || super(*args)
|
14
15
|
end
|
15
16
|
|
16
17
|
def method_missing(name, *args, &block)
|
17
|
-
@output_tracker.__send__(name, *args, &block)
|
18
|
+
@output_tracker.__send__(name, *args, &block) if @output_tracker.respond_to?(name)
|
18
19
|
@orig_stderr.__send__(name, *args, &block)
|
19
20
|
end
|
20
21
|
|
@@ -22,13 +23,35 @@ module RSpec
|
|
22
23
|
@orig_stderr == other
|
23
24
|
end
|
24
25
|
|
26
|
+
def reopen(*args)
|
27
|
+
reset!
|
28
|
+
@orig_stderr.reopen(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
# To work around JRuby error:
|
32
|
+
# can't convert RSpec::Support::StdErrSplitter into String
|
33
|
+
def to_io
|
34
|
+
@orig_stderr.to_io
|
35
|
+
end
|
36
|
+
|
25
37
|
# To work around JRuby error:
|
26
38
|
# TypeError: $stderr must have write method, RSpec::StdErrSplitter given
|
27
39
|
def write(line)
|
28
|
-
if line
|
29
|
-
|
30
|
-
|
31
|
-
|
40
|
+
return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG
|
41
|
+
|
42
|
+
# Ruby 2.7.0 warnings from keyword arguments span multiple lines, extend check above
|
43
|
+
# to look for the next line.
|
44
|
+
return if @last_line =~ %r{^\S+/gems/\S+:\d+: warning:} &&
|
45
|
+
line =~ %r{warning: The called method .* is defined here}
|
46
|
+
|
47
|
+
# Ruby 2.7.0 complains about hashes used in place of keyword arguments
|
48
|
+
# Aruba 0.14.2 uses this internally triggering that here
|
49
|
+
return if line =~ %r{lib/ruby/2\.7\.0/fileutils\.rb:622: warning:}
|
50
|
+
|
51
|
+
@orig_stderr.write(line)
|
52
|
+
@output_tracker.write(line)
|
53
|
+
ensure
|
54
|
+
@last_line = line
|
32
55
|
end
|
33
56
|
|
34
57
|
def has_output?
|
@@ -39,15 +62,14 @@ module RSpec
|
|
39
62
|
@output_tracker = ::StringIO.new
|
40
63
|
end
|
41
64
|
|
42
|
-
def
|
43
|
-
|
65
|
+
def verify_no_warnings!
|
66
|
+
raise "Warnings were generated: #{output}" if has_output?
|
44
67
|
reset!
|
45
68
|
end
|
46
69
|
|
47
70
|
def output
|
48
71
|
@output_tracker.string
|
49
72
|
end
|
50
|
-
|
51
73
|
end
|
52
74
|
end
|
53
75
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rspec/matchers'
|
2
|
+
# Special matcher for comparing encoded strings so that
|
3
|
+
# we don't run any expectation failures through the Differ,
|
4
|
+
# which also relies on EncodedString. Instead, confirm the
|
5
|
+
# strings have the same bytes.
|
6
|
+
RSpec::Matchers.define :be_identical_string do |expected|
|
7
|
+
if String.method_defined?(:encoding)
|
8
|
+
match do
|
9
|
+
expected_encoding? &&
|
10
|
+
actual.bytes.to_a == expected.bytes.to_a
|
11
|
+
end
|
12
|
+
|
13
|
+
failure_message do
|
14
|
+
"expected\n#{actual.inspect} (#{actual.encoding.name}) to be identical to\n"\
|
15
|
+
"#{expected.inspect} (#{expected.encoding.name})\n"\
|
16
|
+
"The exact bytes are printed below for more detail:\n"\
|
17
|
+
"#{actual.bytes.to_a}\n"\
|
18
|
+
"#{expected.bytes.to_a}\n"\
|
19
|
+
end
|
20
|
+
|
21
|
+
# Depends on chaining :with_same_encoding for it to
|
22
|
+
# check for string encoding.
|
23
|
+
def expected_encoding?
|
24
|
+
if defined?(@expect_same_encoding) && @expect_same_encoding
|
25
|
+
actual.encoding == expected.encoding
|
26
|
+
else
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
match do
|
32
|
+
actual.split(//) == expected.split(//)
|
33
|
+
end
|
34
|
+
|
35
|
+
failure_message do
|
36
|
+
"expected\n#{actual.inspect} to be identical to\n#{expected.inspect}\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
chain :with_same_encoding do
|
41
|
+
@expect_same_encoding ||= true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
RSpec::Matchers.alias_matcher :a_string_identical_to, :be_identical_string
|
45
|
+
RSpec::Matchers.alias_matcher :be_diffed_as, :be_identical_string
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
RSpec.shared_context "isolated directory" do
|
4
|
+
around do |ex|
|
5
|
+
Dir.mktmpdir do |tmp_dir|
|
6
|
+
Dir.chdir(tmp_dir, &ex)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.include_context "isolated directory", :isolated_directory => true
|
13
|
+
end
|
data/lib/rspec/support/spec.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'rspec/support'
|
2
|
+
require 'rspec/support/spec/in_sub_process'
|
3
|
+
|
2
4
|
RSpec::Support.require_rspec_support "spec/deprecation_helpers"
|
5
|
+
RSpec::Support.require_rspec_support "spec/diff_helpers"
|
3
6
|
RSpec::Support.require_rspec_support "spec/with_isolated_stderr"
|
4
7
|
RSpec::Support.require_rspec_support "spec/stderr_splitter"
|
5
8
|
RSpec::Support.require_rspec_support "spec/formatting_support"
|
9
|
+
RSpec::Support.require_rspec_support "spec/with_isolated_directory"
|
10
|
+
RSpec::Support.require_rspec_support "ruby_features"
|
6
11
|
|
7
12
|
warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
|
8
13
|
|
@@ -10,14 +15,15 @@ RSpec.configure do |c|
|
|
10
15
|
c.include RSpecHelpers
|
11
16
|
c.include RSpec::Support::WithIsolatedStdErr
|
12
17
|
c.include RSpec::Support::FormattingSupport
|
18
|
+
c.include RSpec::Support::InSubProcess
|
13
19
|
|
14
20
|
unless defined?(Debugger) # debugger causes warnings when used
|
15
21
|
c.before do
|
16
22
|
warning_preventer.reset!
|
17
23
|
end
|
18
24
|
|
19
|
-
c.after do
|
20
|
-
warning_preventer.
|
25
|
+
c.after do
|
26
|
+
warning_preventer.verify_no_warnings!
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
@@ -26,37 +32,51 @@ RSpec.configure do |c|
|
|
26
32
|
c.default_formatter = 'doc'
|
27
33
|
end
|
28
34
|
|
29
|
-
c.
|
30
|
-
c.run_all_when_everything_filtered = true
|
31
|
-
end
|
35
|
+
c.filter_run_when_matching :focus
|
32
36
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
c.example_status_persistence_file_path = "./spec/examples.txt"
|
38
|
+
|
39
|
+
c.define_derived_metadata :failing_on_windows_ci do |meta|
|
40
|
+
meta[:pending] ||= "This spec fails on Windows CI and needs someone to fix it."
|
41
|
+
end if RSpec::Support::OS.windows? && ENV['CI']
|
42
|
+
end
|
37
43
|
|
38
|
-
|
44
|
+
module RSpec
|
45
|
+
module Support
|
46
|
+
module Spec
|
47
|
+
def self.setup_simplecov(&block)
|
48
|
+
# Simplecov emits some ruby warnings when loaded, so silence them.
|
49
|
+
old_verbose, $VERBOSE = $VERBOSE, false
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
return if RSpec.configuration.files_to_run.one?
|
51
|
+
return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3'
|
52
|
+
return if RUBY_ENGINE != 'ruby' || RSpec::Support::OS.windows?
|
43
53
|
|
44
|
-
|
54
|
+
# Don't load it when we're running a single isolated
|
55
|
+
# test file rather than the whole suite.
|
56
|
+
return if RSpec.configuration.files_to_run.one?
|
45
57
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/')
|
58
|
+
require 'simplecov'
|
59
|
+
start_simplecov(&block)
|
60
|
+
rescue LoadError
|
61
|
+
warn "Simplecov could not be loaded"
|
62
|
+
ensure
|
63
|
+
$VERBOSE = old_verbose
|
53
64
|
end
|
54
65
|
|
55
|
-
|
66
|
+
def self.start_simplecov(&block)
|
67
|
+
SimpleCov.start do
|
68
|
+
add_filter "bundle/"
|
69
|
+
add_filter "tmp/"
|
70
|
+
add_filter do |source_file|
|
71
|
+
# Filter out `spec` directory except when it is under `lib`
|
72
|
+
# (as is the case in rspec-support)
|
73
|
+
source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/')
|
74
|
+
end
|
75
|
+
|
76
|
+
instance_eval(&block) if block
|
77
|
+
end
|
78
|
+
end
|
79
|
+
private_class_method :start_simplecov
|
56
80
|
end
|
57
|
-
rescue LoadError
|
58
|
-
ensure
|
59
|
-
$VERBOSE = old_verbose
|
60
81
|
end
|
61
82
|
end
|
62
|
-
|
@@ -4,7 +4,7 @@ RSpec::Support.require_rspec_support "caller_filter"
|
|
4
4
|
module RSpec
|
5
5
|
module Support
|
6
6
|
module Warnings
|
7
|
-
def deprecate(deprecated, options
|
7
|
+
def deprecate(deprecated, options={})
|
8
8
|
warn_with "DEPRECATION: #{deprecated} is deprecated.", options
|
9
9
|
end
|
10
10
|
|
@@ -12,7 +12,7 @@ module RSpec
|
|
12
12
|
#
|
13
13
|
# Used internally to print deprecation warnings
|
14
14
|
# when rspec-core isn't loaded
|
15
|
-
def warn_deprecation(message, options
|
15
|
+
def warn_deprecation(message, options={})
|
16
16
|
warn_with "DEPRECATION: \n #{message}", options
|
17
17
|
end
|
18
18
|
|
@@ -26,11 +26,11 @@ module RSpec
|
|
26
26
|
# @private
|
27
27
|
#
|
28
28
|
# Used internally to print longer warnings
|
29
|
-
def warn_with(message, options
|
29
|
+
def warn_with(message, options={})
|
30
30
|
call_site = options.fetch(:call_site) { CallerFilter.first_non_rspec_line }
|
31
|
-
message
|
32
|
-
message
|
33
|
-
|
31
|
+
message += " Use #{options[:replacement]} instead." if options[:replacement]
|
32
|
+
message += " Called from #{call_site}." if call_site
|
33
|
+
Support.warning_notifier.call message
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec::Support.require_rspec_support("method_signature_verifier")
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
module WithKeywordsWhenNeeded
|
6
|
+
# This module adds keyword sensitive support for core ruby methods
|
7
|
+
# where we cannot use `ruby2_keywords` directly.
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
if RSpec::Support::RubyFeatures.kw_args_supported?
|
12
|
+
# Remove this in RSpec 4 in favour of explicitly passed in kwargs where
|
13
|
+
# this is used. Works around a warning in Ruby 2.7
|
14
|
+
|
15
|
+
def class_exec(klass, *args, &block)
|
16
|
+
if MethodSignature.new(block).has_kw_args_in?(args)
|
17
|
+
binding.eval(<<-CODE, __FILE__, __LINE__)
|
18
|
+
kwargs = args.pop
|
19
|
+
klass.class_exec(*args, **kwargs, &block)
|
20
|
+
CODE
|
21
|
+
else
|
22
|
+
klass.class_exec(*args, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
ruby2_keywords :class_exec if respond_to?(:ruby2_keywords, true)
|
26
|
+
else
|
27
|
+
def class_exec(klass, *args, &block)
|
28
|
+
klass.class_exec(*args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/rspec/support.rb
CHANGED
@@ -14,7 +14,12 @@ module RSpec
|
|
14
14
|
def self.define_optimized_require_for_rspec(lib, &require_relative)
|
15
15
|
name = "require_rspec_#{lib}"
|
16
16
|
|
17
|
-
if Kernel.respond_to?(:
|
17
|
+
if RUBY_PLATFORM == 'java' && !Kernel.respond_to?(:require)
|
18
|
+
# JRuby 9.1.17.0 has developed a regression for require
|
19
|
+
(class << self; self; end).__send__(:define_method, name) do |f|
|
20
|
+
Kernel.send(:require, "rspec/#{lib}/#{f}")
|
21
|
+
end
|
22
|
+
elsif Kernel.respond_to?(:require_relative)
|
18
23
|
(class << self; self; end).__send__(:define_method, name) do |f|
|
19
24
|
require_relative.call("#{lib}/#{f}")
|
20
25
|
end
|
@@ -51,7 +56,7 @@ module RSpec
|
|
51
56
|
handle = object.method(method_name)
|
52
57
|
raise original unless handle.is_a? Method
|
53
58
|
handle
|
54
|
-
rescue
|
59
|
+
rescue Support::AllExceptionsExceptOnesWeMustNotRescue
|
55
60
|
raise original
|
56
61
|
end
|
57
62
|
end
|
@@ -67,10 +72,89 @@ module RSpec
|
|
67
72
|
handle = object.method(method_name)
|
68
73
|
raise original unless handle.is_a? Method
|
69
74
|
handle
|
70
|
-
rescue
|
75
|
+
rescue Support::AllExceptionsExceptOnesWeMustNotRescue
|
71
76
|
raise original
|
72
77
|
end
|
73
78
|
end
|
74
79
|
end
|
80
|
+
|
81
|
+
# @api private
|
82
|
+
#
|
83
|
+
# Used internally to get a class of a given object, even if it does not respond to #class.
|
84
|
+
def self.class_of(object)
|
85
|
+
object.class
|
86
|
+
rescue NoMethodError
|
87
|
+
singleton_class = class << object; self; end
|
88
|
+
singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) }
|
89
|
+
end
|
90
|
+
|
91
|
+
# A single thread local variable so we don't excessively pollute that namespace.
|
92
|
+
if RUBY_VERSION.to_f >= 2
|
93
|
+
def self.thread_local_data
|
94
|
+
Thread.current.thread_variable_get(:__rspec) || Thread.current.thread_variable_set(:__rspec, {})
|
95
|
+
end
|
96
|
+
else
|
97
|
+
def self.thread_local_data
|
98
|
+
Thread.current[:__rspec] ||= {}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# @api private
|
103
|
+
def self.failure_notifier=(callable)
|
104
|
+
thread_local_data[:failure_notifier] = callable
|
105
|
+
end
|
106
|
+
|
107
|
+
# @private
|
108
|
+
DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }
|
109
|
+
|
110
|
+
# @api private
|
111
|
+
def self.failure_notifier
|
112
|
+
thread_local_data[:failure_notifier] || DEFAULT_FAILURE_NOTIFIER
|
113
|
+
end
|
114
|
+
|
115
|
+
# @api private
|
116
|
+
def self.notify_failure(failure, options={})
|
117
|
+
failure_notifier.call(failure, options)
|
118
|
+
end
|
119
|
+
|
120
|
+
# @api private
|
121
|
+
def self.with_failure_notifier(callable)
|
122
|
+
orig_notifier = failure_notifier
|
123
|
+
self.failure_notifier = callable
|
124
|
+
yield
|
125
|
+
ensure
|
126
|
+
self.failure_notifier = orig_notifier
|
127
|
+
end
|
128
|
+
|
129
|
+
class << self
|
130
|
+
# @api private
|
131
|
+
attr_writer :warning_notifier
|
132
|
+
end
|
133
|
+
|
134
|
+
# @private
|
135
|
+
DEFAULT_WARNING_NOTIFIER = lambda { |warning| ::Kernel.warn warning }
|
136
|
+
|
137
|
+
# @api private
|
138
|
+
def self.warning_notifier
|
139
|
+
@warning_notifier ||= DEFAULT_WARNING_NOTIFIER
|
140
|
+
end
|
141
|
+
|
142
|
+
# @private
|
143
|
+
module AllExceptionsExceptOnesWeMustNotRescue
|
144
|
+
# These exceptions are dangerous to rescue as rescuing them
|
145
|
+
# would interfere with things we should not interfere with.
|
146
|
+
AVOID_RESCUING = [NoMemoryError, SignalException, Interrupt, SystemExit]
|
147
|
+
|
148
|
+
def self.===(exception)
|
149
|
+
AVOID_RESCUING.none? { |ar| ar === exception }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# The Differ is only needed when a spec fails with a diffable failure.
|
154
|
+
# In the more common case of all specs passing or the only failures being
|
155
|
+
# non-diffable, we can avoid the extra cost of loading the differ, diff-lcs,
|
156
|
+
# pp, etc by avoiding an unnecessary require. Instead, autoload will take
|
157
|
+
# care of loading the differ on first use.
|
158
|
+
autoload :Differ, "rspec/support/differ"
|
75
159
|
end
|
76
160
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|