json_spec 0.5.0 → 0.6.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.
- data/.travis.yml +6 -0
- data/README.md +36 -1
- data/features/inclusion.feature +154 -0
- data/features/memory.feature +37 -0
- data/lib/json_spec.rb +1 -0
- data/lib/json_spec/cucumber.rb +16 -0
- data/lib/json_spec/exclusion.rb +26 -0
- data/lib/json_spec/matchers.rb +33 -14
- data/lib/json_spec/version.rb +1 -1
- data/spec/json_spec/matchers_spec.rb +54 -0
- metadata +13 -10
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -22,9 +22,10 @@ Continuous Integration
|
|
22
22
|
|
23
23
|
RSpec
|
24
24
|
--------------
|
25
|
-
json_spec defines
|
25
|
+
json_spec defines five new RSpec matchers:
|
26
26
|
|
27
27
|
* `be_json_eql`
|
28
|
+
* `include_json`
|
28
29
|
* `have_json_path`
|
29
30
|
* `have_json_type`
|
30
31
|
* `have_json_size`
|
@@ -50,6 +51,7 @@ The new matchers could be used in RSpec as follows:
|
|
50
51
|
json.should have_json_size(0).at_path("friends")
|
51
52
|
user.friends << User.create!(:first_name => "Catie", :last_name => "Richert")
|
52
53
|
json.should have_json_size(1).at_path("friends")
|
54
|
+
json.should include_json(%({"first_name":"Catie","last_name":"Richert"}))
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -170,6 +172,39 @@ different formats:
|
|
170
172
|
Then the JSON at "path" should be false
|
171
173
|
Then the JSON at "path" should be null
|
172
174
|
|
175
|
+
Then the JSON should include:
|
176
|
+
"""
|
177
|
+
{
|
178
|
+
"key": "value"
|
179
|
+
}
|
180
|
+
"""
|
181
|
+
Then the JSON at "path" should include:
|
182
|
+
"""
|
183
|
+
[
|
184
|
+
"entry",
|
185
|
+
"entry"
|
186
|
+
]
|
187
|
+
"""
|
188
|
+
|
189
|
+
Then the JSON should include {"key":"value"}
|
190
|
+
Then the JSON at "path" should include {"key":"value"}
|
191
|
+
Then the JSON should include ["entry","entry"]
|
192
|
+
Then the JSON at "path" should include ["entry","entry"]
|
193
|
+
Then the JSON should include "string"
|
194
|
+
Then the JSON at "path" should include "string"
|
195
|
+
Then the JSON should include 10
|
196
|
+
Then the JSON at "path" should include 10
|
197
|
+
Then the JSON should include 10.0
|
198
|
+
Then the JSON at "path" should include 10.0
|
199
|
+
Then the JSON should include 1e+1
|
200
|
+
Then the JSON at "path" should include 1e+1
|
201
|
+
Then the JSON should include true
|
202
|
+
Then the JSON at "path" should include true
|
203
|
+
Then the JSON should include false
|
204
|
+
Then the JSON at "path" should include false
|
205
|
+
Then the JSON should include null
|
206
|
+
Then the JSON at "path" should include null
|
207
|
+
|
173
208
|
Then the JSON should have "path"
|
174
209
|
|
175
210
|
Then the JSON should be a hash
|
@@ -0,0 +1,154 @@
|
|
1
|
+
Feature: Inclusion
|
2
|
+
Background:
|
3
|
+
Given the JSON is:
|
4
|
+
"""
|
5
|
+
{
|
6
|
+
"array": [
|
7
|
+
"json",
|
8
|
+
"spec"
|
9
|
+
],
|
10
|
+
"created_at": "2011-07-08 02:27:34",
|
11
|
+
"empty_array": [
|
12
|
+
|
13
|
+
],
|
14
|
+
"empty_hash": {
|
15
|
+
},
|
16
|
+
"false": false,
|
17
|
+
"float": 10.0,
|
18
|
+
"hash": {
|
19
|
+
"json": "spec"
|
20
|
+
},
|
21
|
+
"id": 1,
|
22
|
+
"integer": 10,
|
23
|
+
"negative": -10,
|
24
|
+
"null": null,
|
25
|
+
"string": "json_spec",
|
26
|
+
"true": true,
|
27
|
+
"updated_at": "2011-07-08 02:28:50",
|
28
|
+
"nested": {
|
29
|
+
"id": 2,
|
30
|
+
"key": "value"
|
31
|
+
}
|
32
|
+
}
|
33
|
+
"""
|
34
|
+
|
35
|
+
Scenario: String
|
36
|
+
When I get the JSON
|
37
|
+
Then the JSON should include "json_spec"
|
38
|
+
And the JSON should include:
|
39
|
+
"""
|
40
|
+
"json_spec"
|
41
|
+
"""
|
42
|
+
|
43
|
+
Scenario: Integer
|
44
|
+
When I get the JSON
|
45
|
+
Then the JSON should include 10
|
46
|
+
And the JSON should include:
|
47
|
+
"""
|
48
|
+
10
|
49
|
+
"""
|
50
|
+
|
51
|
+
Scenario: Negative integer
|
52
|
+
When I get the JSON
|
53
|
+
Then the JSON should include -10
|
54
|
+
And the JSON should include:
|
55
|
+
"""
|
56
|
+
-10
|
57
|
+
"""
|
58
|
+
|
59
|
+
Scenario: Float
|
60
|
+
When I get the JSON
|
61
|
+
Then the JSON should include 10.0
|
62
|
+
And the JSON should include 10.0e0
|
63
|
+
And the JSON should include 10.0e+0
|
64
|
+
And the JSON should include 10.0e-0
|
65
|
+
And the JSON should include 10e0
|
66
|
+
And the JSON should include 10e+0
|
67
|
+
And the JSON should include 10e-0
|
68
|
+
And the JSON should include 1.0e1
|
69
|
+
And the JSON should include 1.0e+1
|
70
|
+
And the JSON should include 1e1
|
71
|
+
And the JSON should include 1e+1
|
72
|
+
And the JSON should include 100.0e-1
|
73
|
+
And the JSON should include 100e-1
|
74
|
+
And the JSON should include:
|
75
|
+
"""
|
76
|
+
10.0
|
77
|
+
"""
|
78
|
+
|
79
|
+
Scenario: Array
|
80
|
+
When I get the JSON
|
81
|
+
Then the JSON should include ["json","spec"]
|
82
|
+
And the JSON at "array" should include "json"
|
83
|
+
And the JSON at "array" should include "spec"
|
84
|
+
And the JSON should include:
|
85
|
+
"""
|
86
|
+
[
|
87
|
+
"json",
|
88
|
+
"spec"
|
89
|
+
]
|
90
|
+
"""
|
91
|
+
|
92
|
+
Scenario: Empty array
|
93
|
+
When I get the JSON
|
94
|
+
Then the JSON should include []
|
95
|
+
And the JSON should include:
|
96
|
+
"""
|
97
|
+
[
|
98
|
+
|
99
|
+
]
|
100
|
+
"""
|
101
|
+
|
102
|
+
Scenario: Hash
|
103
|
+
When I get the JSON
|
104
|
+
Then the JSON should include {"json":"spec"}
|
105
|
+
And the JSON at "hash" should include "spec"
|
106
|
+
And the JSON should include:
|
107
|
+
"""
|
108
|
+
{
|
109
|
+
"json": "spec"
|
110
|
+
}
|
111
|
+
"""
|
112
|
+
|
113
|
+
Scenario: Empty hash
|
114
|
+
When I get the JSON
|
115
|
+
Then the JSON should include {}
|
116
|
+
And the JSON should include:
|
117
|
+
"""
|
118
|
+
{
|
119
|
+
}
|
120
|
+
"""
|
121
|
+
|
122
|
+
Scenario: True
|
123
|
+
When I get the JSON
|
124
|
+
Then the JSON should include true
|
125
|
+
And the JSON should include:
|
126
|
+
"""
|
127
|
+
true
|
128
|
+
"""
|
129
|
+
|
130
|
+
Scenario: False
|
131
|
+
When I get the JSON
|
132
|
+
Then the JSON should include false
|
133
|
+
And the JSON should include:
|
134
|
+
"""
|
135
|
+
false
|
136
|
+
"""
|
137
|
+
|
138
|
+
Scenario: Null
|
139
|
+
When I get the JSON
|
140
|
+
Then the JSON should include null
|
141
|
+
And the JSON should include:
|
142
|
+
"""
|
143
|
+
null
|
144
|
+
"""
|
145
|
+
|
146
|
+
Scenario: Excluded value
|
147
|
+
When I get the JSON
|
148
|
+
Then the JSON should include "2011-07-08 02:27:34"
|
149
|
+
And the JSON should include 1
|
150
|
+
And the JSON should include "2011-07-08 02:28:50"
|
151
|
+
|
152
|
+
Scenario: Nested exclusions
|
153
|
+
When I get the JSON
|
154
|
+
Then the JSON should include {"key":"value"}
|
data/features/memory.feature
CHANGED
@@ -182,3 +182,40 @@ Feature: Memory
|
|
182
182
|
"true": true
|
183
183
|
}
|
184
184
|
"""
|
185
|
+
|
186
|
+
Scenario: Table format
|
187
|
+
When I keep the JSON at "string" as "STRING"
|
188
|
+
And I keep the JSON at "integer" as "INTEGER"
|
189
|
+
And I keep the JSON at "float" as "FLOAT"
|
190
|
+
And I keep the JSON at "array" as "ARRAY"
|
191
|
+
And I keep the JSON at "hash" as "HASH"
|
192
|
+
And I keep the JSON at "true" as "TRUE"
|
193
|
+
And I keep the JSON at "false" as "FALSE"
|
194
|
+
And I keep the JSON at "null" as "NULL"
|
195
|
+
Then the JSON should have the following:
|
196
|
+
| string | %{STRING} |
|
197
|
+
| integer | %{INTEGER} |
|
198
|
+
| float | %{FLOAT} |
|
199
|
+
| array | %{ARRAY} |
|
200
|
+
| hash | %{HASH} |
|
201
|
+
| true | %{TRUE} |
|
202
|
+
| false | %{FALSE} |
|
203
|
+
| null | %{NULL} |
|
204
|
+
|
205
|
+
Scenario: Inclusion
|
206
|
+
When I keep the JSON at "string" as "STRING"
|
207
|
+
And I keep the JSON at "integer" as "INTEGER"
|
208
|
+
And I keep the JSON at "float" as "FLOAT"
|
209
|
+
And I keep the JSON at "array" as "ARRAY"
|
210
|
+
And I keep the JSON at "hash" as "HASH"
|
211
|
+
And I keep the JSON at "true" as "TRUE"
|
212
|
+
And I keep the JSON at "false" as "FALSE"
|
213
|
+
And I keep the JSON at "null" as "NULL"
|
214
|
+
Then the JSON should include %{STRING}
|
215
|
+
And the JSON should include %{INTEGER}
|
216
|
+
And the JSON should include %{FLOAT}
|
217
|
+
And the JSON should include %{ARRAY}
|
218
|
+
And the JSON should include %{HASH}
|
219
|
+
And the JSON should include %{TRUE}
|
220
|
+
And the JSON should include %{FALSE}
|
221
|
+
And the JSON should include %{NULL}
|
data/lib/json_spec.rb
CHANGED
data/lib/json_spec/cucumber.rb
CHANGED
@@ -26,6 +26,22 @@ Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? be (".*"|\-?
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? include:$/ do |path, negative, json|
|
30
|
+
if negative
|
31
|
+
last_json.should_not include_json(JsonSpec.remember(json)).at_path(path)
|
32
|
+
else
|
33
|
+
last_json.should include_json(JsonSpec.remember(json)).at_path(path)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? include (".*"|\-?\d+(?:\.\d+)?(?:[eE][\+\-]?\d+)?|\[.*\]|%?\{.*\}|true|false|null)$/ do |path, negative, value|
|
38
|
+
if negative
|
39
|
+
last_json.should_not include_json(JsonSpec.remember(value)).at_path(path)
|
40
|
+
else
|
41
|
+
last_json.should include_json(JsonSpec.remember(value)).at_path(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
29
45
|
Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should have the following:$/ do |base, table|
|
30
46
|
table.rows.each do |path, value|
|
31
47
|
path = [base, path].compact.join("/")
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module JsonSpec
|
2
|
+
module Exclusion
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def exclude_keys(ruby)
|
6
|
+
case ruby
|
7
|
+
when Hash
|
8
|
+
ruby.sort.inject({}) do |hash, (key, value)|
|
9
|
+
hash[key] = exclude_keys(value) unless exclude_key?(key)
|
10
|
+
hash
|
11
|
+
end
|
12
|
+
when Array
|
13
|
+
ruby.map{|v| exclude_keys(v) }
|
14
|
+
else ruby
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def exclude_key?(key)
|
19
|
+
excluded_keys.include?(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def excluded_keys
|
23
|
+
@excluded_keys ||= Set.new(JsonSpec.excluded_keys)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/json_spec/matchers.rb
CHANGED
@@ -3,6 +3,7 @@ require "rspec"
|
|
3
3
|
|
4
4
|
RSpec::Matchers.define :be_json_eql do |expected_json|
|
5
5
|
include JsonSpec::Helpers
|
6
|
+
include JsonSpec::Exclusion
|
6
7
|
|
7
8
|
diffable
|
8
9
|
|
@@ -38,26 +39,44 @@ RSpec::Matchers.define :be_json_eql do |expected_json|
|
|
38
39
|
def scrub(json, path = nil)
|
39
40
|
generate_normalized_json(exclude_keys(parse_json(json, path))).chomp + "\n"
|
40
41
|
end
|
42
|
+
end
|
43
|
+
|
44
|
+
RSpec::Matchers.define :include_json do |expected_json|
|
45
|
+
include JsonSpec::Helpers
|
46
|
+
include JsonSpec::Exclusion
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
when Array
|
50
|
-
ruby.map{|v| exclude_keys(v) }
|
51
|
-
else ruby
|
48
|
+
match do |actual_json|
|
49
|
+
actual = parse_json(actual_json, @path)
|
50
|
+
expected = exclude_keys(parse_json(expected_json))
|
51
|
+
case actual
|
52
|
+
when Hash then actual.values.map{|v| exclude_keys(v) }.include?(expected)
|
53
|
+
when Array then actual.map{|e| exclude_keys(e) }.include?(expected)
|
54
|
+
else false
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
chain :at_path do |path|
|
59
|
+
@path = path
|
60
|
+
end
|
61
|
+
|
62
|
+
chain :excluding do |*keys|
|
63
|
+
excluded_keys.add(*keys.map{|k| k.to_s })
|
64
|
+
end
|
65
|
+
|
66
|
+
chain :including do |*keys|
|
67
|
+
excluded_keys.subtract(keys.map{|k| k.to_s })
|
57
68
|
end
|
58
69
|
|
59
|
-
|
60
|
-
|
70
|
+
failure_message_for_should do
|
71
|
+
message = "Expected included JSON"
|
72
|
+
message << %( at path "#{@path}") if @path
|
73
|
+
message
|
74
|
+
end
|
75
|
+
|
76
|
+
failure_message_for_should_not do
|
77
|
+
message = "Expected excluded JSON"
|
78
|
+
message << %( at path "#{@path}") if @path
|
79
|
+
message
|
61
80
|
end
|
62
81
|
end
|
63
82
|
|
data/lib/json_spec/version.rb
CHANGED
@@ -78,6 +78,60 @@ describe "Matchers:" do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
context "include_json" do
|
82
|
+
it "matches included array elements" do
|
83
|
+
json = %(["one",1,1.0,true,false,null])
|
84
|
+
json.should include_json(%("one"))
|
85
|
+
json.should include_json(%(1))
|
86
|
+
json.should include_json(%(1.0))
|
87
|
+
json.should include_json(%(true))
|
88
|
+
json.should include_json(%(false))
|
89
|
+
json.should include_json(%(null))
|
90
|
+
end
|
91
|
+
|
92
|
+
it "matches an array included in an array" do
|
93
|
+
json = %([[1,2,3],[4,5,6]])
|
94
|
+
json.should include_json(%([1,2,3]))
|
95
|
+
json.should include_json(%([4,5,6]))
|
96
|
+
end
|
97
|
+
|
98
|
+
it "matches a hash included in an array" do
|
99
|
+
json = %([{"one":1},{"two":2}])
|
100
|
+
json.should include_json(%({"one":1}))
|
101
|
+
json.should include_json(%({"two":2}))
|
102
|
+
end
|
103
|
+
|
104
|
+
it "matches include hash values" do
|
105
|
+
json = %({"string":"one","integer":1,"float":1.0,"true":true,"false":false,"null":null})
|
106
|
+
json.should include_json(%("one"))
|
107
|
+
json.should include_json(%(1))
|
108
|
+
json.should include_json(%(1.0))
|
109
|
+
json.should include_json(%(true))
|
110
|
+
json.should include_json(%(false))
|
111
|
+
json.should include_json(%(null))
|
112
|
+
end
|
113
|
+
|
114
|
+
it "matches a hash included in a hash" do
|
115
|
+
json = %({"one":{"two":3},"four":{"five":6}})
|
116
|
+
json.should include_json(%({"two":3}))
|
117
|
+
json.should include_json(%({"five":6}))
|
118
|
+
end
|
119
|
+
|
120
|
+
it "matches an array included in a hash" do
|
121
|
+
json = %({"one":[2,3],"four":[5,6]})
|
122
|
+
json.should include_json(%([2,3]))
|
123
|
+
json.should include_json(%([5,6]))
|
124
|
+
end
|
125
|
+
|
126
|
+
it "matches at a path" do
|
127
|
+
%({"one":{"two":[3,4]}}).should include_json(%([3,4])).at_path("one")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "ignores excluded keys" do
|
131
|
+
%([{"id":1,"two":3}]).should include_json(%({"two":3}))
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
81
135
|
context "have_json_size" do
|
82
136
|
it "counts array entries" do
|
83
137
|
%([1,2,3]).should have_json_size(3)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-07-
|
12
|
+
date: 2011-07-20 00:00:00.000000000 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
17
|
-
requirement: &
|
17
|
+
requirement: &70202465651180 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '1.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70202465651180
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rspec
|
28
|
-
requirement: &
|
28
|
+
requirement: &70202465650680 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '2.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70202465650680
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: rake
|
39
|
-
requirement: &
|
39
|
+
requirement: &70202465650220 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0.9'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70202465650220
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: cucumber
|
50
|
-
requirement: &
|
50
|
+
requirement: &70202465649760 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
version: '1.0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70202465649760
|
59
59
|
description: Easily handle JSON in RSpec and Cucumber
|
60
60
|
email:
|
61
61
|
- steve.richert@gmail.com
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- README.md
|
71
71
|
- Rakefile
|
72
72
|
- features/equivalence.feature
|
73
|
+
- features/inclusion.feature
|
73
74
|
- features/memory.feature
|
74
75
|
- features/paths.feature
|
75
76
|
- features/sizes.feature
|
@@ -81,6 +82,7 @@ files:
|
|
81
82
|
- lib/json_spec/configuration.rb
|
82
83
|
- lib/json_spec/cucumber.rb
|
83
84
|
- lib/json_spec/errors.rb
|
85
|
+
- lib/json_spec/exclusion.rb
|
84
86
|
- lib/json_spec/helpers.rb
|
85
87
|
- lib/json_spec/matchers.rb
|
86
88
|
- lib/json_spec/memory.rb
|
@@ -117,6 +119,7 @@ specification_version: 3
|
|
117
119
|
summary: Easily handle JSON in RSpec and Cucumber
|
118
120
|
test_files:
|
119
121
|
- features/equivalence.feature
|
122
|
+
- features/inclusion.feature
|
120
123
|
- features/memory.feature
|
121
124
|
- features/paths.feature
|
122
125
|
- features/sizes.feature
|