@@ -5,7 +5,7 @@ module Support
5
5
# Provide additional output details beyond what `inspect` provides when
6
6
# printing Time, DateTime, or BigDecimal
7
7
# @api private
8
- class ObjectFormatter
8
+ class ObjectFormatter # rubocop:disable ClassLength
9
9
attr_accessor :max_formatted_output_length
10
10
11
11
def initialize ( max_formatted_output_length = 200 )
@@ -37,8 +37,6 @@ def self.format(object)
37
37
@default_instance . format ( object )
38
38
end
39
39
40
- # rubocop:disable MethodLength
41
-
42
40
# Prepares the provided object to be formatted by wrapping it as needed
43
41
# in something that, when `inspect` is called on it, will produce the
44
42
# desired output.
@@ -48,7 +46,7 @@ def self.format(object)
48
46
# with custom items that have `inspect` defined to return the desired output
49
47
# for that item. Then we can just use `Array#inspect` or `Hash#inspect` to
50
48
# format the entire thing.
51
- def prepare_for_inspection ( object )
49
+ def prepare_for_inspection ( object ) # rubocop:disable MethodLength, CyclomaticComplexity
52
50
case object
53
51
when Array
54
52
return object . map { |o | prepare_for_inspection ( o ) }
@@ -61,6 +59,8 @@ def prepare_for_inspection(object)
61
59
inspection = format_date_time ( object )
62
60
elsif defined? ( BigDecimal ) && BigDecimal === object
63
61
inspection = "#{ object . to_s 'F' } (#{ object . inspect } )"
62
+ elsif UninspectableObjectInspector . uninspectable_object? ( object )
63
+ return UninspectableObjectInspector . new ( object )
64
64
elsif RSpec ::Support . is_a_matcher? ( object ) && object . respond_to? ( :description )
65
65
inspection = object . description
66
66
else
@@ -70,7 +70,6 @@ def prepare_for_inspection(object)
70
70
71
71
InspectableItem . new ( inspection )
72
72
end
73
- # rubocop:enable MethodLength
74
73
75
74
def self . prepare_for_inspection ( object )
76
75
@default_instance . prepare_for_inspection ( object )
@@ -141,6 +140,41 @@ def pretty_print(pp)
141
140
pp . text inspect
142
141
end
143
142
end
143
+
144
+ UninspectableObjectInspector = Struct . new ( :object ) do
145
+ OBJECT_ID_FORMAT = '%#016x'
146
+
147
+ def self . uninspectable_object? ( object )
148
+ object . inspect
149
+ false
150
+ rescue NoMethodError
151
+ true
152
+ end
153
+
154
+ # NoMethodError: undefined method `inspect' for #<BasicObject:0x007fe26d175140>
155
+ def inspect
156
+ "#<#{ klass } :#{ native_object_id } >"
157
+ end
158
+
159
+ def pretty_print ( pp )
160
+ pp . text inspect
161
+ end
162
+
163
+ private
164
+
165
+ def klass
166
+ singleton_class = class << object ; self ; end
167
+ singleton_class . ancestors . find { |ancestor | !ancestor . equal? ( singleton_class ) }
168
+ end
169
+
170
+ # http://stackoverflow.com/a/2818916
171
+ def native_object_id
172
+ OBJECT_ID_FORMAT % ( object . __id__ << 1 )
173
+ rescue NoMethodError
174
+ # In Ruby 1.9.2, BasicObject responds to none of #__id__, #object_id, #id...
175
+ '-'
176
+ end
177
+ end
144
178
end
145
179
end
146
180
end
0 commit comments