airborne 0.0.21 → 0.0.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac24980885b43225b94ae50551b7dbc902a530ff
4
- data.tar.gz: 3f283170d3c681ba2b951f36c1d3c2be0f007b9f
3
+ metadata.gz: e009399096d82e3b30b22f4c8f6fc7255e11699f
4
+ data.tar.gz: 32d38638f1dac42754cc53750ad2a6599be88674
5
5
  SHA512:
6
- metadata.gz: ef83ca97f295ded5b8c56a46f993cbffe546dc9a21e71cc7892c2fd124b72a09cb524271626f2cdedb6909b67f9489d465f5a3e7743fdc99e5d5e24c65400cf1
7
- data.tar.gz: 2b093bcf6f591e4458cae28e59f3d384a58b6df3b8cdefda4e692cc3d1c7b278c0451b9979cc9ee99d303dcfa35a3651a3cffc4d93c472e5473a4e1cfb2df428
6
+ metadata.gz: 35ac6a72835f11646301b47fbd8ee40134a3f6063e173999866bb4726cadebbd7777194d1aed4a3663b9baa46fdb5c3fff1bc75483b9fa336ae9cc167d2e532f
7
+ data.tar.gz: 5a574890b43ad0d9e2953055912bbb86ca74c68b7f0b7ceb6e2346ef8e302a59f5b8890ec4c2cd8bc9423ca4af951b97666b0f854262eee6b3e5dfdcf9833e16
data/Gemfile CHANGED
@@ -7,6 +7,6 @@ gem 'activesupport'
7
7
  gem 'coveralls', require: false
8
8
 
9
9
  group :test do
10
- gem 'webmock'
11
- gem 'sinatra'
10
+ gem 'webmock'
11
+ gem 'sinatra'
12
12
  end
data/README.md CHANGED
@@ -138,32 +138,22 @@ Under the covers, Airborne uses [rack-test](https://github.com/brynary/rack-test
138
138
 
139
139
  ##Rails Applications
140
140
 
141
- If you're testing and API you've written in Rails, Airborne plays along with `rspec-rails` using the following setup:
141
+ If you're testing an API you've written in Rails, Airborne plays along with `rspec-rails`:
142
142
 
143
- In your `spec/rails_helper.rb` file, change RSpec configure to Airborne configure, and set the `rack_app` configuration setting to your Rails Application:
144
-
145
- ```ruby
146
- Airborne.configure do |config|
147
- config.rack_app = Rails.application
148
- end
149
- ```
150
-
151
- Then, in your actual tests, since `rspec-rails` already has `get`, `post`, `put`... functions, you need to use `airborne_get`, `airborne_post` instead:
152
143
 
153
144
  ```ruby
154
145
  require 'rails_helper'
155
146
 
156
- RSpec.describe FooController, :type => :controller do
157
- describe "GET bar" do
147
+ RSpec.describe HomeController, :type => :controller do
148
+ describe "GET index" do
158
149
  it "returns correct types" do
159
- airborne_get '/foo/bar.json'
150
+ get :index, :format => 'json' #if your route responds to both html and json
160
151
  expect_json_types({foo: :string})
161
152
  end
162
153
  end
163
154
  end
164
155
  ```
165
- Just like with all other Rack applications, Airborne uses [rack-test](https://github.com/brynary/rack-test) to make the requests.
166
-
156
+
167
157
  ##API
168
158
 
169
159
  * `expect_json_types` - Tests the types of the JSON property values returned
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'airborne'
3
- s.version = '0.0.21'
3
+ s.version = '0.0.22'
4
4
  s.date = '2014-09-12'
5
5
  s.summary = "RSpec driven API testing framework"
6
6
  s.authors = ["Alex Friedman", "Seth Pollack"]
@@ -7,10 +7,10 @@ require 'airborne/base'
7
7
 
8
8
 
9
9
  RSpec.configure do |config|
10
- config.include Airborne
11
- config.add_setting :base_url
12
- config.add_setting :headers
13
- config.add_setting :rack_app
14
- config.add_setting :requester_type
15
- config.add_setting :requester_module
10
+ config.include Airborne
11
+ config.add_setting :base_url
12
+ config.add_setting :headers
13
+ config.add_setting :rack_app
14
+ config.add_setting :requester_type
15
+ config.add_setting :requester_module
16
16
  end
@@ -2,88 +2,78 @@ require 'json'
2
2
  require 'active_support/hash_with_indifferent_access'
3
3
 
4
4
  module Airborne
5
- include RequestExpectations
6
-
7
- def self.configure
8
- RSpec.configure do |config|
9
- yield config
10
- end
11
- end
12
-
13
- def self.included(base)
14
- if(!Airborne.configuration.requester_module.nil?)
15
- base.send(:include, Airborne.configuration.requester_module)
16
- elsif(!Airborne.configuration.rack_app.nil?)
17
- base.send(:include, RackTestRequester)
18
- else
19
- base.send(:include, RestClientRequester)
20
- end
21
- end
22
-
23
- def self.configuration
24
- RSpec.configuration
25
- end
26
-
27
- def get(url, headers = nil)
28
- set_response(make_request(:get, url, {headers: headers}))
29
- end
30
-
31
- def post(url, post_body = nil, headers = nil)
32
- set_response(make_request(:post, url, {body: post_body, headers: headers}))
33
- end
34
-
35
- def patch(url, patch_body = nil, headers = nil )
36
- set_response(make_request(:patch, url, {body: patch_body, headers: headers}))
37
- end
38
-
39
- def put(url, put_body = nil, headers = nil )
40
- set_response(make_request(:put, url, {body: put_body, headers: headers}))
41
- end
42
-
43
- def delete(url, headers = nil)
44
- set_response(make_request(:delete, url, {headers: headers}))
45
- end
46
-
47
- def response
48
- @response
49
- end
50
-
51
- def headers
52
- @headers
53
- end
54
-
55
- def body
56
- @body
57
- end
58
-
59
- def json_body
60
- @json_body
61
- end
62
-
63
- alias_method :airborne_get, :get
64
- alias_method :airborne_post, :post
65
- alias_method :airborne_patch, :patch
66
- alias_method :airborne_put, :put
67
- alias_method :airborne_delete, :delete
68
- alias_method :airborne_response, :response
69
- alias_method :airborne_headers, :headers
70
- alias_method :airborne_body, :body
71
- alias_method :airborne_json_body, :json_body
72
-
73
- private
74
-
75
- def get_url(url)
76
- base = Airborne.configuration.base_url || ""
77
- base + url
78
- end
79
-
80
- def set_response(res)
81
- @response = res
82
- @body = res.body
83
- @headers = HashWithIndifferentAccess.new(res.headers.deep_symbolize_keys) unless res.headers.nil?
84
- begin
85
- @json_body = JSON.parse(res.body, symbolize_names: true) unless res.body.empty?
86
- rescue
87
- end
88
- end
5
+ include RequestExpectations
6
+
7
+ def self.configure
8
+ RSpec.configure do |config|
9
+ yield config
10
+ end
11
+ end
12
+
13
+ def self.included(base)
14
+ if(!Airborne.configuration.requester_module.nil?)
15
+ base.send(:include, Airborne.configuration.requester_module)
16
+ elsif(!Airborne.configuration.rack_app.nil?)
17
+ base.send(:include, RackTestRequester)
18
+ else
19
+ base.send(:include, RestClientRequester)
20
+ end
21
+ end
22
+
23
+ def self.configuration
24
+ RSpec.configuration
25
+ end
26
+
27
+ def get(url, headers = nil)
28
+ set_response(make_request(:get, url, {headers: headers}))
29
+ end
30
+
31
+ def post(url, post_body = nil, headers = nil)
32
+ set_response(make_request(:post, url, {body: post_body, headers: headers}))
33
+ end
34
+
35
+ def patch(url, patch_body = nil, headers = nil )
36
+ set_response(make_request(:patch, url, {body: patch_body, headers: headers}))
37
+ end
38
+
39
+ def put(url, put_body = nil, headers = nil )
40
+ set_response(make_request(:put, url, {body: put_body, headers: headers}))
41
+ end
42
+
43
+ def delete(url, headers = nil)
44
+ set_response(make_request(:delete, url, {headers: headers}))
45
+ end
46
+
47
+ def response
48
+ @response
49
+ end
50
+
51
+ def headers
52
+ @headers
53
+ end
54
+
55
+ def body
56
+ @body
57
+ end
58
+
59
+ def json_body
60
+ @json_body
61
+ end
62
+
63
+ private
64
+
65
+ def get_url(url)
66
+ base = Airborne.configuration.base_url || ""
67
+ base + url
68
+ end
69
+
70
+ def set_response(res)
71
+ @response = res
72
+ @body = res.body
73
+ @headers = HashWithIndifferentAccess.new(res.headers.deep_symbolize_keys) unless res.headers.nil?
74
+ begin
75
+ @json_body = JSON.parse(res.body, symbolize_names: true) unless res.body.empty?
76
+ rescue
77
+ end
78
+ end
89
79
  end
@@ -1,15 +1,15 @@
1
1
  module Airborne
2
- class OptionalHashTypeExpectations
3
- include Enumerable
4
- attr_accessor :hash
5
- def initialize(hash)
6
- @hash = hash
7
- end
2
+ class OptionalHashTypeExpectations
3
+ include Enumerable
4
+ attr_accessor :hash
5
+ def initialize(hash)
6
+ @hash = hash
7
+ end
8
8
 
9
- def each
10
- @hash.each do|k,v|
11
- yield(k,v)
12
- end
13
- end
14
- end
9
+ def each
10
+ @hash.each do|k,v|
11
+ yield(k,v)
12
+ end
13
+ end
14
+ end
15
15
  end
@@ -1,45 +1,45 @@
1
1
  module Airborne
2
- module PathMatcher
3
- def get_by_path(path, json, &block)
4
- type = false
5
- parts = path.split('.')
6
- parts.each_with_index do |part, index|
7
- if part == '*' || part == '?'
8
- type = part
9
- raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
10
- if index < parts.length.pred
11
- json.each do |element|
12
- sub_path = parts[(index.next)...(parts.length)].join('.')
13
- get_by_path(sub_path, element, &block)
14
- end
15
- return
16
- end
17
- next
18
- end
19
- if /^[\d]+(\.[\d]+){0,1}$/ === part
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
26
- end
27
- if type == '*'
28
- json.each{|part| yield part}
29
- elsif type == '?'
30
- item_count = json.length
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
40
- else
41
- yield json
42
- end
43
- end
44
- end
2
+ module PathMatcher
3
+ def get_by_path(path, json, &block)
4
+ type = false
5
+ parts = path.split('.')
6
+ parts.each_with_index do |part, index|
7
+ if part == '*' || part == '?'
8
+ type = part
9
+ raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
10
+ if index < parts.length.pred
11
+ json.each do |element|
12
+ sub_path = parts[(index.next)...(parts.length)].join('.')
13
+ get_by_path(sub_path, element, &block)
14
+ end
15
+ return
16
+ end
17
+ next
18
+ end
19
+ if /^[\d]+(\.[\d]+){0,1}$/ === part
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
26
+ end
27
+ if type == '*'
28
+ json.each{|part| yield part}
29
+ elsif type == '?'
30
+ item_count = json.length
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
40
+ else
41
+ yield json
42
+ end
43
+ end
44
+ end
45
45
  end
@@ -1,11 +1,11 @@
1
1
  require 'rack/test'
2
2
 
3
3
  module Airborne
4
- module RackTestRequester
5
- def make_request(method, url, options = {})
6
- browser = Rack::Test::Session.new(Rack::MockSession.new(Airborne.configuration.rack_app))
7
- browser.send(method, url, options[:body] || {}, options[:headers] || {})
8
- browser.last_response
9
- end
10
- end
4
+ module RackTestRequester
5
+ def make_request(method, url, options = {})
6
+ browser = Rack::Test::Session.new(Rack::MockSession.new(Airborne.configuration.rack_app))
7
+ browser.send(method, url, options[:body] || {}, options[:headers] || {})
8
+ browser.last_response
9
+ end
10
+ end
11
11
  end
@@ -1,130 +1,136 @@
1
1
  require 'rspec'
2
2
 
3
3
  module Airborne
4
- module RequestExpectations
5
- include RSpec
6
- include PathMatcher
4
+ module RequestExpectations
5
+ include RSpec
6
+ include PathMatcher
7
7
 
8
- def expect_json_types(*args)
9
- call_with_path(args) do |param, body|
10
- expect_json_types_impl(param, body)
11
- end
12
- end
8
+ def expect_json_types(*args)
9
+ set_response(@response) if @json_body.nil?
10
+ call_with_path(args) do |param, body|
11
+ expect_json_types_impl(param, body)
12
+ end
13
+ end
13
14
 
14
- def expect_json(*args)
15
- call_with_path(args) do |param, body|
16
- expect_json_impl(param, body)
17
- end
18
- end
15
+ def expect_json(*args)
16
+ set_response(@response) if @json_body.nil?
17
+ call_with_path(args) do |param, body|
18
+ expect_json_impl(param, body)
19
+ end
20
+ end
19
21
 
20
- def expect_json_keys(*args)
21
- call_with_path(args) do |param, body|
22
- expect(body.keys).to include(*param)
23
- end
24
- end
22
+ def expect_json_keys(*args)
23
+ set_response(@response) if @json_body.nil?
24
+ call_with_path(args) do |param, body|
25
+ expect(body.keys).to include(*param)
26
+ end
27
+ end
25
28
 
26
- def expect_status(code)
27
- expect(response.code).to eq(code)
28
- end
29
+ def expect_status(code)
30
+ set_response(@response) if @json_body.nil?
31
+ expect(response.code).to eq(code)
32
+ end
29
33
 
30
- def expect_header(key, content)
31
- header = headers[key]
32
- if header
33
- expect(header.downcase).to eq(content.downcase)
34
- else
35
- raise "Header #{key} not present in HTTP response"
36
- end
37
- end
34
+ def expect_header(key, content)
35
+ set_response(@response) if @json_body.nil?
36
+ header = headers[key]
37
+ if header
38
+ expect(header.downcase).to eq(content.downcase)
39
+ else
40
+ raise "Header #{key} not present in HTTP response"
41
+ end
42
+ end
38
43
 
39
- def expect_header_contains(key, content)
40
- header = headers[key]
41
- if header
42
- expect(header.downcase).to include(content.downcase)
43
- else
44
- raise "Header #{key} not present in HTTP response"
45
- end
46
- end
44
+ def expect_header_contains(key, content)
45
+ set_response(@response) if @json_body.nil?
46
+ header = headers[key]
47
+ if header
48
+ expect(header.downcase).to include(content.downcase)
49
+ else
50
+ raise "Header #{key} not present in HTTP response"
51
+ end
52
+ end
47
53
 
48
- def optional(hash)
49
- OptionalHashTypeExpectations.new(hash)
50
- end
54
+ def optional(hash)
55
+ OptionalHashTypeExpectations.new(hash)
56
+ end
51
57
 
52
- def regex(reg)
53
- Regexp.new(reg)
54
- end
58
+ def regex(reg)
59
+ Regexp.new(reg)
60
+ end
55
61
 
56
- private
62
+ private
57
63
 
58
- def call_with_path(args)
59
- if args.length == 2
60
- get_by_path(args[0], json_body) do|json_chunk|
61
- yield(args[1], json_chunk)
62
- end
63
- else
64
- yield(args[0], json_body)
65
- end
66
- end
64
+ def call_with_path(args)
65
+ if args.length == 2
66
+ get_by_path(args[0], json_body) do|json_chunk|
67
+ yield(args[1], json_chunk)
68
+ end
69
+ else
70
+ yield(args[0], json_body)
71
+ end
72
+ end
67
73
 
68
- def get_mapper
69
- base_mapper = {
70
- integer: [Fixnum,Bignum],
71
- array_of_integers: [Fixnum,Bignum],
72
- int: [Fixnum,Bignum],
73
- array_of_ints: [Fixnum,Bignum],
74
- float: [Float,Fixnum,Bignum],
75
- array_of_floats: [Float,Fixnum,Bignum],
76
- string: [String],
77
- array_of_strings: [String],
78
- boolean: [TrueClass, FalseClass],
79
- array_of_booleans: [TrueClass, FalseClass],
80
- bool: [TrueClass, FalseClass],
81
- array_of_bools: [TrueClass, FalseClass],
82
- object: [Hash],
83
- array_of_objects: [Hash],
84
- array: [Array],
85
- array_of_arrays: [Array]
86
- }
74
+ def get_mapper
75
+ base_mapper = {
76
+ integer: [Fixnum,Bignum],
77
+ array_of_integers: [Fixnum,Bignum],
78
+ int: [Fixnum,Bignum],
79
+ array_of_ints: [Fixnum,Bignum],
80
+ float: [Float,Fixnum,Bignum],
81
+ array_of_floats: [Float,Fixnum,Bignum],
82
+ string: [String],
83
+ array_of_strings: [String],
84
+ boolean: [TrueClass, FalseClass],
85
+ array_of_booleans: [TrueClass, FalseClass],
86
+ bool: [TrueClass, FalseClass],
87
+ array_of_bools: [TrueClass, FalseClass],
88
+ object: [Hash],
89
+ array_of_objects: [Hash],
90
+ array: [Array],
91
+ array_of_arrays: [Array]
92
+ }
87
93
 
88
- mapper = base_mapper.clone
89
- base_mapper.each do |key, value|
90
- mapper[(key.to_s + "_or_null").to_sym] = value + [NilClass]
91
- end
92
- mapper
93
- end
94
+ mapper = base_mapper.clone
95
+ base_mapper.each do |key, value|
96
+ mapper[(key.to_s + "_or_null").to_sym] = value + [NilClass]
97
+ end
98
+ mapper
99
+ end
94
100
 
95
- def expect_json_types_impl(expectations, hash)
96
- return if expectations.class == Airborne::OptionalHashTypeExpectations && hash.nil?
97
- @mapper ||= get_mapper
98
- expectations.each do |prop_name, expected_type|
99
- value = hash[prop_name]
100
- if expected_type.class == Hash || expected_type.class == Airborne::OptionalHashTypeExpectations
101
- expect_json_types_impl(expected_type, value)
102
- elsif expected_type.class == Proc
103
- expected_type.call(value)
104
- elsif expected_type.to_s.include?("array_of")
105
- expect(value.class).to eq(Array), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
106
- value.each do |val|
107
- expect(@mapper[expected_type].include?(val.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{val.class} instead"
108
- end
109
- else
110
- expect(@mapper[expected_type].include?(value.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
111
- end
112
- end
113
- end
101
+ def expect_json_types_impl(expectations, hash)
102
+ return if expectations.class == Airborne::OptionalHashTypeExpectations && hash.nil?
103
+ @mapper ||= get_mapper
104
+ expectations.each do |prop_name, expected_type|
105
+ value = hash[prop_name]
106
+ if expected_type.class == Hash || expected_type.class == Airborne::OptionalHashTypeExpectations
107
+ expect_json_types_impl(expected_type, value)
108
+ elsif expected_type.class == Proc
109
+ expected_type.call(value)
110
+ elsif expected_type.to_s.include?("array_of")
111
+ expect(value.class).to eq(Array), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
112
+ 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"
114
+ end
115
+ else
116
+ expect(@mapper[expected_type].include?(value.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
117
+ end
118
+ end
119
+ end
114
120
 
115
- def expect_json_impl(expectations, hash)
116
- expectations.each do |prop_name, expected_value|
117
- actual_value = hash[prop_name]
118
- if expected_value.class == Hash
119
- expect_json_impl(expected_value, actual_value)
120
- elsif expected_value.class == Proc
121
- expected_value.call(actual_value)
122
- elsif expected_value.class == Regexp
123
- expect(actual_value).to match(expected_value)
124
- else
125
- expect(actual_value).to eq(expected_value)
126
- end
127
- end
128
- end
129
- end
121
+ def expect_json_impl(expectations, hash)
122
+ expectations.each do |prop_name, expected_value|
123
+ actual_value = hash[prop_name]
124
+ if expected_value.class == Hash
125
+ expect_json_impl(expected_value, actual_value)
126
+ elsif expected_value.class == Proc
127
+ expected_value.call(actual_value)
128
+ elsif expected_value.class == Regexp
129
+ expect(actual_value).to match(expected_value)
130
+ else
131
+ expect(actual_value).to eq(expected_value)
132
+ end
133
+ end
134
+ end
135
+ end
130
136
  end