spec_forge 0.6.0 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +174 -8
- data/README.md +135 -10
- data/flake.lock +3 -3
- data/flake.nix +3 -3
- data/lib/spec_forge/attribute/factory.rb +1 -1
- data/lib/spec_forge/attribute/transform.rb +1 -1
- data/lib/spec_forge/callbacks.rb +9 -0
- data/lib/spec_forge/cli/docs/generate.rb +72 -0
- data/lib/spec_forge/cli/docs.rb +92 -0
- data/lib/spec_forge/cli/init.rb +39 -7
- data/lib/spec_forge/cli/new.rb +13 -3
- data/lib/spec_forge/cli/run.rb +12 -4
- data/lib/spec_forge/cli/serve.rb +156 -0
- data/lib/spec_forge/cli.rb +14 -6
- data/lib/spec_forge/configuration.rb +13 -9
- data/lib/spec_forge/context/store.rb +23 -40
- data/lib/spec_forge/core_ext/array.rb +27 -0
- data/lib/spec_forge/documentation/builder.rb +383 -0
- data/lib/spec_forge/documentation/document/operation.rb +47 -0
- data/lib/spec_forge/documentation/document/parameter.rb +22 -0
- data/lib/spec_forge/documentation/document/request_body.rb +24 -0
- data/lib/spec_forge/documentation/document/response.rb +39 -0
- data/lib/spec_forge/documentation/document/response_body.rb +27 -0
- data/lib/spec_forge/documentation/document.rb +48 -0
- data/lib/spec_forge/documentation/generators/base.rb +81 -0
- data/lib/spec_forge/documentation/generators/openapi/base.rb +100 -0
- data/lib/spec_forge/documentation/generators/openapi/error_formatter.rb +149 -0
- data/lib/spec_forge/documentation/generators/openapi/v3_0.rb +65 -0
- data/lib/spec_forge/documentation/generators/openapi.rb +59 -0
- data/lib/spec_forge/documentation/generators.rb +17 -0
- data/lib/spec_forge/documentation/loader/cache.rb +138 -0
- data/lib/spec_forge/documentation/loader.rb +159 -0
- data/lib/spec_forge/documentation/openapi/base.rb +33 -0
- data/lib/spec_forge/documentation/openapi/v3_0/example.rb +44 -0
- data/lib/spec_forge/documentation/openapi/v3_0/media_type.rb +42 -0
- data/lib/spec_forge/documentation/openapi/v3_0/operation.rb +175 -0
- data/lib/spec_forge/documentation/openapi/v3_0/response.rb +65 -0
- data/lib/spec_forge/documentation/openapi/v3_0/schema.rb +80 -0
- data/lib/spec_forge/documentation/openapi/v3_0/tag.rb +71 -0
- data/lib/spec_forge/documentation/openapi.rb +23 -0
- data/lib/spec_forge/documentation.rb +27 -0
- data/lib/spec_forge/error.rb +17 -0
- data/lib/spec_forge/factory.rb +2 -2
- data/lib/spec_forge/filter.rb +3 -4
- data/lib/spec_forge/forge.rb +5 -4
- data/lib/spec_forge/http/backend.rb +5 -0
- data/lib/spec_forge/http/request.rb +14 -3
- data/lib/spec_forge/loader.rb +14 -24
- data/lib/spec_forge/normalizer/default.rb +51 -0
- data/lib/spec_forge/normalizer/definition.rb +248 -0
- data/lib/spec_forge/normalizer/validators.rb +99 -0
- data/lib/spec_forge/normalizer.rb +356 -199
- data/lib/spec_forge/normalizers/_shared.yml +76 -0
- data/lib/spec_forge/normalizers/configuration.yml +23 -0
- data/lib/spec_forge/normalizers/constraint.yml +8 -0
- data/lib/spec_forge/normalizers/expectation.yml +47 -0
- data/lib/spec_forge/normalizers/factory.yml +12 -0
- data/lib/spec_forge/normalizers/factory_reference.yml +15 -0
- data/lib/spec_forge/normalizers/global_context.yml +28 -0
- data/lib/spec_forge/normalizers/spec.yml +50 -0
- data/lib/spec_forge/runner/adapter.rb +181 -0
- data/lib/spec_forge/runner/debug_proxy.rb +44 -42
- data/lib/spec_forge/runner/state.rb +4 -5
- data/lib/spec_forge/runner.rb +40 -124
- data/lib/spec_forge/spec/expectation/constraint.rb +13 -5
- data/lib/spec_forge/spec/expectation.rb +7 -3
- data/lib/spec_forge/spec.rb +13 -58
- data/lib/spec_forge/version.rb +1 -1
- data/lib/spec_forge.rb +30 -23
- data/lib/templates/openapi.yml.tt +22 -0
- data/lib/templates/redoc.html.tt +28 -0
- data/lib/templates/swagger.html.tt +59 -0
- metadata +92 -14
- data/lib/spec_forge/normalizer/configuration.rb +0 -90
- data/lib/spec_forge/normalizer/constraint.rb +0 -60
- data/lib/spec_forge/normalizer/expectation.rb +0 -105
- data/lib/spec_forge/normalizer/factory.rb +0 -78
- data/lib/spec_forge/normalizer/factory_reference.rb +0 -85
- data/lib/spec_forge/normalizer/global_context.rb +0 -88
- data/lib/spec_forge/normalizer/spec.rb +0 -97
- /data/lib/templates/{forge_helper.tt → forge_helper.rb.tt} +0 -0
- /data/lib/templates/{new_factory.tt → new_factory.yml.tt} +0 -0
- /data/lib/templates/{new_spec.tt → new_spec.yml.tt} +0 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
id: string
|
2
|
+
|
3
|
+
name: string
|
4
|
+
|
5
|
+
line_number: integer
|
6
|
+
|
7
|
+
base_url:
|
8
|
+
type: string
|
9
|
+
default: null
|
10
|
+
required: false
|
11
|
+
aliases:
|
12
|
+
- base_path
|
13
|
+
|
14
|
+
url:
|
15
|
+
type: string
|
16
|
+
default: null
|
17
|
+
required: false
|
18
|
+
aliases:
|
19
|
+
- path
|
20
|
+
|
21
|
+
http_verb:
|
22
|
+
type: string
|
23
|
+
default: null # Do not default this to "GET". Leave it null. Seriously.
|
24
|
+
required: false
|
25
|
+
aliases:
|
26
|
+
- method
|
27
|
+
- http_method
|
28
|
+
validator: http_verb
|
29
|
+
|
30
|
+
headers:
|
31
|
+
type: hash
|
32
|
+
default: {}
|
33
|
+
required: false
|
34
|
+
|
35
|
+
query:
|
36
|
+
type:
|
37
|
+
- hash
|
38
|
+
- string
|
39
|
+
aliases:
|
40
|
+
- params
|
41
|
+
default: {}
|
42
|
+
required: false
|
43
|
+
|
44
|
+
body:
|
45
|
+
type:
|
46
|
+
- hash
|
47
|
+
- string
|
48
|
+
aliases:
|
49
|
+
- data
|
50
|
+
default: {}
|
51
|
+
required: false
|
52
|
+
|
53
|
+
variables:
|
54
|
+
type:
|
55
|
+
- hash
|
56
|
+
- string
|
57
|
+
default: {}
|
58
|
+
required: false
|
59
|
+
|
60
|
+
debug:
|
61
|
+
type: boolean
|
62
|
+
aliases:
|
63
|
+
- pry
|
64
|
+
- breakpoint
|
65
|
+
default: false
|
66
|
+
required: false
|
67
|
+
|
68
|
+
callback:
|
69
|
+
type: string
|
70
|
+
required: false
|
71
|
+
validator: callback
|
72
|
+
|
73
|
+
documentation:
|
74
|
+
type: boolean
|
75
|
+
required: false
|
76
|
+
default: true
|
@@ -0,0 +1,23 @@
|
|
1
|
+
base_url: string
|
2
|
+
|
3
|
+
headers:
|
4
|
+
reference: headers
|
5
|
+
|
6
|
+
query:
|
7
|
+
reference: query
|
8
|
+
|
9
|
+
factories:
|
10
|
+
type: hash
|
11
|
+
default: {}
|
12
|
+
structure:
|
13
|
+
###########################################
|
14
|
+
auto_discover:
|
15
|
+
type: boolean
|
16
|
+
default: true
|
17
|
+
|
18
|
+
paths:
|
19
|
+
type: array
|
20
|
+
default: []
|
21
|
+
|
22
|
+
on_debug_proc:
|
23
|
+
type: proc
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Internal
|
2
|
+
id:
|
3
|
+
reference: id
|
4
|
+
|
5
|
+
line_number:
|
6
|
+
reference: line_number
|
7
|
+
|
8
|
+
# User defined
|
9
|
+
name:
|
10
|
+
reference: name
|
11
|
+
|
12
|
+
base_url:
|
13
|
+
reference: base_url
|
14
|
+
|
15
|
+
url:
|
16
|
+
reference: url
|
17
|
+
|
18
|
+
http_verb:
|
19
|
+
reference: http_verb
|
20
|
+
|
21
|
+
headers:
|
22
|
+
reference: headers
|
23
|
+
|
24
|
+
query:
|
25
|
+
reference: query
|
26
|
+
|
27
|
+
body:
|
28
|
+
reference: body
|
29
|
+
|
30
|
+
variables:
|
31
|
+
reference: variables
|
32
|
+
|
33
|
+
debug:
|
34
|
+
reference: debug
|
35
|
+
|
36
|
+
store_as:
|
37
|
+
type: string
|
38
|
+
default: ""
|
39
|
+
|
40
|
+
documentation:
|
41
|
+
reference: documentation
|
42
|
+
|
43
|
+
expect:
|
44
|
+
type: hash
|
45
|
+
structure:
|
46
|
+
###########################################
|
47
|
+
reference: constraint
|
@@ -0,0 +1,28 @@
|
|
1
|
+
variables:
|
2
|
+
reference: variables
|
3
|
+
|
4
|
+
callbacks:
|
5
|
+
type: array
|
6
|
+
default: []
|
7
|
+
structure:
|
8
|
+
###########################################
|
9
|
+
type: hash
|
10
|
+
default: {}
|
11
|
+
structure:
|
12
|
+
###########################################
|
13
|
+
before_file:
|
14
|
+
reference: callback
|
15
|
+
before_spec:
|
16
|
+
reference: callback
|
17
|
+
before_each:
|
18
|
+
reference: callback
|
19
|
+
aliases:
|
20
|
+
- before
|
21
|
+
after_each:
|
22
|
+
reference: callback
|
23
|
+
aliases:
|
24
|
+
- after
|
25
|
+
after_spec:
|
26
|
+
reference: callback
|
27
|
+
after_file:
|
28
|
+
reference: callback
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Internal
|
2
|
+
id:
|
3
|
+
reference: id
|
4
|
+
|
5
|
+
name:
|
6
|
+
reference: name
|
7
|
+
|
8
|
+
file_name: string
|
9
|
+
|
10
|
+
file_path: string
|
11
|
+
|
12
|
+
line_number:
|
13
|
+
reference: line_number
|
14
|
+
|
15
|
+
# User defined
|
16
|
+
base_url:
|
17
|
+
reference: base_url
|
18
|
+
|
19
|
+
url:
|
20
|
+
reference: url
|
21
|
+
|
22
|
+
http_verb:
|
23
|
+
reference: http_verb
|
24
|
+
|
25
|
+
headers:
|
26
|
+
reference: headers
|
27
|
+
|
28
|
+
query:
|
29
|
+
reference: query
|
30
|
+
|
31
|
+
body:
|
32
|
+
reference: body
|
33
|
+
|
34
|
+
variables:
|
35
|
+
reference: variables
|
36
|
+
|
37
|
+
debug:
|
38
|
+
reference: debug
|
39
|
+
|
40
|
+
documentation:
|
41
|
+
reference: documentation
|
42
|
+
|
43
|
+
expectations:
|
44
|
+
type: array
|
45
|
+
structure:
|
46
|
+
###########################################
|
47
|
+
type: hash
|
48
|
+
structure:
|
49
|
+
###########################################
|
50
|
+
reference: expectation
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SpecForge
|
4
|
+
class Runner
|
5
|
+
#
|
6
|
+
# Bridges SpecForge specs with RSpec execution
|
7
|
+
#
|
8
|
+
# Converts SpecForge forge objects into RSpec test structures
|
9
|
+
# and manages the test execution lifecycle.
|
10
|
+
#
|
11
|
+
class Adapter
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
#
|
15
|
+
# Configures RSpec with forge definitions
|
16
|
+
#
|
17
|
+
# Sets up RSpec and prepares everything for running tests
|
18
|
+
#
|
19
|
+
# @param forges [Array<Forge>] The forges to set up for testing
|
20
|
+
#
|
21
|
+
def self.setup(forges)
|
22
|
+
# Defines the forges with RSpec
|
23
|
+
forges.each { |forge| instance.describe(forge) }
|
24
|
+
|
25
|
+
# Disable autorun because RSpec does it
|
26
|
+
RSpec::Core::Runner.disable_autorun!
|
27
|
+
|
28
|
+
# Allows modifying the error backtrace reporting within rspec
|
29
|
+
RSpec.configuration.instance_variable_set(:@backtrace_formatter, BacktraceFormatter)
|
30
|
+
|
31
|
+
# Listen for passed/failed events to trigger the "after_each" callback
|
32
|
+
RSpec.configuration.reporter.register_listener(
|
33
|
+
Listener.instance,
|
34
|
+
:example_passed, :example_failed
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Executes the configured RSpec tests
|
40
|
+
#
|
41
|
+
# Runs all configured tests through RSpec with optional exit behavior.
|
42
|
+
#
|
43
|
+
# @param exit_on_finish [Boolean] Whether to exit the process when done
|
44
|
+
# @param exit_on_failure [Boolean] Whether to exit the process if any test fails
|
45
|
+
#
|
46
|
+
# @return [Integer, nil] Exit status if exit_on_finish is false
|
47
|
+
#
|
48
|
+
def self.run(exit_on_finish: false, exit_on_failure: false)
|
49
|
+
status = RSpec::Core::Runner.run([]).to_i
|
50
|
+
|
51
|
+
exit(status) if exit_on_finish || (exit_on_failure && status != 0)
|
52
|
+
|
53
|
+
status
|
54
|
+
end
|
55
|
+
|
56
|
+
##########################################################################
|
57
|
+
|
58
|
+
#
|
59
|
+
# Defines RSpec examples for a specific forge
|
60
|
+
# Creates the test structure for a single forge file
|
61
|
+
#
|
62
|
+
# @param forge [Forge] The forge to define
|
63
|
+
#
|
64
|
+
def describe(forge)
|
65
|
+
# This is just like writing a normal RSpec test, except with loops ;)
|
66
|
+
RSpec.describe(forge.name) do
|
67
|
+
# Callback for the file
|
68
|
+
before(:context) { Callbacks.before_file(forge) }
|
69
|
+
after(:context) { Callbacks.after_file(forge) }
|
70
|
+
|
71
|
+
# Specs
|
72
|
+
forge.specs.each do |spec|
|
73
|
+
# Describe the spec
|
74
|
+
describe(spec.name) do
|
75
|
+
# Request data is for the spec and contains the base and overlays
|
76
|
+
let!(:request_data) { forge.request[spec.id] }
|
77
|
+
|
78
|
+
# The HTTP client for the spec
|
79
|
+
let!(:http_client) { HTTP::Client.new(**request_data[:base]) }
|
80
|
+
|
81
|
+
# Callback for the spec
|
82
|
+
before(:context) { Callbacks.before_spec(forge, spec) }
|
83
|
+
after(:context) { Callbacks.after_spec(forge, spec) }
|
84
|
+
|
85
|
+
# Expectations
|
86
|
+
spec.expectations.each do |expectation|
|
87
|
+
# Onto the actual expectation itself
|
88
|
+
describe(expectation.name) do
|
89
|
+
# Set metadata for the example group for error reporting
|
90
|
+
Metadata.set_for_group(spec, expectation, self)
|
91
|
+
|
92
|
+
# Lazily load the constraints
|
93
|
+
let(:constraints) { expectation.constraints.as_matchers }
|
94
|
+
|
95
|
+
let(:match_status) { constraints[:status] }
|
96
|
+
let(:match_json) { constraints[:json] }
|
97
|
+
let(:match_json_class) { be_kind_of(match_json.class) }
|
98
|
+
let(:match_headers) { constraints[:headers] }
|
99
|
+
|
100
|
+
# The request for the test itself. Overlays the expectation's data if it exists
|
101
|
+
let(:request) do
|
102
|
+
request = request_data[:base]
|
103
|
+
|
104
|
+
if (overlay = request_data[:overlay][expectation.id])
|
105
|
+
request = request.deep_merge(overlay)
|
106
|
+
end
|
107
|
+
|
108
|
+
HTTP::Request.new(**request)
|
109
|
+
end
|
110
|
+
|
111
|
+
# The Faraday response
|
112
|
+
subject(:response) { http_client.call(request) }
|
113
|
+
|
114
|
+
# Callbacks for the expectation
|
115
|
+
before :each do
|
116
|
+
Callbacks.before_expectation(
|
117
|
+
forge, spec, expectation, self, RSpec.current_example
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
# The 'after_expectation' callback is handled by Listener due to RSpec not
|
122
|
+
# reporting the example's status until after the describe block has finished.
|
123
|
+
after :each do
|
124
|
+
# However, the downside about having the callback triggered later is that RSpec
|
125
|
+
# will have reset the memoized let variables back to nil.
|
126
|
+
# This causes an issue when an expectation goes to store the state, it will end
|
127
|
+
# up re-calling the various variables and triggering another HTTP request.
|
128
|
+
# Since the variables are still memoized in this hook, it is the perfect
|
129
|
+
# time to store the referenced to them.
|
130
|
+
State.set(response:)
|
131
|
+
end
|
132
|
+
|
133
|
+
# The test itself
|
134
|
+
it(expectation.constraints.description) do
|
135
|
+
# Debugging
|
136
|
+
if spec.debug? || expectation.debug?
|
137
|
+
Callbacks.on_debug(forge, spec, expectation, self)
|
138
|
+
end
|
139
|
+
|
140
|
+
############################################################
|
141
|
+
# Status check
|
142
|
+
expect(response.status).to match_status
|
143
|
+
|
144
|
+
############################################################
|
145
|
+
# Headers check
|
146
|
+
if match_headers.present?
|
147
|
+
match_headers.each do |key, matcher|
|
148
|
+
expect(response.headers).to include(key.downcase => matcher)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
############################################################
|
153
|
+
# JSON check
|
154
|
+
if match_json.present?
|
155
|
+
case match_json
|
156
|
+
when Hash
|
157
|
+
match_json.each do |key, matcher|
|
158
|
+
expect(response.body).to include(key)
|
159
|
+
|
160
|
+
begin
|
161
|
+
expect(response.body[key]).to matcher
|
162
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
163
|
+
# Add the key that failed to the front of the error message
|
164
|
+
e.message.insert(0, "Key: #{key.in_quotes}\n")
|
165
|
+
raise e
|
166
|
+
end
|
167
|
+
end
|
168
|
+
else
|
169
|
+
expect(response.body).to match_json
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -30,7 +30,46 @@ module SpecForge
|
|
30
30
|
# @return [Proc] The default debugging handler that outputs JSON state information
|
31
31
|
#
|
32
32
|
def self.default
|
33
|
-
|
33
|
+
lambda do
|
34
|
+
puts <<~STRING
|
35
|
+
|
36
|
+
Debug triggered for:
|
37
|
+
> #{example.metadata[:rerun_file_path]} on line #{expectation.line_number}
|
38
|
+
|
39
|
+
Available debugging contexts:
|
40
|
+
- spec: Current spec details
|
41
|
+
- expectation: Current expectation being tested
|
42
|
+
- variables: Variables defined for this test
|
43
|
+
- global: Global context shared across tests
|
44
|
+
- store: Stored data from expectations
|
45
|
+
|
46
|
+
Request & Response:
|
47
|
+
- request: HTTP request details (method, url, headers, body)
|
48
|
+
- response: HTTP response with headers, status and body
|
49
|
+
|
50
|
+
Expectations:
|
51
|
+
- expected_status: Expected HTTP status code
|
52
|
+
- expected_json: Expected response body structure
|
53
|
+
|
54
|
+
Matchers:
|
55
|
+
- match_status: Matcher used to test status
|
56
|
+
- match_json: Matcher used to test response body
|
57
|
+
|
58
|
+
Helper objects:
|
59
|
+
- http_client: The HTTP client used for the request
|
60
|
+
- request_data: Raw request configuration data
|
61
|
+
- example_group: Current RSpec example group
|
62
|
+
- example: Current RSpec example
|
63
|
+
- forge: Current file being tested
|
64
|
+
|
65
|
+
💡 Pro tips:
|
66
|
+
- Type 'self' or 'inspect' for a pretty-printed JSON overview
|
67
|
+
- Use 'to_h' for the hash representation
|
68
|
+
- Access the shared context with 'SpecForge.context'
|
69
|
+
STRING
|
70
|
+
|
71
|
+
puts inspect
|
72
|
+
end
|
34
73
|
end
|
35
74
|
|
36
75
|
# @return [RSpec::Forge] The current Forge that is being tested
|
@@ -67,7 +106,7 @@ module SpecForge
|
|
67
106
|
# @return [SpecForge::Runner::DebugProxy]
|
68
107
|
#
|
69
108
|
def initialize(forge, spec, expectation, example_group)
|
70
|
-
@callback = SpecForge.configuration.
|
109
|
+
@callback = SpecForge.configuration.on_debug_proc
|
71
110
|
|
72
111
|
@forge = forge
|
73
112
|
@spec = spec
|
@@ -90,43 +129,6 @@ module SpecForge
|
|
90
129
|
# @return [void]
|
91
130
|
#
|
92
131
|
def call
|
93
|
-
puts <<~STRING
|
94
|
-
|
95
|
-
Debug triggered for:
|
96
|
-
> #{example.metadata[:rerun_file_path]} on line #{expectation.line_number}
|
97
|
-
|
98
|
-
Available debugging contexts:
|
99
|
-
- spec: Current spec details
|
100
|
-
- expectation: Current expectation being tested
|
101
|
-
- variables: Variables defined for this test
|
102
|
-
- global: Global context shared across tests
|
103
|
-
- store: Stored data from expectations
|
104
|
-
|
105
|
-
Request & Response:
|
106
|
-
- request: HTTP request details (method, url, headers, body)
|
107
|
-
- response: HTTP response with headers, status and body
|
108
|
-
|
109
|
-
Expectations:
|
110
|
-
- expected_status: Expected HTTP status code
|
111
|
-
- expected_json: Expected response body structure
|
112
|
-
|
113
|
-
Matchers:
|
114
|
-
- match_status: Matcher used to test status
|
115
|
-
- match_json: Matcher used to test response body
|
116
|
-
|
117
|
-
Helper objects:
|
118
|
-
- http_client: The HTTP client used for the request
|
119
|
-
- request_data: Raw request configuration data
|
120
|
-
- example_group: Current RSpec example group
|
121
|
-
- example: Current RSpec example
|
122
|
-
- forge: Current file being tested
|
123
|
-
|
124
|
-
💡 Pro tips:
|
125
|
-
- Type 'self' or 'inspect' for a pretty-printed JSON overview
|
126
|
-
- Use 'to_h' for the hash representation
|
127
|
-
- Access the shared context with 'SpecForge.context'
|
128
|
-
STRING
|
129
|
-
|
130
132
|
instance_exec(&@callback)
|
131
133
|
end
|
132
134
|
|
@@ -179,14 +181,14 @@ module SpecForge
|
|
179
181
|
expectation_hash[:expect][:json] = matchers_to_description(expectation_hash[:expect][:json])
|
180
182
|
|
181
183
|
{
|
184
|
+
global:,
|
185
|
+
variables:,
|
186
|
+
request: request.to_h,
|
182
187
|
response: {
|
183
188
|
status: response.status,
|
184
189
|
body: response.body,
|
185
190
|
headers: response.headers
|
186
191
|
},
|
187
|
-
global:,
|
188
|
-
variables:,
|
189
|
-
request: request.to_h,
|
190
192
|
expectation: expectation_hash,
|
191
193
|
spec: spec_hash
|
192
194
|
}
|
@@ -87,11 +87,10 @@ module SpecForge
|
|
87
87
|
scope:,
|
88
88
|
request: request&.to_h,
|
89
89
|
variables: SpecForge.context.variables.deep_dup,
|
90
|
-
response
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
}
|
90
|
+
response:,
|
91
|
+
headers: response&.headers,
|
92
|
+
status: response&.status,
|
93
|
+
body: response&.body
|
95
94
|
)
|
96
95
|
end
|
97
96
|
end
|