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 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