api-validator 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +27 -0
- data/README.md +80 -0
- data/Rakefile +8 -0
- data/api-validator.gemspec +27 -0
- data/lib/api-validator.rb +19 -0
- data/lib/api-validator/assertion.rb +32 -0
- data/lib/api-validator/base.rb +47 -0
- data/lib/api-validator/header.rb +77 -0
- data/lib/api-validator/json.rb +56 -0
- data/lib/api-validator/json_schema.rb +228 -0
- data/lib/api-validator/json_schemas.rb +20 -0
- data/lib/api-validator/mixins.rb +7 -0
- data/lib/api-validator/mixins/deep_merge.rb +28 -0
- data/lib/api-validator/response_expectation.rb +90 -0
- data/lib/api-validator/response_expectation/results.rb +62 -0
- data/lib/api-validator/spec.rb +153 -0
- data/lib/api-validator/spec/results.rb +28 -0
- data/lib/api-validator/status.rb +37 -0
- data/lib/api-validator/version.rb +3 -0
- data/spec/header_validator_spec.rb +108 -0
- data/spec/json_schema_validator_spec.rb +463 -0
- data/spec/json_validator_spec.rb +174 -0
- data/spec/response_expectation_results_spec.rb +105 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/spec_results_spec.rb +52 -0
- data/spec/spec_spec.rb +196 -0
- data/spec/status_validator_spec.rb +46 -0
- data/spec/support/hash_wrapper.rb +50 -0
- data/spec/support/shared_examples/shared_example_declaration.rb +8 -0
- data/spec/support/shared_examples/shared_example_lookup.rb +5 -0
- data/spec/support/shared_examples/validation_declaration.rb +65 -0
- data/spec/support/validator_shared_examples.rb +21 -0
- metadata +188 -0
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'faraday'
|
3
|
+
|
4
|
+
require 'support/validator_shared_examples'
|
5
|
+
|
6
|
+
describe ApiValidator::Json do
|
7
|
+
let(:env) { HashWrapper.new(:status => 200, :response_headers => {}, :body => '') }
|
8
|
+
let(:response) { Faraday::Response.new(env) }
|
9
|
+
let(:validator) { stub(:everything) }
|
10
|
+
let(:instance) { described_class.new(expected_properties) }
|
11
|
+
let(:expectation_key) { :response_body }
|
12
|
+
|
13
|
+
let(:res) { instance.validate(response) }
|
14
|
+
|
15
|
+
describe "#validate" do
|
16
|
+
let(:expected_properties) do
|
17
|
+
{
|
18
|
+
:water => {
|
19
|
+
:fire => "air",
|
20
|
+
:coords => {
|
21
|
+
:lat => "-19.65",
|
22
|
+
:lng => "86.86"
|
23
|
+
}
|
24
|
+
},
|
25
|
+
:air => "water fire",
|
26
|
+
:fire => /\Aair/,
|
27
|
+
:altitude => 500_000,
|
28
|
+
:snacks => [
|
29
|
+
{
|
30
|
+
:name => "Chunky Bar",
|
31
|
+
:quantity => 12
|
32
|
+
},
|
33
|
+
{
|
34
|
+
:name => "Celery Sticks",
|
35
|
+
:quantity => 30
|
36
|
+
},
|
37
|
+
{
|
38
|
+
:name => "Peanut Butter Cups",
|
39
|
+
:quantity => 1024
|
40
|
+
},
|
41
|
+
{
|
42
|
+
:name => "Date Squares",
|
43
|
+
:quantity => 256,
|
44
|
+
:ingredients => [["Dates", { :quantity => 4, :units => "cups" }], ["Almonds", { :quantity => 10, :units => "cups" }]]
|
45
|
+
}
|
46
|
+
]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:expected_assertions) do
|
51
|
+
[
|
52
|
+
{ :op => "test", :path => "/water/fire", :value => "air" },
|
53
|
+
{ :op => "test", :path => "/water/coords/lat", :value => "-19.65" },
|
54
|
+
{ :op => "test", :path => "/water/coords/lng", :value => "86.86" },
|
55
|
+
{ :op => "test", :path => "/air", :value => "water fire" },
|
56
|
+
{ :op => "test", :path => "/fire", :value => "/^air/", :type => "regexp" },
|
57
|
+
{ :op => "test", :path => "/altitude", :value => 500_000 },
|
58
|
+
{ :op => "test", :path => "/snacks/0/name", :value => "Chunky Bar" },
|
59
|
+
{ :op => "test", :path => "/snacks/0/quantity", :value => 12 },
|
60
|
+
{ :op => "test", :path => "/snacks/1/name", :value => "Celery Sticks" },
|
61
|
+
{ :op => "test", :path => "/snacks/1/quantity", :value => 30 },
|
62
|
+
{ :op => "test", :path => "/snacks/2/name", :value => "Peanut Butter Cups" },
|
63
|
+
{ :op => "test", :path => "/snacks/2/quantity", :value => 1024 },
|
64
|
+
{ :op => "test", :path => "/snacks/3/name", :value => "Date Squares" },
|
65
|
+
{ :op => "test", :path => "/snacks/3/quantity", :value => 256 },
|
66
|
+
{ :op => "test", :path => "/snacks/3/ingredients/0/0", :value => "Dates" },
|
67
|
+
{ :op => "test", :path => "/snacks/3/ingredients/0/1/quantity", :value => 4 },
|
68
|
+
{ :op => "test", :path => "/snacks/3/ingredients/0/1/units", :value => "cups" },
|
69
|
+
{ :op => "test", :path => "/snacks/3/ingredients/1/0", :value => "Almonds" },
|
70
|
+
{ :op => "test", :path => "/snacks/3/ingredients/1/1/quantity", :value => 10 },
|
71
|
+
{ :op => "test", :path => "/snacks/3/ingredients/1/1/units", :value => "cups" },
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when expectation fails" do
|
76
|
+
it_behaves_like "a validator #validate method"
|
77
|
+
|
78
|
+
before do
|
79
|
+
env.body = {
|
80
|
+
"water" => {
|
81
|
+
"fire" => "very hot",
|
82
|
+
"depth" => 2_000_000_000,
|
83
|
+
"coords" => {
|
84
|
+
"lat" => "-19.65",
|
85
|
+
"type" => "latlng"
|
86
|
+
}
|
87
|
+
},
|
88
|
+
"fire" => "air water fire",
|
89
|
+
"altitude" => 500_000,
|
90
|
+
"type" => "random_data",
|
91
|
+
"snacks" => [
|
92
|
+
{
|
93
|
+
"name" => "Chunky Bar",
|
94
|
+
"quantity" => 12
|
95
|
+
},
|
96
|
+
{
|
97
|
+
"name" => "Celery Sticks",
|
98
|
+
"quantity" => 30
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"name" => "Peanut Butter Cups",
|
102
|
+
"quantity" => 1024
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"name" => "Date Squares",
|
106
|
+
"quantity" => 256,
|
107
|
+
"ingredients" => [["Dates", { "quantity" => 4, "units" => "cups" }], ["Almonds", { "quantity" => 10, "units" => "cups" }]]
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
let(:expected_failed_assertions) do
|
114
|
+
[
|
115
|
+
{ :op => "test", :path => "/water/fire", :value => "air" },
|
116
|
+
{ :op => "test", :path => "/water/coords/lng", :value => "86.86" },
|
117
|
+
{ :op => "test", :path => "/air", :value => "water fire" }
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:expected_diff) do
|
122
|
+
[
|
123
|
+
{ :op => "replace", :path => "/water/fire", :value => "air", :current_value => "very hot" },
|
124
|
+
{ :op => "add", :path => "/water/coords/lng", :value => "86.86" },
|
125
|
+
{ :op => "add", :path => "/air", :value => "water fire" }
|
126
|
+
]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "when expectation passes" do
|
131
|
+
it_behaves_like "a validator #validate method"
|
132
|
+
|
133
|
+
before do
|
134
|
+
env.body = {
|
135
|
+
"water" => {
|
136
|
+
"fire" => "air",
|
137
|
+
"depth" => 2_000_000_000,
|
138
|
+
"coords" => {
|
139
|
+
"lat" => "-19.65",
|
140
|
+
"lng" => "86.86",
|
141
|
+
"type" => "latlng"
|
142
|
+
}
|
143
|
+
},
|
144
|
+
"air" => "water fire",
|
145
|
+
"fire" => "air water fire",
|
146
|
+
"altitude" => 500_000,
|
147
|
+
"type" => "random_data",
|
148
|
+
"snacks" => [
|
149
|
+
{
|
150
|
+
"name" => "Chunky Bar",
|
151
|
+
"quantity" => 12
|
152
|
+
},
|
153
|
+
{
|
154
|
+
"name" => "Celery Sticks",
|
155
|
+
"quantity" => 30
|
156
|
+
},
|
157
|
+
{
|
158
|
+
"name" => "Peanut Butter Cups",
|
159
|
+
"quantity" => 1024
|
160
|
+
},
|
161
|
+
{
|
162
|
+
"name" => "Date Squares",
|
163
|
+
"quantity" => 256,
|
164
|
+
"ingredients" => [["Dates", { "quantity" => 4, "units" => "cups" }], ["Almonds", { "quantity" => 10, "units" => "cups" }]]
|
165
|
+
}
|
166
|
+
]
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
let(:expected_diff) { [] }
|
171
|
+
let(:expected_failed_assertions) { [] }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApiValidator::ResponseExpectation::Results do
|
4
|
+
let(:request_url) { "http://lindeichmann.example.com/ollie?foo=bar" }
|
5
|
+
let(:request_headers) { { "Accept" => "text/plain" } }
|
6
|
+
let(:request_body) { "Ping" }
|
7
|
+
let(:response_headers) { { "Count" => "285", "Sugar" => "Crack from Mary Poppins" } }
|
8
|
+
let(:response_body) { "Pong" }
|
9
|
+
let(:env) {
|
10
|
+
HashWrapper.new(
|
11
|
+
:status => 200,
|
12
|
+
:request_headers => request_headers,
|
13
|
+
:request_body => request_body,
|
14
|
+
:method => 'get',
|
15
|
+
:url => URI(request_url),
|
16
|
+
:body => response_body,
|
17
|
+
:response_headers => response_headers
|
18
|
+
)
|
19
|
+
}
|
20
|
+
let(:results) {
|
21
|
+
[
|
22
|
+
{
|
23
|
+
:key => :response_headers,
|
24
|
+
:assertions => [
|
25
|
+
{ :op => "test", :path => "/Count", :value => "/^\\d+$/", :type => "regexp" }
|
26
|
+
],
|
27
|
+
:failed_assertions => [],
|
28
|
+
:diff => [],
|
29
|
+
:valid => true
|
30
|
+
},
|
31
|
+
{
|
32
|
+
:key => :response_headers,
|
33
|
+
:assertions => [
|
34
|
+
{ :op => "test", :path => "/Sugar", :value => "Sweet" }
|
35
|
+
],
|
36
|
+
:failed_assertions => [
|
37
|
+
{ :op => "test", :path => "/Sugar", :value => "Sweet" }
|
38
|
+
],
|
39
|
+
:diff => [
|
40
|
+
{ :op => "replace", :path => "/Sugar", :value => "Sweet" },
|
41
|
+
{ :op => "add", :path => "/Content-Type", :value => "text/plain" }
|
42
|
+
],
|
43
|
+
:valid => false
|
44
|
+
},
|
45
|
+
{
|
46
|
+
:key => :response_status,
|
47
|
+
:assertions => [
|
48
|
+
{ :op => "test", :path => "", :value => 200 }
|
49
|
+
],
|
50
|
+
:failed_assertions => [],
|
51
|
+
:diff => [],
|
52
|
+
:valid => true
|
53
|
+
}
|
54
|
+
]
|
55
|
+
}
|
56
|
+
let(:response) { Faraday::Response.new(env) }
|
57
|
+
let(:instance) { described_class.new(response, results) }
|
58
|
+
|
59
|
+
describe "#as_json" do
|
60
|
+
let(:expected_output) {
|
61
|
+
{
|
62
|
+
:expected => {
|
63
|
+
:response_headers => {
|
64
|
+
:assertions => [
|
65
|
+
{ :op => "test", :path => "/Count", :value => "/^\\d+$/", :type => "regexp" },
|
66
|
+
{ :op => "test", :path => "/Sugar", :value => "Sweet" }
|
67
|
+
],
|
68
|
+
:failed_assertions => [
|
69
|
+
{ :op => "test", :path => "/Sugar", :value => "Sweet" }
|
70
|
+
],
|
71
|
+
:diff => [
|
72
|
+
{ :op => "replace", :path => "/Sugar", :value => "Sweet" },
|
73
|
+
{ :op => "add", :path => "/Content-Type", :value => "text/plain" }
|
74
|
+
],
|
75
|
+
:valid => false
|
76
|
+
},
|
77
|
+
:response_status => {
|
78
|
+
:assertions => [
|
79
|
+
{ :op => "test", :path => "", :value => 200 }
|
80
|
+
],
|
81
|
+
:failed_assertions => [],
|
82
|
+
:diff => [],
|
83
|
+
:valid => true
|
84
|
+
}
|
85
|
+
},
|
86
|
+
:actual => {
|
87
|
+
:request_headers => request_headers,
|
88
|
+
:request_body => request_body,
|
89
|
+
:request_path => "/ollie",
|
90
|
+
:request_params => { "foo" => "bar" },
|
91
|
+
:request_url => request_url,
|
92
|
+
:request_method => 'GET',
|
93
|
+
|
94
|
+
:response_headers => response_headers,
|
95
|
+
:response_body => response_body,
|
96
|
+
:response_status => 200
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
it "merges expectation results with actual data" do
|
102
|
+
expect(instance.as_json).to eql(expected_output)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'api-validator'
|
6
|
+
require 'support/hash_wrapper'
|
7
|
+
require 'mocha/api'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.mock_with :mocha
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApiValidator::Spec::Results do
|
4
|
+
let(:validator) { stub(:name => "GET /foo") }
|
5
|
+
let(:other_validator) { stub(:name => "with bar") }
|
6
|
+
let(:results) {
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:response_headers => {
|
10
|
+
:assertions => [],
|
11
|
+
:failed_assertions => [],
|
12
|
+
:diff => [],
|
13
|
+
:valid => true
|
14
|
+
}
|
15
|
+
}
|
16
|
+
]
|
17
|
+
}
|
18
|
+
let(:instance) { described_class.new(validator, results) }
|
19
|
+
let(:other_instance) { described_class.new(other_validator, results) }
|
20
|
+
|
21
|
+
describe "#as_json" do
|
22
|
+
let(:expected_output) {
|
23
|
+
{
|
24
|
+
"GET /foo" => {
|
25
|
+
:results => results
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
it "returns results nested under validator name" do
|
30
|
+
expect(instance.as_json).to eql(expected_output)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#merge!" do
|
35
|
+
let(:expected_output) {
|
36
|
+
{
|
37
|
+
"GET /foo" => {
|
38
|
+
:results => results,
|
39
|
+
"with bar" => {
|
40
|
+
:results => results
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
it "merges given results as children and returns self" do
|
47
|
+
expect(instance.merge!(other_instance)).to eql(instance)
|
48
|
+
expect(instance.results).to eql(expected_output)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/spec/spec_spec.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/shared_examples/validation_declaration'
|
3
|
+
require 'support/shared_examples/shared_example_declaration'
|
4
|
+
require 'support/shared_examples/shared_example_lookup'
|
5
|
+
|
6
|
+
describe ApiValidator::Spec do
|
7
|
+
describe "class methods" do
|
8
|
+
let(:instance) { described_class }
|
9
|
+
|
10
|
+
describe ".describe" do
|
11
|
+
it_behaves_like "a validation declaration" do
|
12
|
+
let(:method_name) { :describe }
|
13
|
+
let(:parent) { nil }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".context" do
|
18
|
+
it_behaves_like "a validation declaration" do
|
19
|
+
let(:method_name) { :describe }
|
20
|
+
let(:parent) { nil }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".shared_example" do
|
25
|
+
it_behaves_like "a shared example declaration"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "instance methods" do
|
30
|
+
let(:instance) { described_class.new("foo bar") }
|
31
|
+
|
32
|
+
describe "#describe" do
|
33
|
+
it_behaves_like "a validation declaration" do
|
34
|
+
let(:method_name) { :describe }
|
35
|
+
let(:parent) { instance }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#context" do
|
40
|
+
it_behaves_like "a validation declaration" do
|
41
|
+
let(:method_name) { :context }
|
42
|
+
let(:parent) { instance }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#shared_example" do
|
47
|
+
it_behaves_like "a shared example declaration"
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#find_shared_example" do
|
51
|
+
let(:block) { lambda {} }
|
52
|
+
let(:name) { :foo }
|
53
|
+
|
54
|
+
context "when example in current instance" do
|
55
|
+
before do
|
56
|
+
instance.shared_examples[name] = block
|
57
|
+
end
|
58
|
+
|
59
|
+
it_behaves_like "shared example lookup"
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when example in parent instance" do
|
63
|
+
before do
|
64
|
+
i = described_class.new("bar baz")
|
65
|
+
instance.instance_eval { @parent = i }
|
66
|
+
i.shared_examples[name] = block
|
67
|
+
end
|
68
|
+
|
69
|
+
it_behaves_like "shared example lookup"
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when example in parent of parent instance" do
|
73
|
+
before do
|
74
|
+
i = described_class.new("bar bar")
|
75
|
+
instance.instance_eval { @parent = i }
|
76
|
+
|
77
|
+
i2 = described_class.new("baz biz")
|
78
|
+
i.instance_eval { @parent = i2 }
|
79
|
+
|
80
|
+
i2.shared_examples[name] = block
|
81
|
+
end
|
82
|
+
|
83
|
+
it_behaves_like "shared example lookup"
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when example in class" do
|
87
|
+
before do
|
88
|
+
described_class.shared_examples[name] = block
|
89
|
+
end
|
90
|
+
|
91
|
+
it_behaves_like "shared example lookup"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#behaves_as" do
|
96
|
+
let(:name) { :bar }
|
97
|
+
|
98
|
+
context "when shared example exists" do
|
99
|
+
it "calls block in scope of validator" do
|
100
|
+
ref = nil
|
101
|
+
example_block = proc { ref = self }
|
102
|
+
|
103
|
+
instance.stubs(:find_shared_example).with(name).returns(example_block)
|
104
|
+
instance.behaves_as(name)
|
105
|
+
|
106
|
+
expect(ref).to eql(instance)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when shared example does not exist" do
|
111
|
+
it "raises BehaviourNotFoundError" do
|
112
|
+
expect { instance.behaves_as(name) }.to raise_error(ApiValidator::Spec::BehaviourNotFoundError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#expect_response" do
|
118
|
+
it "creates a new response expectation" do
|
119
|
+
expect(instance.expect_response).to be_a(ApiValidator::ResponseExpectation)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "appends expectation to list of expectations" do
|
123
|
+
expect { instance.expect_response }.to change(instance.expectations, :size).by(1)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#run" do
|
128
|
+
it "calls before hooks in context of validator" do
|
129
|
+
ref = nil
|
130
|
+
before_hook = proc { ref = self }
|
131
|
+
instance.before_hooks << before_hook
|
132
|
+
|
133
|
+
instance.run
|
134
|
+
expect(ref).to eql(instance)
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when before hook is an instance method" do
|
138
|
+
it "calls before hooks in context of validator" do
|
139
|
+
ref = nil
|
140
|
+
instance.class.class_eval do
|
141
|
+
define_method :something do
|
142
|
+
ref = self
|
143
|
+
end
|
144
|
+
end
|
145
|
+
instance.before_hooks << instance.method(:something)
|
146
|
+
|
147
|
+
instance.run
|
148
|
+
expect(ref).to eql(instance)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it "executes response expectations" do
|
153
|
+
response_expectation = stub
|
154
|
+
instance.expectations << response_expectation
|
155
|
+
|
156
|
+
response_expectation.expects(:run).returns([])
|
157
|
+
instance.run
|
158
|
+
end
|
159
|
+
|
160
|
+
it "runs child validations" do
|
161
|
+
child = stub
|
162
|
+
instance.validations << child
|
163
|
+
|
164
|
+
child.expects(:run).returns(stub(:results => {}))
|
165
|
+
instance.run
|
166
|
+
end
|
167
|
+
|
168
|
+
it "returns validator results object" do
|
169
|
+
child = described_class.new("biz baz")
|
170
|
+
instance.validations << child
|
171
|
+
|
172
|
+
child.stubs(:run).returns(stub(
|
173
|
+
:results => {
|
174
|
+
"biz baz" => {
|
175
|
+
:results => [
|
176
|
+
{ :response_headers => { :valid => true } }
|
177
|
+
]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
))
|
181
|
+
|
182
|
+
res = instance.run
|
183
|
+
expect(res.as_json).to eql(
|
184
|
+
instance.name => {
|
185
|
+
:results => [],
|
186
|
+
child.name => {
|
187
|
+
:results => [
|
188
|
+
{ :response_headers => { :valid => true } }
|
189
|
+
]
|
190
|
+
}
|
191
|
+
}
|
192
|
+
)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|