rspec-expectations 3.2.1 → 3.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +55 -4
- data/README.md +1 -1
- data/lib/rspec/expectations.rb +13 -1
- data/lib/rspec/expectations/configuration.rb +17 -0
- data/lib/rspec/expectations/expectation_target.rb +3 -9
- data/lib/rspec/expectations/fail_with.rb +1 -3
- data/lib/rspec/expectations/failure_aggregator.rb +194 -0
- data/lib/rspec/expectations/minitest_integration.rb +13 -0
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +59 -5
- data/lib/rspec/matchers/built_in/base_matcher.rb +56 -7
- data/lib/rspec/matchers/built_in/be.rb +25 -15
- data/lib/rspec/matchers/built_in/be_between.rb +1 -1
- data/lib/rspec/matchers/built_in/be_within.rb +2 -2
- data/lib/rspec/matchers/built_in/contain_exactly.rb +12 -8
- data/lib/rspec/matchers/built_in/eq.rb +3 -38
- data/lib/rspec/matchers/built_in/eql.rb +2 -2
- data/lib/rspec/matchers/built_in/equal.rb +3 -3
- data/lib/rspec/matchers/built_in/exist.rb +2 -2
- data/lib/rspec/matchers/built_in/has.rb +3 -1
- data/lib/rspec/matchers/built_in/have_attributes.rb +5 -4
- data/lib/rspec/matchers/built_in/include.rb +44 -19
- data/lib/rspec/matchers/built_in/match.rb +9 -1
- data/lib/rspec/matchers/built_in/operators.rb +14 -5
- data/lib/rspec/matchers/built_in/output.rb +9 -2
- data/lib/rspec/matchers/built_in/raise_error.rb +64 -22
- data/lib/rspec/matchers/built_in/respond_to.rb +2 -3
- data/lib/rspec/matchers/built_in/satisfy.rb +7 -9
- data/lib/rspec/matchers/built_in/start_or_end_with.rb +3 -1
- data/lib/rspec/matchers/built_in/throw_symbol.rb +1 -1
- data/lib/rspec/matchers/built_in/yield.rb +7 -5
- data/lib/rspec/matchers/composable.rb +5 -4
- data/lib/rspec/matchers/dsl.rb +19 -6
- data/lib/rspec/matchers/english_phrasing.rb +42 -0
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +2 -8
- data/lib/rspec/matchers/fail_matchers.rb +42 -0
- data/lib/rspec/matchers/matcher_delegator.rb +2 -0
- metadata +9 -7
- metadata.gz.sig +0 -0
- data/lib/rspec/matchers/pretty.rb +0 -77
@@ -114,7 +114,7 @@ module RSpec
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def throw_description(symbol, arg)
|
117
|
-
symbol_description = symbol.is_a?(String) ? symbol : symbol
|
117
|
+
symbol_description = symbol.is_a?(String) ? symbol : description_of(symbol)
|
118
118
|
|
119
119
|
arg_description = if arg
|
120
120
|
" with #{description_of arg}"
|
@@ -78,6 +78,7 @@ module RSpec
|
|
78
78
|
"matcher. Pass the argument as a block on to the method you are testing."
|
79
79
|
end
|
80
80
|
else
|
81
|
+
# :nocov:
|
81
82
|
# On 1.8.7, `lambda { }.arity` and `lambda { |*a| }.arity` both return -1,
|
82
83
|
# so we can't distinguish between accepting no args and an arg splat.
|
83
84
|
# It's OK to skip, this, though; it just provides a nice error message
|
@@ -86,6 +87,7 @@ module RSpec
|
|
86
87
|
def assert_valid_expect_block!
|
87
88
|
# nothing to do
|
88
89
|
end
|
90
|
+
# :nocov:
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
@@ -247,7 +249,7 @@ module RSpec
|
|
247
249
|
def positive_failure_reason
|
248
250
|
return "was not a block" unless @probe.has_block?
|
249
251
|
return "did not yield" if @probe.num_yields.zero?
|
250
|
-
"yielded with arguments: #{@probe.single_yield_args
|
252
|
+
"yielded with arguments: #{description_of @probe.single_yield_args}"
|
251
253
|
end
|
252
254
|
|
253
255
|
def negative_failure_reason
|
@@ -317,7 +319,7 @@ module RSpec
|
|
317
319
|
elsif all_args_match?
|
318
320
|
"yielded with expected arguments" \
|
319
321
|
"\nexpected not: #{surface_descriptions_in(@expected).inspect}" +
|
320
|
-
"\n got: #{
|
322
|
+
"\n got: #{actual_formatted}"
|
321
323
|
else
|
322
324
|
"did"
|
323
325
|
end
|
@@ -332,7 +334,7 @@ module RSpec
|
|
332
334
|
unless (match = all_args_match?)
|
333
335
|
@positive_args_failure = "yielded with unexpected arguments" \
|
334
336
|
"\nexpected: #{surface_descriptions_in(@expected).inspect}" +
|
335
|
-
"\n got: #{
|
337
|
+
"\n got: #{actual_formatted}"
|
336
338
|
end
|
337
339
|
|
338
340
|
match
|
@@ -400,7 +402,7 @@ module RSpec
|
|
400
402
|
|
401
403
|
"yielded with unexpected arguments" \
|
402
404
|
"\nexpected: #{surface_descriptions_in(@expected).inspect}" \
|
403
|
-
"\n got: #{
|
405
|
+
"\n got: #{actual_formatted}"
|
404
406
|
end
|
405
407
|
|
406
408
|
def negative_failure_reason
|
@@ -408,7 +410,7 @@ module RSpec
|
|
408
410
|
|
409
411
|
"yielded with expected arguments" \
|
410
412
|
"\nexpected not: #{surface_descriptions_in(@expected).inspect}" \
|
411
|
-
"\n got: #{
|
413
|
+
"\n got: #{actual_formatted}"
|
412
414
|
end
|
413
415
|
end
|
414
416
|
end
|
@@ -80,8 +80,7 @@ module RSpec
|
|
80
80
|
#
|
81
81
|
# @!visibility public
|
82
82
|
def description_of(object)
|
83
|
-
|
84
|
-
object.inspect
|
83
|
+
RSpec::Support::ObjectFormatter.format(object)
|
85
84
|
end
|
86
85
|
|
87
86
|
# Transforms the given data structue (typically a hash or array)
|
@@ -102,12 +101,12 @@ module RSpec
|
|
102
101
|
elsif Hash === item
|
103
102
|
Hash[surface_descriptions_in(item.to_a)]
|
104
103
|
elsif Struct === item
|
105
|
-
item
|
104
|
+
RSpec::Support::ObjectFormatter.format(item)
|
106
105
|
elsif should_enumerate?(item)
|
107
106
|
begin
|
108
107
|
item.map { |subitem| surface_descriptions_in(subitem) }
|
109
108
|
rescue IOError # STDOUT is enumerable but `map` raises an error
|
110
|
-
item
|
109
|
+
RSpec::Support::ObjectFormatter.format(item)
|
111
110
|
end
|
112
111
|
else
|
113
112
|
item
|
@@ -149,6 +148,7 @@ module RSpec
|
|
149
148
|
end
|
150
149
|
|
151
150
|
if String.ancestors.include?(Enumerable) # 1.8.7
|
151
|
+
# :nocov:
|
152
152
|
# Strings are not enumerable on 1.9, and on 1.8 they are an infinitely
|
153
153
|
# nested enumerable: since ruby lacks a character class, it yields
|
154
154
|
# 1-character strings, which are themselves enumerable, composed of a
|
@@ -159,6 +159,7 @@ module RSpec
|
|
159
159
|
return false if String === item
|
160
160
|
Enumerable === item && !(Range === item)
|
161
161
|
end
|
162
|
+
# :nocov:
|
162
163
|
else
|
163
164
|
# @api private
|
164
165
|
def should_enumerate?(item)
|
data/lib/rspec/matchers/dsl.rb
CHANGED
@@ -24,9 +24,11 @@ module RSpec
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
else
|
27
|
+
# :nocov:
|
27
28
|
def warn_about_block_args(*)
|
28
29
|
# There's no way to detect block params on 1.8 since the method reflection APIs don't expose it
|
29
30
|
end
|
31
|
+
# :nocov:
|
30
32
|
end
|
31
33
|
|
32
34
|
RSpec.configure { |c| c.extend self } if RSpec.respond_to?(:configure)
|
@@ -58,13 +60,18 @@ module RSpec
|
|
58
60
|
define_user_override(:matches?, match_block) do |actual|
|
59
61
|
begin
|
60
62
|
@actual = actual
|
61
|
-
|
63
|
+
RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do
|
64
|
+
super(*actual_arg_for(match_block))
|
65
|
+
end
|
62
66
|
rescue RSpec::Expectations::ExpectationNotMetError
|
63
67
|
false
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
72
|
+
# @private
|
73
|
+
RAISE_NOTIFIER = Proc.new { |err, _opts| raise err }
|
74
|
+
|
68
75
|
# Use this to define the block for a negative expectation (`expect(...).not_to`)
|
69
76
|
# when the positive and negative forms require different handling. This
|
70
77
|
# is rarely necessary, but can be helpful, for example, when specifying
|
@@ -300,7 +307,9 @@ module RSpec
|
|
300
307
|
|
301
308
|
# The default description.
|
302
309
|
def description
|
303
|
-
|
310
|
+
english_name = EnglishPhrasing.split_words(name)
|
311
|
+
expected_list = EnglishPhrasing.list(expected)
|
312
|
+
"#{english_name}#{expected_list}#{chained_method_clause_sentences}"
|
304
313
|
end
|
305
314
|
|
306
315
|
# Matchers do not support block expectations by default. You
|
@@ -320,7 +329,9 @@ module RSpec
|
|
320
329
|
return '' unless Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions?
|
321
330
|
|
322
331
|
@chained_method_clauses.map do |(method_name, method_args)|
|
323
|
-
|
332
|
+
english_name = EnglishPhrasing.split_words(method_name)
|
333
|
+
arg_list = EnglishPhrasing.list(method_args)
|
334
|
+
" #{english_name}#{arg_list}"
|
324
335
|
end.join
|
325
336
|
end
|
326
337
|
end
|
@@ -336,9 +347,6 @@ module RSpec
|
|
336
347
|
# Allows expectation expressions to be used in the match block.
|
337
348
|
include RSpec::Matchers
|
338
349
|
|
339
|
-
# Converts matcher name and expected args to an English expresion.
|
340
|
-
include RSpec::Matchers::Pretty
|
341
|
-
|
342
350
|
# Supports the matcher composability features of RSpec 3+.
|
343
351
|
include Composable
|
344
352
|
|
@@ -357,6 +365,9 @@ module RSpec
|
|
357
365
|
# The block parameter used in the expectation
|
358
366
|
attr_reader :block_arg
|
359
367
|
|
368
|
+
# The name of the matcher.
|
369
|
+
attr_reader :name
|
370
|
+
|
360
371
|
# @api private
|
361
372
|
def initialize(name, declarations, matcher_execution_context, *expected, &block_arg)
|
362
373
|
@name = name
|
@@ -406,11 +417,13 @@ module RSpec
|
|
406
417
|
super || @matcher_execution_context.respond_to?(method, include_private)
|
407
418
|
end
|
408
419
|
else # for 1.8.7
|
420
|
+
# :nocov:
|
409
421
|
# Indicates that this matcher responds to messages
|
410
422
|
# from the `@matcher_execution_context` as well.
|
411
423
|
def respond_to?(method, include_private=false)
|
412
424
|
super || @matcher_execution_context.respond_to?(method, include_private)
|
413
425
|
end
|
426
|
+
# :nocov:
|
414
427
|
end
|
415
428
|
|
416
429
|
private
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Matchers
|
3
|
+
# Facilitates converting ruby objects to English phrases.
|
4
|
+
module EnglishPhrasing
|
5
|
+
# Converts a symbol into an English expression.
|
6
|
+
#
|
7
|
+
# split_words(:banana_creme_pie) #=> "banana creme pie"
|
8
|
+
#
|
9
|
+
def self.split_words(sym)
|
10
|
+
sym.to_s.gsub(/_/, ' ')
|
11
|
+
end
|
12
|
+
|
13
|
+
# @note The returned string has a leading space except
|
14
|
+
# when given an empty list.
|
15
|
+
#
|
16
|
+
# Converts an object (often a collection of objects)
|
17
|
+
# into an English list.
|
18
|
+
#
|
19
|
+
# list(['banana', 'kiwi', 'mango'])
|
20
|
+
# #=> " \"banana\", \"kiwi\", and \"mango\""
|
21
|
+
#
|
22
|
+
# Given an empty collection, returns the empty string.
|
23
|
+
#
|
24
|
+
# list([]) #=> ""
|
25
|
+
#
|
26
|
+
def self.list(obj)
|
27
|
+
return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj
|
28
|
+
items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) }
|
29
|
+
case items.length
|
30
|
+
when 0
|
31
|
+
""
|
32
|
+
when 1
|
33
|
+
" #{items[0]}"
|
34
|
+
when 2
|
35
|
+
" #{items[0]} and #{items[1]}"
|
36
|
+
else
|
37
|
+
" #{items[0...-1].join(', ')}, and #{items[-1]}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -53,13 +53,7 @@ module RSpec
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def self.diff_label_for(matcher)
|
56
|
-
"Diff for (#{truncated(
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.description_for(matcher)
|
60
|
-
matcher.description
|
61
|
-
rescue NoMethodError
|
62
|
-
matcher.inspect
|
56
|
+
"Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):"
|
63
57
|
end
|
64
58
|
|
65
59
|
def self.truncated(description)
|
@@ -70,7 +64,7 @@ module RSpec
|
|
70
64
|
def diffs(differ, actual)
|
71
65
|
@expected_list.map do |(expected, diff_label)|
|
72
66
|
diff = differ.diff(actual, expected)
|
73
|
-
next if diff.empty?
|
67
|
+
next if diff.strip.empty?
|
74
68
|
"#{diff_label}#{diff}"
|
75
69
|
end.compact.join("\n")
|
76
70
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rspec/expectations'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Matchers
|
5
|
+
# Matchers for testing RSpec matchers. Include them with:
|
6
|
+
#
|
7
|
+
# require 'rspec/matchers/fail_matchers'
|
8
|
+
# RSpec.configure do |config|
|
9
|
+
# config.include RSpec::Matchers::FailMatchers
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
module FailMatchers
|
13
|
+
# Matches if an expectation fails
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# expect { some_expectation }.to fail
|
17
|
+
def fail(&block)
|
18
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Matches if an expectation fails with the provided message
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# expect { some_expectation }.to fail_with("some failure message")
|
25
|
+
# expect { some_expectation }.to fail_with(/some failure message/)
|
26
|
+
def fail_with(message)
|
27
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, message)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Matches if an expectation fails including the provided message
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# expect { some_expectation }.to fail_including("portion of some failure message")
|
34
|
+
def fail_including(*snippets)
|
35
|
+
raise_error(
|
36
|
+
RSpec::Expectations::ExpectationNotMetError,
|
37
|
+
a_string_including(*snippets)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -19,9 +19,11 @@ module RSpec
|
|
19
19
|
super || base_matcher.respond_to?(name, include_all)
|
20
20
|
end
|
21
21
|
else
|
22
|
+
# :nocov:
|
22
23
|
def respond_to?(name, include_all=false)
|
23
24
|
super || base_matcher.respond_to?(name, include_all)
|
24
25
|
end
|
26
|
+
# :nocov:
|
25
27
|
end
|
26
28
|
|
27
29
|
def initialize_copy(other)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-expectations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Baker
|
@@ -45,7 +45,7 @@ cert_chain:
|
|
45
45
|
ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
|
46
46
|
F3MdtaDehhjC
|
47
47
|
-----END CERTIFICATE-----
|
48
|
-
date: 2015-
|
48
|
+
date: 2015-06-12 00:00:00.000000000 Z
|
49
49
|
dependencies:
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: rspec-support
|
@@ -53,14 +53,14 @@ dependencies:
|
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: 3.
|
56
|
+
version: 3.3.0
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 3.
|
63
|
+
version: 3.3.0
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
65
|
name: diff-lcs
|
66
66
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- lib/rspec/expectations/configuration.rb
|
154
154
|
- lib/rspec/expectations/expectation_target.rb
|
155
155
|
- lib/rspec/expectations/fail_with.rb
|
156
|
+
- lib/rspec/expectations/failure_aggregator.rb
|
156
157
|
- lib/rspec/expectations/handler.rb
|
157
158
|
- lib/rspec/expectations/minitest_integration.rb
|
158
159
|
- lib/rspec/expectations/syntax.rb
|
@@ -189,11 +190,12 @@ files:
|
|
189
190
|
- lib/rspec/matchers/built_in/yield.rb
|
190
191
|
- lib/rspec/matchers/composable.rb
|
191
192
|
- lib/rspec/matchers/dsl.rb
|
193
|
+
- lib/rspec/matchers/english_phrasing.rb
|
192
194
|
- lib/rspec/matchers/expecteds_for_multiple_diffs.rb
|
195
|
+
- lib/rspec/matchers/fail_matchers.rb
|
193
196
|
- lib/rspec/matchers/generated_descriptions.rb
|
194
197
|
- lib/rspec/matchers/matcher_delegator.rb
|
195
198
|
- lib/rspec/matchers/matcher_protocol.rb
|
196
|
-
- lib/rspec/matchers/pretty.rb
|
197
199
|
homepage: http://github.com/rspec/rspec-expectations
|
198
200
|
licenses:
|
199
201
|
- MIT
|
@@ -214,10 +216,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
216
|
- !ruby/object:Gem::Version
|
215
217
|
version: '0'
|
216
218
|
requirements: []
|
217
|
-
rubyforge_project:
|
219
|
+
rubyforge_project:
|
218
220
|
rubygems_version: 2.2.2
|
219
221
|
signing_key:
|
220
222
|
specification_version: 4
|
221
|
-
summary: rspec-expectations-3.
|
223
|
+
summary: rspec-expectations-3.3.0
|
222
224
|
test_files: []
|
223
225
|
has_rdoc:
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,77 +0,0 @@
|
|
1
|
-
module RSpec
|
2
|
-
module Matchers
|
3
|
-
# @api private
|
4
|
-
# Contains logic to facilitate converting ruby symbols and
|
5
|
-
# objects to english phrases.
|
6
|
-
module Pretty
|
7
|
-
# @api private
|
8
|
-
# Converts a symbol into an english expression.
|
9
|
-
def split_words(sym)
|
10
|
-
sym.to_s.gsub(/_/, ' ')
|
11
|
-
end
|
12
|
-
module_function :split_words
|
13
|
-
|
14
|
-
# @api private
|
15
|
-
# Converts a collection of objects into an english expression.
|
16
|
-
def to_sentence(words)
|
17
|
-
return " #{words.inspect}" if !words || Struct === words
|
18
|
-
words = Array(words).map { |w| to_word(w) }
|
19
|
-
case words.length
|
20
|
-
when 0
|
21
|
-
""
|
22
|
-
when 1
|
23
|
-
" #{words[0]}"
|
24
|
-
when 2
|
25
|
-
" #{words[0]} and #{words[1]}"
|
26
|
-
else
|
27
|
-
" #{words[0...-1].join(', ')}, and #{words[-1]}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# @api private
|
32
|
-
# Converts the given item to string suitable for use in a list expression.
|
33
|
-
def to_word(item)
|
34
|
-
is_matcher_with_description?(item) ? item.description : item.inspect
|
35
|
-
end
|
36
|
-
|
37
|
-
# @private
|
38
|
-
# Provides an English expression for the matcher name.
|
39
|
-
def name_to_sentence
|
40
|
-
split_words(name)
|
41
|
-
end
|
42
|
-
|
43
|
-
# @api private
|
44
|
-
# Provides a name for the matcher.
|
45
|
-
def name
|
46
|
-
defined?(@name) ? @name : underscore(self.class.name.split("::").last)
|
47
|
-
end
|
48
|
-
|
49
|
-
# @private
|
50
|
-
# Borrowed from ActiveSupport
|
51
|
-
def underscore(camel_cased_word)
|
52
|
-
word = camel_cased_word.to_s.dup
|
53
|
-
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
54
|
-
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
55
|
-
word.tr!("-", "_")
|
56
|
-
word.downcase!
|
57
|
-
word
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def is_matcher_with_description?(object)
|
63
|
-
RSpec::Matchers.is_a_matcher?(object) && object.respond_to?(:description)
|
64
|
-
end
|
65
|
-
|
66
|
-
# `{ :a => 5, :b => 2 }.inspect` produces:
|
67
|
-
# {:a=>5, :b=>2}
|
68
|
-
# ...but it looks much better as:
|
69
|
-
# {:a => 5, :b => 2}
|
70
|
-
#
|
71
|
-
# This is idempotent and safe to run on a string multiple times.
|
72
|
-
def improve_hash_formatting(inspect_string)
|
73
|
-
inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2')
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|