airborne 0.1.20 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|