rspec-support 3.5.0.beta2 → 3.5.0.beta3
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +8 -0
- data/lib/rspec/support/encoded_string.rb +12 -2
- data/lib/rspec/support/object_formatter.rb +171 -66
- data/lib/rspec/support/spec.rb +2 -2
- data/lib/rspec/support/version.rb +1 -1
- metadata +4 -4
- 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: d159591f4da601722c04e7443c888b74e6def234
|
4
|
+
data.tar.gz: 81984c1aed88ed161165bcee99627e9a4903e6d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0650cc39b1439e2f7309fecf5feb528c4b3c35bf17b6e3ee58019d79cf0b26fcac1fe6eb1a580690e029ef5027f3ed20b7439872c56b02a0774e3adbc839084f
|
7
|
+
data.tar.gz: a966de2f00b14b2a3952f1bc930421692f966027e4b6dcd843321ae476319c6a743d0920e5b73ba96ab7db53dcf98e8b7b0c4ece15cbd4fcb3b02294e6b32ef8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
### Development
|
2
2
|
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta1...master)
|
3
3
|
|
4
|
+
Bug Fixes:
|
5
|
+
|
6
|
+
* Fix `ObjectFormatter` so that formatting objects that don't respond to
|
7
|
+
`#inspect` (such as `BasicObject`) does not cause `NoMethodError`.
|
8
|
+
(Yuji Nakayama, #269)
|
9
|
+
* Fix `ObjectFormatter` so that formatting recursive array or hash does not
|
10
|
+
cause `SystemStackError`. (Yuji Nakayama, #270, #272)
|
11
|
+
|
4
12
|
### 3.5.0.beta1 / 2016-02-06
|
5
13
|
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.1...v3.5.0.beta1)
|
6
14
|
|
@@ -47,8 +47,18 @@ module RSpec
|
|
47
47
|
@string << matching_encoding(string)
|
48
48
|
end
|
49
49
|
|
50
|
-
|
51
|
-
|
50
|
+
if Ruby.jruby?
|
51
|
+
def split(regex_or_string)
|
52
|
+
@string.split(matching_encoding(regex_or_string))
|
53
|
+
rescue ArgumentError
|
54
|
+
# JRuby raises an ArgumentError when splitting a source string that
|
55
|
+
# contains invalid bytes.
|
56
|
+
remove_invalid_bytes(@string).split regex_or_string
|
57
|
+
end
|
58
|
+
else
|
59
|
+
def split(regex_or_string)
|
60
|
+
@string.split(matching_encoding(regex_or_string))
|
61
|
+
end
|
52
62
|
end
|
53
63
|
|
54
64
|
def to_s
|
@@ -1,20 +1,33 @@
|
|
1
|
+
RSpec::Support.require_rspec_support 'matcher_definition'
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Support
|
3
5
|
# Provide additional output details beyond what `inspect` provides when
|
4
6
|
# printing Time, DateTime, or BigDecimal
|
5
7
|
# @api private
|
6
|
-
class ObjectFormatter
|
7
|
-
|
8
|
+
class ObjectFormatter # rubocop:disable Style/ClassLength
|
9
|
+
ELLIPSIS = "..."
|
8
10
|
|
9
|
-
|
10
|
-
@max_formatted_output_length = max_formatted_output_length
|
11
|
-
end
|
11
|
+
attr_accessor :max_formatted_output_length
|
12
12
|
|
13
13
|
# Methods are deferred to a default instance of the class to maintain the interface
|
14
14
|
# For example, calling ObjectFormatter.format is still possible
|
15
|
-
|
15
|
+
def self.default_instance
|
16
|
+
@default_instance ||= new
|
17
|
+
end
|
16
18
|
|
17
|
-
|
19
|
+
def self.format(object)
|
20
|
+
default_instance.format(object)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.prepare_for_inspection(object)
|
24
|
+
default_instance.prepare_for_inspection(object)
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(max_formatted_output_length=200)
|
28
|
+
@max_formatted_output_length = max_formatted_output_length
|
29
|
+
@current_structure_stack = []
|
30
|
+
end
|
18
31
|
|
19
32
|
def format(object)
|
20
33
|
if max_formatted_output_length.nil?
|
@@ -31,12 +44,6 @@ module RSpec
|
|
31
44
|
end
|
32
45
|
end
|
33
46
|
|
34
|
-
def self.format(object)
|
35
|
-
@default_instance.format(object)
|
36
|
-
end
|
37
|
-
|
38
|
-
# rubocop:disable MethodLength
|
39
|
-
|
40
47
|
# Prepares the provided object to be formatted by wrapping it as needed
|
41
48
|
# in something that, when `inspect` is called on it, will produce the
|
42
49
|
# desired output.
|
@@ -49,96 +56,194 @@ module RSpec
|
|
49
56
|
def prepare_for_inspection(object)
|
50
57
|
case object
|
51
58
|
when Array
|
52
|
-
|
59
|
+
prepare_array(object)
|
53
60
|
when Hash
|
54
|
-
|
55
|
-
when Time
|
56
|
-
inspection = format_time(object)
|
61
|
+
prepare_hash(object)
|
57
62
|
else
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) }
|
64
|
+
inspector_class.new(object, self)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def prepare_array(array)
|
69
|
+
with_entering_structure(array) do
|
70
|
+
array.map { |element| prepare_element(element) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def prepare_hash(input_hash)
|
75
|
+
with_entering_structure(input_hash) do
|
76
|
+
input_hash.inject({}) do |output_hash, key_and_value|
|
77
|
+
key, value = key_and_value.map { |element| prepare_element(element) }
|
78
|
+
output_hash[key] = value
|
79
|
+
output_hash
|
66
80
|
end
|
67
81
|
end
|
82
|
+
end
|
68
83
|
|
69
|
-
|
84
|
+
def prepare_element(element)
|
85
|
+
if recursive_structure?(element)
|
86
|
+
case element
|
87
|
+
when Array then InspectableItem.new('[...]')
|
88
|
+
when Hash then InspectableItem.new('{...}')
|
89
|
+
else raise # This won't happen
|
90
|
+
end
|
91
|
+
else
|
92
|
+
prepare_for_inspection(element)
|
93
|
+
end
|
70
94
|
end
|
71
|
-
# rubocop:enable MethodLength
|
72
95
|
|
73
|
-
def
|
74
|
-
@
|
96
|
+
def with_entering_structure(structure)
|
97
|
+
@current_structure_stack.push(structure)
|
98
|
+
return_value = yield
|
99
|
+
@current_structure_stack.pop
|
100
|
+
return_value
|
75
101
|
end
|
76
102
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
103
|
+
def recursive_structure?(object)
|
104
|
+
@current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) }
|
105
|
+
end
|
106
|
+
|
107
|
+
InspectableItem = Struct.new(:text) do
|
108
|
+
def inspect
|
109
|
+
text
|
110
|
+
end
|
111
|
+
|
112
|
+
def pretty_print(pp)
|
113
|
+
pp.text(text)
|
81
114
|
end
|
82
115
|
end
|
83
116
|
|
84
|
-
|
85
|
-
|
117
|
+
BaseInspector = Struct.new(:object, :formatter) do
|
118
|
+
def self.can_inspect?(_object)
|
119
|
+
raise NotImplementedError
|
120
|
+
end
|
121
|
+
|
122
|
+
def inspect
|
123
|
+
raise NotImplementedError
|
124
|
+
end
|
125
|
+
|
126
|
+
def pretty_print(pp)
|
127
|
+
pp.text(inspect)
|
128
|
+
end
|
86
129
|
end
|
87
130
|
|
88
|
-
|
131
|
+
class TimeInspector < BaseInspector
|
132
|
+
FORMAT = "%Y-%m-%d %H:%M:%S"
|
89
133
|
|
90
|
-
|
91
|
-
|
92
|
-
time.strftime("#{TIME_FORMAT}.#{"%09d" % time.nsec} %z")
|
134
|
+
def self.can_inspect?(object)
|
135
|
+
Time === object
|
93
136
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
137
|
+
|
138
|
+
if Time.method_defined?(:nsec)
|
139
|
+
def inspect
|
140
|
+
object.strftime("#{FORMAT}.#{"%09d" % object.nsec} %z")
|
141
|
+
end
|
142
|
+
else # for 1.8.7
|
143
|
+
def inspect
|
144
|
+
object.strftime("#{FORMAT}.#{"%06d" % object.usec} %z")
|
145
|
+
end
|
97
146
|
end
|
98
147
|
end
|
99
148
|
|
100
|
-
|
101
|
-
|
149
|
+
class DateTimeInspector < BaseInspector
|
150
|
+
FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z"
|
151
|
+
|
152
|
+
def self.can_inspect?(object)
|
153
|
+
defined?(DateTime) && DateTime === object
|
154
|
+
end
|
155
|
+
|
156
|
+
# ActiveSupport sometimes overrides inspect. If `ActiveSupport` is
|
157
|
+
# defined use a custom format string that includes more time precision.
|
158
|
+
def inspect
|
159
|
+
if defined?(ActiveSupport)
|
160
|
+
object.strftime(FORMAT)
|
161
|
+
else
|
162
|
+
object.inspect
|
163
|
+
end
|
164
|
+
end
|
102
165
|
end
|
103
166
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
date_time.inspect
|
167
|
+
class BigDecimalInspector < BaseInspector
|
168
|
+
def self.can_inspect?(object)
|
169
|
+
defined?(BigDecimal) && BigDecimal === object
|
170
|
+
end
|
171
|
+
|
172
|
+
def inspect
|
173
|
+
"#{object.to_s('F')} (#{object.inspect})"
|
112
174
|
end
|
113
175
|
end
|
114
176
|
|
115
|
-
|
116
|
-
|
177
|
+
class DescribableMatcherInspector < BaseInspector
|
178
|
+
def self.can_inspect?(object)
|
179
|
+
Support.is_a_matcher?(object) && object.respond_to?(:description)
|
180
|
+
end
|
181
|
+
|
182
|
+
def inspect
|
183
|
+
object.description
|
184
|
+
end
|
117
185
|
end
|
118
186
|
|
119
|
-
|
187
|
+
class UninspectableObjectInspector < BaseInspector
|
188
|
+
OBJECT_ID_FORMAT = '%#016x'
|
189
|
+
|
190
|
+
def self.can_inspect?(object)
|
191
|
+
object.inspect
|
192
|
+
false
|
193
|
+
rescue NoMethodError
|
194
|
+
true
|
195
|
+
end
|
196
|
+
|
120
197
|
def inspect
|
121
|
-
|
198
|
+
"#<#{klass}:#{native_object_id}>"
|
122
199
|
end
|
123
200
|
|
124
|
-
def
|
125
|
-
|
201
|
+
def klass
|
202
|
+
singleton_class = class << object; self; end
|
203
|
+
singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) }
|
204
|
+
end
|
205
|
+
|
206
|
+
# http://stackoverflow.com/a/2818916
|
207
|
+
def native_object_id
|
208
|
+
OBJECT_ID_FORMAT % (object.__id__ << 1)
|
209
|
+
rescue NoMethodError
|
210
|
+
# In Ruby 1.9.2, BasicObject responds to none of #__id__, #object_id, #id...
|
211
|
+
'-'
|
126
212
|
end
|
127
213
|
end
|
128
214
|
|
129
|
-
|
215
|
+
class DelegatorInspector < BaseInspector
|
216
|
+
def self.can_inspect?(object)
|
217
|
+
defined?(Delegator) && Delegator === object
|
218
|
+
end
|
219
|
+
|
130
220
|
def inspect
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
221
|
+
"#<#{object.class}(#{formatter.format(object.__getobj__)})>"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class InspectableObjectInspector < BaseInspector
|
226
|
+
def self.can_inspect?(object)
|
227
|
+
object.inspect
|
228
|
+
true
|
229
|
+
rescue NoMethodError
|
230
|
+
false
|
136
231
|
end
|
137
232
|
|
138
|
-
def
|
139
|
-
|
233
|
+
def inspect
|
234
|
+
object.inspect
|
140
235
|
end
|
141
236
|
end
|
237
|
+
|
238
|
+
INSPECTOR_CLASSES = [
|
239
|
+
TimeInspector,
|
240
|
+
DateTimeInspector,
|
241
|
+
BigDecimalInspector,
|
242
|
+
UninspectableObjectInspector,
|
243
|
+
DescribableMatcherInspector,
|
244
|
+
DelegatorInspector,
|
245
|
+
InspectableObjectInspector
|
246
|
+
]
|
142
247
|
end
|
143
248
|
end
|
144
249
|
end
|
data/lib/rspec/support/spec.rb
CHANGED
@@ -31,8 +31,8 @@ RSpec.configure do |c|
|
|
31
31
|
c.default_formatter = 'doc'
|
32
32
|
end
|
33
33
|
|
34
|
-
c.
|
35
|
-
|
34
|
+
c.filter_run_when_matching :focus
|
35
|
+
|
36
36
|
c.example_status_persistence_file_path = "./spec/examples.txt"
|
37
37
|
|
38
38
|
c.define_derived_metadata :failing_on_appveyor do |meta|
|
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.5.0.
|
4
|
+
version: 3.5.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chelimsky
|
@@ -48,7 +48,7 @@ cert_chain:
|
|
48
48
|
ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
|
49
49
|
F3MdtaDehhjC
|
50
50
|
-----END CERTIFICATE-----
|
51
|
-
date: 2016-
|
51
|
+
date: 2016-04-02 00:00:00.000000000 Z
|
52
52
|
dependencies:
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: bundler
|
@@ -149,8 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
version: 1.3.1
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.5.1
|
152
|
+
rubygems_version: 2.4.5.1
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
|
-
summary: rspec-support-3.5.0.
|
155
|
+
summary: rspec-support-3.5.0.beta3
|
156
156
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|