rspec-hive 0.2.0 → 0.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
- data/lib/rspec/hive/matchers.rb +84 -8
- data/lib/rspec/hive/version.rb +1 -1
- data/spec/lib/rspec/hive/matchers_spec.rb +105 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b75898c0b7364fe12b80f91a36da04a54c5bab6
|
4
|
+
data.tar.gz: 86e7fcbbb5a50fc536a0954ddc27fd4cb90ef915
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da919d5129641e77e15c5bfeed2bef2396e3d02dd3eaa93ef61dae7af099323d6a9106a8b9b8ac02644035ab39588a88c6cbabbe40f7f53832e961d499a7244f
|
7
|
+
data.tar.gz: 2ea4738a1f9bb1d84426ed4873a33bfb2b8f2480a1b557fbb73e2b5fe8821fbb266defffe8fab57c3114558d6c10c3e0a8f9ee3d11fc0fd0c5138de884c4748c
|
data/lib/rspec/hive/matchers.rb
CHANGED
@@ -2,28 +2,104 @@ require 'rspec/matchers'
|
|
2
2
|
|
3
3
|
RSpec::Matchers.define :match_result_set do |expected|
|
4
4
|
match do |actual|
|
5
|
-
|
5
|
+
@diffable_actual = []
|
6
6
|
|
7
|
-
|
7
|
+
@actual = actual.clone
|
8
|
+
|
9
|
+
expected.map.with_index do |expected_row, i|
|
8
10
|
if expected_row.respond_to?(:each_pair)
|
9
11
|
if @partial_match
|
10
|
-
|
11
|
-
|
12
|
+
result_set_match?(
|
13
|
+
actual[i], expected_row,
|
14
|
+
expected_transformer: ->(e) { e.values },
|
15
|
+
actual_transformer: ->(candidate) { candidate.values_at(*expected_row.keys) },
|
16
|
+
diffable_transformer: ->(candidate) { candidate.select { |k, _v| expected_row.keys.include?(k) } }
|
17
|
+
)
|
12
18
|
else
|
13
|
-
|
19
|
+
result_set_match?(actual[i], expected_row)
|
14
20
|
end
|
15
21
|
elsif expected_row.respond_to?(:each)
|
16
22
|
raise ArgumentError, "Can't use partially matcher with Arrays" if @partial_match
|
17
|
-
|
23
|
+
result_set_match?(
|
24
|
+
actual[i], expected_row,
|
25
|
+
actual_transformer: ->(candidate) { candidate.values }
|
26
|
+
)
|
18
27
|
else
|
19
28
|
raise ArgumentError, 'Unknown type'
|
20
29
|
end
|
21
|
-
end
|
30
|
+
end.all? && expected.size == actual.size
|
22
31
|
end
|
23
32
|
|
24
33
|
chain :partially do
|
25
34
|
@partial_match = true
|
26
35
|
end
|
27
36
|
|
28
|
-
|
37
|
+
chain :unordered do
|
38
|
+
@unordered = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def result_set_match?(
|
42
|
+
actual, expected_row,
|
43
|
+
expected_transformer: ->(expected) { expected },
|
44
|
+
actual_transformer: ->(candidate) { candidate },
|
45
|
+
diffable_transformer: actual_transformer
|
46
|
+
)
|
47
|
+
if @unordered
|
48
|
+
unordered_result_set_match?(expected_row, expected_transformer, actual_transformer, diffable_transformer)
|
49
|
+
else
|
50
|
+
ordered_result_set_match?(actual, expected_row, expected_transformer, actual_transformer, diffable_transformer)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def unordered_result_set_match?(expected_row, expected_transformer, actual_transformer, diffable_transformer)
|
55
|
+
found_index = @actual.find_index do |candidate|
|
56
|
+
values_match?(expected_transformer.call(expected_row), actual_transformer.call(candidate))
|
57
|
+
end
|
58
|
+
return false unless found_index
|
59
|
+
found = @actual[found_index]
|
60
|
+
@actual.delete_at(found_index)
|
61
|
+
@diffable_actual << diffable_transformer.call(found)
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
def ordered_result_set_match?(actual, expected_row, expected_transformer, actual_transformer, diffable_transformer)
|
66
|
+
@diffable_actual << diffable_transformer.call(actual)
|
67
|
+
values_match?(expected_transformer.call(expected_row), actual_transformer.call(actual))
|
68
|
+
end
|
69
|
+
|
70
|
+
failure_message do |actual|
|
71
|
+
"expected #{actual} to match result set #{expected}\n#{diff_message(expected)}"
|
72
|
+
end
|
73
|
+
|
74
|
+
failure_message_when_negated do |actual|
|
75
|
+
"expected #{actual} not to match result set #{expected}, but did\n#{diff_message(expected)}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def diff_message(expected)
|
79
|
+
"Diff: #{differ.diff_as_object(@diffable_actual, expected)}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def differ
|
83
|
+
RSpec::Support::Differ.new(
|
84
|
+
object_preparer: ->(object) { surface_descriptions_in(object) },
|
85
|
+
color: RSpec::Matchers.configuration.color?
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Copied and adapted from RSpec::Matchers::Composable
|
90
|
+
# rubocop:disable Style/CaseEquality
|
91
|
+
def surface_descriptions_in(item)
|
92
|
+
if RSpec::Matchers.is_a_describable_matcher?(item)
|
93
|
+
RSpec::Matchers::Composable::DescribableItem.new(item)
|
94
|
+
elsif Hash === item
|
95
|
+
Hash[surface_descriptions_in(item.to_a.sort)]
|
96
|
+
elsif Struct === item || unreadable_io?(item)
|
97
|
+
RSpec::Support::ObjectFormatter.format(item)
|
98
|
+
elsif should_enumerate?(item)
|
99
|
+
item.map { |subitem| surface_descriptions_in(subitem) }
|
100
|
+
else
|
101
|
+
item
|
102
|
+
end
|
103
|
+
end
|
104
|
+
# rubocop:enable Style/CaseEquality
|
29
105
|
end
|
data/lib/rspec/hive/version.rb
CHANGED
@@ -8,9 +8,24 @@ RSpec.describe 'match_result_set' do
|
|
8
8
|
let(:paul) { {first_name: 'Paul', last_name: 'McCartney', age: 73} }
|
9
9
|
|
10
10
|
let(:full_match) { expect(actual_rows).to match_result_set(expected_rows) }
|
11
|
+
let(:unordered_match) { expect(actual_rows).to match_result_set(expected_rows).unordered }
|
11
12
|
let(:partial_match) { expect(actual_rows).to match_result_set(expected_rows).partially }
|
13
|
+
let(:partial_unordered_match) { expect(actual_rows).to match_result_set(expected_rows).partially.unordered }
|
14
|
+
|
12
15
|
let(:full_match_fails) { expect(actual_rows).not_to match_result_set(expected_rows) }
|
16
|
+
let(:unordered_match_fails) { expect(actual_rows).not_to match_result_set(expected_rows).unordered }
|
13
17
|
let(:partial_match_fails) { expect(actual_rows).not_to match_result_set(expected_rows).partially }
|
18
|
+
let(:partial_unordered_match_fails) { expect(actual_rows).not_to match_result_set(expected_rows).partially.unordered }
|
19
|
+
|
20
|
+
let(:partial_match_raises_error) do
|
21
|
+
error_message = "Can't use partially matcher with Arrays"
|
22
|
+
aggregate_failures do
|
23
|
+
expect { partial_match }.to raise_error(ArgumentError, error_message)
|
24
|
+
expect { partial_match_fails }.to raise_error(ArgumentError, error_message)
|
25
|
+
expect { partial_unordered_match }.to raise_error(ArgumentError, error_message)
|
26
|
+
expect { partial_unordered_match_fails }.to raise_error(ArgumentError, error_message)
|
27
|
+
end
|
28
|
+
end
|
14
29
|
|
15
30
|
context 'when the expected set has only one row' do
|
16
31
|
context 'but the actual set has more rows' do
|
@@ -20,14 +35,17 @@ RSpec.describe 'match_result_set' do
|
|
20
35
|
let(:expected_rows) { [john.values] }
|
21
36
|
|
22
37
|
specify { full_match_fails }
|
23
|
-
specify {
|
38
|
+
specify { unordered_match_fails }
|
39
|
+
specify { partial_match_raises_error }
|
24
40
|
end
|
25
41
|
|
26
42
|
context 'when the row is given as a hash' do
|
27
43
|
let(:expected_rows) { [john] }
|
28
44
|
|
29
45
|
specify { full_match_fails }
|
46
|
+
specify { unordered_match_fails }
|
30
47
|
specify { partial_match_fails }
|
48
|
+
specify { partial_unordered_match_fails }
|
31
49
|
end
|
32
50
|
end
|
33
51
|
|
@@ -39,24 +57,32 @@ RSpec.describe 'match_result_set' do
|
|
39
57
|
let(:expected_rows) { [john.values << 'yoko'] }
|
40
58
|
|
41
59
|
specify { full_match_fails }
|
60
|
+
specify { unordered_match_fails }
|
61
|
+
specify { partial_match_raises_error }
|
42
62
|
end
|
43
63
|
|
44
64
|
context 'when the actual and expected have are different' do
|
45
65
|
let(:expected_rows) { [paul.values] }
|
46
66
|
|
47
67
|
specify { full_match_fails }
|
68
|
+
specify { unordered_match_fails }
|
69
|
+
specify { partial_match_raises_error }
|
48
70
|
end
|
49
71
|
|
50
72
|
context 'when the actual and expected rows are equal' do
|
51
73
|
let(:expected_rows) { [john.values] }
|
52
74
|
|
53
75
|
specify { full_match }
|
76
|
+
specify { unordered_match }
|
77
|
+
specify { partial_match_raises_error }
|
54
78
|
end
|
55
79
|
|
56
80
|
context 'when the actual and expected rows are equal with rspec matchers' do
|
57
81
|
let(:expected_rows) { [[a_string_matching('John'), a_string_matching(/lennon/i), 40]] }
|
58
82
|
|
59
83
|
specify { full_match }
|
84
|
+
specify { unordered_match }
|
85
|
+
specify { partial_match_raises_error }
|
60
86
|
end
|
61
87
|
end
|
62
88
|
|
@@ -65,28 +91,106 @@ RSpec.describe 'match_result_set' do
|
|
65
91
|
let(:expected_rows) { [john.dup.tap { |j| j[:ono] = 'yoko' }] }
|
66
92
|
|
67
93
|
specify { full_match_fails }
|
94
|
+
specify { unordered_match_fails }
|
68
95
|
specify { partial_match_fails }
|
96
|
+
specify { partial_unordered_match_fails }
|
69
97
|
end
|
70
98
|
|
71
99
|
context 'when the actual and expected have are different' do
|
72
100
|
let(:expected_rows) { [john.dup.tap { |j| j[:first_name] = 'yoko' }] }
|
73
101
|
|
74
102
|
specify { full_match_fails }
|
103
|
+
specify { unordered_match_fails }
|
75
104
|
specify { partial_match_fails }
|
105
|
+
specify { partial_unordered_match_fails }
|
76
106
|
end
|
77
107
|
|
78
108
|
context 'when the actual and expected rows are equal' do
|
79
109
|
let(:expected_rows) { [john] }
|
80
110
|
|
81
111
|
specify { full_match }
|
112
|
+
specify { unordered_match }
|
82
113
|
specify { partial_match }
|
114
|
+
specify { partial_unordered_match }
|
83
115
|
end
|
84
116
|
|
85
117
|
context 'when matching a subset of columns' do
|
86
118
|
let(:expected_rows) { [{first_name: john[:first_name]}] }
|
87
119
|
|
88
120
|
specify { full_match_fails }
|
121
|
+
specify { unordered_match_fails }
|
89
122
|
specify { partial_match }
|
123
|
+
specify { partial_unordered_match }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when the expected set has multiple rows' do
|
130
|
+
let(:ringo) { {first_name: 'Richard', last_name: 'Starkey', age: -75} }
|
131
|
+
|
132
|
+
context 'and the actual set has the same number of rows' do
|
133
|
+
let(:actual_rows) { [ringo, paul, john] }
|
134
|
+
|
135
|
+
context 'when the row is given as an array' do
|
136
|
+
context 'when rows are returned in order' do
|
137
|
+
let(:expected_rows) { [ringo.values, paul.values, john.values] }
|
138
|
+
|
139
|
+
specify { full_match }
|
140
|
+
specify { unordered_match }
|
141
|
+
specify { partial_match_raises_error }
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'when rows are returned in different order' do
|
145
|
+
let(:expected_rows) { [paul.values, john.values, ringo.values] }
|
146
|
+
|
147
|
+
specify { full_match_fails }
|
148
|
+
specify { unordered_match }
|
149
|
+
specify { partial_match_raises_error }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'when the row is given as a hash' do
|
154
|
+
context 'when matching all columns' do
|
155
|
+
context 'when rows are returned in order' do
|
156
|
+
let(:expected_rows) { [ringo, paul, john] }
|
157
|
+
|
158
|
+
specify { full_match }
|
159
|
+
specify { unordered_match }
|
160
|
+
specify { partial_match }
|
161
|
+
specify { partial_unordered_match }
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when rows are returned in different order' do
|
165
|
+
let(:expected_rows) { [paul, john, ringo] }
|
166
|
+
|
167
|
+
specify { full_match_fails }
|
168
|
+
specify { unordered_match }
|
169
|
+
specify { partial_match_fails }
|
170
|
+
specify { partial_unordered_match }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'when matching a subset of columns' do
|
175
|
+
let(:expected_rows) { members.map { |member| {age: member[:age]} } }
|
176
|
+
|
177
|
+
context 'when rows are returned in order' do
|
178
|
+
let(:members) { [ringo, paul, john] }
|
179
|
+
|
180
|
+
specify { full_match_fails }
|
181
|
+
specify { unordered_match_fails }
|
182
|
+
specify { partial_match }
|
183
|
+
specify { partial_unordered_match }
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'when rows are returned in different order' do
|
187
|
+
let(:members) { [john, paul, ringo] }
|
188
|
+
|
189
|
+
specify { full_match_fails }
|
190
|
+
specify { unordered_match_fails }
|
191
|
+
specify { partial_match_fails }
|
192
|
+
specify { partial_unordered_match }
|
193
|
+
end
|
90
194
|
end
|
91
195
|
end
|
92
196
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-hive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wojtek Mielczarek
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-05-
|
12
|
+
date: 2016-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|