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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba444e9c321897ecfaef00955d78b897f2132701
4
- data.tar.gz: 381bfa291924bf00bf35993995df35eb7717cd97
3
+ metadata.gz: 635c0cad90f8b318d89952ee50c859dc7bc4110b
4
+ data.tar.gz: 430f157ca89a149f6f0c99e655ae6ebe40180ae1
5
5
  SHA512:
6
- metadata.gz: 032cf41af9b2d4e74c966bcccf82a88d5389c517bc2b2d9180667224a3bae38105781acb608eb6d6539e32b8870dbb7751f830e56bf325194666db3487d5bf14
7
- data.tar.gz: 8f295dce2669d24d8bf6bdaa33ca78644e49d27829c6bd56058fa70c9915dacad15be31a26bba2f67f462dccd95f631951cb20bd8df144826825921605f80cba
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] + HANDLED_BY_SIMPLE_VALUE_HANDLER + RSPECMATCHERS
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) || expected.is_a?(Array)
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
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module JsonExpectations
3
- VERSION = "1.2.2"
3
+ VERSION = "1.3.0"
4
4
  end
5
5
  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.2.2
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-17 00:00:00.000000000 Z
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: