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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7636681b4e17a1765852cbe17a55590690fda3df
4
- data.tar.gz: c340715fbaea1731f1c8e78d264cbb2a9c080eaa
3
+ metadata.gz: d159591f4da601722c04e7443c888b74e6def234
4
+ data.tar.gz: 81984c1aed88ed161165bcee99627e9a4903e6d2
5
5
  SHA512:
6
- metadata.gz: 4400cd6c8b0dba274d279addd3c553051469c595f032fd3e867a1732e698d30c0567188efcce13ad674b36bbb8687ec82d32b96874c461b1c43c603ca17caff9
7
- data.tar.gz: 8bdf0429715765f0ec796b282e0c825907b0ef65cffc2dcc4b511b4a0a5d0f4865386952a76b9a470ae5eccd2da726038b0a3cef6c23827199abfafae79aa2b6
6
+ metadata.gz: 0650cc39b1439e2f7309fecf5feb528c4b3c35bf17b6e3ee58019d79cf0b26fcac1fe6eb1a580690e029ef5027f3ed20b7439872c56b02a0774e3adbc839084f
7
+ data.tar.gz: a966de2f00b14b2a3952f1bc930421692f966027e4b6dcd843321ae476319c6a743d0920e5b73ba96ab7db53dcf98e8b7b0c4ece15cbd4fcb3b02294e6b32ef8
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -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
- def split(regex_or_string)
51
- @string.split(matching_encoding(regex_or_string))
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
- attr_accessor :max_formatted_output_length
8
+ class ObjectFormatter # rubocop:disable Style/ClassLength
9
+ ELLIPSIS = "..."
8
10
 
9
- def initialize(max_formatted_output_length=200)
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
- @default_instance = new(200)
15
+ def self.default_instance
16
+ @default_instance ||= new
17
+ end
16
18
 
17
- ELLIPSIS = "..."
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
- return object.map { |o| prepare_for_inspection(o) }
59
+ prepare_array(object)
53
60
  when Hash
54
- return prepare_hash(object)
55
- when Time
56
- inspection = format_time(object)
61
+ prepare_hash(object)
57
62
  else
58
- if defined?(DateTime) && DateTime === object
59
- inspection = format_date_time(object)
60
- elsif defined?(BigDecimal) && BigDecimal === object
61
- inspection = "#{object.to_s 'F'} (#{object.inspect})"
62
- elsif RSpec::Support.is_a_matcher?(object) && object.respond_to?(:description)
63
- inspection = object.description
64
- else
65
- return DelegatingInspector.new(object)
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
- InspectableItem.new(inspection)
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 self.prepare_for_inspection(object)
74
- @default_instance.prepare_for_inspection(object)
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 prepare_hash(input)
78
- input.inject({}) do |hash, (k, v)|
79
- hash[prepare_for_inspection(k)] = prepare_for_inspection(v)
80
- hash
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
- def self.prepare_hash(input)
85
- @default_instance.prepare_hash(input)
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
- TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
131
+ class TimeInspector < BaseInspector
132
+ FORMAT = "%Y-%m-%d %H:%M:%S"
89
133
 
90
- if Time.method_defined?(:nsec)
91
- def format_time(time)
92
- time.strftime("#{TIME_FORMAT}.#{"%09d" % time.nsec} %z")
134
+ def self.can_inspect?(object)
135
+ Time === object
93
136
  end
94
- else # for 1.8.7
95
- def format_time(time)
96
- time.strftime("#{TIME_FORMAT}.#{"%06d" % time.usec} %z")
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
- def self.format_time(time)
101
- @default_instance.format_time(time)
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
- DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z"
105
- # ActiveSupport sometimes overrides inspect. If `ActiveSupport` is
106
- # defined use a custom format string that includes more time precision.
107
- def format_date_time(date_time)
108
- if defined?(ActiveSupport)
109
- date_time.strftime(DATE_TIME_FORMAT)
110
- else
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
- def self.format_date_time(date_time)
116
- @default_instance.format_date_time(date_time)
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
- InspectableItem = Struct.new(:inspection) do
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
- inspection
198
+ "#<#{klass}:#{native_object_id}>"
122
199
  end
123
200
 
124
- def pretty_print(pp)
125
- pp.text inspection
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
- DelegatingInspector = Struct.new(:object) do
215
+ class DelegatorInspector < BaseInspector
216
+ def self.can_inspect?(object)
217
+ defined?(Delegator) && Delegator === object
218
+ end
219
+
130
220
  def inspect
131
- if defined?(::Delegator) && ::Delegator === object
132
- "#<#{object.class}(#{ObjectFormatter.format(object.__getobj__)})>"
133
- else
134
- object.inspect
135
- end
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 pretty_print(pp)
139
- pp.text inspect
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
@@ -31,8 +31,8 @@ RSpec.configure do |c|
31
31
  c.default_formatter = 'doc'
32
32
  end
33
33
 
34
- c.filter_run :focus
35
- c.run_all_when_everything_filtered = true
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|
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Support
3
3
  module Version
4
- STRING = '3.5.0.beta2'
4
+ STRING = '3.5.0.beta3'
5
5
  end
6
6
  end
7
7
  end
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.beta2
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-03-10 00:00:00.000000000 Z
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.beta2
155
+ summary: rspec-support-3.5.0.beta3
156
156
  test_files: []
metadata.gz.sig CHANGED
Binary file