json_assertions 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/json_assertions.rb +266 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65316188f107601a91a3a764746c943b579eb276
|
4
|
+
data.tar.gz: 265a3d5e12ba21cd957d711bcb9331651473eac0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 905421c50f096fd52e926f0e74b084d45b7f19514fe298b4ed6a28bdc91ccee8ea5e3eb83bb16d743eedac6c87de04616dc621ee16cb1123c29d49fd4c8a92d4
|
7
|
+
data.tar.gz: 0582679f2f50bff3a913a9238936b26ca0c1ee4b6f5d5126c0b7f5fe729f956ff22b9d52cb81ff8917cf266ec023cc538cf7002d265339b06108b7f58512d7ff
|
@@ -0,0 +1,266 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module JsonAssertions
|
4
|
+
|
5
|
+
# Prettifies json
|
6
|
+
def pretty_json(json)
|
7
|
+
hash = JSON.parse json
|
8
|
+
JSON.pretty_generate(hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the response body for you.
|
12
|
+
def json_response
|
13
|
+
JSON.parse response.body
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_json_equal(expected, path, message=nil)
|
17
|
+
JsonResponseTester.new(json_response, self).equal(expected, path, message)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def assert_json_match(regex, path, message=nil)
|
22
|
+
JsonResponseTester.new(json_response, self).matches(regex, path, message)
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_json_missing(path, message=nil)
|
26
|
+
JsonResponseTester.new(json_response, self).must_not_have(path, message)
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert_json_has(path, message=nil)
|
30
|
+
JsonResponseTester.new(json_response, self).must_have(path, message)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_json_array_size(expected, path, message=nil)
|
34
|
+
assert_equal expected, JsonResponseTester.new(json_response, self).value_at(path).size, message
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_json_is_array(path, message=nil)
|
38
|
+
JsonResponseTester.new(json_response, self).is_array?(path, message)
|
39
|
+
end
|
40
|
+
|
41
|
+
def with_json(json, &block)
|
42
|
+
block.call JsonResponseTester.new(json, self)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class JsonResponseTester
|
47
|
+
|
48
|
+
def initialize(json, controller_test)
|
49
|
+
@controller_test = controller_test
|
50
|
+
if json.class == String
|
51
|
+
begin
|
52
|
+
@json_hash = JSON.parse json
|
53
|
+
rescue Exception
|
54
|
+
test_failure "Could not parse JSON string \"#{json.slice(0, 100)}\""
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@json_hash = json
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def [](key)
|
62
|
+
return @json_hash[key]
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# equal
|
67
|
+
# @param expected
|
68
|
+
# @path
|
69
|
+
def equal(expected, path, message=nil)
|
70
|
+
value = value_at(path)
|
71
|
+
|
72
|
+
if value != expected
|
73
|
+
error_msg = message || "JSON value #{value} != #{expected} at path #{path}"
|
74
|
+
test_failure error_msg, path
|
75
|
+
else
|
76
|
+
@controller_test.assert true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
alias :equals :equal
|
80
|
+
|
81
|
+
def matches(regex, path, message=nil)
|
82
|
+
unless regex =~ value_at(path)
|
83
|
+
error_msg = message || "JSON value of #{value_at(path).inspect} at path #{path} does not match #{regex}."
|
84
|
+
test_failure error_msg, path
|
85
|
+
else
|
86
|
+
@controller_test.assert true
|
87
|
+
end
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def must_have(path, message=nil)
|
92
|
+
error_msg = message || "JSON path #{path} does not exist but is expected."
|
93
|
+
begin
|
94
|
+
value = value_at(path)
|
95
|
+
if value.nil?
|
96
|
+
test_failure error_msg, path
|
97
|
+
else
|
98
|
+
@controller_test.assert true
|
99
|
+
end
|
100
|
+
rescue Exception
|
101
|
+
test_failure error_msg, path
|
102
|
+
end
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
def must_not_have(path, message=nil)
|
107
|
+
value = value_at(path)
|
108
|
+
if value != nil
|
109
|
+
error_msg = message || "JSON path #{path} exists but expected to be missing."
|
110
|
+
test_failure error_msg, path
|
111
|
+
else
|
112
|
+
@controller_test.assert true
|
113
|
+
end
|
114
|
+
return true
|
115
|
+
end
|
116
|
+
|
117
|
+
def array_size_gte(expected_size, path, message=nil)
|
118
|
+
is_array?(path)
|
119
|
+
value = value_at(path)
|
120
|
+
unless value.size >= expected_size
|
121
|
+
error_msg = message || "JSON array at #{path} expected to be gte #{expected_size} elements but has #{value.size}."
|
122
|
+
test_failure error_msg, path
|
123
|
+
else
|
124
|
+
@controller_test.assert true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def array_size_is(expected_size, path, message=nil)
|
130
|
+
is_array?(path)
|
131
|
+
value = value_at(path)
|
132
|
+
unless value.size == expected_size
|
133
|
+
error_msg = message || "JSON array at #{path} expected have #{expected_size} elements but has #{value.size}."
|
134
|
+
test_failure error_msg, path
|
135
|
+
else
|
136
|
+
@controller_test.assert true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
alias :array_length_is :array_size_is
|
140
|
+
|
141
|
+
def is_array?(path, message=nil)
|
142
|
+
if value_at(path).class != Array
|
143
|
+
error_msg = message || "JSON at path #{path} expected to be an array."
|
144
|
+
test_failure error_msg, path
|
145
|
+
else
|
146
|
+
@controller_test.assert true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
alias :is_array :is_array?
|
150
|
+
|
151
|
+
def array_map_equals(expected_list, list_path, value_path, message=nil)
|
152
|
+
value_list = value_at(list_path).map do |hash|
|
153
|
+
|
154
|
+
last = hash
|
155
|
+
|
156
|
+
value_path.split('/').each do |index|
|
157
|
+
next if index == ''
|
158
|
+
|
159
|
+
if index =~ /\d/
|
160
|
+
last = last[index.to_i]
|
161
|
+
else
|
162
|
+
last = last[index]
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
last
|
167
|
+
end
|
168
|
+
|
169
|
+
if expected_list != value_list
|
170
|
+
error_msg = message || "List did not equal #{expected_list.inspect} #{value_list.inspect}"
|
171
|
+
test_failure error_msg
|
172
|
+
else
|
173
|
+
@controller_test.assert true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def value_at(path, message=nil)
|
179
|
+
if path[0] != '/'
|
180
|
+
error_msg = message || "Currently we can only scan JSON from base. Start path with /"
|
181
|
+
test_failure error_msg
|
182
|
+
end
|
183
|
+
|
184
|
+
last = @json_hash
|
185
|
+
|
186
|
+
path.split('/').each do |index|
|
187
|
+
next if index == ''
|
188
|
+
|
189
|
+
if index =~ /\d/
|
190
|
+
#puts last.inspect
|
191
|
+
#puts index.to_i
|
192
|
+
last = last[index.to_i]
|
193
|
+
else
|
194
|
+
last = last[index]
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
return last
|
200
|
+
rescue TypeError
|
201
|
+
test_failure "JSON path #{path} is not the type expected. Array instead of object perhaps."
|
202
|
+
rescue NoMethodError
|
203
|
+
test_failure "JSON path #{path} does not exist.", path
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
207
|
+
|
208
|
+
def test_failure(message, path='')
|
209
|
+
if @json_hash
|
210
|
+
simple_hash = simplify_json(@json_hash, path)
|
211
|
+
message += "\n" + JSON.pretty_generate(simple_hash)
|
212
|
+
end
|
213
|
+
@controller_test.assert false, message
|
214
|
+
end
|
215
|
+
|
216
|
+
# Shortens arrays, remove extra keys
|
217
|
+
def simplify_json(json, path)
|
218
|
+
out_json = json.clone
|
219
|
+
|
220
|
+
# Allow for passing in a blank path
|
221
|
+
if path != ''
|
222
|
+
next_path = path.sub(/^\/[^\/]+/, '') # remove first path
|
223
|
+
current_search = path.split('/')[1] # Root search name /search/other
|
224
|
+
else
|
225
|
+
next_path = ''
|
226
|
+
current_search = nil
|
227
|
+
end
|
228
|
+
|
229
|
+
if json.class == Array
|
230
|
+
out_json = [ json[0] ]
|
231
|
+
out_json << "... (#{json.size} total) ..." if json.size > 1
|
232
|
+
|
233
|
+
return out_json
|
234
|
+
end
|
235
|
+
|
236
|
+
if json.class == Hash
|
237
|
+
json.each do |key, value|
|
238
|
+
|
239
|
+
# Only include keys that were in the path
|
240
|
+
|
241
|
+
if current_search != nil && current_search != key
|
242
|
+
out_json.delete(key)
|
243
|
+
# but return a list of the keys
|
244
|
+
out_json['__additional keys__'] = json.keys
|
245
|
+
next
|
246
|
+
end
|
247
|
+
|
248
|
+
if value.class == Array && value.length > 0
|
249
|
+
out_json[key] = [simplify_json(value[0], next_path)]
|
250
|
+
out_json[key] << "... (#{value.size} total) ..." if value.size > 1
|
251
|
+
|
252
|
+
elsif value.class == Hash
|
253
|
+
out_json[key] = simplify_json(json[key], next_path)
|
254
|
+
else
|
255
|
+
out_json[key] = value
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
return out_json
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json_assertions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tyler Roberts
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-30 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Provides test assert methods useful for validate JSON documents. It also
|
14
|
+
provides helpers for extracting values using a path syntax.
|
15
|
+
email: code@polar-concepts.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/json_assertions.rb
|
21
|
+
homepage: http://github.com/bdevel/json_assertions
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 2.2.2
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: Test helpers for parsing and validating JSON for REST API development in
|
45
|
+
Ruby.
|
46
|
+
test_files: []
|
47
|
+
has_rdoc:
|