rspec-json_expectations 1.2.2 → 1.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/features/rspec/json_expectations/unordered_array_support.feature +200 -0
- data/lib/rspec/json_expectations/failure_presenter.rb +21 -1
- data/lib/rspec/json_expectations/json_traverser.rb +13 -1
- data/lib/rspec/json_expectations/matchers.rb +46 -1
- data/lib/rspec/json_expectations/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 635c0cad90f8b318d89952ee50c859dc7bc4110b
|
4
|
+
data.tar.gz: 430f157ca89a149f6f0c99e655ae6ebe40180ae1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07b925d6f73e3478dae9b094e7bcf8a624c3b814e9d22b6c2b877bc628c9676d05bc628e5a0a344b48d16746184f93a2f578c1555502c9a39be4d79dc39048e1
|
7
|
+
data.tar.gz: 20ea442c480d27d1af256ea657d206e86f527b38171709aafa3710135565ff0f664a87c8ac981b924ad64d95287f33d2d83c937f9d63ef5d1cf7772c1789dd8e
|
@@ -0,0 +1,200 @@
|
|
1
|
+
Feature: Unordered array matching support for include_json matcher
|
2
|
+
|
3
|
+
As a developer extensively testing my APIs
|
4
|
+
I want to be able to match json parts with array
|
5
|
+
And I don't want to be explicit about the order of the elements
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a file "spec/spec_helper.rb" with:
|
9
|
+
"""ruby
|
10
|
+
require "rspec/json_expectations"
|
11
|
+
|
12
|
+
RSpec.configure do |c|
|
13
|
+
c.include RSpec::JsonExpectations::Matchers
|
14
|
+
end
|
15
|
+
"""
|
16
|
+
And a local "JSON_WITH_ARRAY" with:
|
17
|
+
"""json
|
18
|
+
{
|
19
|
+
"per_page": 3,
|
20
|
+
"count": 17,
|
21
|
+
"page": 2,
|
22
|
+
"page_count": 6,
|
23
|
+
"results": [
|
24
|
+
{
|
25
|
+
"id": 25,
|
26
|
+
"email": "john.smith@example.com",
|
27
|
+
"badges": ["first flight", "day & night"],
|
28
|
+
"name": "John"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"id": 26,
|
32
|
+
"email": "john.smith@example.com",
|
33
|
+
"badges": ["first flight"],
|
34
|
+
"name": "John"
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"id": 27,
|
38
|
+
"email": "john.smith@example.com",
|
39
|
+
"badges": ["day & night"],
|
40
|
+
"name": "John"
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
"""
|
45
|
+
And a local "JSON_WITH_ROOT_ARRAY" with:
|
46
|
+
"""json
|
47
|
+
[
|
48
|
+
"first flight",
|
49
|
+
"day & night"
|
50
|
+
]
|
51
|
+
"""
|
52
|
+
|
53
|
+
Scenario: Expecting json string to fully include json with arrays
|
54
|
+
Given a file "spec/nested_example_spec.rb" with:
|
55
|
+
"""ruby
|
56
|
+
require "spec_helper"
|
57
|
+
|
58
|
+
RSpec.describe "A json response" do
|
59
|
+
subject { '%{JSON_WITH_ARRAY}' }
|
60
|
+
|
61
|
+
it "has basic info about user" do
|
62
|
+
expect(subject).to include_json(
|
63
|
+
results: UnorderedArray(
|
64
|
+
{ id: 25, badges: ["first flight", "day & night"] },
|
65
|
+
{ id: 26, badges: ["first flight"] },
|
66
|
+
{ id: 27, badges: ["day & night"] }
|
67
|
+
)
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
"""
|
72
|
+
When I run "rspec spec/nested_example_spec.rb"
|
73
|
+
Then I see:
|
74
|
+
"""
|
75
|
+
1 example, 0 failures
|
76
|
+
"""
|
77
|
+
|
78
|
+
Scenario: Expecting json string to fully include json with arrays with different order
|
79
|
+
Given a file "spec/nested_example_spec.rb" with:
|
80
|
+
"""ruby
|
81
|
+
require "spec_helper"
|
82
|
+
|
83
|
+
RSpec.describe "A json response" do
|
84
|
+
subject { '%{JSON_WITH_ARRAY}' }
|
85
|
+
|
86
|
+
it "has basic info about user" do
|
87
|
+
expect(subject).to include_json(
|
88
|
+
results: UnorderedArray(
|
89
|
+
{ id: 26, badges: ["first flight"] },
|
90
|
+
{ id: 27, badges: ["day & night"] },
|
91
|
+
{ id: 25, badges: ["first flight", "day & night"] }
|
92
|
+
)
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
"""
|
97
|
+
When I run "rspec spec/nested_example_spec.rb"
|
98
|
+
Then I see:
|
99
|
+
"""
|
100
|
+
1 example, 0 failures
|
101
|
+
"""
|
102
|
+
|
103
|
+
Scenario: Expecting json string to fully include json with wrong values
|
104
|
+
Given a file "spec/nested_example_spec.rb" with:
|
105
|
+
"""ruby
|
106
|
+
require "spec_helper"
|
107
|
+
|
108
|
+
RSpec.describe "A json response" do
|
109
|
+
subject { '%{JSON_WITH_ARRAY}' }
|
110
|
+
|
111
|
+
it "has basic info about user" do
|
112
|
+
expect(subject).to include_json(
|
113
|
+
results: UnorderedArray(
|
114
|
+
{ id: 26, badges: ["first flight"] },
|
115
|
+
{ id: 35, badges: ["unknown", "badge"] },
|
116
|
+
{ id: 27, badges: ["day & night"] },
|
117
|
+
{ id: 25, badges: ["first flight", "day & night"] }
|
118
|
+
)
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
"""
|
123
|
+
When I run "rspec spec/nested_example_spec.rb"
|
124
|
+
Then I see:
|
125
|
+
"""
|
126
|
+
json atom at path "results/1" is missing
|
127
|
+
"""
|
128
|
+
And I see:
|
129
|
+
"""
|
130
|
+
expected: {:id=>35, :badges=>["unknown", "badge"]}
|
131
|
+
got: nil
|
132
|
+
"""
|
133
|
+
|
134
|
+
Scenario: Expecting json string with array at root to fully include json with arrays
|
135
|
+
Given a file "spec/nested_example_spec.rb" with:
|
136
|
+
"""ruby
|
137
|
+
require "spec_helper"
|
138
|
+
|
139
|
+
RSpec.describe "A json response" do
|
140
|
+
subject { '%{JSON_WITH_ROOT_ARRAY}' }
|
141
|
+
|
142
|
+
it "has basic info about user" do
|
143
|
+
expect(subject).to include_json(
|
144
|
+
UnorderedArray( "first flight", "day & night" )
|
145
|
+
)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
"""
|
149
|
+
When I run "rspec spec/nested_example_spec.rb"
|
150
|
+
Then I see:
|
151
|
+
"""
|
152
|
+
1 example, 0 failures
|
153
|
+
"""
|
154
|
+
|
155
|
+
Scenario: Expecting json string with array at root to fully include json with arrays with different order
|
156
|
+
Given a file "spec/nested_example_spec.rb" with:
|
157
|
+
"""ruby
|
158
|
+
require "spec_helper"
|
159
|
+
|
160
|
+
RSpec.describe "A json response" do
|
161
|
+
subject { '%{JSON_WITH_ROOT_ARRAY}' }
|
162
|
+
|
163
|
+
it "has basic info about user" do
|
164
|
+
expect(subject).to include_json(
|
165
|
+
UnorderedArray( "day & night", "first flight" )
|
166
|
+
)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
"""
|
170
|
+
When I run "rspec spec/nested_example_spec.rb"
|
171
|
+
Then I see:
|
172
|
+
"""
|
173
|
+
1 example, 0 failures
|
174
|
+
"""
|
175
|
+
|
176
|
+
Scenario: Expecting json string with array at root to fully include json with wrong values
|
177
|
+
Given a file "spec/nested_example_spec.rb" with:
|
178
|
+
"""ruby
|
179
|
+
require "spec_helper"
|
180
|
+
|
181
|
+
RSpec.describe "A json response" do
|
182
|
+
subject { '%{JSON_WITH_ROOT_ARRAY}' }
|
183
|
+
|
184
|
+
it "has basic info about user" do
|
185
|
+
expect(subject).to include_json(
|
186
|
+
UnorderedArray( "day & night", "unknown", "first flight" )
|
187
|
+
)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
"""
|
191
|
+
When I run "rspec spec/nested_example_spec.rb"
|
192
|
+
Then I see:
|
193
|
+
"""
|
194
|
+
json atom at path "1" is missing
|
195
|
+
"""
|
196
|
+
And I see:
|
197
|
+
"""
|
198
|
+
expected: "unknown"
|
199
|
+
got: nil
|
200
|
+
"""
|
@@ -14,7 +14,8 @@ module RSpec
|
|
14
14
|
[
|
15
15
|
render_no_key(path, error, negate),
|
16
16
|
render_not_eq(path, error, negate),
|
17
|
-
render_not_match(path, error, negate)
|
17
|
+
render_not_match(path, error, negate),
|
18
|
+
render_missing(path, error, negate)
|
18
19
|
].select { |e| e }.first
|
19
20
|
end
|
20
21
|
|
@@ -42,6 +43,21 @@ module RSpec
|
|
42
43
|
} if error_is_not_match?(error)
|
43
44
|
end
|
44
45
|
|
46
|
+
def render_missing(path, error, negate=false)
|
47
|
+
return unless error_is_missing?(error)
|
48
|
+
|
49
|
+
prefix = "#{path}/" if path && !path.empty?
|
50
|
+
|
51
|
+
items = error[:missing].map do |item|
|
52
|
+
%{
|
53
|
+
json atom at path "#{prefix}#{item[:index]}" is missing
|
54
|
+
|
55
|
+
expected: #{item[:item].inspect}
|
56
|
+
got: nil
|
57
|
+
}
|
58
|
+
end.join("\n")
|
59
|
+
end
|
60
|
+
|
45
61
|
def error_is_not_eq?(error)
|
46
62
|
error.is_a?(Hash) && error.has_key?(:expected) && !error[:expected].is_a?(Regexp)
|
47
63
|
end
|
@@ -49,6 +65,10 @@ module RSpec
|
|
49
65
|
def error_is_not_match?(error)
|
50
66
|
error.is_a?(Hash) && error.has_key?(:expected) && error[:expected].is_a?(Regexp)
|
51
67
|
end
|
68
|
+
|
69
|
+
def error_is_missing?(error)
|
70
|
+
error.is_a?(Hash) && error.has_key?(:missing)
|
71
|
+
end
|
52
72
|
end
|
53
73
|
end
|
54
74
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "json"
|
2
|
+
require "rspec/json_expectations/matchers"
|
2
3
|
|
3
4
|
module RSpec
|
4
5
|
module JsonExpectations
|
@@ -9,13 +10,15 @@ module RSpec
|
|
9
10
|
class JsonTraverser
|
10
11
|
HANDLED_BY_SIMPLE_VALUE_HANDLER = [String, Numeric, FalseClass, TrueClass, NilClass]
|
11
12
|
RSPECMATCHERS = defined?(RSpec::Matchers) ? [RSpec::Matchers::BuiltIn::BaseMatcher] : []
|
12
|
-
SUPPORTED_VALUES = [Hash, Regexp, Array] +
|
13
|
+
SUPPORTED_VALUES = [Hash, Regexp, Array, Matchers::UnorderedArrayMatcher] +
|
14
|
+
HANDLED_BY_SIMPLE_VALUE_HANDLER + RSPECMATCHERS
|
13
15
|
|
14
16
|
class << self
|
15
17
|
def traverse(errors, expected, actual, negate=false, prefix=[])
|
16
18
|
[
|
17
19
|
handle_hash(errors, expected, actual, negate, prefix),
|
18
20
|
handle_array(errors, expected, actual, negate, prefix),
|
21
|
+
handle_unordered(errors, expected, actual, negate, prefix),
|
19
22
|
handle_value(errors, expected, actual, negate, prefix),
|
20
23
|
handle_regex(errors, expected, actual, negate, prefix),
|
21
24
|
handle_rspec_matcher(errors, expected, actual, negate, prefix),
|
@@ -50,6 +53,15 @@ module RSpec
|
|
50
53
|
handle_keyvalue(errors, transformed_expected, actual, negate, prefix)
|
51
54
|
end
|
52
55
|
|
56
|
+
def handle_unordered(errors, expected, actual, negate=false, prefix=[])
|
57
|
+
return nil unless expected.is_a?(Matchers::UnorderedArrayMatcher)
|
58
|
+
|
59
|
+
conditionally_negate(
|
60
|
+
expected.match(errors, actual, prefix),
|
61
|
+
negate
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
53
65
|
def handle_value(errors, expected, actual, negate=false, prefix=[])
|
54
66
|
return nil unless handled_by_simple_value?(expected)
|
55
67
|
|
@@ -36,7 +36,9 @@ RSpec::Matchers.define :include_json do |expected|
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def traverse(expected, actual, negate=false)
|
39
|
-
unless expected.is_a?(Hash) ||
|
39
|
+
unless expected.is_a?(Hash) ||
|
40
|
+
expected.is_a?(Array) ||
|
41
|
+
expected.is_a?(::RSpec::JsonExpectations::Matchers::UnorderedArrayMatcher)
|
40
42
|
raise ArgumentError,
|
41
43
|
"Expected value must be a json for include_json matcher"
|
42
44
|
end
|
@@ -52,3 +54,46 @@ RSpec::Matchers.define :include_json do |expected|
|
|
52
54
|
)
|
53
55
|
end
|
54
56
|
end
|
57
|
+
|
58
|
+
module RSpec
|
59
|
+
module JsonExpectations
|
60
|
+
module Matchers
|
61
|
+
class UnorderedArrayMatcher
|
62
|
+
attr_reader :array
|
63
|
+
def initialize(array)
|
64
|
+
@array = array
|
65
|
+
end
|
66
|
+
|
67
|
+
def match(errors, actual, prefix)
|
68
|
+
missing_items = []
|
69
|
+
errors[prefix.join("/")] = { missing: missing_items }
|
70
|
+
|
71
|
+
all? do |expected_item, index|
|
72
|
+
match_one(missing_items, expected_item, index, actual)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def match_one(missing, item, index, actual)
|
77
|
+
check_for_missing(missing, item, index,
|
78
|
+
actual.any? do |actual_item|
|
79
|
+
JsonTraverser.traverse({}, item, actual_item, false)
|
80
|
+
end
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_for_missing(missing, item, index, ok)
|
85
|
+
missing << { item: item, index: index } unless ok
|
86
|
+
ok
|
87
|
+
end
|
88
|
+
|
89
|
+
def all?(&blk)
|
90
|
+
array.each_with_index.all?(&blk)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def UnorderedArray(*array)
|
95
|
+
UnorderedArrayMatcher.new(array)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-json_expectations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleksii Fedorov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- features/rspec/json_expectations/regular_expressions_support.feature
|
65
65
|
- features/rspec/json_expectations/rspec_matchers_support.feature
|
66
66
|
- features/rspec/json_expectations/simple_hash_match.feature
|
67
|
+
- features/rspec/json_expectations/unordered_array_support.feature
|
67
68
|
- features/step_definitions/steps.rb
|
68
69
|
- features/support/env.rb
|
69
70
|
- gemfiles/rspec-2
|
@@ -108,6 +109,7 @@ test_files:
|
|
108
109
|
- features/rspec/json_expectations/regular_expressions_support.feature
|
109
110
|
- features/rspec/json_expectations/rspec_matchers_support.feature
|
110
111
|
- features/rspec/json_expectations/simple_hash_match.feature
|
112
|
+
- features/rspec/json_expectations/unordered_array_support.feature
|
111
113
|
- features/step_definitions/steps.rb
|
112
114
|
- features/support/env.rb
|
113
115
|
has_rdoc:
|