rspec_deep_eq 0.0.1
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 +7 -0
- data/README.md +70 -0
- data/lib/deep_eq.rb +7 -0
- data/lib/deep_eq/deep_equal_checker.rb +135 -0
- data/lib/deep_eq/matcher.rb +58 -0
- data/lib/deep_eq/version.rb +3 -0
- data/spec/lib/deep_eq/matcher_spec.rb +265 -0
- data/spec/mocks/fake_record.rb +17 -0
- data/spec/mocks/matcher.rb +5 -0
- data/spec/spec_helper.rb +11 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8e7e2b845d478ad4db3d4633d7edd0ae38c2d626b0307c4c588a83d655bdfaf
|
4
|
+
data.tar.gz: 2105b476d66f1cea36f96690791a21d39be20a44fe60977f673b9c99bfd4f60f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d685dc53ee147d2cf72d7174684342dc2b9f1e545336c78fa01cafe13d476228daeded1f75608eaf02789bc34cb808cc30f3d351bdb74704f696200b464658ea
|
7
|
+
data.tar.gz: 32c8f8b3551af6992b9234b8aa5ca43ca187f99dab6ce503587c47d2a9e090b72d7716cf35fabc7c8f5690025bdfb6e9c5bb974453af7fe12c5c7df2cfb06420
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# RSpec Deep Eq Matches
|
2
|
+
|
3
|
+
This gem adds an RSpec `deep_eq` matcher that recursively compares contents of `Hash` and `Array` data.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
Add gem to your `Gemfile`:
|
7
|
+
```ruby
|
8
|
+
gem 'rspec_deep_eq'
|
9
|
+
```
|
10
|
+
|
11
|
+
And run
|
12
|
+
```
|
13
|
+
bundle install
|
14
|
+
```
|
15
|
+
|
16
|
+
Or install it manually:
|
17
|
+
```bash
|
18
|
+
gem install rspec_deep_eq
|
19
|
+
```
|
20
|
+
|
21
|
+
## Getting started
|
22
|
+
In `rails_helper` file, configure `deep_eq` matcher for RSpec:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# rails_helper.rb
|
26
|
+
|
27
|
+
require 'deep_eq'
|
28
|
+
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.include DeepEq
|
31
|
+
end
|
32
|
+
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
You can compare everything with `deep_eq` matcher, but it's created to compare complex structures like nested hashes and arrays.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
describe 'Deep Equal' do
|
40
|
+
it 'compares' do
|
41
|
+
data = prepare_data
|
42
|
+
|
43
|
+
expect(data).to deep_eq(
|
44
|
+
id: 1,
|
45
|
+
items: [
|
46
|
+
id: 3,
|
47
|
+
images: [
|
48
|
+
{
|
49
|
+
url: 'https://example.com/bass_guitar.png'
|
50
|
+
},
|
51
|
+
{
|
52
|
+
url: 'https://example.com/naked_lady.png'
|
53
|
+
}
|
54
|
+
]
|
55
|
+
],
|
56
|
+
author: {
|
57
|
+
name: 'John Doe'
|
58
|
+
}
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
## Motivation
|
65
|
+
Comparing complex data structures can be easily done using built-in RSpec matchers like `eq`, `match_array` or `hash_including`. But when something goes wrong, it displays hard-to-read error output. This matcher is created to make fixing such tests easier.
|
66
|
+
|
67
|
+
Read more [here](MOTIVATION.md).
|
68
|
+
|
69
|
+
## License
|
70
|
+
Published under MIT license.
|
data/lib/deep_eq.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
module DeepEq
|
2
|
+
class DeepEqualChecker
|
3
|
+
def initialize(current:, expected:, location:, matcher_object:)
|
4
|
+
@current = current
|
5
|
+
@expected = expected
|
6
|
+
@location = location
|
7
|
+
@matcher_object = matcher_object
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform
|
11
|
+
case expected
|
12
|
+
when Array
|
13
|
+
return unless current_ensure_array
|
14
|
+
return unless current_ensure_count
|
15
|
+
|
16
|
+
expected.count.times do |index|
|
17
|
+
DeepEqualChecker.new(
|
18
|
+
current: current[index],
|
19
|
+
expected: expected[index],
|
20
|
+
location: location + "[#{index}]",
|
21
|
+
matcher_object: matcher_object
|
22
|
+
).perform
|
23
|
+
end
|
24
|
+
when Hash
|
25
|
+
return unless current_ensure_hash
|
26
|
+
return unless current_ensure_keys
|
27
|
+
|
28
|
+
expected.keys.each do |key|
|
29
|
+
d = DeepEqualChecker.new(
|
30
|
+
current: current[key],
|
31
|
+
expected: expected[key],
|
32
|
+
location: location + "[#{key.inspect}]",
|
33
|
+
matcher_object: matcher_object
|
34
|
+
).perform
|
35
|
+
end
|
36
|
+
else
|
37
|
+
compare_values
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def compare_values
|
44
|
+
return if current == expected
|
45
|
+
|
46
|
+
add_error "#{location} is invalid (expected #{expected.inspect}, got #{current.inspect})"
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_error(error)
|
50
|
+
matcher_object.add_error error
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def current_ensure_hash
|
55
|
+
return true if current.is_a? Hash
|
56
|
+
|
57
|
+
add_type_mismatch_error('Hash')
|
58
|
+
end
|
59
|
+
|
60
|
+
def current_ensure_array
|
61
|
+
return true if current.is_a? Array
|
62
|
+
|
63
|
+
add_type_mismatch_error('Array')
|
64
|
+
end
|
65
|
+
|
66
|
+
def current_ensure_count
|
67
|
+
return true if current.count === expected.count
|
68
|
+
|
69
|
+
add_error "#{location} is expected to have length #{expected.count}, but has #{current.count}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def current_ensure_keys
|
73
|
+
bad_keys = current.keys.reject { |key| expected.keys.include? key }
|
74
|
+
|
75
|
+
return true if bad_keys.empty?
|
76
|
+
|
77
|
+
add_error "#{location} is expected to not contain keys: #{bad_keys.map(&:inspect).join(', ')}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_type_mismatch_error(expected_class)
|
81
|
+
add_error "#{location} is expected to be #{expected_class}, but #{current.class} found"
|
82
|
+
end
|
83
|
+
|
84
|
+
attr_reader :current, :expected, :location, :matcher_object
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# module DeepEql
|
92
|
+
# module Matchers
|
93
|
+
#
|
94
|
+
# def deep_eql(expected)
|
95
|
+
# DeepEql.new(expected)
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# class DeepEql
|
99
|
+
#
|
100
|
+
# def initialize(expectation)
|
101
|
+
# @expectation = expectation
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# def matches?(target)
|
105
|
+
# result = true
|
106
|
+
# @target = target
|
107
|
+
# case @expectation
|
108
|
+
# when Hash
|
109
|
+
# result &&= @target.is_a?(Hash) && @target.keys.count == @expectation.keys.count
|
110
|
+
# @expectation.keys.each do |key|
|
111
|
+
# result &&= @target.has_key?(key) &&
|
112
|
+
# DeepEql.new(@expectation[key]).matches?(@target[key])
|
113
|
+
# end
|
114
|
+
# when Array
|
115
|
+
# result &&= @target.is_a?(Array) && @target.count == @expectation.count
|
116
|
+
# @expectation.each_index do |index|
|
117
|
+
# result &&= DeepEql.new(@expectation[index]).matches?(@target[index])
|
118
|
+
# end
|
119
|
+
# else
|
120
|
+
# result &&= @target == @expectation
|
121
|
+
# end
|
122
|
+
# result
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# def failure_message_for_should
|
126
|
+
# "expected #{@target.inspect} to be deep_eql with #{@expectation.inspect}"
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# def failure_message_for_should_not
|
130
|
+
# "expected #{@target.inspect} not to be in deep_eql with #{@expectation.inspect}"
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# end
|
135
|
+
# end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './deep_equal_checker'
|
2
|
+
|
3
|
+
module DeepEq
|
4
|
+
class Matcher
|
5
|
+
def initialize(expected)
|
6
|
+
@expected = expected
|
7
|
+
@errors = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(current)
|
11
|
+
@current = current
|
12
|
+
|
13
|
+
perform_deep_equal_check
|
14
|
+
|
15
|
+
errors.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message
|
19
|
+
message = [
|
20
|
+
'Expected',
|
21
|
+
current.inspect,
|
22
|
+
"\nto be deep equal to",
|
23
|
+
expected.inspect,
|
24
|
+
'',
|
25
|
+
"\nFollowing errors found:"
|
26
|
+
]
|
27
|
+
|
28
|
+
message.concat(errors).push("\r").join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def failure_message_when_negated
|
32
|
+
message = [
|
33
|
+
'Expected',
|
34
|
+
current.inspect,
|
35
|
+
"\nnot to be deep equal to",
|
36
|
+
expected.inspect,
|
37
|
+
"\nBut equal values found."
|
38
|
+
].join("\n") + "\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_error(error)
|
42
|
+
errors.push error
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :errors, :current, :expected
|
48
|
+
|
49
|
+
def perform_deep_equal_check
|
50
|
+
DeepEqualChecker.new(
|
51
|
+
current: current,
|
52
|
+
expected: expected,
|
53
|
+
location: 'value',
|
54
|
+
matcher_object: self
|
55
|
+
).perform
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DeepEq::Matcher do
|
4
|
+
describe 'deep_eq' do
|
5
|
+
let!(:matcher_object) { DeepEq::Matcher.new(expected) }
|
6
|
+
let(:errors) { [] }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(DeepEq::Matcher).to receive(:new).and_return(matcher_object)
|
10
|
+
allow(matcher_object).to receive(:add_error).and_call_original
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
expect(matcher_object).to have_received(:add_error).exactly(errors.count).times
|
15
|
+
|
16
|
+
errors.each do |error|
|
17
|
+
expect(matcher_object).to have_received(:add_error).with(error)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'equality check' do
|
22
|
+
after do
|
23
|
+
expect(current).to deep_eq expected
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when comparing integers' do
|
27
|
+
let(:current) { 2 }
|
28
|
+
let(:expected) { 2.0 }
|
29
|
+
|
30
|
+
it 'passes' do; end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when comparing strings' do
|
34
|
+
let(:current) { 'abc' }
|
35
|
+
let(:expected) { 'abc' }
|
36
|
+
|
37
|
+
it 'passes' do; end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when comparing symbols' do
|
41
|
+
let(:current) { :def }
|
42
|
+
let(:expected) { :"def" }
|
43
|
+
|
44
|
+
it 'passes' do; end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when comparing objects' do
|
48
|
+
let(:current) { FakeRecord.new(value: 12) }
|
49
|
+
let(:expected) { FakeRecord.new(value: 12.0) }
|
50
|
+
|
51
|
+
it 'passes' do; end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when comparing arrays' do
|
55
|
+
let(:current) { [1, 4, 2] }
|
56
|
+
let(:expected) { [1, 4, 2] }
|
57
|
+
|
58
|
+
it 'passes' do; end
|
59
|
+
|
60
|
+
context 'with arrays' do
|
61
|
+
let(:current) { [1, 2, [3, 4, 5], 6, [7]] }
|
62
|
+
let(:expected) { [1, 2, [3, 4, 5], 6, [7]] }
|
63
|
+
|
64
|
+
it 'passes' do; end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with hashes' do
|
68
|
+
let(:current) { [1, 2, { foo: 'bar', baz: 1 }] }
|
69
|
+
let(:expected) { [1, 2, { baz: 1, foo: 'bar' }] }
|
70
|
+
|
71
|
+
it 'passes' do; end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when comparing hashes' do
|
76
|
+
let(:current) { { one: 1, two: 2, three: 3 } }
|
77
|
+
let(:expected) { { one: 1, three: 3, two: 2 } }
|
78
|
+
|
79
|
+
it 'passes' do; end
|
80
|
+
|
81
|
+
context 'with arrays' do
|
82
|
+
let(:current) { { one: 1, two: [2, 3, 4]} }
|
83
|
+
let(:expected) { { two: [2, 3, 4], one: 1 } }
|
84
|
+
|
85
|
+
it 'passes' do; end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'with hashes' do
|
89
|
+
let(:current) { { one: 1, two: { full: 2.0, half: 2.5 } } }
|
90
|
+
let(:expected) { { two: { full: 2, half: 2.5 }, one: 1 } }
|
91
|
+
|
92
|
+
it 'passes' do; end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'inequality check' do
|
98
|
+
after do
|
99
|
+
expect(current).to_not deep_eq expected
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when comparing integers' do
|
103
|
+
let(:current) { 2 }
|
104
|
+
let(:expected) { 3.0 }
|
105
|
+
let(:errors) {
|
106
|
+
['value is invalid (expected 3.0, got 2)']
|
107
|
+
}
|
108
|
+
|
109
|
+
it 'passes with errors' do; end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when comparing strings' do
|
113
|
+
let(:current) { 'abc' }
|
114
|
+
let(:expected) { 'abx' }
|
115
|
+
let(:errors) {
|
116
|
+
['value is invalid (expected "abx", got "abc")']
|
117
|
+
}
|
118
|
+
|
119
|
+
it 'passes with errors' do; end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when comparing symbols' do
|
123
|
+
let(:current) { :def }
|
124
|
+
let(:expected) { :"defo" }
|
125
|
+
let(:errors) {
|
126
|
+
['value is invalid (expected :defo, got :def)']
|
127
|
+
}
|
128
|
+
|
129
|
+
it 'passes with errors' do; end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when comparing objects' do
|
133
|
+
let(:current) { FakeRecord.new(value: 12) }
|
134
|
+
let(:expected) { FakeRecord.new(value: 13) }
|
135
|
+
let(:errors) {
|
136
|
+
['value is invalid (expected #<FakeRecord @value=13>, got #<FakeRecord @value=12>)']
|
137
|
+
}
|
138
|
+
|
139
|
+
it 'passes with errors' do; end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when comparing arrays' do
|
143
|
+
context 'of integers' do
|
144
|
+
let(:current) { [1, 4, 2] }
|
145
|
+
let(:expected) { [1, 3, 2] }
|
146
|
+
let(:errors) {
|
147
|
+
['value[1] is invalid (expected 3, got 4)']
|
148
|
+
}
|
149
|
+
|
150
|
+
it 'passes with errors' do; end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'with arrays' do
|
154
|
+
let(:current) { [1, 2, [3, 5, 7], 6, [7]] }
|
155
|
+
let(:expected) { [1, 2, [3, 4, 7], 6, [7]] }
|
156
|
+
let(:errors) {
|
157
|
+
['value[2][1] is invalid (expected 4, got 5)']
|
158
|
+
}
|
159
|
+
|
160
|
+
it 'passes with errors' do; end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with hashes' do
|
164
|
+
let(:current) { [1, 2, { foo: 'bar', baz: 1 }] }
|
165
|
+
let(:expected) { [1, 2, { foo: 'baz', baz: 1 }] }
|
166
|
+
let(:errors) {
|
167
|
+
['value[2][:foo] is invalid (expected "baz", got "bar")']
|
168
|
+
}
|
169
|
+
|
170
|
+
it 'passes with errors' do; end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'when comparing hashes' do
|
175
|
+
context 'with integers' do
|
176
|
+
let(:current) { { one: 1, two: 2, three: 3 } }
|
177
|
+
let(:expected) { { one: 1, three: 30, two: 2 } }
|
178
|
+
let(:errors) {
|
179
|
+
['value[:three] is invalid (expected 30, got 3)']
|
180
|
+
}
|
181
|
+
|
182
|
+
it 'passes with errors' do; end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
context 'with arrays' do
|
187
|
+
let(:current) { { one: 1, two: [2, 3, 4] } }
|
188
|
+
let(:expected) { { two: [2, 3, 4], one: '1' } }
|
189
|
+
let(:errors) {
|
190
|
+
['value[:one] is invalid (expected "1", got 1)']
|
191
|
+
}
|
192
|
+
|
193
|
+
it 'passes with errors' do; end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'with hashes' do
|
197
|
+
let(:current) { { one: 1, two: { full: 2.0, half: 2.5 } } }
|
198
|
+
let(:expected) { { two: { full: 2, half: 'e' }, one: 1 } }
|
199
|
+
let(:errors) {
|
200
|
+
['value[:two][:half] is invalid (expected "e", got 2.5)']
|
201
|
+
}
|
202
|
+
|
203
|
+
it 'passes with errors' do; end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'when comparing hash with integer' do
|
208
|
+
let(:current) { {} }
|
209
|
+
let(:expected) { [] }
|
210
|
+
let(:errors) {
|
211
|
+
['value is expected to be Array, but Hash found']
|
212
|
+
}
|
213
|
+
|
214
|
+
it 'passes with errors' do; end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'when comparing hash with incorrect key' do
|
218
|
+
let(:current) { { foo: { bar: { baz: 10 } } } }
|
219
|
+
let(:expected) { { foo: { bar: { 'baz' => 10 } } } }
|
220
|
+
let(:errors) {
|
221
|
+
['value[:foo][:bar] is expected to not contain keys: :baz']
|
222
|
+
}
|
223
|
+
|
224
|
+
it 'passes with errors' do; end
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'when comparing arrays of different length' do
|
228
|
+
context 'when expected is longer' do
|
229
|
+
let(:current) { [nil, [1, 2]] }
|
230
|
+
let(:expected) { [nil, [1, 2, 3, 4]] }
|
231
|
+
let(:errors) {
|
232
|
+
['value[1] is expected to have length 4, but has 2']
|
233
|
+
}
|
234
|
+
|
235
|
+
it 'passes with errors' do; end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'when expected is shorter' do
|
239
|
+
let(:current) { [[1, 2, 3, 4]] }
|
240
|
+
let(:expected) { [[1, 2, 3]] }
|
241
|
+
let(:errors) {
|
242
|
+
['value[0] is expected to have length 3, but has 4']
|
243
|
+
}
|
244
|
+
|
245
|
+
it 'passes with errors' do; end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when comparing objects with multiple errors' do
|
250
|
+
let(:current) { [4, {}, [{ id: 10 }, { id: 15, name: 'Joe' }], { foo: { bar: :baz } }] }
|
251
|
+
let(:expected) { [3, [], [{ id: 10 }, { id: 150 }], { foo: { bar: :not_baz } }] }
|
252
|
+
let(:errors) {
|
253
|
+
[
|
254
|
+
'value[0] is invalid (expected 3, got 4)',
|
255
|
+
'value[1] is expected to be Array, but Hash found',
|
256
|
+
'value[2][1] is expected to not contain keys: :name',
|
257
|
+
'value[3][:foo][:bar] is invalid (expected :not_baz, got :baz)'
|
258
|
+
]
|
259
|
+
}
|
260
|
+
|
261
|
+
it 'passes with errors' do; end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class FakeRecord
|
2
|
+
def initialize(value:)
|
3
|
+
@value = value
|
4
|
+
end
|
5
|
+
|
6
|
+
def ==(another_record)
|
7
|
+
if another_record.is_a?(FakeRecord)
|
8
|
+
value == another_record.value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
"#<FakeRecord @value=#{value}>"
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :value
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec_deep_eq
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- polakowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard-rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: RSpec deep_eq matcher
|
56
|
+
email:
|
57
|
+
- marek.polakowski@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- README.md
|
63
|
+
- lib/deep_eq.rb
|
64
|
+
- lib/deep_eq/deep_equal_checker.rb
|
65
|
+
- lib/deep_eq/matcher.rb
|
66
|
+
- lib/deep_eq/version.rb
|
67
|
+
- spec/lib/deep_eq/matcher_spec.rb
|
68
|
+
- spec/mocks/fake_record.rb
|
69
|
+
- spec/mocks/matcher.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
homepage: http://github.com/polakowski/rspec_deep_eq
|
72
|
+
licenses: []
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubygems_version: 3.0.3
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: RSpec deep_eq matcher
|
93
|
+
test_files:
|
94
|
+
- spec/mocks/fake_record.rb
|
95
|
+
- spec/mocks/matcher.rb
|
96
|
+
- spec/spec_helper.rb
|
97
|
+
- spec/lib/deep_eq/matcher_spec.rb
|