Commit aa1707d6 by andrew morton

Don't require optional parameters to have value

Fixes #20 Also starts adding some rdocs.
parent 251f26f6
......@@ -12,6 +12,8 @@ module RSpec
data[value]
end
##
# Look up parameter or definition references.
def resolve_ref(ref)
unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref
raise ArgumentError, "Invalid reference: #{ref}"
......
......@@ -4,10 +4,17 @@ module RSpec
class RequestBuilder
attr_reader :metadata, :instance
##
# Creates a new RequestBuilder from the Example class's +metadata+ hash
# and a test +instance+ that we can use to populate the parameter
# values.
def initialize(metadata, instance)
@metadata, @instance = metadata, instance
end
##
# Finds the Document associated with this request so things like schema
# and parameter references can be resolved.
def document
@document ||= begin
name = metadata[:swagger_document]
......@@ -27,6 +34,9 @@ module RSpec
Array(metadata[:swagger_operation][:consumes]).presence || Array(document[:consumes])
end
##
# Returns parameters defined in the operation and path item. Providing
# a +location+ will limit the parameters by their `in` value.
def parameters location = nil
path_item = metadata[:swagger_path_item] || {}
operation = metadata[:swagger_operation] || {}
......@@ -39,12 +49,10 @@ module RSpec
end
def parameter_values location
# Don't bother looking at the full parameter bodies since all we need
# are location and name which are in the key.
values = parameters(location)
.keys
.map{ |k| k.split('&').last }
.map{ |name| [name, instance.send(name)] }
values = parameters(location).
map{ |_, p| p['$ref'] ? document.resolve_ref(p['$ref']) : p }.
select{ |p| p[:required] || instance.respond_to?(p[:name]) }.
map{ |p| [p[:name], instance.send(p[:name])] }
Hash[values]
end
......
......@@ -98,15 +98,19 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
describe '#parameters' do
subject { described_class.new(metadata, double('instance')) }
let(:metadata) { {
swagger_path_item: { parameters: {
let(:metadata) do
{
swagger_path_item: {
parameters: {
'path&petId' => { name: 'petId', in: :path, description: 'path' },
'query&site' => { name: 'site', in: :query }
} },
swagger_operation: { parameters: {
'path&petId' => { name: 'petId', in: :path, description: 'op' }
} },
} }
}
},
swagger_operation: {
parameters: { 'path&petId' => { name: 'petId', in: :path, description: 'op' } }
}
}
end
it 'merges values from the path and operation' do
expect(subject.parameters).to eq({
......@@ -116,6 +120,56 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
end
end
describe '#parameter_values' do
subject { described_class.new(metadata, instance) }
let(:metadata) do
{
swagger_operation: {
parameters: {
"query&date" => { "$ref" => "#/parameters/filter_date" },
"query&subscriber" => { name: "subscriber", type: :string, in: :query, required: required }
}
}
}
end
let(:instance) { double('instance') }
before do
expect(subject).to receive_message_chain(:document, :resolve_ref) do
{ name: "date", type: :integer, in: :query, required: required }
end
end
context 'required parameters' do
let(:required) { true }
it 'includes defined values' do
allow(instance).to receive(:date) { 10 }
allow(instance).to receive(:subscriber) { false }
expect(subject.parameter_values(:query)).to eq({ 'date' => 10, 'subscriber' => false })
end
it 'undefined cause errors' do
expect{ subject.parameter_values(:query) }.to raise_exception(RSpec::Mocks::MockExpectationError)
end
end
context 'optional parameters' do
let(:required) { false }
it 'includes defined values' do
allow(instance).to receive(:date) { 27 }
allow(instance).to receive(:subscriber) { true }
expect(subject.parameter_values(:query)).to eq({ 'date' => 27, 'subscriber' => true })
end
it 'ommits undefined values' do
expect(subject.parameter_values(:query)).to eq({})
end
end
end
describe '#headers' do
subject { described_class.new(double('metadata'), instance) }
let(:instance) { double('instance') }
......@@ -170,7 +224,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
context 'with header params' do
it 'returns them in a string' do
expect(subject).to receive(:parameters).with(:header) { {
'header&X-Magic' => { same: :here }
'header&X-Magic' => { name: 'X-Magic', in: :header }
} }
expect(instance).to receive('X-Magic'.to_sym) { :pickles }
......@@ -221,7 +275,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
context 'with query params' do
it 'returns them in a string' do
expect(subject).to receive(:parameters).with(:query) { {
'query&site' => { same: :here }
'query&site' => { name: 'site', in: :query }
} }
expect(instance).to receive(:site) { :pickles }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment