rspec-support 3.0.4 → 3.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 71ada7066e53a0b40d343dd8f26528715c2fbf24
4
- data.tar.gz: 712553112d6764d89e35fa1a1657a268f16d2d83
3
+ metadata.gz: 4617d19ee06926ebbcff3a74a7b9f4f4b33c5cea
4
+ data.tar.gz: d604a3eea3884a0bfdb9e6752d0c9661cab04a57
5
5
  SHA512:
6
- metadata.gz: 2e5ffa54dcf62a550f3b87fdbfb1c548e2db1ac97f70a5b3608c9c51955fd81b496738b37050e991987788b32bbdd8d76179ef86fa091e99437593c34145947d
7
- data.tar.gz: a394b169979e054239c96ec27a10326f96273098ae993159a78c9db9e72f2fbc1ea334c3513f73d48b39771f47f31f16a339824c1ce602ea913230d0800fd0a8
6
+ metadata.gz: 7e1921b73a9af0bd4c3877d51eeac845c47708e1c3bfbe2c4a33a1501d41b2260ca567ee7f5e9c9f46d2102a5a85705c53d37dddf823eedf14fa07d826a649c4
7
+ data.tar.gz: 98b5498e60ee2901a87243c33b28bc85f60d0815e7a04bf32fb69833dd5dd9f6973d81c52e9a46e726e15a3540ec3aef4987bfb1f5d2de63c6d51e622c4e05b4
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- J9�u�Ʃ�_s+�Y�$e�/C�[��y ��B��Up��֤�*ϖ&]�0H�궢�1L+���0�^g��Xf�r��
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
- while !line
43
+ until line
45
44
  stack = caller(i, increment)
46
45
  raise "No non-lib lines in stack" unless stack
47
46
 
@@ -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(format).to_s)
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.flatten.none? { |a| Proc === a}
72
+ safely_flatten(args).none? { |a| Proc === a }
72
73
  end
73
74
 
74
75
  def all_strings?(*args)
75
- args.flatten.all? { |a| String === a}
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.flatten.any? { |a| multiline?(a) }
80
+ all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) }
80
81
  end
81
82
 
82
83
  def no_numbers?(*args)
83
- args.flatten.none? { |a| Numeric === a}
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 format
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 { |line|
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
- }.join
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(source_a, source_b)
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 (#{@actual.source_encoding}) "+
198
- "differs from the encoding of the expected string (#{@expected.source_encoding})"
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 (#{@expected.source_encoding})"
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 = nil)
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(string)
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
-
@@ -42,7 +42,6 @@ module RSpec
42
42
  def context_lines
43
43
  3
44
44
  end
45
-
46
45
  end
47
46
  end
48
47
  end
@@ -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
- when min_non_kw_args then min_non_kw_args.to_s
21
- when INFINITY then "#{min_non_kw_args} or more"
22
- else "#{min_non_kw_args} to #{max_non_kw_args}"
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
- return false unless Hash === args.last
62
- return false if args.count <= min_non_kw_args
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
- # def foo(a:)
75
- when :keyreq then @required_kw_args << name
76
- # def foo(a: 1)
77
- when :key then @optional_kw_args << name
78
- # def foo(**kw_args)
79
- when :keyrest then @allows_any_kw_args = true
80
- # def foo(a)
81
- when :req then @min_non_kw_args += 1
82
- # def foo(a = 1)
83
- when :opt then optional_non_kw_args += 1
84
- # def foo(*a)
85
- when :rest then optional_non_kw_args = INFINITY
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(given_kw_args)
105
+ def missing_kw_args_from(_given_kw_args)
98
106
  []
99
107
  end
100
108
 
101
- def invalid_kw_args_from(given_kw_args)
109
+ def invalid_kw_args_from(_given_kw_args)
102
110
  []
103
111
  end
104
112
 
105
- def has_kw_args_in?(args)
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 always
131
- # want to pass a value for each received argument and our `and_yield` has
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
- # Figures out wheter a given method can accept various arguments.
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
- missing_kw_args.empty? &&
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
- actual = non_kw_args.length
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
- args.pop.keys
197
- else
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
- [args, kw_args]
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
@@ -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::Support::Spec
34
- def self.setup_simplecov(&block)
35
- # Simplecov emits some ruby warnings when loaded, so silence them.
36
- old_verbose, $VERBOSE = $VERBOSE, false
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
- return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' || RUBY_ENGINE != 'ruby'
41
+ return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' || RUBY_ENGINE != 'ruby'
39
42
 
40
- # Don't load it when we're running a single isolated
41
- # test file rather than the whole suite.
42
- return if RSpec.configuration.files_to_run.one?
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
- require 'simplecov'
45
-
46
- SimpleCov.start do
47
- add_filter "./bundle/"
48
- add_filter "./tmp/"
49
- add_filter do |source_file|
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
- instance_eval(&block) if block
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 !~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG
29
- @orig_stderr.write(line)
30
- @output_tracker.write(line)
31
- end
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
@@ -0,0 +1,9 @@
1
+ require 'tmpdir'
2
+
3
+ RSpec.shared_context "isolated directory", :isolated_directory => true do
4
+ around do |ex|
5
+ Dir.mktmpdir do |tmp_dir|
6
+ Dir.chdir(tmp_dir, &ex)
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,6 @@
1
1
  module RSpec
2
2
  module Support
3
3
  module WithIsolatedStdErr
4
-
5
4
  def with_isolated_stderr
6
5
  original = $stderr
7
6
  $stderr = StringIO.new
@@ -9,7 +8,6 @@ module RSpec
9
8
  ensure
10
9
  $stderr = original
11
10
  end
12
-
13
11
  end
14
12
  end
15
13
  end
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Support
3
3
  module Version
4
- STRING = '3.0.4'
4
+ STRING = '3.1.0'
5
5
  end
6
6
  end
7
7
  end
@@ -26,18 +26,18 @@ module RSpec
26
26
 
27
27
  def raise_too_low_error
28
28
  raise LibraryVersionTooLowError,
29
- "You are using #{@library_name} #{@library_version}. " +
30
- "RSpec requires version #{version_requirement}."
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
- 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
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
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-08-14 00:00:00.000000000 Z
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.4
125
+ summary: rspec-support-3.1.0
134
126
  test_files: []
metadata.gz.sig CHANGED
Binary file