airborne 0.0.21 → 0.0.22

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: 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