airborne 0.0.22 → 0.0.23

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