rspec-support 3.0.4 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/Changelog.md +10 -0
- data/lib/rspec/support/caller_filter.rb +1 -2
- data/lib/rspec/support/differ.rb +25 -16
- data/lib/rspec/support/directory_maker.rb +30 -0
- data/lib/rspec/support/encoded_string.rb +8 -5
- data/lib/rspec/support/fuzzy_matcher.rb +1 -2
- data/lib/rspec/support/hunk_generator.rb +0 -1
- data/lib/rspec/support/matcher_definition.rb +31 -0
- data/lib/rspec/support/method_signature_verifier.rb +99 -36
- data/lib/rspec/support/recursive_const_methods.rb +76 -0
- data/lib/rspec/support/spec.rb +31 -22
- data/lib/rspec/support/spec/deprecation_helpers.rb +2 -3
- data/lib/rspec/support/spec/in_sub_process.rb +4 -1
- data/lib/rspec/support/spec/prevent_load_time_warnings.rb +44 -0
- data/lib/rspec/support/spec/shell_out.rb +54 -0
- data/lib/rspec/support/spec/stderr_splitter.rb +5 -6
- data/lib/rspec/support/spec/with_isolated_directory.rb +9 -0
- data/lib/rspec/support/spec/with_isolated_stderr.rb +0 -2
- data/lib/rspec/support/version.rb +1 -1
- data/lib/rspec/support/version_checker.rb +8 -8
- data/lib/rspec/support/warnings.rb +3 -3
- metadata +9 -17
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4617d19ee06926ebbcff3a74a7b9f4f4b33c5cea
|
4
|
+
data.tar.gz: d604a3eea3884a0bfdb9e6752d0c9661cab04a57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e1921b73a9af0bd4c3877d51eeac845c47708e1c3bfbe2c4a33a1501d41b2260ca567ee7f5e9c9f46d2102a5a85705c53d37dddf823eedf14fa07d826a649c4
|
7
|
+
data.tar.gz: 98b5498e60ee2901a87243c33b28bc85f60d0815e7a04bf32fb69833dd5dd9f6973d81c52e9a46e726e15a3540ec3aef4987bfb1f5d2de63c6d51e622c4e05b4
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
{�BUg�
|
2
|
+
1<�"&����rq'!�an�~WeǺ��e��zD=(�������Xx��a����K�z���$�7K�\�ޝ�7h톎��n�8o^O���>k��"j|��"�������Xb�@���"q9�qQy37db���:3��EG
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
### 3.1.0 / 2014-09-04
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.4...v3.1.0)
|
3
|
+
|
4
|
+
Bug Fixes:
|
5
|
+
|
6
|
+
* Fix `FuzzyMatcher` so that it does not wrongly match a struct against
|
7
|
+
an array. (Myron Marston, #97)
|
8
|
+
* Prevent infinitely recursing `#flatten` methods from causing the differ
|
9
|
+
to hang. (Jon Rowe, #101)
|
10
|
+
|
1
11
|
### 3.0.4 / 2014-08-14
|
2
12
|
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.3...v3.0.4)
|
3
13
|
|
@@ -4,7 +4,6 @@ module RSpec
|
|
4
4
|
# the code using the library, which is far more useful than the particular
|
5
5
|
# internal method that raised an error.
|
6
6
|
class CallerFilter
|
7
|
-
|
8
7
|
RSPEC_LIBS = %w[
|
9
8
|
core
|
10
9
|
mocks
|
@@ -41,7 +40,7 @@ module RSpec
|
|
41
40
|
i = 1
|
42
41
|
line = nil
|
43
42
|
|
44
|
-
|
43
|
+
until line
|
45
44
|
stack = caller(i, increment)
|
46
45
|
raise "No non-lib lines in stack" unless stack
|
47
46
|
|
data/lib/rspec/support/differ.rb
CHANGED
@@ -5,6 +5,7 @@ require 'pp'
|
|
5
5
|
|
6
6
|
module RSpec
|
7
7
|
module Support
|
8
|
+
# rubocop:disable ClassLength
|
8
9
|
class Differ
|
9
10
|
def diff(actual, expected)
|
10
11
|
diff = ""
|
@@ -22,6 +23,7 @@ module RSpec
|
|
22
23
|
diff.to_s
|
23
24
|
end
|
24
25
|
|
26
|
+
# rubocop:disable MethodLength
|
25
27
|
def diff_as_string(actual, expected)
|
26
28
|
@encoding = pick_encoding actual, expected
|
27
29
|
|
@@ -35,21 +37,20 @@ module RSpec
|
|
35
37
|
if current_hunk.overlaps?(prev_hunk)
|
36
38
|
add_old_hunk_to_hunk(current_hunk, prev_hunk)
|
37
39
|
else
|
38
|
-
add_to_output(output, prev_hunk.diff(
|
40
|
+
add_to_output(output, prev_hunk.diff(format_type).to_s)
|
39
41
|
end
|
40
42
|
ensure
|
41
43
|
add_to_output(output, "\n")
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
if hunks.last
|
46
|
-
finalize_output(output, hunks.last.diff(format).to_s)
|
47
|
-
end
|
47
|
+
finalize_output(output, hunks.last.diff(format_type).to_s) if hunks.last
|
48
48
|
|
49
49
|
color_diff output
|
50
50
|
rescue Encoding::CompatibilityError
|
51
51
|
handle_encoding_errors
|
52
52
|
end
|
53
|
+
# rubocop:enable MethodLength
|
53
54
|
|
54
55
|
def diff_as_object(actual, expected)
|
55
56
|
actual_as_string = object_to_string(actual)
|
@@ -68,19 +69,19 @@ module RSpec
|
|
68
69
|
private
|
69
70
|
|
70
71
|
def no_procs?(*args)
|
71
|
-
args.
|
72
|
+
safely_flatten(args).none? { |a| Proc === a }
|
72
73
|
end
|
73
74
|
|
74
75
|
def all_strings?(*args)
|
75
|
-
args.
|
76
|
+
safely_flatten(args).all? { |a| String === a }
|
76
77
|
end
|
77
78
|
|
78
79
|
def any_multiline_strings?(*args)
|
79
|
-
all_strings?(*args) && args.
|
80
|
+
all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) }
|
80
81
|
end
|
81
82
|
|
82
83
|
def no_numbers?(*args)
|
83
|
-
args.
|
84
|
+
safely_flatten(args).none? { |a| Numeric === a }
|
84
85
|
end
|
85
86
|
|
86
87
|
def coerce_to_string(string_or_array)
|
@@ -125,7 +126,12 @@ module RSpec
|
|
125
126
|
hunk.merge(oldhunk)
|
126
127
|
end
|
127
128
|
|
128
|
-
def
|
129
|
+
def safely_flatten(array)
|
130
|
+
array = array.flatten(1) until (array == array.flatten(1))
|
131
|
+
array
|
132
|
+
end
|
133
|
+
|
134
|
+
def format_type
|
129
135
|
:unified
|
130
136
|
end
|
131
137
|
|
@@ -152,7 +158,7 @@ module RSpec
|
|
152
158
|
def color_diff(diff)
|
153
159
|
return diff unless color?
|
154
160
|
|
155
|
-
diff.lines.map
|
161
|
+
diff.lines.map do |line|
|
156
162
|
case line[0].chr
|
157
163
|
when "+"
|
158
164
|
green line
|
@@ -163,7 +169,7 @@ module RSpec
|
|
163
169
|
else
|
164
170
|
normal(line)
|
165
171
|
end
|
166
|
-
|
172
|
+
end.join
|
167
173
|
end
|
168
174
|
|
169
175
|
def object_to_string(object)
|
@@ -179,7 +185,7 @@ module RSpec
|
|
179
185
|
when String
|
180
186
|
object =~ /\n/ ? object : object.inspect
|
181
187
|
else
|
182
|
-
PP.pp(object,"")
|
188
|
+
PP.pp(object, "")
|
183
189
|
end
|
184
190
|
end
|
185
191
|
|
@@ -188,18 +194,21 @@ module RSpec
|
|
188
194
|
Encoding.compatible?(source_a, source_b) || Encoding.default_external
|
189
195
|
end
|
190
196
|
else
|
191
|
-
def pick_encoding(
|
197
|
+
def pick_encoding(_source_a, _source_b)
|
192
198
|
end
|
193
199
|
end
|
194
200
|
|
195
201
|
def handle_encoding_errors
|
196
202
|
if @actual.source_encoding != @expected.source_encoding
|
197
|
-
"Could not produce a diff because the encoding of the actual string
|
198
|
-
|
203
|
+
"Could not produce a diff because the encoding of the actual string " \
|
204
|
+
"(#{@actual.source_encoding}) differs from the encoding of the expected " \
|
205
|
+
"string (#{@expected.source_encoding})"
|
199
206
|
else
|
200
|
-
"Could not produce a diff because of the encoding of the string
|
207
|
+
"Could not produce a diff because of the encoding of the string " \
|
208
|
+
"(#{@expected.source_encoding})"
|
201
209
|
end
|
202
210
|
end
|
203
211
|
end
|
212
|
+
# rubocop:enable ClassLength
|
204
213
|
end
|
205
214
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Support
|
3
|
+
# @api private
|
4
|
+
#
|
5
|
+
# Replacement for fileutils#mkdir_p because we don't want to require parts
|
6
|
+
# of stdlib in RSpec.
|
7
|
+
class DirectoryMaker
|
8
|
+
# @api private
|
9
|
+
#
|
10
|
+
# Implements nested directory construction
|
11
|
+
def self.mkdir_p(path)
|
12
|
+
stack = path.start_with?(File::SEPARATOR) ? File::SEPARATOR : "."
|
13
|
+
path.split(File::SEPARATOR).each do |part|
|
14
|
+
stack = File.join(stack, part)
|
15
|
+
|
16
|
+
begin
|
17
|
+
Dir.mkdir(stack) unless directory_exists?(stack)
|
18
|
+
rescue Errno::ENOTDIR => e
|
19
|
+
raise Errno::EEXIST, e.message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.directory_exists?(dirname)
|
25
|
+
File.exist?(dirname) && File.directory?(dirname)
|
26
|
+
end
|
27
|
+
private_class_method :directory_exists?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -2,10 +2,9 @@ module RSpec
|
|
2
2
|
module Support
|
3
3
|
# @private
|
4
4
|
class EncodedString
|
5
|
-
|
6
5
|
MRI_UNICODE_UNKOWN_CHARACTER = "\xEF\xBF\xBD"
|
7
6
|
|
8
|
-
def initialize(string, encoding
|
7
|
+
def initialize(string, encoding=nil)
|
9
8
|
@encoding = encoding
|
10
9
|
@source_encoding = detect_source_encoding(string)
|
11
10
|
@string = matching_encoding(string)
|
@@ -30,9 +29,10 @@ module RSpec
|
|
30
29
|
end
|
31
30
|
alias :to_str :to_s
|
32
31
|
|
33
|
-
private
|
34
|
-
|
35
32
|
if String.method_defined?(:encoding)
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
36
|
def matching_encoding(string)
|
37
37
|
string.encode(@encoding)
|
38
38
|
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
|
@@ -53,11 +53,14 @@ module RSpec
|
|
53
53
|
string.encoding
|
54
54
|
end
|
55
55
|
else
|
56
|
+
|
57
|
+
private
|
58
|
+
|
56
59
|
def matching_encoding(string)
|
57
60
|
string
|
58
61
|
end
|
59
62
|
|
60
|
-
def detect_source_encoding(
|
63
|
+
def detect_source_encoding(_string)
|
61
64
|
'US-ASCII'
|
62
65
|
end
|
63
66
|
end
|
@@ -6,7 +6,7 @@ module RSpec
|
|
6
6
|
module FuzzyMatcher
|
7
7
|
# @api private
|
8
8
|
def self.values_match?(expected, actual)
|
9
|
-
if Array === expected && Enumerable === actual
|
9
|
+
if Array === expected && Enumerable === actual && !(Struct === actual)
|
10
10
|
return arrays_match?(expected, actual.to_a)
|
11
11
|
elsif Hash === expected && Hash === actual
|
12
12
|
return hashes_match?(expected, actual)
|
@@ -46,4 +46,3 @@ module RSpec
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Support
|
3
|
+
# @private
|
4
|
+
def self.matcher_definitions
|
5
|
+
@matcher_definitions ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
# Used internally to break cyclic dependency between mocks, expectations,
|
9
|
+
# and support. We don't currently have a consistent implementation of our
|
10
|
+
# matchers, though we are considering changing that:
|
11
|
+
# https://github.com/rspec/rspec-mocks/issues/513
|
12
|
+
#
|
13
|
+
# @private
|
14
|
+
def self.register_matcher_definition(&block)
|
15
|
+
matcher_definitions << block
|
16
|
+
end
|
17
|
+
|
18
|
+
# Remove a previously registered matcher. Useful for cleaning up after
|
19
|
+
# yourself in specs.
|
20
|
+
#
|
21
|
+
# @private
|
22
|
+
def self.deregister_matcher_definition(&block)
|
23
|
+
matcher_definitions.delete(block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
def self.is_a_matcher?(object)
|
28
|
+
matcher_definitions.any? { |md| md.call(object) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rspec/support'
|
2
2
|
RSpec::Support.require_rspec_support "ruby_features"
|
3
|
+
RSpec::Support.require_rspec_support "matcher_definition"
|
3
4
|
|
4
5
|
module RSpec
|
5
6
|
module Support
|
@@ -17,12 +18,17 @@ module RSpec
|
|
17
18
|
|
18
19
|
def non_kw_args_arity_description
|
19
20
|
case max_non_kw_args
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
when min_non_kw_args then min_non_kw_args.to_s
|
22
|
+
when INFINITY then "#{min_non_kw_args} or more"
|
23
|
+
else "#{min_non_kw_args} to #{max_non_kw_args}"
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
27
|
+
def valid_non_kw_args?(positional_arg_count)
|
28
|
+
min_non_kw_args <= positional_arg_count &&
|
29
|
+
positional_arg_count <= max_non_kw_args
|
30
|
+
end
|
31
|
+
|
26
32
|
if RubyFeatures.optional_and_splat_args_supported?
|
27
33
|
def description
|
28
34
|
@description ||= begin
|
@@ -40,9 +46,7 @@ module RSpec
|
|
40
46
|
parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})"
|
41
47
|
end
|
42
48
|
|
43
|
-
if @allows_any_kw_args
|
44
|
-
parts << "any additional keyword args"
|
45
|
-
end
|
49
|
+
parts << "any additional keyword args" if @allows_any_kw_args
|
46
50
|
|
47
51
|
parts.join(" and ")
|
48
52
|
end
|
@@ -58,9 +62,13 @@ module RSpec
|
|
58
62
|
end
|
59
63
|
|
60
64
|
def has_kw_args_in?(args)
|
61
|
-
|
62
|
-
|
65
|
+
Hash === args.last && could_contain_kw_args?(args)
|
66
|
+
end
|
63
67
|
|
68
|
+
# Without considering what the last arg is, could it
|
69
|
+
# contain keyword arguments?
|
70
|
+
def could_contain_kw_args?(args)
|
71
|
+
return false if args.count <= min_non_kw_args
|
64
72
|
@allows_any_kw_args || @allowed_kw_args.any?
|
65
73
|
end
|
66
74
|
|
@@ -71,18 +79,18 @@ module RSpec
|
|
71
79
|
|
72
80
|
@method.parameters.each do |(type, name)|
|
73
81
|
case type
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
# def foo(a:)
|
83
|
+
when :keyreq then @required_kw_args << name
|
84
|
+
# def foo(a: 1)
|
85
|
+
when :key then @optional_kw_args << name
|
86
|
+
# def foo(**kw_args)
|
87
|
+
when :keyrest then @allows_any_kw_args = true
|
88
|
+
# def foo(a)
|
89
|
+
when :req then @min_non_kw_args += 1
|
90
|
+
# def foo(a = 1)
|
91
|
+
when :opt then optional_non_kw_args += 1
|
92
|
+
# def foo(*a)
|
93
|
+
when :rest then optional_non_kw_args = INFINITY
|
86
94
|
end
|
87
95
|
end
|
88
96
|
|
@@ -94,15 +102,15 @@ module RSpec
|
|
94
102
|
"arity of #{non_kw_args_arity_description}"
|
95
103
|
end
|
96
104
|
|
97
|
-
def missing_kw_args_from(
|
105
|
+
def missing_kw_args_from(_given_kw_args)
|
98
106
|
[]
|
99
107
|
end
|
100
108
|
|
101
|
-
def invalid_kw_args_from(
|
109
|
+
def invalid_kw_args_from(_given_kw_args)
|
102
110
|
[]
|
103
111
|
end
|
104
112
|
|
105
|
-
def has_kw_args_in?(
|
113
|
+
def has_kw_args_in?(_args)
|
106
114
|
false
|
107
115
|
end
|
108
116
|
|
@@ -120,16 +128,16 @@ module RSpec
|
|
120
128
|
end
|
121
129
|
end
|
122
130
|
|
123
|
-
INFINITY = 1/0.0
|
131
|
+
INFINITY = 1 / 0.0
|
124
132
|
end
|
125
133
|
|
126
134
|
# Deals with the slightly different semantics of block arguments.
|
127
135
|
# For methods, arguments are required unless a default value is provided.
|
128
136
|
# For blocks, arguments are optional, even if no default value is provided.
|
129
137
|
#
|
130
|
-
# However, we want to treat block args as required since you virtually
|
131
|
-
# want to pass a value for each received argument and our
|
132
|
-
# treated block args as required for many years.
|
138
|
+
# However, we want to treat block args as required since you virtually
|
139
|
+
# always want to pass a value for each received argument and our
|
140
|
+
# `and_yield` has treated block args as required for many years.
|
133
141
|
#
|
134
142
|
# @api private
|
135
143
|
class BlockSignature < MethodSignature
|
@@ -141,10 +149,9 @@ module RSpec
|
|
141
149
|
end
|
142
150
|
end
|
143
151
|
|
144
|
-
#
|
145
|
-
# Surprisingly non-trivial.
|
152
|
+
# Abstract base class for signature verifiers.
|
146
153
|
#
|
147
|
-
# @private
|
154
|
+
# @api private
|
148
155
|
class MethodSignatureVerifier
|
149
156
|
attr_reader :non_kw_args, :kw_args
|
150
157
|
|
@@ -154,7 +161,7 @@ module RSpec
|
|
154
161
|
end
|
155
162
|
|
156
163
|
def valid?
|
157
|
-
|
164
|
+
missing_kw_args.empty? &&
|
158
165
|
invalid_kw_args.empty? &&
|
159
166
|
valid_non_kw_args?
|
160
167
|
end
|
@@ -179,8 +186,7 @@ module RSpec
|
|
179
186
|
private
|
180
187
|
|
181
188
|
def valid_non_kw_args?
|
182
|
-
|
183
|
-
@signature.min_non_kw_args <= actual && actual <= @signature.max_non_kw_args
|
189
|
+
@signature.valid_non_kw_args?(non_kw_args.length)
|
184
190
|
end
|
185
191
|
|
186
192
|
def missing_kw_args
|
@@ -193,12 +199,69 @@ module RSpec
|
|
193
199
|
|
194
200
|
def split_args(*args)
|
195
201
|
kw_args = if @signature.has_kw_args_in?(args)
|
196
|
-
|
197
|
-
|
202
|
+
args.pop.keys
|
203
|
+
else
|
204
|
+
[]
|
205
|
+
end
|
206
|
+
|
207
|
+
[args, kw_args]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Figures out wether a given method can accept various arguments.
|
212
|
+
# Surprisingly non-trivial.
|
213
|
+
#
|
214
|
+
# @private
|
215
|
+
StrictSignatureVerifier = MethodSignatureVerifier
|
216
|
+
|
217
|
+
# Allows matchers to be used instead of providing keyword arguments. In
|
218
|
+
# practice, when this happens only the arity of the method is verified.
|
219
|
+
#
|
220
|
+
# @private
|
221
|
+
class LooseSignatureVerifier < MethodSignatureVerifier
|
222
|
+
private
|
223
|
+
|
224
|
+
def split_args(*args)
|
225
|
+
if RSpec::Support.is_a_matcher?(args.last) && @signature.could_contain_kw_args?(args)
|
226
|
+
args.pop
|
227
|
+
@signature = SignatureWithKeywordArgumentsMatcher.new(@signature)
|
228
|
+
end
|
229
|
+
|
230
|
+
super(*args)
|
231
|
+
end
|
232
|
+
|
233
|
+
# If a matcher is used in a signature in place of keyword arguments, all
|
234
|
+
# keyword argument validation needs to be skipped since the matcher is
|
235
|
+
# opaque.
|
236
|
+
#
|
237
|
+
# Instead, keyword arguments will be validated when the method is called
|
238
|
+
# and they are actually known.
|
239
|
+
#
|
240
|
+
# @private
|
241
|
+
class SignatureWithKeywordArgumentsMatcher
|
242
|
+
def initialize(signature)
|
243
|
+
@signature = signature
|
244
|
+
end
|
245
|
+
|
246
|
+
def missing_kw_args_from(_kw_args)
|
198
247
|
[]
|
199
248
|
end
|
200
249
|
|
201
|
-
|
250
|
+
def invalid_kw_args_from(_kw_args)
|
251
|
+
[]
|
252
|
+
end
|
253
|
+
|
254
|
+
def non_kw_args_arity_description
|
255
|
+
@signature.non_kw_args_arity_description
|
256
|
+
end
|
257
|
+
|
258
|
+
def valid_non_kw_args?(*args)
|
259
|
+
@signature.valid_non_kw_args?(*args)
|
260
|
+
end
|
261
|
+
|
262
|
+
def has_kw_args_in?(args)
|
263
|
+
@signature.has_kw_args_in?(args)
|
264
|
+
end
|
202
265
|
end
|
203
266
|
end
|
204
267
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Support
|
3
|
+
# Provides recursive constant lookup methods useful for
|
4
|
+
# constant stubbing.
|
5
|
+
module RecursiveConstMethods
|
6
|
+
# We only want to consider constants that are defined directly on a
|
7
|
+
# particular module, and not include top-level/inherited constants.
|
8
|
+
# Unfortunately, the constant API changed between 1.8 and 1.9, so
|
9
|
+
# we need to conditionally define methods to ignore the top-level/inherited
|
10
|
+
# constants.
|
11
|
+
#
|
12
|
+
# Given:
|
13
|
+
# class A; B = 1; end
|
14
|
+
# class C < A; end
|
15
|
+
#
|
16
|
+
# On 1.8:
|
17
|
+
# - C.const_get("Hash") # => ::Hash
|
18
|
+
# - C.const_defined?("Hash") # => false
|
19
|
+
# - C.constants # => ["B"]
|
20
|
+
# - None of these methods accept the extra `inherit` argument
|
21
|
+
# On 1.9:
|
22
|
+
# - C.const_get("Hash") # => ::Hash
|
23
|
+
# - C.const_defined?("Hash") # => true
|
24
|
+
# - C.const_get("Hash", false) # => raises NameError
|
25
|
+
# - C.const_defined?("Hash", false) # => false
|
26
|
+
# - C.constants # => [:B]
|
27
|
+
# - C.constants(false) #=> []
|
28
|
+
if Module.method(:const_defined?).arity == 1
|
29
|
+
def const_defined_on?(mod, const_name)
|
30
|
+
mod.const_defined?(const_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_const_defined_on(mod, const_name)
|
34
|
+
return mod.const_get(const_name) if const_defined_on?(mod, const_name)
|
35
|
+
|
36
|
+
raise NameError, "uninitialized constant #{mod.name}::#{const_name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def constants_defined_on(mod)
|
40
|
+
mod.constants.select { |c| const_defined_on?(mod, c) }
|
41
|
+
end
|
42
|
+
else
|
43
|
+
def const_defined_on?(mod, const_name)
|
44
|
+
mod.const_defined?(const_name, false)
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_const_defined_on(mod, const_name)
|
48
|
+
mod.const_get(const_name, false)
|
49
|
+
end
|
50
|
+
|
51
|
+
def constants_defined_on(mod)
|
52
|
+
mod.constants(false)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def recursive_const_get(const_name)
|
57
|
+
normalize_const_name(const_name).split('::').inject(Object) do |mod, name|
|
58
|
+
get_const_defined_on(mod, name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def recursive_const_defined?(const_name)
|
63
|
+
parts = normalize_const_name(const_name).split('::')
|
64
|
+
parts.inject([Object, '']) do |(mod, full_name), name|
|
65
|
+
yield(full_name, name) if block_given? && !(Module === mod)
|
66
|
+
return false unless const_defined_on?(mod, name)
|
67
|
+
[get_const_defined_on(mod, name), [mod, name].join('::')]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def normalize_const_name(const_name)
|
72
|
+
const_name.sub(/\A::/, '')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/rspec/support/spec.rb
CHANGED
@@ -3,6 +3,7 @@ RSpec::Support.require_rspec_support "spec/deprecation_helpers"
|
|
3
3
|
RSpec::Support.require_rspec_support "spec/with_isolated_stderr"
|
4
4
|
RSpec::Support.require_rspec_support "spec/stderr_splitter"
|
5
5
|
RSpec::Support.require_rspec_support "spec/formatting_support"
|
6
|
+
RSpec::Support.require_rspec_support "spec/with_isolated_directory"
|
6
7
|
|
7
8
|
warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
|
8
9
|
|
@@ -30,33 +31,41 @@ RSpec.configure do |c|
|
|
30
31
|
c.run_all_when_everything_filtered = true
|
31
32
|
end
|
32
33
|
|
33
|
-
module RSpec
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
module RSpec
|
35
|
+
module Support
|
36
|
+
module Spec
|
37
|
+
def self.setup_simplecov(&block)
|
38
|
+
# Simplecov emits some ruby warnings when loaded, so silence them.
|
39
|
+
old_verbose, $VERBOSE = $VERBOSE, false
|
37
40
|
|
38
|
-
|
41
|
+
return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' || RUBY_ENGINE != 'ruby'
|
39
42
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
# Don't load it when we're running a single isolated
|
44
|
+
# test file rather than the whole suite.
|
45
|
+
return if RSpec.configuration.files_to_run.one?
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# Filter out `spec` directory except when it is under `lib`
|
51
|
-
# (as is the case in rspec-support)
|
52
|
-
source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/')
|
47
|
+
require 'simplecov'
|
48
|
+
start_simplecov(&block)
|
49
|
+
rescue LoadError
|
50
|
+
warn "Simplecov could not be loaded"
|
51
|
+
ensure
|
52
|
+
$VERBOSE = old_verbose
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
def self.start_simplecov(&block)
|
56
|
+
SimpleCov.start do
|
57
|
+
add_filter "./bundle/"
|
58
|
+
add_filter "./tmp/"
|
59
|
+
add_filter do |source_file|
|
60
|
+
# Filter out `spec` directory except when it is under `lib`
|
61
|
+
# (as is the case in rspec-support)
|
62
|
+
source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/')
|
63
|
+
end
|
64
|
+
|
65
|
+
instance_eval(&block) if block
|
66
|
+
end
|
67
|
+
end
|
68
|
+
private_class_method :start_simplecov
|
56
69
|
end
|
57
|
-
rescue LoadError
|
58
|
-
ensure
|
59
|
-
$VERBOSE = old_verbose
|
60
70
|
end
|
61
71
|
end
|
62
|
-
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module RSpecHelpers
|
2
|
-
|
3
2
|
def expect_no_deprecation
|
4
3
|
expect(RSpec.configuration.reporter).not_to receive(:deprecation)
|
5
4
|
end
|
@@ -41,14 +40,14 @@ module RSpecHelpers
|
|
41
40
|
expect(RSpec.configuration.reporter).not_to receive(:deprecation)
|
42
41
|
end
|
43
42
|
|
44
|
-
def expect_warning_without_call_site(expected
|
43
|
+
def expect_warning_without_call_site(expected=//)
|
45
44
|
expect(::Kernel).to receive(:warn) do |message|
|
46
45
|
expect(message).to match expected
|
47
46
|
expect(message).to_not match(/Called from/)
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
51
|
-
def expect_warning_with_call_site(file, line, expected
|
50
|
+
def expect_warning_with_call_site(file, line, expected=//)
|
52
51
|
expect(::Kernel).to receive(:warn) do |message|
|
53
52
|
expect(message).to match expected
|
54
53
|
expect(message).to match(/Called from #{file}:#{line}/)
|
@@ -3,6 +3,8 @@ module RSpec
|
|
3
3
|
module InSubProcess
|
4
4
|
if Process.respond_to?(:fork) && !(RUBY_PLATFORM == 'java' && RUBY_VERSION == '1.8.7')
|
5
5
|
# Useful as a way to isolate a global change to a subprocess.
|
6
|
+
|
7
|
+
# rubocop:disable MethodLength
|
6
8
|
def in_sub_process
|
7
9
|
readme, writeme = IO.pipe
|
8
10
|
|
@@ -31,10 +33,11 @@ module RSpec
|
|
31
33
|
end
|
32
34
|
else
|
33
35
|
def in_sub_process
|
34
|
-
skip "This spec requires forking to work properly, "
|
36
|
+
skip "This spec requires forking to work properly, " \
|
35
37
|
"and your platform does not support forking"
|
36
38
|
end
|
37
39
|
end
|
40
|
+
# rubocop:enable MethodLength
|
38
41
|
end
|
39
42
|
end
|
40
43
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rspec/support/spec/shell_out'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
module WarningsPrevention
|
6
|
+
def files_to_require_for(lib)
|
7
|
+
slash = File::SEPARATOR
|
8
|
+
lib_path_re = /#{slash + lib}[^#{slash}]*#{slash}lib/
|
9
|
+
load_path = $LOAD_PATH.grep(lib_path_re).first
|
10
|
+
files = Dir["#{load_path}/**/*.rb"]
|
11
|
+
extract_regex = /#{Regexp.escape(load_path) + File::SEPARATOR}(.+)\.rb$/
|
12
|
+
|
13
|
+
# We sort to ensure the files are loaded in a consistent order, regardless
|
14
|
+
# of OS. Otherwise, it could load in a different order on Travis than
|
15
|
+
# locally, and potentially trigger a "circular require considered harmful"
|
16
|
+
# warning or similar.
|
17
|
+
files.sort.map { |file| file[extract_regex, 1] }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.shared_examples_for "a library that issues no warnings when loaded" do |lib, *preamble_stmnts|
|
24
|
+
include RSpec::Support::ShellOut
|
25
|
+
include RSpec::Support::WarningsPrevention
|
26
|
+
|
27
|
+
it "issues no warnings when loaded", :slow do
|
28
|
+
# We want to explicitly load every file because each lib has some files that
|
29
|
+
# aren't automatically loaded, instead being delayed based on an autoload
|
30
|
+
# (such as for rspec-expectations' matchers) or based on a config option
|
31
|
+
# (e.g. `config.mock_with :rr` => 'rspec/core/mocking_adapters/rr').
|
32
|
+
statements = preamble_stmnts + files_to_require_for(lib).map do |file|
|
33
|
+
"require '#{file}'"
|
34
|
+
end
|
35
|
+
|
36
|
+
command = statements.join("; ")
|
37
|
+
|
38
|
+
stdout, stderr, status = run_ruby_with_current_load_path(command, "-w")
|
39
|
+
|
40
|
+
expect(stdout).to eq("")
|
41
|
+
expect(stderr).to eq("")
|
42
|
+
expect(status.exitstatus).to eq(0)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
Open3.capture3(*command)
|
22
|
+
end
|
23
|
+
else # 1.8.7
|
24
|
+
def shell_out(*command)
|
25
|
+
stdout = stderr = nil
|
26
|
+
|
27
|
+
Open3.popen3(*command) do |_in, out, err|
|
28
|
+
stdout = out.read
|
29
|
+
stderr = err.read
|
30
|
+
end
|
31
|
+
|
32
|
+
# popen3 doesn't provide the exit status so we fake it out.
|
33
|
+
status = instance_double(Process::Status, :exitstatus => 0)
|
34
|
+
return stdout, stderr, status
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_ruby_with_current_load_path(ruby_command, *flags)
|
39
|
+
command = [
|
40
|
+
FileUtils::RUBY,
|
41
|
+
"-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}",
|
42
|
+
"-e", ruby_command, *flags
|
43
|
+
]
|
44
|
+
|
45
|
+
# Unset these env vars because `ruby -w` will issue warnings whenever
|
46
|
+
# they are set to non-default values.
|
47
|
+
with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil,
|
48
|
+
'RUBY_FREE_MIN' => nil do
|
49
|
+
shell_out(*command)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -25,10 +25,10 @@ module RSpec
|
|
25
25
|
# To work around JRuby error:
|
26
26
|
# TypeError: $stderr must have write method, RSpec::StdErrSplitter given
|
27
27
|
def write(line)
|
28
|
-
if line
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG
|
29
|
+
|
30
|
+
@orig_stderr.write(line)
|
31
|
+
@output_tracker.write(line)
|
32
32
|
end
|
33
33
|
|
34
34
|
def has_output?
|
@@ -40,14 +40,13 @@ module RSpec
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def verify_example!(example)
|
43
|
-
example.send(:fail,"Warnings were generated: #{output}") if has_output?
|
43
|
+
example.send(:fail, "Warnings were generated: #{output}") if has_output?
|
44
44
|
reset!
|
45
45
|
end
|
46
46
|
|
47
47
|
def output
|
48
48
|
@output_tracker.string
|
49
49
|
end
|
50
|
-
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -26,18 +26,18 @@ module RSpec
|
|
26
26
|
|
27
27
|
def raise_too_low_error
|
28
28
|
raise LibraryVersionTooLowError,
|
29
|
-
|
30
|
-
|
29
|
+
"You are using #{@library_name} #{@library_version}. " \
|
30
|
+
"RSpec requires version #{version_requirement}."
|
31
31
|
end
|
32
32
|
|
33
33
|
def compare_version
|
34
34
|
case
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
when @major < @min_major then :too_low
|
36
|
+
when @major > @min_major then :ok
|
37
|
+
when @minor < @min_minor then :too_low
|
38
|
+
when @minor > @min_minor then :ok
|
39
|
+
when @patch < @min_patch then :too_low
|
40
|
+
else :ok
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -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,7 +26,7 @@ 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
31
|
message << " Use #{options[:replacement]} instead." if options[:replacement]
|
32
32
|
message << " Called from #{call_site}." if call_site
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chelimsky
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
1yHC1AcSYpvi2dAbOiHT5iQF+krm4wse8KctXgTNnjMsHEoGKulJS2/sZl90jcCz
|
37
37
|
muA=
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2014-
|
39
|
+
date: 2014-09-05 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 10.0.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 3.0.0.pre
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 3.0.0.pre
|
83
69
|
description: Support utilities for RSpec gems
|
84
70
|
email: rspec-users@rubyforge.org
|
85
71
|
executables: []
|
@@ -92,16 +78,22 @@ files:
|
|
92
78
|
- lib/rspec/support.rb
|
93
79
|
- lib/rspec/support/caller_filter.rb
|
94
80
|
- lib/rspec/support/differ.rb
|
81
|
+
- lib/rspec/support/directory_maker.rb
|
95
82
|
- lib/rspec/support/encoded_string.rb
|
96
83
|
- lib/rspec/support/fuzzy_matcher.rb
|
97
84
|
- lib/rspec/support/hunk_generator.rb
|
85
|
+
- lib/rspec/support/matcher_definition.rb
|
98
86
|
- lib/rspec/support/method_signature_verifier.rb
|
87
|
+
- lib/rspec/support/recursive_const_methods.rb
|
99
88
|
- lib/rspec/support/ruby_features.rb
|
100
89
|
- lib/rspec/support/spec.rb
|
101
90
|
- lib/rspec/support/spec/deprecation_helpers.rb
|
102
91
|
- lib/rspec/support/spec/formatting_support.rb
|
103
92
|
- lib/rspec/support/spec/in_sub_process.rb
|
93
|
+
- lib/rspec/support/spec/prevent_load_time_warnings.rb
|
94
|
+
- lib/rspec/support/spec/shell_out.rb
|
104
95
|
- lib/rspec/support/spec/stderr_splitter.rb
|
96
|
+
- lib/rspec/support/spec/with_isolated_directory.rb
|
105
97
|
- lib/rspec/support/spec/with_isolated_stderr.rb
|
106
98
|
- lib/rspec/support/version.rb
|
107
99
|
- lib/rspec/support/version_checker.rb
|
@@ -130,5 +122,5 @@ rubyforge_project: rspec
|
|
130
122
|
rubygems_version: 2.2.2
|
131
123
|
signing_key:
|
132
124
|
specification_version: 4
|
133
|
-
summary: rspec-support-3.0
|
125
|
+
summary: rspec-support-3.1.0
|
134
126
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|