airborne 0.0.22 → 0.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/airborne.gemspec +1 -1
- data/lib/airborne/path_matcher.rb +75 -23
- data/lib/airborne/request_expectations.rb +18 -9
- data/spec/airborne/{headers_spec.rb → expectations/expect_header_contains_spec.rb} +2 -14
- data/spec/airborne/expectations/expect_header_spec.rb +24 -0
- data/spec/airborne/expectations/expect_json_keys_path_spec.rb +17 -0
- data/spec/airborne/{expect_json_keys_spec.rb → expectations/expect_json_keys_spec.rb} +2 -12
- data/spec/airborne/expectations/expect_json_lambda_spec.rb +11 -0
- data/spec/airborne/expectations/expect_json_path_spec.rb +102 -0
- data/spec/airborne/expectations/expect_json_regex_spec.rb +35 -0
- data/spec/airborne/expectations/expect_json_spec.rb +23 -0
- data/spec/airborne/expectations/expect_json_types_lambda_spec.rb +11 -0
- data/spec/airborne/expectations/expect_json_types_optional_spec.rb +17 -0
- data/spec/airborne/expectations/expect_json_types_path_spec.rb +59 -0
- data/spec/airborne/expectations/expect_json_types_spec.rb +47 -0
- data/spec/airborne/{expect_status_spec.rb → expectations/expect_status_spec.rb} +0 -0
- data/spec/airborne/{rack_sinatra_spec.rb → rack/rack_sinatra_spec.rb} +0 -0
- data/spec/test_responses/array_with_nested.json +14 -13
- metadata +37 -29
- data/spec/airborne/expect_json_spec.rb +0 -65
- data/spec/airborne/expect_json_types_spec.rb +0 -111
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2db47b8f533a4c04a03ab8fd64258bac9eb6c943
|
4
|
+
data.tar.gz: 46ec329525c710f2264396853ec4ae26d9d52081
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4a8397f77c164291b8a72b567e40d1100d45d3bef5f8a76e1158c2ee97d0b6824de5ec6acae5eadb1bcd4cb443b51058fb72171e79d99fc54d1efa055c47ade
|
7
|
+
data.tar.gz: 18c6eb65f280e579efdf1347fcc94b1b36fbb9bcf7c96b76586840ec189556a0b616f8cfce767eb5bb4d3edf35cf271286167fa518397125b6fb132775ca8b90
|
data/.gitignore
CHANGED
data/airborne.gemspec
CHANGED
@@ -1,45 +1,97 @@
|
|
1
1
|
module Airborne
|
2
2
|
module PathMatcher
|
3
|
+
|
3
4
|
def get_by_path(path, json, &block)
|
4
5
|
type = false
|
5
6
|
parts = path.split('.')
|
6
7
|
parts.each_with_index do |part, index|
|
7
8
|
if part == '*' || part == '?'
|
9
|
+
ensure_array(path, json)
|
8
10
|
type = part
|
9
|
-
raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
|
10
11
|
if index < parts.length.pred
|
11
|
-
json
|
12
|
-
sub_path = parts[(index.next)...(parts.length)].join('.')
|
13
|
-
get_by_path(sub_path, element, &block)
|
14
|
-
end
|
12
|
+
walk_with_path(type, index, path, parts, json, &block)
|
15
13
|
return
|
16
14
|
end
|
17
15
|
next
|
18
16
|
end
|
19
|
-
|
20
|
-
part = part.to_i
|
21
|
-
json = json[part]
|
22
|
-
else
|
23
|
-
json = json[part.to_sym]
|
24
|
-
raise "Expected #{path} to be object or array got #{json.class} from JSON response" unless [Array, Hash, NilClass].include?(json.class)
|
25
|
-
end
|
17
|
+
json = process_json(part, json)
|
26
18
|
end
|
27
19
|
if type == '*'
|
28
|
-
json
|
20
|
+
expect_all(json, &block)
|
29
21
|
elsif type == '?'
|
30
|
-
|
31
|
-
error_count = 0
|
32
|
-
json.each do |part|
|
33
|
-
begin
|
34
|
-
yield part
|
35
|
-
rescue Exception => e
|
36
|
-
error_count += 1
|
37
|
-
raise "Expected one object in path #{path} to match provided JSON values" if item_count == error_count
|
38
|
-
end
|
39
|
-
end
|
22
|
+
expect_one(path, json, &block)
|
40
23
|
else
|
41
24
|
yield json
|
42
25
|
end
|
43
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def walk_with_path(type, index, path, parts, json, &block)
|
31
|
+
last_error = nil
|
32
|
+
item_count = json.length
|
33
|
+
error_count = 0
|
34
|
+
json.each do |element|
|
35
|
+
begin
|
36
|
+
sub_path = parts[(index.next)...(parts.length)].join('.')
|
37
|
+
get_by_path(sub_path, element, &block)
|
38
|
+
rescue Exception => e
|
39
|
+
last_error = e
|
40
|
+
error_count += 1
|
41
|
+
end
|
42
|
+
ensure_match_all(last_error) if type == '*'
|
43
|
+
ensure_match_one(path, item_count, error_count) if type == '?'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def process_json(part, json)
|
48
|
+
if is_index?(part)
|
49
|
+
part = part.to_i
|
50
|
+
json = json[part]
|
51
|
+
else
|
52
|
+
json = json[part.to_sym]
|
53
|
+
end
|
54
|
+
json
|
55
|
+
end
|
56
|
+
|
57
|
+
def is_index?(part)
|
58
|
+
part =~ /^\d+$/
|
59
|
+
end
|
60
|
+
|
61
|
+
def expect_one(path, json, &block)
|
62
|
+
item_count = json.length
|
63
|
+
error_count = 0
|
64
|
+
json.each do |part|
|
65
|
+
begin
|
66
|
+
yield part
|
67
|
+
rescue Exception => e
|
68
|
+
error_count += 1
|
69
|
+
ensure_match_one(path, item_count, error_count)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def expect_all(json, &block)
|
75
|
+
last_error = nil
|
76
|
+
begin
|
77
|
+
json.each{|part| yield part}
|
78
|
+
rescue Exception => e
|
79
|
+
last_error = e
|
80
|
+
end
|
81
|
+
ensure_match_all(last_error)
|
82
|
+
end
|
83
|
+
|
84
|
+
def ensure_match_one(path, item_count, error_count)
|
85
|
+
raise "Expected one object in path #{path} to match provided JSON values" if item_count == error_count
|
86
|
+
end
|
87
|
+
|
88
|
+
def ensure_match_all(error)
|
89
|
+
raise error unless error.nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
def ensure_array(path, json)
|
93
|
+
raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
|
94
|
+
end
|
95
|
+
|
44
96
|
end
|
45
97
|
end
|
@@ -6,33 +6,28 @@ module Airborne
|
|
6
6
|
include PathMatcher
|
7
7
|
|
8
8
|
def expect_json_types(*args)
|
9
|
-
set_response(@response) if @json_body.nil?
|
10
9
|
call_with_path(args) do |param, body|
|
11
10
|
expect_json_types_impl(param, body)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
15
14
|
def expect_json(*args)
|
16
|
-
set_response(@response) if @json_body.nil?
|
17
15
|
call_with_path(args) do |param, body|
|
18
16
|
expect_json_impl(param, body)
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
22
20
|
def expect_json_keys(*args)
|
23
|
-
set_response(@response) if @json_body.nil?
|
24
21
|
call_with_path(args) do |param, body|
|
25
22
|
expect(body.keys).to include(*param)
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
26
|
def expect_status(code)
|
30
|
-
set_response(@response) if @json_body.nil?
|
31
27
|
expect(response.code).to eq(code)
|
32
28
|
end
|
33
29
|
|
34
30
|
def expect_header(key, content)
|
35
|
-
set_response(@response) if @json_body.nil?
|
36
31
|
header = headers[key]
|
37
32
|
if header
|
38
33
|
expect(header.downcase).to eq(content.downcase)
|
@@ -42,7 +37,6 @@ module Airborne
|
|
42
37
|
end
|
43
38
|
|
44
39
|
def expect_header_contains(key, content)
|
45
|
-
set_response(@response) if @json_body.nil?
|
46
40
|
header = headers[key]
|
47
41
|
if header
|
48
42
|
expect(header.downcase).to include(content.downcase)
|
@@ -59,8 +53,20 @@ module Airborne
|
|
59
53
|
Regexp.new(reg)
|
60
54
|
end
|
61
55
|
|
56
|
+
[:expect_json_types, :expect_json, :expect_json_keys, :expect_status, :expect_header, :expect_header_contains].each do |method_name|
|
57
|
+
method = instance_method(method_name)
|
58
|
+
define_method(method_name) do |*args, &block|
|
59
|
+
set_rails_response
|
60
|
+
method.bind(self).(*args, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
62
64
|
private
|
63
65
|
|
66
|
+
def set_rails_response
|
67
|
+
set_response(@response) if @json_body.nil?
|
68
|
+
end
|
69
|
+
|
64
70
|
def call_with_path(args)
|
65
71
|
if args.length == 2
|
66
72
|
get_by_path(args[0], json_body) do|json_chunk|
|
@@ -101,6 +107,7 @@ module Airborne
|
|
101
107
|
def expect_json_types_impl(expectations, hash)
|
102
108
|
return if expectations.class == Airborne::OptionalHashTypeExpectations && hash.nil?
|
103
109
|
@mapper ||= get_mapper
|
110
|
+
return expect(@mapper[expectations].include?(hash.class)).to eq(true) if expectations.class == Symbol
|
104
111
|
expectations.each do |prop_name, expected_type|
|
105
112
|
value = hash[prop_name]
|
106
113
|
if expected_type.class == Hash || expected_type.class == Airborne::OptionalHashTypeExpectations
|
@@ -110,7 +117,7 @@ module Airborne
|
|
110
117
|
elsif expected_type.to_s.include?("array_of")
|
111
118
|
expect(value.class).to eq(Array), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
|
112
119
|
value.each do |val|
|
113
|
-
expect(@mapper[expected_type].include?(val.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{val.class} instead"
|
120
|
+
expect(@mapper[expected_type].include?(val.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{val.class} instead"
|
114
121
|
end
|
115
122
|
else
|
116
123
|
expect(@mapper[expected_type].include?(value.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
|
@@ -119,6 +126,8 @@ module Airborne
|
|
119
126
|
end
|
120
127
|
|
121
128
|
def expect_json_impl(expectations, hash)
|
129
|
+
hash = hash.to_s if expectations.class == Regexp
|
130
|
+
return expect(hash).to match(expectations) if [String, Regexp, Float, Fixnum, Bignum].include?(expectations.class)
|
122
131
|
expectations.each do |prop_name, expected_value|
|
123
132
|
actual_value = hash[prop_name]
|
124
133
|
if expected_value.class == Hash
|
@@ -126,11 +135,11 @@ module Airborne
|
|
126
135
|
elsif expected_value.class == Proc
|
127
136
|
expected_value.call(actual_value)
|
128
137
|
elsif expected_value.class == Regexp
|
129
|
-
expect(actual_value).to match(expected_value)
|
138
|
+
expect(actual_value.to_s).to match(expected_value)
|
130
139
|
else
|
131
140
|
expect(actual_value).to eq(expected_value)
|
132
141
|
end
|
133
142
|
end
|
134
143
|
end
|
135
144
|
end
|
136
|
-
end
|
145
|
+
end
|
@@ -1,20 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'expect header' do
|
4
|
-
it 'should find exact match for header content' do
|
5
|
-
mock_get('simple_get', {'Content-Type' => 'application/json'})
|
6
|
-
get '/simple_get'
|
7
|
-
expect_header(:content_type, 'application/json')
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should ensure correct headers are present' do
|
11
|
-
mock_get('simple_get', {'Content-Type' => 'application/json'})
|
12
|
-
get '/simple_get'
|
13
|
-
expect{expect_header(:foo, 'bar')}.to raise_error
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
3
|
describe 'expect header contains' do
|
4
|
+
|
18
5
|
it 'should ensure partial header match exists' do
|
19
6
|
mock_get('simple_get', {'Content-Type' => 'application/json'})
|
20
7
|
get '/simple_get'
|
@@ -32,4 +19,5 @@ describe 'expect header contains' do
|
|
32
19
|
get '/simple_get'
|
33
20
|
expect{expect_header_contains(:content_type, 'bar')}.to raise_error
|
34
21
|
end
|
22
|
+
|
35
23
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect header' do
|
4
|
+
|
5
|
+
it 'should find exact match for header content' do
|
6
|
+
mock_get('simple_get', {'Content-Type' => 'application/json'})
|
7
|
+
get '/simple_get'
|
8
|
+
expect_header(:content_type, 'application/json')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should find exact match for header content' do
|
12
|
+
mock_get('simple_get', {'Content-Type' => 'json'})
|
13
|
+
get '/simple_get'
|
14
|
+
expect{expect_header(:content_type, 'application/json')}.to raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should ensure correct headers are present' do
|
18
|
+
mock_get('simple_get', {'Content-Type' => 'application/json'})
|
19
|
+
get '/simple_get'
|
20
|
+
expect{expect_header(:foo, 'bar')}.to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json_keys with path' do
|
4
|
+
|
5
|
+
it 'should ensure json keys with path' do
|
6
|
+
mock_get('simple_nested_path')
|
7
|
+
get '/simple_nested_path', {}
|
8
|
+
expect_json_keys('address', [:street, :city])
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail when keys are missing with path' do
|
12
|
+
mock_get('simple_nested_path')
|
13
|
+
get '/simple_nested_path', {}
|
14
|
+
expect{expect_json_keys('address', [:bad])}.to raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'expect_json_keys' do
|
4
|
+
|
4
5
|
it 'should fail when json keys are missing' do
|
5
6
|
mock_get('simple_json')
|
6
7
|
get '/simple_json', {}
|
@@ -18,16 +19,5 @@ describe 'expect_json_keys' do
|
|
18
19
|
get '/simple_json', {}
|
19
20
|
expect_json_keys([:foo, :bar])
|
20
21
|
end
|
21
|
-
|
22
|
-
it 'should ensure json keys with path' do
|
23
|
-
mock_get('simple_nested_path')
|
24
|
-
get '/simple_nested_path', {}
|
25
|
-
expect_json_keys('address', [:street, :city])
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should fail when keys are missing with path' do
|
29
|
-
mock_get('simple_nested_path')
|
30
|
-
get '/simple_nested_path', {}
|
31
|
-
expect{expect_json_keys('address', [:bad])}.to raise_error
|
32
|
-
end
|
22
|
+
|
33
23
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json with path' do
|
4
|
+
|
5
|
+
it 'should allow simple path and verify only that path' do
|
6
|
+
mock_get('simple_path_get')
|
7
|
+
get '/simple_path_get'
|
8
|
+
expect_json('address', {street: "Area 51", city: "Roswell", state: "NM"})
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should allow nested paths' do
|
12
|
+
mock_get('simple_nested_path')
|
13
|
+
get '/simple_nested_path'
|
14
|
+
expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should index into array and test against specific element' do
|
18
|
+
mock_get('array_with_index')
|
19
|
+
get '/array_with_index'
|
20
|
+
expect_json('cars.0', {make: "Tesla", model: "Model S"})
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should test against all elements in the array' do
|
24
|
+
mock_get('array_with_index')
|
25
|
+
get '/array_with_index'
|
26
|
+
expect_json('cars.?', {make: "Tesla", model: "Model S"})
|
27
|
+
expect_json('cars.?', {make: "Lamborghini", model: "Aventador"})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should test against properties in the array' do
|
31
|
+
mock_get('array_with_index')
|
32
|
+
get '/array_with_index'
|
33
|
+
expect_json('cars.?.make', "Tesla")
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should ensure at least one match' do
|
37
|
+
mock_get('array_with_index')
|
38
|
+
get '/array_with_index'
|
39
|
+
expect{expect_json('cars.?.make', "Teslas")}.to raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should check for at least one match' do
|
43
|
+
mock_get('array_with_nested')
|
44
|
+
get '/array_with_nested'
|
45
|
+
expect_json('cars.?.owners.?', {name: "Bart Simpson"})
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should ensure at least one match' do
|
49
|
+
mock_get('array_with_nested')
|
50
|
+
get '/array_with_nested'
|
51
|
+
expect{expect_json('cars.?.owners.?', {name: "Bart Simpsons"})}.to raise_error
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should check for one match that matches all ' do
|
55
|
+
mock_get('array_with_nested')
|
56
|
+
get '/array_with_nested'
|
57
|
+
expect_json('cars.?.owners.*', {name: "Bart Simpson"})
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should check for one match that matches all with lambda' do
|
61
|
+
mock_get('array_with_nested')
|
62
|
+
get '/array_with_nested'
|
63
|
+
expect_json('cars.?.owners.*', {name: -> (name){expect(name).to eq("Bart Simpson")}})
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should ensure one match that matches all with lambda' do
|
67
|
+
mock_get('array_with_nested')
|
68
|
+
get '/array_with_nested'
|
69
|
+
expect{expect_json('cars.?.owners.*', {name: -> (name){expect(name).to eq("Bart Simpsons")}})}.to raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should ensure one match that matches all' do
|
73
|
+
mock_get('array_with_nested')
|
74
|
+
get '/array_with_nested'
|
75
|
+
expect{expect_json('cars.?.owners.*', {name: "Bart Simpsons"})}.to raise_error
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should allow indexing' do
|
79
|
+
mock_get('array_with_nested')
|
80
|
+
get '/array_with_nested'
|
81
|
+
expect_json('cars.0.owners.0', {name: "Bart Simpson"})
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should allow strings (String) to be tested against a path' do
|
85
|
+
mock_get('simple_nested_path')
|
86
|
+
get '/simple_nested_path'
|
87
|
+
expect_json('address.city', "Roswell" )
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should allow floats (Float) to be tested against a path' do
|
91
|
+
mock_get('simple_nested_path')
|
92
|
+
get '/simple_nested_path'
|
93
|
+
expect_json('address.coordinates.lattitude', 33.3872 )
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should allow integers (Fixnum, Bignum) to be tested against a path' do
|
97
|
+
mock_get('simple_get')
|
98
|
+
get '/simple_get'
|
99
|
+
expect_json('age', 32 )
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json regex' do
|
4
|
+
|
5
|
+
it 'should test against regex' do
|
6
|
+
mock_get('simple_get')
|
7
|
+
get '/simple_get'
|
8
|
+
expect_json({name: regex("^A")})
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should raise an error if regex does not match' do
|
12
|
+
mock_get('simple_get')
|
13
|
+
get '/simple_get'
|
14
|
+
expect{expect_json({name: regex("^B")})}.to raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should allow regex(Regexp) to be tested against a path' do
|
18
|
+
mock_get('simple_nested_path')
|
19
|
+
get '/simple_nested_path'
|
20
|
+
expect_json('address.city', regex("^R") )
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should allow testing regex against numbers directly' do
|
24
|
+
mock_get('simple_nested_path')
|
25
|
+
get '/simple_nested_path'
|
26
|
+
expect_json('address.coordinates.lattitude', regex("^3") )
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should allow testing regex against numbers in the hash' do
|
30
|
+
mock_get('simple_nested_path')
|
31
|
+
get '/simple_nested_path'
|
32
|
+
expect_json('address.coordinates', {lattitude: regex("^3")} )
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json' do
|
4
|
+
|
5
|
+
it 'should ensure correct json values' do
|
6
|
+
mock_get('simple_get')
|
7
|
+
get '/simple_get'
|
8
|
+
expect_json({name: "Alex", age: 32 })
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail when incorrect json is tested' do
|
12
|
+
mock_get('simple_get')
|
13
|
+
get '/simple_get'
|
14
|
+
expect{expect_json({bad: "data"})}.to raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should allow full object graph' do
|
18
|
+
mock_get('simple_path_get')
|
19
|
+
get '/simple_path_get'
|
20
|
+
expect_json({name: "Alex", address: {street: "Area 51", city: "Roswell", state: "NM"}})
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json_types optional' do
|
4
|
+
|
5
|
+
it 'should test optional nested hash when exists' do
|
6
|
+
mock_get('simple_nested_path')
|
7
|
+
get '/simple_nested_path'
|
8
|
+
expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should allow optional nested hash' do
|
12
|
+
mock_get('simple_path_get')
|
13
|
+
get '/simple_path_get'
|
14
|
+
expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json_types wih path' do
|
4
|
+
|
5
|
+
it 'should allow simple path and verify only that path' do
|
6
|
+
mock_get('simple_path_get')
|
7
|
+
get '/simple_path_get'
|
8
|
+
expect_json_types('address', {street: :string, city: :string, state: :string})
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should allow nested paths' do
|
12
|
+
mock_get('simple_nested_path')
|
13
|
+
get '/simple_nested_path'
|
14
|
+
expect_json_types('address.coordinates', {lattitude: :float, longitutde: :float} )
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should index into array and test against specific element' do
|
18
|
+
mock_get('array_with_index')
|
19
|
+
get '/array_with_index'
|
20
|
+
expect_json_types('cars.0', {make: :string, model: :string})
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should allow properties to be tested against a path' do
|
24
|
+
mock_get('array_with_index')
|
25
|
+
get '/array_with_index'
|
26
|
+
expect_json_types('cars.0.make', :string)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should test against all elements in the array' do
|
30
|
+
mock_get('array_with_index')
|
31
|
+
get '/array_with_index'
|
32
|
+
expect_json_types('cars.*', {make: :string, model: :string})
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should ensure all elements of array are valid' do
|
36
|
+
mock_get('array_with_index')
|
37
|
+
get '/array_with_index'
|
38
|
+
expect{expect_json_types('cars.*', {make: :string, model: :int})}.to raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should deep symbolize array responses' do
|
42
|
+
mock_get('array_response')
|
43
|
+
get '/array_response'
|
44
|
+
expect_json_types("*", {name: :string})
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should check all nested arrays for specified elements' do
|
48
|
+
mock_get('array_with_nested')
|
49
|
+
get '/array_with_nested'
|
50
|
+
expect_json_types('cars.*.owners.*', {name: :string})
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should ensure all nested arrays contain correct data' do
|
54
|
+
mock_get('array_with_nested_bad_data')
|
55
|
+
get '/array_with_nested_bad_data'
|
56
|
+
expect{expect_json_types('cars.*.owners.*', {name: :string})}.to raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json_types' do
|
4
|
+
|
5
|
+
it 'should detect current type' do
|
6
|
+
mock_get('simple_get')
|
7
|
+
get '/simple_get'
|
8
|
+
expect_json_types({name: :string, age: :int})
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail when incorrect json types tested' do
|
12
|
+
mock_get('simple_get')
|
13
|
+
get '/simple_get'
|
14
|
+
expect{expect_json_types({bad: :bool})}.to raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not fail when optional property is not present' do
|
18
|
+
mock_get('simple_get')
|
19
|
+
get '/simple_get'
|
20
|
+
expect_json_types({name: :string, age: :int, optional: :bool_or_null })
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should allow full object graph' do
|
24
|
+
mock_get('simple_path_get')
|
25
|
+
get '/simple_path_get'
|
26
|
+
expect_json_types({name: :string, address: {street: :string, city: :string, state: :string}})
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should check all types in a simple array' do
|
30
|
+
mock_get('array_of_values')
|
31
|
+
get '/array_of_values'
|
32
|
+
expect_json_types({grades: :array_of_ints})
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should ensure all valid types in a simple array' do
|
36
|
+
mock_get('array_of_values')
|
37
|
+
get '/array_of_values'
|
38
|
+
expect{expect_json_types({bad: :array_of_ints})}.to raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should allow empty array' do
|
42
|
+
mock_get('array_of_values')
|
43
|
+
get '/array_of_values'
|
44
|
+
expect_json_types({emptyArray: :array_of_ints})
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
File without changes
|
File without changes
|
@@ -1,15 +1,16 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
2
|
+
"cars": [{
|
3
|
+
"make": "Tesla",
|
4
|
+
"model": "Model S",
|
5
|
+
"owners": [
|
6
|
+
{"name": "Bart Simpson"}
|
7
|
+
]
|
8
|
+
}, {
|
9
|
+
"make": "Lamborghini",
|
10
|
+
"model": "Aventador",
|
11
|
+
"owners": [
|
12
|
+
{"name": "Peter Griffin"}
|
13
|
+
|
14
|
+
]
|
15
|
+
}]
|
15
16
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airborne
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Friedman
|
@@ -15,88 +15,88 @@ dependencies:
|
|
15
15
|
name: rspec
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '3.1'
|
21
|
-
- -
|
21
|
+
- - '>='
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 3.1.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '3.1'
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 3.1.0
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: rest-client
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.7'
|
41
|
-
- -
|
41
|
+
- - '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.7.2
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
46
|
version_requirements: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
|
-
- -
|
48
|
+
- - ~>
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '1.7'
|
51
|
-
- -
|
51
|
+
- - '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 1.7.2
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: rack-test
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - ~>
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0.6'
|
61
|
-
- -
|
61
|
+
- - '>='
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: 0.6.2
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - ~>
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0.6'
|
71
|
-
- -
|
71
|
+
- - '>='
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: 0.6.2
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
75
|
name: activesupport
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- -
|
78
|
+
- - '>='
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: 4.0.1
|
81
81
|
type: :runtime
|
82
82
|
prerelease: false
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- -
|
85
|
+
- - '>='
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: 4.0.1
|
88
88
|
- !ruby/object:Gem::Dependency
|
89
89
|
name: webmock
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
|
-
- -
|
92
|
+
- - ~>
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
type: :development
|
96
96
|
prerelease: false
|
97
97
|
version_requirements: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - ~>
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
102
|
description:
|
@@ -107,9 +107,9 @@ executables: []
|
|
107
107
|
extensions: []
|
108
108
|
extra_rdoc_files: []
|
109
109
|
files:
|
110
|
-
-
|
111
|
-
-
|
112
|
-
-
|
110
|
+
- .coveralls.yml
|
111
|
+
- .gitignore
|
112
|
+
- .travis.yml
|
113
113
|
- Gemfile
|
114
114
|
- Gemfile.lock
|
115
115
|
- LICENSE
|
@@ -124,15 +124,23 @@ files:
|
|
124
124
|
- lib/airborne/rest_client_requester.rb
|
125
125
|
- spec/airborne/base_spec.rb
|
126
126
|
- spec/airborne/delete_spec.rb
|
127
|
-
- spec/airborne/
|
128
|
-
- spec/airborne/
|
129
|
-
- spec/airborne/
|
130
|
-
- spec/airborne/
|
131
|
-
- spec/airborne/
|
127
|
+
- spec/airborne/expectations/expect_header_contains_spec.rb
|
128
|
+
- spec/airborne/expectations/expect_header_spec.rb
|
129
|
+
- spec/airborne/expectations/expect_json_keys_path_spec.rb
|
130
|
+
- spec/airborne/expectations/expect_json_keys_spec.rb
|
131
|
+
- spec/airborne/expectations/expect_json_lambda_spec.rb
|
132
|
+
- spec/airborne/expectations/expect_json_path_spec.rb
|
133
|
+
- spec/airborne/expectations/expect_json_regex_spec.rb
|
134
|
+
- spec/airborne/expectations/expect_json_spec.rb
|
135
|
+
- spec/airborne/expectations/expect_json_types_lambda_spec.rb
|
136
|
+
- spec/airborne/expectations/expect_json_types_optional_spec.rb
|
137
|
+
- spec/airborne/expectations/expect_json_types_path_spec.rb
|
138
|
+
- spec/airborne/expectations/expect_json_types_spec.rb
|
139
|
+
- spec/airborne/expectations/expect_status_spec.rb
|
132
140
|
- spec/airborne/patch_spec.rb
|
133
141
|
- spec/airborne/post_spec.rb
|
134
142
|
- spec/airborne/put_spec.rb
|
135
|
-
- spec/airborne/rack_sinatra_spec.rb
|
143
|
+
- spec/airborne/rack/rack_sinatra_spec.rb
|
136
144
|
- spec/spec_helper.rb
|
137
145
|
- spec/stub_helper.rb
|
138
146
|
- spec/test_responses/array_of_values.json
|
@@ -158,17 +166,17 @@ require_paths:
|
|
158
166
|
- lib
|
159
167
|
required_ruby_version: !ruby/object:Gem::Requirement
|
160
168
|
requirements:
|
161
|
-
- -
|
169
|
+
- - '>='
|
162
170
|
- !ruby/object:Gem::Version
|
163
171
|
version: '0'
|
164
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
173
|
requirements:
|
166
|
-
- -
|
174
|
+
- - '>='
|
167
175
|
- !ruby/object:Gem::Version
|
168
176
|
version: '0'
|
169
177
|
requirements: []
|
170
178
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.
|
179
|
+
rubygems_version: 2.4.1
|
172
180
|
signing_key:
|
173
181
|
specification_version: 4
|
174
182
|
summary: RSpec driven API testing framework
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'expect_json' do
|
4
|
-
it 'should ensure correct json values' do
|
5
|
-
mock_get('simple_get')
|
6
|
-
get '/simple_get'
|
7
|
-
expect_json({name: "Alex", age: 32 })
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should fail when incorrect json is tested' do
|
11
|
-
mock_get('simple_get')
|
12
|
-
get '/simple_get'
|
13
|
-
expect{expect_json({bad: "data"})}.to raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should allow simple path and verify only that path' do
|
17
|
-
mock_get('simple_path_get')
|
18
|
-
get '/simple_path_get'
|
19
|
-
expect_json('address', {street: "Area 51", city: "Roswell", state: "NM"})
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should allow full object graph' do
|
23
|
-
mock_get('simple_path_get')
|
24
|
-
get '/simple_path_get'
|
25
|
-
expect_json({name: "Alex", address: {street: "Area 51", city: "Roswell", state: "NM"}})
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should allow nested paths' do
|
29
|
-
mock_get('simple_nested_path')
|
30
|
-
get '/simple_nested_path'
|
31
|
-
expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'should index into array and test against specific element' do
|
35
|
-
mock_get('array_with_index')
|
36
|
-
get '/array_with_index'
|
37
|
-
expect_json('cars.0', {make: "Tesla", model: "Model S"})
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should test against all elements in the array' do
|
41
|
-
mock_get('array_with_index')
|
42
|
-
get '/array_with_index'
|
43
|
-
expect_json('cars.?', {make: "Tesla", model: "Model S"})
|
44
|
-
expect_json('cars.?', {make: "Lamborghini", model: "Aventador"})
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should invoke proc passed in' do
|
48
|
-
mock_get('simple_get')
|
49
|
-
get '/simple_get'
|
50
|
-
expect_json({name: -> (name){expect(name.length).to eq(4)}})
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should test against regex' do
|
54
|
-
mock_get('simple_get')
|
55
|
-
get '/simple_get'
|
56
|
-
expect_json({name: regex("^A")})
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'should raise an error if regex does not match' do
|
60
|
-
mock_get('simple_get')
|
61
|
-
get '/simple_get'
|
62
|
-
expect{expect_json({name: regex("^B")})}.to raise_error
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'expect_json_types' do
|
4
|
-
it 'should detect current type' do
|
5
|
-
mock_get('simple_get')
|
6
|
-
get '/simple_get'
|
7
|
-
expect_json_types({name: :string, age: :int})
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should fail when incorrect json types tested' do
|
11
|
-
mock_get('simple_get')
|
12
|
-
get '/simple_get'
|
13
|
-
expect{expect_json_types({bad: :bool})}.to raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should not fail when optional property is not present' do
|
17
|
-
mock_get('simple_get')
|
18
|
-
get '/simple_get'
|
19
|
-
expect_json_types({name: :string, age: :int, optional: :bool_or_null })
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should allow simple path and verify only that path' do
|
23
|
-
mock_get('simple_path_get')
|
24
|
-
get '/simple_path_get'
|
25
|
-
expect_json_types('address', {street: :string, city: :string, state: :string})
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should allow full object graph' do
|
29
|
-
mock_get('simple_path_get')
|
30
|
-
get '/simple_path_get'
|
31
|
-
expect_json_types({name: :string, address: {street: :string, city: :string, state: :string}})
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'should allow nested paths' do
|
35
|
-
mock_get('simple_nested_path')
|
36
|
-
get '/simple_nested_path'
|
37
|
-
expect_json_types('address.coordinates', {lattitude: :float, longitutde: :float} )
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should index into array and test against specific element' do
|
41
|
-
mock_get('array_with_index')
|
42
|
-
get '/array_with_index'
|
43
|
-
expect_json_types('cars.0', {make: :string, model: :string})
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should test against all elements in the array' do
|
47
|
-
mock_get('array_with_index')
|
48
|
-
get '/array_with_index'
|
49
|
-
expect_json_types('cars.*', {make: :string, model: :string})
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'should ensure all elements of array are valid' do
|
53
|
-
mock_get('array_with_index')
|
54
|
-
get '/array_with_index'
|
55
|
-
expect{expect_json_types('cars.*', {make: :string, model: :int})}.to raise_error
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should check all nested arrays for specified elements' do
|
59
|
-
mock_get('array_with_nested')
|
60
|
-
get '/array_with_nested'
|
61
|
-
expect_json_types('cars.*.owners.*', {name: :string})
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should ensure all nested arrays contain correct data' do
|
65
|
-
mock_get('array_with_nested_bad_data')
|
66
|
-
get '/array_with_nested_bad_data'
|
67
|
-
expect{expect_json_types('cars.*.owners.*', {name: :string})}.to raise_error
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should check all types in a simple array' do
|
71
|
-
mock_get('array_of_values')
|
72
|
-
get '/array_of_values'
|
73
|
-
expect_json_types({grades: :array_of_ints})
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'should ensure all valid types in a simple array' do
|
77
|
-
mock_get('array_of_values')
|
78
|
-
get '/array_of_values'
|
79
|
-
expect{expect_json_types({bad: :array_of_ints})}.to raise_error
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should deep symbolize array responses' do
|
83
|
-
mock_get('array_response')
|
84
|
-
get '/array_response'
|
85
|
-
expect_json_types("*", {name: :string})
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'should allow empty array' do
|
89
|
-
mock_get('array_of_values')
|
90
|
-
get '/array_of_values'
|
91
|
-
expect_json_types({emptyArray: :array_of_ints})
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should test optional nested hash when exists' do
|
95
|
-
mock_get('simple_nested_path')
|
96
|
-
get '/simple_nested_path'
|
97
|
-
expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should allow optional nested hash' do
|
101
|
-
mock_get('simple_path_get')
|
102
|
-
get '/simple_path_get'
|
103
|
-
expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should invoke proc passed in' do
|
107
|
-
mock_get('simple_get')
|
108
|
-
get '/simple_get'
|
109
|
-
expect_json_types({name: -> (name){expect(name.length).to eq(4)}})
|
110
|
-
end
|
111
|
-
end
|