airborne 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30e01282823fab4e9cc3061afddc348552c5d168
4
- data.tar.gz: c9046553e132cf9a4b29baa258e8aca2f1a760ec
3
+ metadata.gz: 617736e61c4229477118c5e4c6f9b36e6a84ba3a
4
+ data.tar.gz: 4fa7413cdb076f955e9710dd04f1ebc5cb722f29
5
5
  SHA512:
6
- metadata.gz: 1939155cf55fd3843322b6499b98b5203572f79a0976a1006111b2f331564ffbd6198cb40a9d44b2351e1140efc231da2d772c78d446f4ef11de9d4065a2037f
7
- data.tar.gz: e878815c2fd84cc5f858ec8250728f152fe767673875f22f015a75a2c4807b9385d1d413fb6cf8d76a2d3cdb4d20b1c9cc33ada1ad45323800120aa5b97a3717
6
+ metadata.gz: 81987ab36bcf03af95ccb687409c83df3debec95ce9981c7113320c981936ad27099f5dcc5816fdec2c156e1d635d3b23c37887e9e8edb6ec5e8a994f827dd76
7
+ data.tar.gz: 4144d3be1dee4d53e318ed696c4fa7ef8f97652ce5462fe631e42c9f9458d2ac2c8375ca27c71847342268fca866a12f63058cdca23f526e60ec983173c8ab4a
data/LICENSE CHANGED
@@ -1,9 +1,9 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2011-2014 brooklyndev, sethpollack
3
+ Copyright (c) 2014 brooklyndev, sethpollack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
7
7
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
8
 
9
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Airborne
2
2
 
3
- [![airborne travis](http://img.shields.io/travis/brooklynDev/airborne.svg?branch=master&style=flat)](https://travis-ci.org/brooklynDev/airborne)
4
- [![airborne gem version](http://img.shields.io/gem/v/airborne.svg?style=flat)](http://rubygems.org/gems/airborne)
5
- [![airbore gem downloads](http://img.shields.io/gem/dt/airborne.svg?style=flat)](http://rubygems.org/gems/airborne)
6
- [![airborne gem stable downloads](http://img.shields.io/gem/dv/airborne/stable.svg?style=flat)](http://rubygems.org/gems/airborne)
3
+ [![airborne travis](http://img.shields.io/travis/brooklynDev/airborne.svg?branch=master&style=flat-square)](https://travis-ci.org/brooklynDev/airborne)
4
+ [![airborne gem version](http://img.shields.io/gem/v/airborne.svg?style=flat-square)](http://rubygems.org/gems/airborne)
5
+ [![airbore gem downloads](http://img.shields.io/gem/dt/airborne.svg?style=flat-square)](http://rubygems.org/gems/airborne)
6
+ [![airborne gem stable downloads](http://img.shields.io/gem/dv/airborne/stable.svg?style=flat-square)](http://rubygems.org/gems/airborne)
7
7
 
8
8
  RSpec driven API testing framework inspired by [frisby.js](https://github.com/vlucas/frisby)
9
9
 
@@ -17,15 +17,15 @@ Install Airborne:
17
17
  require 'airborne'
18
18
 
19
19
  describe 'sample spec' do
20
- it 'should validate types' do
21
- get 'http://example.com/api/v1/simple_get' #json api that returns { "name" : "John Doe" }
22
- expect_json_types({name: :string})
23
- end
24
-
25
- it 'should validate values' do
26
- get 'http://example.com/api/v1/simple_get' #json api that returns { "name" : "John Doe" }
27
- expect_json({:name => "John Doe"})
28
- end
20
+ it 'should validate types' do
21
+ get 'http://example.com/api/v1/simple_get' #json api that returns { "name" : "John Doe" }
22
+ expect_json_types({name: :string})
23
+ end
24
+
25
+ it 'should validate values' do
26
+ get 'http://example.com/api/v1/simple_get' #json api that returns { "name" : "John Doe" }
27
+ expect_json({:name => "John Doe"})
28
+ end
29
29
  end
30
30
 
31
31
  When calling expect_json_types, these are the valid types that can be tested against:
@@ -51,7 +51,14 @@ If the properties are optional and may not appear in the response, you can appen
51
51
  expect_json_types({name: :string, age: :int_or_null})
52
52
  end
53
53
  end
54
-
54
+
55
+ Additionally, if an entire object could be null, but you'd still want to test the types if it does exist, you can wrap the expectations in a call to `optional`:
56
+
57
+ it 'should allow optional nested hash' do
58
+ get '/simple_path_get' #may or may not return coordinates
59
+ expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
60
+ end
61
+
55
62
  When calling `expect_json`, you can optionally provide a block and run your own `rspec` expectations:
56
63
 
57
64
  describe 'sample spec' do
@@ -70,6 +77,15 @@ Airborne uses `rest_client` to make the HTTP request, and supports all HTTP verb
70
77
  * `body` - The raw HTTP body returned from the request
71
78
  * `json_body` - A symbolized hash representation of the JSON returned by the request
72
79
 
80
+ Fo example:
81
+
82
+ it 'should validate types' do
83
+ get 'http://example.com/api/v1/simple_get' #json api that returns { "name" : "John Doe" }
84
+ name = json_body[:name] #name will equal "John Doe"
85
+ body_as_string = body
86
+ end
87
+
88
+
73
89
  When calling any of the methods above, you can pass request headers to be used.
74
90
 
75
91
  get 'http://example.com/api/v1/my_api', {'x-auth-token' => 'my_token'}
@@ -92,86 +108,86 @@ When calling `expect_json_types`, `expect_json` or `expect_json_keys` you can op
92
108
  For example, if our API returns the following JSON:
93
109
 
94
110
  {
95
- "name": "Alex",
96
- "address": {
97
- "street": "Area 51",
98
- "city": "Roswell",
99
- "state": "NM",
100
- "coordinates":{
101
- "lattitude": 33.3872,
102
- "longitude": 104.5281
103
- }
104
- }
111
+ "name": "Alex",
112
+ "address": {
113
+ "street": "Area 51",
114
+ "city": "Roswell",
115
+ "state": "NM",
116
+ "coordinates":{
117
+ "lattitude": 33.3872,
118
+ "longitude": 104.5281
119
+ }
120
+ }
105
121
  }
106
122
 
107
123
  This test would only test the address object:
108
124
 
109
125
  describe 'path spec' do
110
- it 'should allow simple path and verify only that path' do
111
- get 'http://example.com/api/v1/simple_path_get'
112
- expect_json_types('address', {street: :string, city: :string, state: :string, coordinates: :object })
113
- #or this
114
- expect_json_types('address', {street: :string, city: :string, state: :string, coordinates: { lattitude: :float, longitude: :float } })
115
- end
126
+ it 'should allow simple path and verify only that path' do
127
+ get 'http://example.com/api/v1/simple_path_get'
128
+ expect_json_types('address', {street: :string, city: :string, state: :string, coordinates: :object })
129
+ #or this
130
+ expect_json_types('address', {street: :string, city: :string, state: :string, coordinates: { lattitude: :float, longitude: :float } })
131
+ end
116
132
  end
117
133
 
118
134
  Alternativley, if we only want to test `coordinates` we can dot into just the `coordinates`:
119
135
 
120
- it 'should allow nested paths' do
121
- get 'http://example.com/api/v1/simple_path_get'
122
- expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
123
- end
136
+ it 'should allow nested paths' do
137
+ get 'http://example.com/api/v1/simple_path_get'
138
+ expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
139
+ end
124
140
 
125
141
  When dealing with `arrays`, we can optionally test all (`*`) or a single (`?` - any, `0` - index) element of the array:
126
142
 
127
143
  Given the following JSON:
128
144
 
129
145
  {
130
- "cars":[
131
- {"make": "Tesla", "model": "Model S"},
132
- {"make": "Lamborghini", "model": "Aventador"}
133
- ]
146
+ "cars":[
147
+ {"make": "Tesla", "model": "Model S"},
148
+ {"make": "Lamborghini", "model": "Aventador"}
149
+ ]
134
150
  }
135
151
 
136
152
  We can test against just the first car like this:
137
153
 
138
- it 'should index into array and test against specific element' do
139
- get '/array_api'
140
- expect_json('cars.0', {make: "Tesla", model: "Model S"})
141
- end
154
+ it 'should index into array and test against specific element' do
155
+ get '/array_api'
156
+ expect_json('cars.0', {make: "Tesla", model: "Model S"})
157
+ end
142
158
 
143
159
  To test the types of all elements in the array:
144
160
 
145
- it 'should test all elements of the array' do
146
- get 'http://example.com/api/v1/array_api
147
- expect_json('cars.?', {make: "Tesla", model: "Model S"}) # tests that one car in array matches the tesla
148
- expect_json_types('cars.*', {make: :string, model: :string}) # tests all cars in array for make and model of type string
149
- end
150
-
161
+ it 'should test all elements of the array' do
162
+ get 'http://example.com/api/v1/array_api
163
+ expect_json('cars.?', {make: "Tesla", model: "Model S"}) # tests that one car in array matches the tesla
164
+ expect_json_types('cars.*', {make: :string, model: :string}) # tests all cars in array for make and model of type string
165
+ end
166
+
151
167
  `*` and `?` work for nested arrays as well. Given the following JSON:
152
168
 
153
169
  {
154
- "cars": [{
155
- "make": "Tesla",
156
- "model": "Model S",
157
- "owners": [{
158
- "name": "Bart Simpson"
159
- }]
160
- }, {
161
- "make": "Lamborghini",
162
- "model": "Aventador",
163
- "owners": [{
164
- "name": "Peter Griffin"
165
- }]
166
- }]
170
+ "cars": [{
171
+ "make": "Tesla",
172
+ "model": "Model S",
173
+ "owners": [{
174
+ "name": "Bart Simpson"
175
+ }]
176
+ }, {
177
+ "make": "Lamborghini",
178
+ "model": "Aventador",
179
+ "owners": [{
180
+ "name": "Peter Griffin"
181
+ }]
182
+ }]
167
183
  }
168
184
 
169
185
  ===
170
186
 
171
187
  it 'should check all nested arrays for specified elements' do
172
- get 'http://example.com/api/v1/array_with_nested'
173
- expect_json_types('cars.*.owners.*', {name: :string})
174
- end
188
+ get 'http://example.com/api/v1/array_with_nested'
189
+ expect_json_types('cars.*.owners.*', {name: :string})
190
+ end
175
191
 
176
192
 
177
193
  ##Configuration
@@ -200,10 +216,10 @@ Additionally, you can specify a `base_url` and default `headers` to be used on e
200
216
 
201
217
  The MIT License
202
218
 
203
- Copyright (c) 2011-2014 brooklyndev, sethpollack
219
+ Copyright (c) 2014 brooklyndev, sethpollack
204
220
 
205
221
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
206
222
 
207
223
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
208
224
 
209
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
225
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'airborne'
3
- s.version = '0.0.16'
3
+ s.version = '0.0.17'
4
4
  s.date = '2014-09-12'
5
5
  s.summary = "RSpec driven API testing framework"
6
6
  s.authors = ["Alex Friedman", "Seth Pollack"]
@@ -1,3 +1,4 @@
1
+ require 'airborne/optional_hash_type_expectations'
1
2
  require 'airborne/path_matcher'
2
3
  require 'airborne/request_expectations'
3
4
  require 'airborne/base'
@@ -83,7 +83,7 @@ module Airborne
83
83
  @body = res.body
84
84
  @headers = res.headers
85
85
  begin
86
- @json_body = JSON.parse(res.body, symbolize_names: true) unless res.body == ""
86
+ @json_body = JSON.parse(res.body, symbolize_names: true) unless res.body.empty?
87
87
  rescue
88
88
  end
89
89
  end
@@ -0,0 +1,15 @@
1
+ module Airborne
2
+ class OptionalHashTypeExpectations
3
+ include Enumerable
4
+ attr_accessor :hash
5
+ def initialize(hash)
6
+ @hash = hash
7
+ end
8
+
9
+ def each
10
+ @hash.each do|k,v|
11
+ yield(k,v)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -21,7 +21,7 @@ module Airborne
21
21
  json = json[part]
22
22
  else
23
23
  json = json[part.to_sym]
24
- raise "Expected #{path} to be object or array got #{json.class} from JSON response" unless json.class == Array || json.class == Hash
24
+ raise "Expected #{path} to be object or array got #{json.class} from JSON response" unless json.class == Array || json.class == Hash || json.nil?
25
25
  end
26
26
  end
27
27
  if type == '*'
@@ -47,6 +47,10 @@ module Airborne
47
47
  end
48
48
  end
49
49
 
50
+ def optional(hash)
51
+ OptionalHashTypeExpectations.new(hash)
52
+ end
53
+
50
54
  private
51
55
 
52
56
  def call_with_path(args)
@@ -87,10 +91,11 @@ module Airborne
87
91
  end
88
92
 
89
93
  def expect_json_types_impl(expectations, hash)
94
+ return if expectations.class == Airborne::OptionalHashTypeExpectations && hash.nil?
90
95
  @mapper ||= get_mapper
91
96
  expectations.each do |prop_name, expected_type|
92
97
  value = hash[prop_name]
93
- if expected_type.class == Hash
98
+ if expected_type.class == Hash || expected_type.class == Airborne::OptionalHashTypeExpectations
94
99
  expect_json_types_impl(expected_type, value)
95
100
  elsif expected_type.to_s.include?("array_of")
96
101
  expect(value.class).to eq(Array), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
@@ -36,6 +36,12 @@ describe 'expect_json' do
36
36
  get '/array_with_index'
37
37
  expect_json('cars.?', {make: "Tesla", model: "Model S"})
38
38
  expect_json('cars.?', {make: "Lamborghini", model: "Aventador"})
39
- end
39
+ end
40
+
41
+ it 'should invoke proc passed in' do
42
+ mock_get('simple_get')
43
+ get '/simple_get'
44
+ expect_json({name: -> (name){expect(name.length).to eq(4)}})
45
+ end
40
46
 
41
47
  end
@@ -84,4 +84,16 @@ describe 'expect_json_types' do
84
84
  get '/array_of_values'
85
85
  expect_json_types({emptyArray: :array_of_ints})
86
86
  end
87
+
88
+ it 'should test optional nested hash when exists' do
89
+ mock_get('simple_nested_path')
90
+ get '/simple_nested_path'
91
+ expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
92
+ end
93
+
94
+ it 'should allow optional nested hash' do
95
+ mock_get('simple_path_get')
96
+ get '/simple_path_get'
97
+ expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
98
+ end
87
99
  end
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.16
4
+ version: 0.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Friedman
@@ -82,6 +82,7 @@ files:
82
82
  - airborne.gemspec
83
83
  - lib/airborne.rb
84
84
  - lib/airborne/base.rb
85
+ - lib/airborne/optional_hash_type_expectations.rb
85
86
  - lib/airborne/path_matcher.rb
86
87
  - lib/airborne/request_expectations.rb
87
88
  - spec/airborne/base_spec.rb