airborne 0.0.22 → 0.0.23
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/.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
|