airborne 0.1.20 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/README.md +37 -8
- data/airborne.gemspec +1 -1
- data/lib/airborne.rb +10 -0
- data/lib/airborne/optional_hash_type_expectations.rb +8 -0
- data/lib/airborne/request_expectations.rb +132 -83
- data/spec/airborne/base_spec.rb +1 -1
- data/spec/airborne/expectations/expect_header_contains_spec.rb +2 -2
- data/spec/airborne/expectations/expect_header_spec.rb +2 -2
- data/spec/airborne/expectations/expect_json_keys_path_spec.rb +1 -1
- data/spec/airborne/expectations/expect_json_keys_spec.rb +1 -1
- data/spec/airborne/expectations/expect_json_path_spec.rb +5 -5
- data/spec/airborne/expectations/expect_json_regex_spec.rb +1 -1
- data/spec/airborne/expectations/expect_json_spec.rb +1 -7
- data/spec/airborne/expectations/expect_json_types_options_spec.rb +59 -0
- data/spec/airborne/expectations/expect_json_types_path_spec.rb +3 -3
- data/spec/airborne/expectations/expect_json_types_spec.rb +4 -4
- data/spec/airborne/expectations/expect_status_spec.rb +1 -1
- data/spec/airborne/path_spec.rb +2 -2
- data/spec/airborne/rack/rack_sinatra_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/stub_helper.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a65123aada9fd5ec28e73e1dd39a55b85b4c120
|
4
|
+
data.tar.gz: df26ba37c5fa926a1c748c4c6e7b441946da49c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac97899e3eb391a2df1f4590b7a8102f7eb40d97fbe4c363ae53ee36e75e5e48ea970780e68e008f8e2af2dde2fa64181c4592128fc49d9845dc30a73125b36b
|
7
|
+
data.tar.gz: 166a72d89beb9dfaa523c5ca402f4b0ca8235f696b523773bf43c381cff4b368fda5eedcb9c9b8ce7888fede5117d5e5674ead901508ce855c87d17ee0b3b249
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -12,13 +12,13 @@ RSpec driven API testing framework
|
|
12
12
|
## Installation
|
13
13
|
|
14
14
|
Install Airborne:
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
```shell
|
16
|
+
$ gem install airborne
|
17
|
+
```
|
18
18
|
Or add it to your Gemfile:
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
```shell
|
20
|
+
$ gem 'airborne'
|
21
|
+
```
|
22
22
|
##Creating Tests
|
23
23
|
|
24
24
|
```ruby
|
@@ -357,10 +357,39 @@ describe 'spec' do
|
|
357
357
|
end
|
358
358
|
```
|
359
359
|
|
360
|
+
You can also control the strictness of `expect_json` and `expect_json_types` with the global settings `match_expected_default` and `match_actual_default` like this.
|
361
|
+
|
362
|
+
```ruby
|
363
|
+
Airborne.configure do |config|
|
364
|
+
config.match_expected_default = true
|
365
|
+
config.match_actual_default = false
|
366
|
+
end
|
367
|
+
```
|
368
|
+
|
369
|
+
Airborne sets `match_expected_default` to `true` and `match_actual_default` to `false` by default.
|
370
|
+
|
371
|
+
You can use the `match_expected` and `match_actual` settings to override your global defaults in test blocks like this.
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
describe 'test something', match_expected: true, match_actual: false do
|
375
|
+
end
|
376
|
+
```
|
377
|
+
|
378
|
+
OR
|
379
|
+
|
380
|
+
```ruby
|
381
|
+
describe 'test something' do
|
382
|
+
Airborne.configuration.match_expected = true
|
383
|
+
Airborne.configuration.match_actual = false
|
384
|
+
end
|
385
|
+
```
|
386
|
+
|
360
387
|
## Run it from the CLI
|
361
388
|
|
362
|
-
|
363
|
-
|
389
|
+
```shell
|
390
|
+
$ cd your/project
|
391
|
+
$ rspec spec
|
392
|
+
```
|
364
393
|
## Authors
|
365
394
|
* [Seth Pollack](https://github.com/sethpollack)
|
366
395
|
* [Alex Friedman](https://github.com/brooklynDev)
|
data/airborne.gemspec
CHANGED
data/lib/airborne.rb
CHANGED
@@ -8,8 +8,18 @@ require 'airborne/base'
|
|
8
8
|
RSpec.configure do |config|
|
9
9
|
config.include Airborne
|
10
10
|
config.add_setting :base_url
|
11
|
+
config.add_setting :match_expected
|
12
|
+
config.add_setting :match_actual
|
13
|
+
config.add_setting :match_expected_default, default: true
|
14
|
+
config.add_setting :match_actual_default, default: false
|
11
15
|
config.add_setting :headers
|
12
16
|
config.add_setting :rack_app
|
13
17
|
config.add_setting :requester_type
|
14
18
|
config.add_setting :requester_module
|
19
|
+
config.before do |example|
|
20
|
+
config.match_expected = example.metadata[:match_expected].nil? ?
|
21
|
+
Airborne.configuration.match_expected_default? : example.metadata[:match_expected]
|
22
|
+
config.match_actual = example.metadata[:match_actual].nil? ?
|
23
|
+
Airborne.configuration.match_actual_default? : example.metadata[:match_actual]
|
24
|
+
end
|
15
25
|
end
|
@@ -67,77 +67,105 @@ module Airborne
|
|
67
67
|
expect(header.downcase).to eq(content.downcase)
|
68
68
|
end
|
69
69
|
else
|
70
|
-
fail RSpec::Expectations::ExpectationNotMetError, "Header #{key} not present in HTTP response"
|
70
|
+
fail RSpec::Expectations::ExpectationNotMetError, "Header #{key} not present in the HTTP response"
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
if
|
76
|
-
get_by_path(args[0], json_body) do|json_chunk|
|
77
|
-
yield(args[1], json_chunk)
|
78
|
-
end
|
79
|
-
else
|
80
|
-
yield(args[0], json_body)
|
81
|
-
end
|
82
|
-
end
|
74
|
+
def expect_json_impl(expected, actual)
|
75
|
+
return if nil_optional_hash?(expected, actual)
|
83
76
|
|
84
|
-
|
85
|
-
base_mapper = {
|
86
|
-
integer: [Fixnum, Bignum],
|
87
|
-
array_of_integers: [Fixnum, Bignum],
|
88
|
-
int: [Fixnum, Bignum],
|
89
|
-
array_of_ints: [Fixnum, Bignum],
|
90
|
-
float: [Float, Fixnum, Bignum],
|
91
|
-
array_of_floats: [Float, Fixnum, Bignum],
|
92
|
-
string: [String],
|
93
|
-
array_of_strings: [String],
|
94
|
-
boolean: [TrueClass, FalseClass],
|
95
|
-
array_of_booleans: [TrueClass, FalseClass],
|
96
|
-
bool: [TrueClass, FalseClass],
|
97
|
-
array_of_bools: [TrueClass, FalseClass],
|
98
|
-
object: [Hash],
|
99
|
-
array_of_objects: [Hash],
|
100
|
-
array: [Array],
|
101
|
-
array_of_arrays: [Array],
|
102
|
-
date: [DateTime],
|
103
|
-
null: [NilClass]
|
104
|
-
}
|
77
|
+
actual = actual.to_s if expected.class == Regexp
|
105
78
|
|
106
|
-
|
107
|
-
|
108
|
-
|
79
|
+
return expect(actual).to match(expected) if property?(expected)
|
80
|
+
|
81
|
+
keys = []
|
82
|
+
|
83
|
+
keys << expected.keys if match_expected?
|
84
|
+
keys << actual.keys if match_actual?
|
85
|
+
keys = expected.keys & actual.keys if match_none?
|
86
|
+
|
87
|
+
keys.flatten.uniq.each do |prop|
|
88
|
+
expected_value = extract_expected(expected, prop)
|
89
|
+
actual_value = extract_actual(actual, prop)
|
90
|
+
|
91
|
+
next expect_json_impl(expected_value, actual_value) if hash?(expected_value)
|
92
|
+
next expected_value.call(actual_value) if expected_value.is_a?(Proc)
|
93
|
+
next expect(actual_value.to_s).to match(expected_value) if expected_value.is_a?(Regexp)
|
94
|
+
|
95
|
+
expect(actual_value).to eq(expected_value)
|
109
96
|
end
|
110
|
-
mapper
|
111
97
|
end
|
112
98
|
|
113
|
-
def expect_json_types_impl(
|
114
|
-
return if nil_optional_hash?(
|
99
|
+
def expect_json_types_impl(expected, actual)
|
100
|
+
return if nil_optional_hash?(expected, actual)
|
115
101
|
|
116
102
|
@mapper ||= get_mapper
|
117
103
|
|
118
|
-
|
104
|
+
actual = convert_to_date(actual) if expected == :date
|
119
105
|
|
120
|
-
return expect_type(
|
121
|
-
return
|
106
|
+
return expect_type(expected, actual.class) if expected.is_a?(Symbol)
|
107
|
+
return expected.call(actual) if expected.is_a?(Proc)
|
122
108
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
value_class = value.class
|
109
|
+
keys = []
|
110
|
+
|
111
|
+
keys << expected.keys if match_expected?
|
112
|
+
keys << actual.keys if match_actual?
|
113
|
+
keys = expected.keys & actual.keys if match_none?
|
129
114
|
|
130
|
-
|
131
|
-
|
115
|
+
keys.flatten.uniq.each do |prop|
|
116
|
+
type = extract_expected(expected, prop)
|
117
|
+
value = extract_actual(actual, prop)
|
118
|
+
value = convert_to_date(value) if type == :date
|
132
119
|
|
133
|
-
if
|
134
|
-
|
120
|
+
next expect_json_types_impl(type, value) if hash?(type)
|
121
|
+
next type.call(value) if type.is_a?(Proc)
|
122
|
+
|
123
|
+
val_class = value.class
|
124
|
+
|
125
|
+
if type.to_s.include?('array_of')
|
126
|
+
check_array_types(value, val_class, prop, type)
|
135
127
|
else
|
136
|
-
expect_type(
|
128
|
+
expect_type(type, val_class, prop)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def call_with_path(args)
|
134
|
+
if args.length == 2
|
135
|
+
get_by_path(args[0], json_body) do |json_chunk|
|
136
|
+
yield(args[1], json_chunk)
|
137
137
|
end
|
138
|
+
else
|
139
|
+
yield(args[0], json_body)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def extract_expected(expected, prop)
|
144
|
+
begin
|
145
|
+
type = expected[prop]
|
146
|
+
type.nil? ? raise : type
|
147
|
+
rescue
|
148
|
+
raise ExpectationError, "Expectation is expected to contain property: #{prop}"
|
138
149
|
end
|
139
150
|
end
|
140
151
|
|
152
|
+
def extract_actual(actual, prop)
|
153
|
+
begin
|
154
|
+
value = actual[prop]
|
155
|
+
rescue
|
156
|
+
raise ExpectationError, "Expected #{actual.class} #{actual}\nto be an object with property #{prop}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def expect_type(expected_type, value_class, prop_name = nil)
|
161
|
+
fail ExpectationError, "Expected type #{expected_type}\nis an invalid type" if @mapper[expected_type].nil?
|
162
|
+
|
163
|
+
insert = prop_name.nil? ? '' : "#{prop_name} to be of type"
|
164
|
+
message = "Expected #{insert} #{expected_type}\n got #{value_class} instead"
|
165
|
+
|
166
|
+
expect(@mapper[expected_type].include?(value_class)).to eq(true), message
|
167
|
+
end
|
168
|
+
|
141
169
|
def convert_to_date(value)
|
142
170
|
begin
|
143
171
|
DateTime.parse(value)
|
@@ -152,46 +180,18 @@ module Airborne
|
|
152
180
|
end
|
153
181
|
end
|
154
182
|
|
155
|
-
def nil_optional_hash?(
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
def expect_type(expected_type, value_class, prop_name = nil)
|
160
|
-
insert = prop_name.nil? ? '' : "#{prop_name} to be of type"
|
161
|
-
msg = "Expected #{insert} #{expected_type}\n got #{value_class} instead"
|
162
|
-
fail ExpectationError, "Expected type #{expected_type}\nis an invalid type" if @mapper[expected_type].nil?
|
163
|
-
expect(@mapper[expected_type].include?(value_class)).to eq(true), msg
|
183
|
+
def nil_optional_hash?(expected, hash)
|
184
|
+
expected.is_a?(Airborne::OptionalHashTypeExpectations) && hash.nil?
|
164
185
|
end
|
165
186
|
|
166
|
-
def hash?(
|
167
|
-
|
187
|
+
def hash?(hash)
|
188
|
+
hash.is_a?(Hash) || hash.is_a?(Airborne::OptionalHashTypeExpectations)
|
168
189
|
end
|
169
190
|
|
170
191
|
def expect_array(value_class, prop_name, expected_type)
|
171
192
|
expect(value_class).to eq(Array), "Expected #{prop_name}\n to be of type #{expected_type}\n got #{value_class} instead"
|
172
193
|
end
|
173
194
|
|
174
|
-
def expect_json_impl(expectations, hash)
|
175
|
-
hash = hash.to_s if expectations.class == Regexp
|
176
|
-
return expect(hash).to match(expectations) if property?(expectations)
|
177
|
-
expectations.each do |prop_name, expected_value|
|
178
|
-
actual_value = ensure_hash_contains_prop(prop_name, hash) { hash[prop_name] }
|
179
|
-
expected_class = expected_value.class
|
180
|
-
next expect(actual_value).to match(expected_value) if expected_class == Hash
|
181
|
-
next expected_value.call(actual_value) if expected_class == Proc
|
182
|
-
next expect(actual_value.to_s).to match(expected_value) if expected_class == Regexp
|
183
|
-
expect(actual_value).to eq(expected_value)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def ensure_hash_contains_prop(prop_name, hash)
|
188
|
-
begin
|
189
|
-
yield
|
190
|
-
rescue
|
191
|
-
raise ExpectationError, "Expected #{hash.class} #{hash}\nto be an object with property #{prop_name}"
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
195
|
def convert_expectations_for_json_sizes(old_expectations)
|
196
196
|
unless old_expectations.is_a?(Hash)
|
197
197
|
return convert_expectation_for_json_sizes(old_expectations)
|
@@ -211,10 +211,47 @@ module Airborne
|
|
211
211
|
->(data) { expect(data.size).to eq(expected_size) }
|
212
212
|
end
|
213
213
|
|
214
|
+
def ensure_hash_contains_prop(prop_name, hash)
|
215
|
+
begin
|
216
|
+
yield
|
217
|
+
rescue
|
218
|
+
raise ExpectationError, "Expected #{hash.class} #{hash}\nto be an object with property #{prop_name}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
214
222
|
def property?(expectations)
|
215
223
|
[String, Regexp, Float, Fixnum, Bignum, TrueClass, FalseClass, NilClass].include?(expectations.class)
|
216
224
|
end
|
217
225
|
|
226
|
+
def get_mapper
|
227
|
+
base_mapper = {
|
228
|
+
integer: [Fixnum, Bignum],
|
229
|
+
array_of_integers: [Fixnum, Bignum],
|
230
|
+
int: [Fixnum, Bignum],
|
231
|
+
array_of_ints: [Fixnum, Bignum],
|
232
|
+
float: [Float, Fixnum, Bignum],
|
233
|
+
array_of_floats: [Float, Fixnum, Bignum],
|
234
|
+
string: [String],
|
235
|
+
array_of_strings: [String],
|
236
|
+
boolean: [TrueClass, FalseClass],
|
237
|
+
array_of_booleans: [TrueClass, FalseClass],
|
238
|
+
bool: [TrueClass, FalseClass],
|
239
|
+
array_of_bools: [TrueClass, FalseClass],
|
240
|
+
object: [Hash],
|
241
|
+
array_of_objects: [Hash],
|
242
|
+
array: [Array],
|
243
|
+
array_of_arrays: [Array],
|
244
|
+
date: [DateTime],
|
245
|
+
null: [NilClass]
|
246
|
+
}
|
247
|
+
|
248
|
+
mapper = base_mapper.clone
|
249
|
+
base_mapper.each do |key, value|
|
250
|
+
mapper[(key.to_s + '_or_null').to_sym] = value + [NilClass]
|
251
|
+
end
|
252
|
+
mapper
|
253
|
+
end
|
254
|
+
|
218
255
|
def resolve_status(candidate, authority)
|
219
256
|
candidate = Rack::Utils::SYMBOL_TO_STATUS_CODE[candidate] if candidate.is_a?(Symbol)
|
220
257
|
case authority
|
@@ -223,5 +260,17 @@ module Airborne
|
|
223
260
|
else candidate
|
224
261
|
end
|
225
262
|
end
|
263
|
+
|
264
|
+
def match_none?
|
265
|
+
!match_actual? && !match_expected?
|
266
|
+
end
|
267
|
+
|
268
|
+
def match_actual?
|
269
|
+
Airborne.configuration.match_actual?
|
270
|
+
end
|
271
|
+
|
272
|
+
def match_expected?
|
273
|
+
Airborne.configuration.match_expected?
|
274
|
+
end
|
226
275
|
end
|
227
276
|
end
|
data/spec/airborne/base_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe 'base spec' do
|
|
17
17
|
mock_get('invalid_json')
|
18
18
|
get '/invalid_json'
|
19
19
|
expect(body).to eq('1234')
|
20
|
-
expect { json_body }.to raise_error
|
20
|
+
expect { json_body }.to raise_error(InvalidJsonError)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'when request is made headers should be hash with indifferent access' do
|
@@ -10,12 +10,12 @@ describe 'expect header contains' do
|
|
10
10
|
it 'should ensure header is present' do
|
11
11
|
mock_get('simple_get', 'Content-Type' => 'application/json')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_header_contains(:foo, 'bar') }.to raise_error
|
13
|
+
expect { expect_header_contains(:foo, 'bar') }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should ensure partial header is present' do
|
17
17
|
mock_get('simple_get', 'Content-Type' => 'application/json')
|
18
18
|
get '/simple_get'
|
19
|
-
expect { expect_header_contains(:content_type, 'bar') }.to raise_error
|
19
|
+
expect { expect_header_contains(:content_type, 'bar') }.to raise_error(ExpectationNotMetError)
|
20
20
|
end
|
21
21
|
end
|
@@ -10,12 +10,12 @@ describe 'expect header' do
|
|
10
10
|
it 'should find exact match for header content' do
|
11
11
|
mock_get('simple_get', 'Content-Type' => 'json')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_header(:content_type, 'application/json') }.to raise_error
|
13
|
+
expect { expect_header(:content_type, 'application/json') }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should ensure correct headers are present' do
|
17
17
|
mock_get('simple_get', 'Content-Type' => 'application/json')
|
18
18
|
get '/simple_get'
|
19
|
-
expect { expect_header(:foo, 'bar') }.to raise_error
|
19
|
+
expect { expect_header(:foo, 'bar') }.to raise_error(ExpectationNotMetError)
|
20
20
|
end
|
21
21
|
end
|
@@ -10,6 +10,6 @@ describe 'expect_json_keys with path' do
|
|
10
10
|
it 'should fail when keys are missing with path' do
|
11
11
|
mock_get('simple_nested_path')
|
12
12
|
get '/simple_nested_path', {}
|
13
|
-
expect { expect_json_keys('address', [:bad]) }.to raise_error
|
13
|
+
expect { expect_json_keys('address', [:bad]) }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
end
|
@@ -4,7 +4,7 @@ describe 'expect_json_keys' do
|
|
4
4
|
it 'should fail when json keys are missing' do
|
5
5
|
mock_get('simple_json')
|
6
6
|
get '/simple_json', {}
|
7
|
-
expect { expect_json_keys([:foo, :bar, :baz, :bax]) }.to raise_error
|
7
|
+
expect { expect_json_keys([:foo, :bar, :baz, :bax]) }.to raise_error(ExpectationNotMetError)
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should ensure correct json keys' do
|
@@ -35,7 +35,7 @@ describe 'expect_json with path' do
|
|
35
35
|
it 'should ensure at least one match' do
|
36
36
|
mock_get('array_with_index')
|
37
37
|
get '/array_with_index'
|
38
|
-
expect { expect_json('cars.?.make', 'Teslas') }.to raise_error
|
38
|
+
expect { expect_json('cars.?.make', 'Teslas') }.to raise_error(ExpectationNotMetError)
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'should check for at least one match' do
|
@@ -47,7 +47,7 @@ describe 'expect_json with path' do
|
|
47
47
|
it 'should ensure at least one match' do
|
48
48
|
mock_get('array_with_nested')
|
49
49
|
get '/array_with_nested'
|
50
|
-
expect { expect_json('cars.?.owners.?', name: 'Bart Simpsons') }.to raise_error
|
50
|
+
expect { expect_json('cars.?.owners.?', name: 'Bart Simpsons') }.to raise_error(ExpectationNotMetError)
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should check for one match that matches all ' do
|
@@ -65,13 +65,13 @@ describe 'expect_json with path' do
|
|
65
65
|
it 'should ensure one match that matches all with lambda' do
|
66
66
|
mock_get('array_with_nested')
|
67
67
|
get '/array_with_nested'
|
68
|
-
expect { expect_json('cars.?.owners.*', name: ->(name) { expect(name).to eq('Bart Simpsons') }) }.to raise_error
|
68
|
+
expect { expect_json('cars.?.owners.*', name: ->(name) { expect(name).to eq('Bart Simpsons') }) }.to raise_error(ExpectationNotMetError)
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'should ensure one match that matches all' do
|
72
72
|
mock_get('array_with_nested')
|
73
73
|
get '/array_with_nested'
|
74
|
-
expect { expect_json('cars.?.owners.*', name: 'Bart Simpsons') }.to raise_error
|
74
|
+
expect { expect_json('cars.?.owners.*', name: 'Bart Simpsons') }.to raise_error(ExpectationNotMetError)
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'should allow indexing' do
|
@@ -103,6 +103,6 @@ describe 'expect_json with path' do
|
|
103
103
|
get '/array_with_index'
|
104
104
|
expect do
|
105
105
|
expect_json('cars.0.make', make: 'Tesla')
|
106
|
-
end.to raise_error(
|
106
|
+
end.to raise_error(ExpectationError, "Expected String Tesla\nto be an object with property make")
|
107
107
|
end
|
108
108
|
end
|
@@ -10,7 +10,7 @@ describe 'expect_json regex' do
|
|
10
10
|
it 'should raise an error if regex does not match' do
|
11
11
|
mock_get('simple_get')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_json(name: regex('^B')) }.to raise_error
|
13
|
+
expect { expect_json(name: regex('^B')) }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should allow regex(Regexp) to be tested against a path' do
|
@@ -10,7 +10,7 @@ describe 'expect_json' do
|
|
10
10
|
it 'should fail when incorrect json is tested' do
|
11
11
|
mock_get('simple_get')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_json(bad: 'data') }.to raise_error
|
13
|
+
expect { expect_json(bad: 'data') }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should allow full object graph' do
|
@@ -18,10 +18,4 @@ describe 'expect_json' do
|
|
18
18
|
get '/simple_path_get'
|
19
19
|
expect_json(name: 'Alex', address: { street: 'Area 51', city: 'Roswell', state: 'NM' })
|
20
20
|
end
|
21
|
-
|
22
|
-
it 'should ensure keys in hashes do match' do
|
23
|
-
mock_get('hash_property')
|
24
|
-
get '/hash_property'
|
25
|
-
expect { expect_json(person: { name: 'Alex', something: nil }) }.to raise_error
|
26
|
-
end
|
27
21
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'expect_json_types options' do
|
4
|
+
describe 'match_expected', match_expected: true, match_actual: false do
|
5
|
+
it 'should require all expected properties' do
|
6
|
+
mock_get 'simple_get'
|
7
|
+
get '/simple_get'
|
8
|
+
expect{ expect_json_types(name: :string, other: :string) }.to raise_error(ExpectationNotMetError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not require the actual properties' do
|
12
|
+
mock_get 'simple_get'
|
13
|
+
get '/simple_get'
|
14
|
+
expect_json_types(name: :string)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'match_actual', match_expected: false, match_actual: true do
|
19
|
+
it 'should require all actual properties' do
|
20
|
+
mock_get 'simple_get'
|
21
|
+
get '/simple_get'
|
22
|
+
expect{ expect_json_types(name: :string) }.to raise_error(ExpectationError)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should not require the expected properties' do
|
26
|
+
mock_get 'simple_get'
|
27
|
+
get '/simple_get'
|
28
|
+
expect_json_types(name: :string, age: :int, address: :null, other: :string)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'match_both', match_expected: true, match_actual: true do
|
33
|
+
it 'should require all actual properties' do
|
34
|
+
mock_get 'simple_get'
|
35
|
+
get '/simple_get'
|
36
|
+
expect{ expect_json_types(name: :string) }.to raise_error(ExpectationError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should require all expected properties' do
|
40
|
+
mock_get 'simple_get'
|
41
|
+
get '/simple_get'
|
42
|
+
expect{ expect_json_types(name: :string, other: :string) }.to raise_error(ExpectationNotMetError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'match_none', match_expected: false, match_actual: false do
|
47
|
+
it 'should not require the actual properties' do
|
48
|
+
mock_get 'simple_get'
|
49
|
+
get '/simple_get'
|
50
|
+
expect_json_types(name: :string)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should not require the expected properties' do
|
54
|
+
mock_get 'simple_get'
|
55
|
+
get '/simple_get'
|
56
|
+
expect_json_types(name: :string, age: :int, address: :null, other: :string)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -34,7 +34,7 @@ describe 'expect_json_types wih path' do
|
|
34
34
|
it 'should ensure all elements of array are valid' do
|
35
35
|
mock_get('array_with_index')
|
36
36
|
get '/array_with_index'
|
37
|
-
expect { expect_json_types('cars.*', make: :string, model: :int) }.to raise_error
|
37
|
+
expect { expect_json_types('cars.*', make: :string, model: :int) }.to raise_error(ExpectationNotMetError)
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should deep symbolize array responses' do
|
@@ -52,7 +52,7 @@ describe 'expect_json_types wih path' do
|
|
52
52
|
it 'should ensure all nested arrays contain correct data' do
|
53
53
|
mock_get('array_with_nested_bad_data')
|
54
54
|
get '/array_with_nested_bad_data'
|
55
|
-
expect { expect_json_types('cars.*.owners.*', name: :string) }.to raise_error
|
55
|
+
expect { expect_json_types('cars.*.owners.*', name: :string) }.to raise_error(ExpectationNotMetError)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'should raise ExpectationError when expectation expects an object instead of type' do
|
@@ -60,6 +60,6 @@ describe 'expect_json_types wih path' do
|
|
60
60
|
get '/array_with_index'
|
61
61
|
expect do
|
62
62
|
expect_json_types('cars.0.make', make: :string)
|
63
|
-
end.to raise_error(
|
63
|
+
end.to raise_error(ExpectationError, "Expected String Tesla\nto be an object with property make")
|
64
64
|
end
|
65
65
|
end
|
@@ -10,7 +10,7 @@ describe 'expect_json_types' do
|
|
10
10
|
it 'should fail when incorrect json types tested' do
|
11
11
|
mock_get('simple_get')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_json_types(bad: :bool) }.to raise_error
|
13
|
+
expect { expect_json_types(bad: :bool) }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should not fail when optional property is not present' do
|
@@ -22,7 +22,7 @@ describe 'expect_json_types' do
|
|
22
22
|
it 'should allow full object graph' do
|
23
23
|
mock_get('simple_path_get')
|
24
24
|
get '/simple_path_get'
|
25
|
-
expect_json_types(name: :string, address: { street: :string, city: :string, state: :string })
|
25
|
+
expect_json_types({name: :string, address: { street: :string, city: :string, state: :string }})
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should check all types in a simple array' do
|
@@ -34,7 +34,7 @@ describe 'expect_json_types' do
|
|
34
34
|
it 'should ensure all valid types in a simple array' do
|
35
35
|
mock_get('array_of_values')
|
36
36
|
get '/array_of_values'
|
37
|
-
expect { expect_json_types(bad: :array_of_ints) }.to raise_error
|
37
|
+
expect { expect_json_types(bad: :array_of_ints) }.to raise_error(ExpectationNotMetError)
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should allow empty array' do
|
@@ -52,6 +52,6 @@ describe 'expect_json_types' do
|
|
52
52
|
it 'Should throw bad type error' do
|
53
53
|
mock_get('simple_get')
|
54
54
|
get '/simple_get'
|
55
|
-
expect { expect_json_types(name: :foo) }.to raise_error(
|
55
|
+
expect { expect_json_types(name: :foo) }.to raise_error(ExpectationError, "Expected type foo\nis an invalid type")
|
56
56
|
end
|
57
57
|
end
|
@@ -10,7 +10,7 @@ describe 'expect_status' do
|
|
10
10
|
it 'should fail when incorrect status code is returned' do
|
11
11
|
mock_get('simple_get')
|
12
12
|
get '/simple_get'
|
13
|
-
expect { expect_status 123 }.to raise_error
|
13
|
+
expect { expect_status 123 }.to raise_error(ExpectationNotMetError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should translate symbol codes to whatever is appropriate for the request' do
|
data/spec/airborne/path_spec.rb
CHANGED
@@ -10,13 +10,13 @@ describe 'expect path' do
|
|
10
10
|
it 'should raise PathError when incorrect path containing .. is used' do
|
11
11
|
expect do
|
12
12
|
expect_json('cars..make', 'Tesla')
|
13
|
-
end.to raise_error(
|
13
|
+
end.to raise_error(PathError, "Invalid Path, contains '..'")
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should raise PathError when trying to call property on an array' do
|
17
17
|
expect do
|
18
18
|
expect_json('cars.make', 'Tesla')
|
19
|
-
end.to raise_error(
|
19
|
+
end.to raise_error(PathError, "Expected Array\nto be an object with property make")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -23,7 +23,7 @@ describe 'rack app' do
|
|
23
23
|
|
24
24
|
it 'should ensure correct values from sinatra app' do
|
25
25
|
get '/'
|
26
|
-
expect { expect_json_types(foo: :int) }.to raise_error
|
26
|
+
expect { expect_json_types(foo: :int) }.to raise_error(ExpectationNotMetError)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'Should set json_body even when not using the airborne http requests' do
|
data/spec/spec_helper.rb
CHANGED
@@ -7,3 +7,8 @@ Airborne.configure do |config|
|
|
7
7
|
config.base_url = 'http://www.example.com'
|
8
8
|
config.include StubHelper
|
9
9
|
end
|
10
|
+
|
11
|
+
ExpectationNotMetError = RSpec::Expectations::ExpectationNotMetError
|
12
|
+
ExpectationError = Airborne::ExpectationError
|
13
|
+
InvalidJsonError = Airborne::InvalidJsonError
|
14
|
+
PathError = Airborne::PathError
|
data/spec/stub_helper.rb
CHANGED
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Friedman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -136,6 +136,7 @@ files:
|
|
136
136
|
- spec/airborne/expectations/expect_json_types_date_spec.rb
|
137
137
|
- spec/airborne/expectations/expect_json_types_lambda_spec.rb
|
138
138
|
- spec/airborne/expectations/expect_json_types_optional_spec.rb
|
139
|
+
- spec/airborne/expectations/expect_json_types_options_spec.rb
|
139
140
|
- spec/airborne/expectations/expect_json_types_path_spec.rb
|
140
141
|
- spec/airborne/expectations/expect_json_types_spec.rb
|
141
142
|
- spec/airborne/expectations/expect_status_spec.rb
|
@@ -187,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
188
|
version: '0'
|
188
189
|
requirements: []
|
189
190
|
rubyforge_project:
|
190
|
-
rubygems_version: 2.
|
191
|
+
rubygems_version: 2.4.3
|
191
192
|
signing_key:
|
192
193
|
specification_version: 4
|
193
194
|
summary: RSpec driven API testing framework
|