rspec_structure_matcher 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 193cd69f56ffdd252aaf2737ff554fed0b3ae767
4
- data.tar.gz: e103d7eee610617d6b33bbeac712f1ff8ce2f678
3
+ metadata.gz: b806804c4a8f7c07e794d2d08d314fed04b2a7c3
4
+ data.tar.gz: c7add716e2fb93116eca59247d69ab20c4e94d56
5
5
  SHA512:
6
- metadata.gz: 99823fa6ba3e1b747e2487af5ccb9858df3dbb0985a33a056d045be6fc44d4d911742a789cc91b51ab4106758e7e9f87c0267c3b2ce1a4bbecbeb4b1bd5e798c
7
- data.tar.gz: 3c48db7cb3414c6f6a824ee45409250e51c090b50eedef1a7d94c264f96d790564932edef9004e95656537e33407e079f7395b2f2ddfb29f96867087e64895c7
6
+ metadata.gz: 89dc486be69a92be0e6084c803fbc3f3187edc62c44ddb80785c831eec1440efb31168ebd71f8b91347516ddceebee176453a4b5ee1e3f506becdffa66b7ee0d
7
+ data.tar.gz: 78157d392b7b7d48bbe1374b1518fe1c0a01c093fcf73a53e7dfa99b223278f2cdaaa1960e24ebf0e00a551fcc4fb015b9d9b4f7fff0a2f8c00d165113751454
data/README.md CHANGED
@@ -57,6 +57,27 @@ Callable proc/lambda
57
57
  Exact match
58
58
  : Other values will be compared directly with `==`.
59
59
 
60
+ ### Testing arrays
61
+
62
+ You often want to match each item in an array of objects against the same structure. To do so, simply define your structure with a single item in the array. This item will be matched against all items in the array you are testing.
63
+
64
+ expected_structure = {
65
+ items: [
66
+ {
67
+ name: String
68
+ }
69
+ ]
70
+ }
71
+
72
+ actual_object = {
73
+ items: [
74
+ { name: 'Bob' },
75
+ { name: 'Jane' }
76
+ ]
77
+ }
78
+
79
+ expect(actual_object).to have_structure(expected_structure) # true
80
+
60
81
  ### Testing Optional Values
61
82
 
62
83
  As mentioned above, you can use `optionally` to test optional values, so that the test will pass even if the response contains a `null`. `optionally` is nothing more than a helpful lambda generation method, much like the proc/lambda that you can write yourself.
@@ -1,6 +1,6 @@
1
1
  require 'pp'
2
2
 
3
- RSpec::Matchers.define :have_structure do |expected, opts|
3
+ RSpec::Matchers.define :have_structure do |expected|
4
4
  match do |actual|
5
5
  HaveStructureMatcher.match?(actual, expected)
6
6
  end
@@ -10,8 +10,20 @@ module HaveStructureMatcher
10
10
  end
11
11
 
12
12
  def self.build_diff(actual, expected)
13
- return expected unless actual.is_a?(Hash)
13
+ if actual.is_a?(Array) && expected.is_a?(Array)
14
+ build_array_diff(actual, expected)
15
+ elsif actual.is_a?(Hash) && expected.is_a?(Hash)
16
+ build_hash_diff(actual, expected)
17
+ elsif actual.is_a?(Hash)
18
+ expected
19
+ elsif value_match?(actual, expected)
20
+ actual
21
+ else
22
+ expected
23
+ end
24
+ end
14
25
 
26
+ def self.build_hash_diff(actual, expected)
15
27
  keys = actual.keys | expected.keys
16
28
 
17
29
  keys.each_with_object({}) do |key, memo|
@@ -22,7 +34,7 @@ module HaveStructureMatcher
22
34
  if expected_value.is_a?(Hash)
23
35
  memo[key] = build_diff(actual_value, expected_value)
24
36
  elsif expected_value.is_a?(Array)
25
- memo[key] = expected_value.zip(actual_value).map { |(e,a)| build_diff(a, e) }
37
+ memo[key] = build_array_diff(actual_value, expected_value)
26
38
  elsif value_match?(actual_value, expected_value)
27
39
  memo[key] = actual_value
28
40
  else
@@ -35,6 +47,14 @@ module HaveStructureMatcher
35
47
  end
36
48
  end
37
49
 
50
+ def self.build_array_diff(actual_value, expected_value)
51
+ if expected_value.length == 1 && actual_value.is_a?(Array)
52
+ actual_value.map { |a| build_diff(a, expected_value[0]) }
53
+ else
54
+ expected_value.zip(actual_value).map { |(e,a)| build_diff(a, e) }
55
+ end
56
+ end
57
+
38
58
  def self.print_expected_value(expected_value)
39
59
  if expected_value.respond_to?(:call)
40
60
  "Proc [#{expected_value.source_location.join(':')}]"
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RspecStructureMatcher
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'rspec_structure_matcher'
3
2
 
4
3
  describe 'have_structure' do
5
4
  let(:expected_structure) {
@@ -19,7 +18,7 @@ describe 'have_structure' do
19
18
  it 'raises the correct error' do
20
19
  expect {
21
20
  expect(structure).to have_structure(expected_structure)
22
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /-"bar" => String/)
21
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError, Regexp.new('-{"foo"=>"baz", "bar"=>String}'))
23
22
  end
24
23
  end
25
24
 
@@ -35,7 +34,10 @@ describe 'have_structure' do
35
34
  it 'raises the correct error' do
36
35
  expect {
37
36
  expect(structure).to have_structure(expected_structure)
38
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\+"bam" => "baz"/)
37
+ }.to raise_error(
38
+ RSpec::Expectations::ExpectationNotMetError,
39
+ Regexp.new(Regexp.escape('+{"foo"=>"baz", "bar"=>"baz", "bam"=>"baz"}'))
40
+ )
39
41
  end
40
42
  end
41
43
 
@@ -50,7 +52,10 @@ describe 'have_structure' do
50
52
  it 'raises the correct error' do
51
53
  expect {
52
54
  expect(structure).to have_structure(expected_structure)
53
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /-"foo" => String/)
55
+ }.to raise_error(
56
+ RSpec::Expectations::ExpectationNotMetError,
57
+ Regexp.new(Regexp.escape('+{"foo"=>1, "bar"=>"baz"}'))
58
+ )
54
59
  end
55
60
  end
56
61
 
@@ -80,7 +85,10 @@ describe 'have_structure' do
80
85
  it 'fails validation' do
81
86
  expect {
82
87
  expect(structure).to have_structure(expected_structure)
83
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /-"foo" => String/)
88
+ }.to raise_error(
89
+ RSpec::Expectations::ExpectationNotMetError,
90
+ Regexp.new(Regexp.escape('+{:foo=>"baz", "bar"=>"baz"}'))
91
+ )
84
92
  end
85
93
  end
86
94
 
@@ -118,7 +126,10 @@ describe 'have_structure' do
118
126
  it 'fails validation' do
119
127
  expect {
120
128
  expect(structure).to have_structure(expected_structure)
121
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /-"foo" => 2/)
129
+ }.to raise_error(
130
+ RSpec::Expectations::ExpectationNotMetError,
131
+ Regexp.new(Regexp.escape('+{"foo"=>1, "bar"=>"baz"}'))
132
+ )
122
133
  end
123
134
  end
124
135
  end
@@ -148,7 +159,10 @@ describe 'have_structure' do
148
159
  it 'fails validation' do
149
160
  expect {
150
161
  expect(structure).to have_structure(expected_structure)
151
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\+"foo" => 100/)
162
+ }.to raise_error(
163
+ RSpec::Expectations::ExpectationNotMetError,
164
+ Regexp.new(Regexp.quote('+{"foo"=>100}'))
165
+ )
152
166
  end
153
167
  end
154
168
  end
@@ -179,6 +193,17 @@ describe 'have_structure' do
179
193
  }.not_to raise_error
180
194
  end
181
195
  end
196
+
197
+ context 'regular expression' do
198
+ let(:expected_structure) { {'foo' => optionally(/\w+/)} }
199
+ let(:structure) { {'foo' => 'hello'} }
200
+
201
+ it 'raises no error' do
202
+ expect {
203
+ expect(structure).to have_structure(expected_structure)
204
+ }.not_to raise_error
205
+ end
206
+ end
182
207
  end
183
208
 
184
209
  context "with nested structure" do
@@ -219,9 +244,49 @@ describe 'have_structure' do
219
244
  it 'fails validation' do
220
245
  expect {
221
246
  expect(structure).to have_structure(expected_structure)
222
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\+"bar" => "a"/)
247
+ }.to raise_error(
248
+ RSpec::Expectations::ExpectationNotMetError,
249
+ Regexp.new(Regexp.quote('+{"foo"=>1, "bar"=>"a"}'))
250
+ )
223
251
  end
224
252
  end
253
+ end
254
+
255
+ context "matching against an array of objects" do
256
+ let(:expected_structure) do
257
+ {
258
+ 'items' => [
259
+ {
260
+ 'name' => String
261
+ }
262
+ ]
263
+ }
264
+ end
265
+
266
+ let(:structure) do
267
+ {
268
+ 'items' => [
269
+ { 'name' => 'Bob' },
270
+ { 'name' => 'Jane' }
271
+ ]
272
+ }
273
+ end
225
274
 
275
+ it 'passes validation' do
276
+ expect {
277
+ expect(structure).to have_structure(expected_structure)
278
+ }.not_to raise_error
279
+ end
280
+ end
281
+
282
+ context "matching two arrays" do
283
+ let(:expected_structure) { [Integer] }
284
+ let(:structure) { [10, 20, 30] }
285
+
286
+ it 'passes validation' do
287
+ expect {
288
+ expect(structure).to have_structure(expected_structure)
289
+ }.not_to raise_error
290
+ end
226
291
  end
227
292
  end
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,8 @@ require "bundler/setup"
2
2
  Bundler.setup
3
3
 
4
4
  require "pry-byebug"
5
+ require "rspec_structure_matcher"
6
+
7
+ RSpec.configure do |config|
8
+ config.include HaveStructureMatcher::Methods
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec_structure_matcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Marklove
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-11 00:00:00.000000000 Z
11
+ date: 2017-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec