rspec-support 3.0.4 → 3.12.1
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 +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
|