airborne 0.0.22 → 0.0.23

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: e009399096d82e3b30b22f4c8f6fc7255e11699f
4
- data.tar.gz: 32d38638f1dac42754cc53750ad2a6599be88674
3
+ metadata.gz: 2db47b8f533a4c04a03ab8fd64258bac9eb6c943
4
+ data.tar.gz: 46ec329525c710f2264396853ec4ae26d9d52081
5
5
  SHA512:
6
- metadata.gz: 35ac6a72835f11646301b47fbd8ee40134a3f6063e173999866bb4726cadebbd7777194d1aed4a3663b9baa46fdb5c3fff1bc75483b9fa336ae9cc167d2e532f
7
- data.tar.gz: 5a574890b43ad0d9e2953055912bbb86ca74c68b7f0b7ceb6e2346ef8e302a59f5b8890ec4c2cd8bc9423ca4af951b97666b0f854262eee6b3e5dfdcf9833e16
6
+ metadata.gz: d4a8397f77c164291b8a72b567e40d1100d45d3bef5f8a76e1158c2ee97d0b6824de5ec6acae5eadb1bcd4cb443b51058fb72171e79d99fc54d1efa055c47ade
7
+ data.tar.gz: 18c6eb65f280e579efdf1347fcc94b1b36fbb9bcf7c96b76586840ec189556a0b616f8cfce767eb5bb4d3edf35cf271286167fa518397125b6fb132775ca8b90
data/.gitignore CHANGED
@@ -32,5 +32,5 @@ build/
32
32
 
33
33
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
34
  .rvmrc
35
-
35
+ .idea
36
36
  .DS_store
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'airborne'
3
- s.version = '0.0.22'
3
+ s.version = '0.0.23'
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,45 +1,97 @@
1
1
  module Airborne
2
2
  module PathMatcher
3
+
3
4
  def get_by_path(path, json, &block)
4
5
  type = false
5
6
  parts = path.split('.')
6
7
  parts.each_with_index do |part, index|
7
8
  if part == '*' || part == '?'
9
+ ensure_array(path, json)
8
10
  type = part
9
- raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
10
11
  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
12
+ walk_with_path(type, index, path, parts, json, &block)
15
13
  return
16
14
  end
17
15
  next
18
16
  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
17
+ json = process_json(part, json)
26
18
  end
27
19
  if type == '*'
28
- json.each{|part| yield part}
20
+ expect_all(json, &block)
29
21
  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
22
+ expect_one(path, json, &block)
40
23
  else
41
24
  yield json
42
25
  end
43
26
  end
27
+
28
+ private
29
+
30
+ def walk_with_path(type, index, path, parts, json, &block)
31
+ last_error = nil
32
+ item_count = json.length
33
+ error_count = 0
34
+ json.each do |element|
35
+ begin
36
+ sub_path = parts[(index.next)...(parts.length)].join('.')
37
+ get_by_path(sub_path, element, &block)
38
+ rescue Exception => e
39
+ last_error = e
40
+ error_count += 1
41
+ end
42
+ ensure_match_all(last_error) if type == '*'
43
+ ensure_match_one(path, item_count, error_count) if type == '?'
44
+ end
45
+ end
46
+
47
+ def process_json(part, json)
48
+ if is_index?(part)
49
+ part = part.to_i
50
+ json = json[part]
51
+ else
52
+ json = json[part.to_sym]
53
+ end
54
+ json
55
+ end
56
+
57
+ def is_index?(part)
58
+ part =~ /^\d+$/
59
+ end
60
+
61
+ def expect_one(path, json, &block)
62
+ item_count = json.length
63
+ error_count = 0
64
+ json.each do |part|
65
+ begin
66
+ yield part
67
+ rescue Exception => e
68
+ error_count += 1
69
+ ensure_match_one(path, item_count, error_count)
70
+ end
71
+ end
72
+ end
73
+
74
+ def expect_all(json, &block)
75
+ last_error = nil
76
+ begin
77
+ json.each{|part| yield part}
78
+ rescue Exception => e
79
+ last_error = e
80
+ end
81
+ ensure_match_all(last_error)
82
+ end
83
+
84
+ def ensure_match_one(path, item_count, error_count)
85
+ raise "Expected one object in path #{path} to match provided JSON values" if item_count == error_count
86
+ end
87
+
88
+ def ensure_match_all(error)
89
+ raise error unless error.nil?
90
+ end
91
+
92
+ def ensure_array(path, json)
93
+ raise "Expected #{path} to be array got #{json.class} from JSON response" unless json.class == Array
94
+ end
95
+
44
96
  end
45
97
  end
@@ -6,33 +6,28 @@ module Airborne
6
6
  include PathMatcher
7
7
 
8
8
  def expect_json_types(*args)
9
- set_response(@response) if @json_body.nil?
10
9
  call_with_path(args) do |param, body|
11
10
  expect_json_types_impl(param, body)
12
11
  end
13
12
  end
14
13
 
15
14
  def expect_json(*args)
16
- set_response(@response) if @json_body.nil?
17
15
  call_with_path(args) do |param, body|
18
16
  expect_json_impl(param, body)
19
17
  end
20
18
  end
21
19
 
22
20
  def expect_json_keys(*args)
23
- set_response(@response) if @json_body.nil?
24
21
  call_with_path(args) do |param, body|
25
22
  expect(body.keys).to include(*param)
26
23
  end
27
24
  end
28
25
 
29
26
  def expect_status(code)
30
- set_response(@response) if @json_body.nil?
31
27
  expect(response.code).to eq(code)
32
28
  end
33
29
 
34
30
  def expect_header(key, content)
35
- set_response(@response) if @json_body.nil?
36
31
  header = headers[key]
37
32
  if header
38
33
  expect(header.downcase).to eq(content.downcase)
@@ -42,7 +37,6 @@ module Airborne
42
37
  end
43
38
 
44
39
  def expect_header_contains(key, content)
45
- set_response(@response) if @json_body.nil?
46
40
  header = headers[key]
47
41
  if header
48
42
  expect(header.downcase).to include(content.downcase)
@@ -59,8 +53,20 @@ module Airborne
59
53
  Regexp.new(reg)
60
54
  end
61
55
 
56
+ [:expect_json_types, :expect_json, :expect_json_keys, :expect_status, :expect_header, :expect_header_contains].each do |method_name|
57
+ method = instance_method(method_name)
58
+ define_method(method_name) do |*args, &block|
59
+ set_rails_response
60
+ method.bind(self).(*args, &block)
61
+ end
62
+ end
63
+
62
64
  private
63
65
 
66
+ def set_rails_response
67
+ set_response(@response) if @json_body.nil?
68
+ end
69
+
64
70
  def call_with_path(args)
65
71
  if args.length == 2
66
72
  get_by_path(args[0], json_body) do|json_chunk|
@@ -101,6 +107,7 @@ module Airborne
101
107
  def expect_json_types_impl(expectations, hash)
102
108
  return if expectations.class == Airborne::OptionalHashTypeExpectations && hash.nil?
103
109
  @mapper ||= get_mapper
110
+ return expect(@mapper[expectations].include?(hash.class)).to eq(true) if expectations.class == Symbol
104
111
  expectations.each do |prop_name, expected_type|
105
112
  value = hash[prop_name]
106
113
  if expected_type.class == Hash || expected_type.class == Airborne::OptionalHashTypeExpectations
@@ -110,7 +117,7 @@ module Airborne
110
117
  elsif expected_type.to_s.include?("array_of")
111
118
  expect(value.class).to eq(Array), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
112
119
  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"
120
+ expect(@mapper[expected_type].include?(val.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{val.class} instead"
114
121
  end
115
122
  else
116
123
  expect(@mapper[expected_type].include?(value.class)).to eq(true), "Expected #{prop_name} to be of type #{expected_type}, got #{value.class} instead"
@@ -119,6 +126,8 @@ module Airborne
119
126
  end
120
127
 
121
128
  def expect_json_impl(expectations, hash)
129
+ hash = hash.to_s if expectations.class == Regexp
130
+ return expect(hash).to match(expectations) if [String, Regexp, Float, Fixnum, Bignum].include?(expectations.class)
122
131
  expectations.each do |prop_name, expected_value|
123
132
  actual_value = hash[prop_name]
124
133
  if expected_value.class == Hash
@@ -126,11 +135,11 @@ module Airborne
126
135
  elsif expected_value.class == Proc
127
136
  expected_value.call(actual_value)
128
137
  elsif expected_value.class == Regexp
129
- expect(actual_value).to match(expected_value)
138
+ expect(actual_value.to_s).to match(expected_value)
130
139
  else
131
140
  expect(actual_value).to eq(expected_value)
132
141
  end
133
142
  end
134
143
  end
135
144
  end
136
- end
145
+ end
@@ -1,20 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'expect header' do
4
- it 'should find exact match for header content' do
5
- mock_get('simple_get', {'Content-Type' => 'application/json'})
6
- get '/simple_get'
7
- expect_header(:content_type, 'application/json')
8
- end
9
-
10
- it 'should ensure correct headers are present' do
11
- mock_get('simple_get', {'Content-Type' => 'application/json'})
12
- get '/simple_get'
13
- expect{expect_header(:foo, 'bar')}.to raise_error
14
- end
15
- end
16
-
17
3
  describe 'expect header contains' do
4
+
18
5
  it 'should ensure partial header match exists' do
19
6
  mock_get('simple_get', {'Content-Type' => 'application/json'})
20
7
  get '/simple_get'
@@ -32,4 +19,5 @@ describe 'expect header contains' do
32
19
  get '/simple_get'
33
20
  expect{expect_header_contains(:content_type, 'bar')}.to raise_error
34
21
  end
22
+
35
23
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect header' do
4
+
5
+ it 'should find exact match for header content' do
6
+ mock_get('simple_get', {'Content-Type' => 'application/json'})
7
+ get '/simple_get'
8
+ expect_header(:content_type, 'application/json')
9
+ end
10
+
11
+ it 'should find exact match for header content' do
12
+ mock_get('simple_get', {'Content-Type' => 'json'})
13
+ get '/simple_get'
14
+ expect{expect_header(:content_type, 'application/json')}.to raise_error
15
+ end
16
+
17
+ it 'should ensure correct headers are present' do
18
+ mock_get('simple_get', {'Content-Type' => 'application/json'})
19
+ get '/simple_get'
20
+ expect{expect_header(:foo, 'bar')}.to raise_error
21
+ end
22
+
23
+ end
24
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json_keys with path' do
4
+
5
+ it 'should ensure json keys with path' do
6
+ mock_get('simple_nested_path')
7
+ get '/simple_nested_path', {}
8
+ expect_json_keys('address', [:street, :city])
9
+ end
10
+
11
+ it 'should fail when keys are missing with path' do
12
+ mock_get('simple_nested_path')
13
+ get '/simple_nested_path', {}
14
+ expect{expect_json_keys('address', [:bad])}.to raise_error
15
+ end
16
+
17
+ end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'expect_json_keys' do
4
+
4
5
  it 'should fail when json keys are missing' do
5
6
  mock_get('simple_json')
6
7
  get '/simple_json', {}
@@ -18,16 +19,5 @@ describe 'expect_json_keys' do
18
19
  get '/simple_json', {}
19
20
  expect_json_keys([:foo, :bar])
20
21
  end
21
-
22
- it 'should ensure json keys with path' do
23
- mock_get('simple_nested_path')
24
- get '/simple_nested_path', {}
25
- expect_json_keys('address', [:street, :city])
26
- end
27
-
28
- it 'should fail when keys are missing with path' do
29
- mock_get('simple_nested_path')
30
- get '/simple_nested_path', {}
31
- expect{expect_json_keys('address', [:bad])}.to raise_error
32
- end
22
+
33
23
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json lambda' do
4
+
5
+ it 'should invoke proc passed in' do
6
+ mock_get('simple_get')
7
+ get '/simple_get'
8
+ expect_json({name: -> (name){expect(name.length).to eq(4)}})
9
+ end
10
+
11
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json with path' do
4
+
5
+ it 'should allow simple path and verify only that path' do
6
+ mock_get('simple_path_get')
7
+ get '/simple_path_get'
8
+ expect_json('address', {street: "Area 51", city: "Roswell", state: "NM"})
9
+ end
10
+
11
+ it 'should allow nested paths' do
12
+ mock_get('simple_nested_path')
13
+ get '/simple_nested_path'
14
+ expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
15
+ end
16
+
17
+ it 'should index into array and test against specific element' do
18
+ mock_get('array_with_index')
19
+ get '/array_with_index'
20
+ expect_json('cars.0', {make: "Tesla", model: "Model S"})
21
+ end
22
+
23
+ it 'should test against all elements in the array' do
24
+ mock_get('array_with_index')
25
+ get '/array_with_index'
26
+ expect_json('cars.?', {make: "Tesla", model: "Model S"})
27
+ expect_json('cars.?', {make: "Lamborghini", model: "Aventador"})
28
+ end
29
+
30
+ it 'should test against properties in the array' do
31
+ mock_get('array_with_index')
32
+ get '/array_with_index'
33
+ expect_json('cars.?.make', "Tesla")
34
+ end
35
+
36
+ it 'should ensure at least one match' do
37
+ mock_get('array_with_index')
38
+ get '/array_with_index'
39
+ expect{expect_json('cars.?.make', "Teslas")}.to raise_error
40
+ end
41
+
42
+ it 'should check for at least one match' do
43
+ mock_get('array_with_nested')
44
+ get '/array_with_nested'
45
+ expect_json('cars.?.owners.?', {name: "Bart Simpson"})
46
+ end
47
+
48
+ it 'should ensure at least one match' do
49
+ mock_get('array_with_nested')
50
+ get '/array_with_nested'
51
+ expect{expect_json('cars.?.owners.?', {name: "Bart Simpsons"})}.to raise_error
52
+ end
53
+
54
+ it 'should check for one match that matches all ' do
55
+ mock_get('array_with_nested')
56
+ get '/array_with_nested'
57
+ expect_json('cars.?.owners.*', {name: "Bart Simpson"})
58
+ end
59
+
60
+ it 'should check for one match that matches all with lambda' do
61
+ mock_get('array_with_nested')
62
+ get '/array_with_nested'
63
+ expect_json('cars.?.owners.*', {name: -> (name){expect(name).to eq("Bart Simpson")}})
64
+ end
65
+
66
+ it 'should ensure one match that matches all with lambda' do
67
+ mock_get('array_with_nested')
68
+ get '/array_with_nested'
69
+ expect{expect_json('cars.?.owners.*', {name: -> (name){expect(name).to eq("Bart Simpsons")}})}.to raise_error
70
+ end
71
+
72
+ it 'should ensure one match that matches all' do
73
+ mock_get('array_with_nested')
74
+ get '/array_with_nested'
75
+ expect{expect_json('cars.?.owners.*', {name: "Bart Simpsons"})}.to raise_error
76
+ end
77
+
78
+ it 'should allow indexing' do
79
+ mock_get('array_with_nested')
80
+ get '/array_with_nested'
81
+ expect_json('cars.0.owners.0', {name: "Bart Simpson"})
82
+ end
83
+
84
+ it 'should allow strings (String) to be tested against a path' do
85
+ mock_get('simple_nested_path')
86
+ get '/simple_nested_path'
87
+ expect_json('address.city', "Roswell" )
88
+ end
89
+
90
+ it 'should allow floats (Float) to be tested against a path' do
91
+ mock_get('simple_nested_path')
92
+ get '/simple_nested_path'
93
+ expect_json('address.coordinates.lattitude', 33.3872 )
94
+ end
95
+
96
+ it 'should allow integers (Fixnum, Bignum) to be tested against a path' do
97
+ mock_get('simple_get')
98
+ get '/simple_get'
99
+ expect_json('age', 32 )
100
+ end
101
+
102
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json regex' do
4
+
5
+ it 'should test against regex' do
6
+ mock_get('simple_get')
7
+ get '/simple_get'
8
+ expect_json({name: regex("^A")})
9
+ end
10
+
11
+ it 'should raise an error if regex does not match' do
12
+ mock_get('simple_get')
13
+ get '/simple_get'
14
+ expect{expect_json({name: regex("^B")})}.to raise_error
15
+ end
16
+
17
+ it 'should allow regex(Regexp) to be tested against a path' do
18
+ mock_get('simple_nested_path')
19
+ get '/simple_nested_path'
20
+ expect_json('address.city', regex("^R") )
21
+ end
22
+
23
+ it 'should allow testing regex against numbers directly' do
24
+ mock_get('simple_nested_path')
25
+ get '/simple_nested_path'
26
+ expect_json('address.coordinates.lattitude', regex("^3") )
27
+ end
28
+
29
+ it 'should allow testing regex against numbers in the hash' do
30
+ mock_get('simple_nested_path')
31
+ get '/simple_nested_path'
32
+ expect_json('address.coordinates', {lattitude: regex("^3")} )
33
+ end
34
+
35
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json' do
4
+
5
+ it 'should ensure correct json values' do
6
+ mock_get('simple_get')
7
+ get '/simple_get'
8
+ expect_json({name: "Alex", age: 32 })
9
+ end
10
+
11
+ it 'should fail when incorrect json is tested' do
12
+ mock_get('simple_get')
13
+ get '/simple_get'
14
+ expect{expect_json({bad: "data"})}.to raise_error
15
+ end
16
+
17
+ it 'should allow full object graph' do
18
+ mock_get('simple_path_get')
19
+ get '/simple_path_get'
20
+ expect_json({name: "Alex", address: {street: "Area 51", city: "Roswell", state: "NM"}})
21
+ end
22
+
23
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json_types lambda' do
4
+
5
+ it 'should invoke proc passed in' do
6
+ mock_get('simple_get')
7
+ get '/simple_get'
8
+ expect_json_types({name: -> (name){expect(name.length).to eq(4)}})
9
+ end
10
+
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json_types optional' do
4
+
5
+ it 'should test optional nested hash when exists' do
6
+ mock_get('simple_nested_path')
7
+ get '/simple_nested_path'
8
+ expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
9
+ end
10
+
11
+ it 'should allow optional nested hash' do
12
+ mock_get('simple_path_get')
13
+ get '/simple_path_get'
14
+ expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
15
+ end
16
+
17
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json_types wih path' do
4
+
5
+ it 'should allow simple path and verify only that path' do
6
+ mock_get('simple_path_get')
7
+ get '/simple_path_get'
8
+ expect_json_types('address', {street: :string, city: :string, state: :string})
9
+ end
10
+
11
+ it 'should allow nested paths' do
12
+ mock_get('simple_nested_path')
13
+ get '/simple_nested_path'
14
+ expect_json_types('address.coordinates', {lattitude: :float, longitutde: :float} )
15
+ end
16
+
17
+ it 'should index into array and test against specific element' do
18
+ mock_get('array_with_index')
19
+ get '/array_with_index'
20
+ expect_json_types('cars.0', {make: :string, model: :string})
21
+ end
22
+
23
+ it 'should allow properties to be tested against a path' do
24
+ mock_get('array_with_index')
25
+ get '/array_with_index'
26
+ expect_json_types('cars.0.make', :string)
27
+ end
28
+
29
+ it 'should test against all elements in the array' do
30
+ mock_get('array_with_index')
31
+ get '/array_with_index'
32
+ expect_json_types('cars.*', {make: :string, model: :string})
33
+ end
34
+
35
+ it 'should ensure all elements of array are valid' do
36
+ mock_get('array_with_index')
37
+ get '/array_with_index'
38
+ expect{expect_json_types('cars.*', {make: :string, model: :int})}.to raise_error
39
+ end
40
+
41
+ it 'should deep symbolize array responses' do
42
+ mock_get('array_response')
43
+ get '/array_response'
44
+ expect_json_types("*", {name: :string})
45
+ end
46
+
47
+ it 'should check all nested arrays for specified elements' do
48
+ mock_get('array_with_nested')
49
+ get '/array_with_nested'
50
+ expect_json_types('cars.*.owners.*', {name: :string})
51
+ end
52
+
53
+ it 'should ensure all nested arrays contain correct data' do
54
+ mock_get('array_with_nested_bad_data')
55
+ get '/array_with_nested_bad_data'
56
+ expect{expect_json_types('cars.*.owners.*', {name: :string})}.to raise_error
57
+ end
58
+
59
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'expect_json_types' do
4
+
5
+ it 'should detect current type' do
6
+ mock_get('simple_get')
7
+ get '/simple_get'
8
+ expect_json_types({name: :string, age: :int})
9
+ end
10
+
11
+ it 'should fail when incorrect json types tested' do
12
+ mock_get('simple_get')
13
+ get '/simple_get'
14
+ expect{expect_json_types({bad: :bool})}.to raise_error
15
+ end
16
+
17
+ it 'should not fail when optional property is not present' do
18
+ mock_get('simple_get')
19
+ get '/simple_get'
20
+ expect_json_types({name: :string, age: :int, optional: :bool_or_null })
21
+ end
22
+
23
+ it 'should allow full object graph' do
24
+ mock_get('simple_path_get')
25
+ get '/simple_path_get'
26
+ expect_json_types({name: :string, address: {street: :string, city: :string, state: :string}})
27
+ end
28
+
29
+ it 'should check all types in a simple array' do
30
+ mock_get('array_of_values')
31
+ get '/array_of_values'
32
+ expect_json_types({grades: :array_of_ints})
33
+ end
34
+
35
+ it 'should ensure all valid types in a simple array' do
36
+ mock_get('array_of_values')
37
+ get '/array_of_values'
38
+ expect{expect_json_types({bad: :array_of_ints})}.to raise_error
39
+ end
40
+
41
+ it 'should allow empty array' do
42
+ mock_get('array_of_values')
43
+ get '/array_of_values'
44
+ expect_json_types({emptyArray: :array_of_ints})
45
+ end
46
+
47
+ end
@@ -1,15 +1,16 @@
1
1
  {
2
- "cars": [{
3
- "make": "Tesla",
4
- "model": "Model S",
5
- "owners": [{
6
- "name": "Bart Simpson"
7
- }]
8
- }, {
9
- "make": "Lamborghini",
10
- "model": "Aventador",
11
- "owners": [{
12
- "name": "Peter Griffin"
13
- }]
14
- }]
2
+ "cars": [{
3
+ "make": "Tesla",
4
+ "model": "Model S",
5
+ "owners": [
6
+ {"name": "Bart Simpson"}
7
+ ]
8
+ }, {
9
+ "make": "Lamborghini",
10
+ "model": "Aventador",
11
+ "owners": [
12
+ {"name": "Peter Griffin"}
13
+
14
+ ]
15
+ }]
15
16
  }
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.22
4
+ version: 0.0.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Friedman
@@ -15,88 +15,88 @@ dependencies:
15
15
  name: rspec
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ~>
19
19
  - !ruby/object:Gem::Version
20
20
  version: '3.1'
21
- - - ">="
21
+ - - '>='
22
22
  - !ruby/object:Gem::Version
23
23
  version: 3.1.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - "~>"
28
+ - - ~>
29
29
  - !ruby/object:Gem::Version
30
30
  version: '3.1'
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: 3.1.0
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: rest-client
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.7'
41
- - - ">="
41
+ - - '>='
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.7.2
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - "~>"
48
+ - - ~>
49
49
  - !ruby/object:Gem::Version
50
50
  version: '1.7'
51
- - - ">="
51
+ - - '>='
52
52
  - !ruby/object:Gem::Version
53
53
  version: 1.7.2
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rack-test
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ~>
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0.6'
61
- - - ">="
61
+ - - '>='
62
62
  - !ruby/object:Gem::Version
63
63
  version: 0.6.2
64
64
  type: :runtime
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - "~>"
68
+ - - ~>
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0.6'
71
- - - ">="
71
+ - - '>='
72
72
  - !ruby/object:Gem::Version
73
73
  version: 0.6.2
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: activesupport
76
76
  requirement: !ruby/object:Gem::Requirement
77
77
  requirements:
78
- - - ">="
78
+ - - '>='
79
79
  - !ruby/object:Gem::Version
80
80
  version: 4.0.1
81
81
  type: :runtime
82
82
  prerelease: false
83
83
  version_requirements: !ruby/object:Gem::Requirement
84
84
  requirements:
85
- - - ">="
85
+ - - '>='
86
86
  - !ruby/object:Gem::Version
87
87
  version: 4.0.1
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: webmock
90
90
  requirement: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - "~>"
92
+ - - ~>
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  type: :development
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - "~>"
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
101
  version: '0'
102
102
  description:
@@ -107,9 +107,9 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
- - ".coveralls.yml"
111
- - ".gitignore"
112
- - ".travis.yml"
110
+ - .coveralls.yml
111
+ - .gitignore
112
+ - .travis.yml
113
113
  - Gemfile
114
114
  - Gemfile.lock
115
115
  - LICENSE
@@ -124,15 +124,23 @@ files:
124
124
  - lib/airborne/rest_client_requester.rb
125
125
  - spec/airborne/base_spec.rb
126
126
  - spec/airborne/delete_spec.rb
127
- - spec/airborne/expect_json_keys_spec.rb
128
- - spec/airborne/expect_json_spec.rb
129
- - spec/airborne/expect_json_types_spec.rb
130
- - spec/airborne/expect_status_spec.rb
131
- - spec/airborne/headers_spec.rb
127
+ - spec/airborne/expectations/expect_header_contains_spec.rb
128
+ - spec/airborne/expectations/expect_header_spec.rb
129
+ - spec/airborne/expectations/expect_json_keys_path_spec.rb
130
+ - spec/airborne/expectations/expect_json_keys_spec.rb
131
+ - spec/airborne/expectations/expect_json_lambda_spec.rb
132
+ - spec/airborne/expectations/expect_json_path_spec.rb
133
+ - spec/airborne/expectations/expect_json_regex_spec.rb
134
+ - spec/airborne/expectations/expect_json_spec.rb
135
+ - spec/airborne/expectations/expect_json_types_lambda_spec.rb
136
+ - spec/airborne/expectations/expect_json_types_optional_spec.rb
137
+ - spec/airborne/expectations/expect_json_types_path_spec.rb
138
+ - spec/airborne/expectations/expect_json_types_spec.rb
139
+ - spec/airborne/expectations/expect_status_spec.rb
132
140
  - spec/airborne/patch_spec.rb
133
141
  - spec/airborne/post_spec.rb
134
142
  - spec/airborne/put_spec.rb
135
- - spec/airborne/rack_sinatra_spec.rb
143
+ - spec/airborne/rack/rack_sinatra_spec.rb
136
144
  - spec/spec_helper.rb
137
145
  - spec/stub_helper.rb
138
146
  - spec/test_responses/array_of_values.json
@@ -158,17 +166,17 @@ require_paths:
158
166
  - lib
159
167
  required_ruby_version: !ruby/object:Gem::Requirement
160
168
  requirements:
161
- - - ">="
169
+ - - '>='
162
170
  - !ruby/object:Gem::Version
163
171
  version: '0'
164
172
  required_rubygems_version: !ruby/object:Gem::Requirement
165
173
  requirements:
166
- - - ">="
174
+ - - '>='
167
175
  - !ruby/object:Gem::Version
168
176
  version: '0'
169
177
  requirements: []
170
178
  rubyforge_project:
171
- rubygems_version: 2.2.0
179
+ rubygems_version: 2.4.1
172
180
  signing_key:
173
181
  specification_version: 4
174
182
  summary: RSpec driven API testing framework
@@ -1,65 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'expect_json' do
4
- it 'should ensure correct json values' do
5
- mock_get('simple_get')
6
- get '/simple_get'
7
- expect_json({name: "Alex", age: 32 })
8
- end
9
-
10
- it 'should fail when incorrect json is tested' do
11
- mock_get('simple_get')
12
- get '/simple_get'
13
- expect{expect_json({bad: "data"})}.to raise_error
14
- end
15
-
16
- it 'should allow simple path and verify only that path' do
17
- mock_get('simple_path_get')
18
- get '/simple_path_get'
19
- expect_json('address', {street: "Area 51", city: "Roswell", state: "NM"})
20
- end
21
-
22
- it 'should allow full object graph' do
23
- mock_get('simple_path_get')
24
- get '/simple_path_get'
25
- expect_json({name: "Alex", address: {street: "Area 51", city: "Roswell", state: "NM"}})
26
- end
27
-
28
- it 'should allow nested paths' do
29
- mock_get('simple_nested_path')
30
- get '/simple_nested_path'
31
- expect_json('address.coordinates', {lattitude: 33.3872, longitutde: 104.5281} )
32
- end
33
-
34
- it 'should index into array and test against specific element' do
35
- mock_get('array_with_index')
36
- get '/array_with_index'
37
- expect_json('cars.0', {make: "Tesla", model: "Model S"})
38
- end
39
-
40
- it 'should test against all elements in the array' do
41
- mock_get('array_with_index')
42
- get '/array_with_index'
43
- expect_json('cars.?', {make: "Tesla", model: "Model S"})
44
- expect_json('cars.?', {make: "Lamborghini", model: "Aventador"})
45
- end
46
-
47
- it 'should invoke proc passed in' do
48
- mock_get('simple_get')
49
- get '/simple_get'
50
- expect_json({name: -> (name){expect(name.length).to eq(4)}})
51
- end
52
-
53
- it 'should test against regex' do
54
- mock_get('simple_get')
55
- get '/simple_get'
56
- expect_json({name: regex("^A")})
57
- end
58
-
59
- it 'should raise an error if regex does not match' do
60
- mock_get('simple_get')
61
- get '/simple_get'
62
- expect{expect_json({name: regex("^B")})}.to raise_error
63
- end
64
-
65
- end
@@ -1,111 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'expect_json_types' do
4
- it 'should detect current type' do
5
- mock_get('simple_get')
6
- get '/simple_get'
7
- expect_json_types({name: :string, age: :int})
8
- end
9
-
10
- it 'should fail when incorrect json types tested' do
11
- mock_get('simple_get')
12
- get '/simple_get'
13
- expect{expect_json_types({bad: :bool})}.to raise_error
14
- end
15
-
16
- it 'should not fail when optional property is not present' do
17
- mock_get('simple_get')
18
- get '/simple_get'
19
- expect_json_types({name: :string, age: :int, optional: :bool_or_null })
20
- end
21
-
22
- it 'should allow simple path and verify only that path' do
23
- mock_get('simple_path_get')
24
- get '/simple_path_get'
25
- expect_json_types('address', {street: :string, city: :string, state: :string})
26
- end
27
-
28
- it 'should allow full object graph' do
29
- mock_get('simple_path_get')
30
- get '/simple_path_get'
31
- expect_json_types({name: :string, address: {street: :string, city: :string, state: :string}})
32
- end
33
-
34
- it 'should allow nested paths' do
35
- mock_get('simple_nested_path')
36
- get '/simple_nested_path'
37
- expect_json_types('address.coordinates', {lattitude: :float, longitutde: :float} )
38
- end
39
-
40
- it 'should index into array and test against specific element' do
41
- mock_get('array_with_index')
42
- get '/array_with_index'
43
- expect_json_types('cars.0', {make: :string, model: :string})
44
- end
45
-
46
- it 'should test against all elements in the array' do
47
- mock_get('array_with_index')
48
- get '/array_with_index'
49
- expect_json_types('cars.*', {make: :string, model: :string})
50
- end
51
-
52
- it 'should ensure all elements of array are valid' do
53
- mock_get('array_with_index')
54
- get '/array_with_index'
55
- expect{expect_json_types('cars.*', {make: :string, model: :int})}.to raise_error
56
- end
57
-
58
- it 'should check all nested arrays for specified elements' do
59
- mock_get('array_with_nested')
60
- get '/array_with_nested'
61
- expect_json_types('cars.*.owners.*', {name: :string})
62
- end
63
-
64
- it 'should ensure all nested arrays contain correct data' do
65
- mock_get('array_with_nested_bad_data')
66
- get '/array_with_nested_bad_data'
67
- expect{expect_json_types('cars.*.owners.*', {name: :string})}.to raise_error
68
- end
69
-
70
- it 'should check all types in a simple array' do
71
- mock_get('array_of_values')
72
- get '/array_of_values'
73
- expect_json_types({grades: :array_of_ints})
74
- end
75
-
76
- it 'should ensure all valid types in a simple array' do
77
- mock_get('array_of_values')
78
- get '/array_of_values'
79
- expect{expect_json_types({bad: :array_of_ints})}.to raise_error
80
- end
81
-
82
- it 'should deep symbolize array responses' do
83
- mock_get('array_response')
84
- get '/array_response'
85
- expect_json_types("*", {name: :string})
86
- end
87
-
88
- it 'should allow empty array' do
89
- mock_get('array_of_values')
90
- get '/array_of_values'
91
- expect_json_types({emptyArray: :array_of_ints})
92
- end
93
-
94
- it 'should test optional nested hash when exists' do
95
- mock_get('simple_nested_path')
96
- get '/simple_nested_path'
97
- expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
98
- end
99
-
100
- it 'should allow optional nested hash' do
101
- mock_get('simple_path_get')
102
- get '/simple_path_get'
103
- expect_json_types("address.coordinates", optional({lattitude: :float, longitutde: :float}))
104
- end
105
-
106
- it 'should invoke proc passed in' do
107
- mock_get('simple_get')
108
- get '/simple_get'
109
- expect_json_types({name: -> (name){expect(name.length).to eq(4)}})
110
- end
111
- end