Skip to content

Commit

Permalink
Add #find_definition method.
Browse files Browse the repository at this point in the history
  • Loading branch information
myronmarston committed Apr 3, 2012
1 parent 598a952 commit f109617
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
25 changes: 24 additions & 1 deletion lib/interpol/configuration.rb
Expand Up @@ -3,6 +3,28 @@
require 'yaml'

module Interpol
module DefinitionFinder
include HashFetcher
NoDefinitionFound = Class.new

def find_definition(options)
method, path, version = extract_search_options_from(options)
endpoint = find { |e| e.method == method && e.route_matches?(path) }
return NoDefinitionFound if endpoint.nil?
endpoint.definitions.find { |d| d.version == version } || NoDefinitionFound
end

private

def extract_search_options_from(options)
method = fetch_from(options, :method).downcase.to_sym
path = fetch_from(options, :path)
version = fetch_from(options, :version)

return method, path, version
end
end

# Public: Defines interpol configuration.
class Configuration
attr_reader :endpoint_definition_files, :endpoints
Expand All @@ -11,12 +33,13 @@ def initialize
api_version do
raise ConfigurationError, "api_version has not been configured"
end
self.endpoint_definition_files = []
end

def endpoint_definition_files=(files)
@endpoints = files.map do |file|
Endpoint.new(YAML.load_file file)
end
end.extend(DefinitionFinder)
@endpoint_definition_files = files
end

Expand Down
66 changes: 66 additions & 0 deletions spec/unit/interpol/configuration_spec.rb
Expand Up @@ -2,6 +2,64 @@
require 'interpol/configuration'

module Interpol
describe DefinitionFinder do
describe '#find_definition' do
def endpoint(method, route, *versions)
Endpoint.new \
'name' => 'endpoint_name',
'route' => route,
'method' => method,
'definitions' => [{
'versions' => versions,
'schema' => {},
'examples' => {}
}]
end

let(:endpoint_1) { endpoint 'GET', '/users/:user_id/overview', '1.3' }
let(:endpoint_2) { endpoint 'POST', '/foo/bar', '2.3', '2.7' }
let(:all_endpoints) { [endpoint_1, endpoint_2].extend(DefinitionFinder) }

def find(*args)
all_endpoints.find_definition(*args)
end

it 'finds a matching endpoint' do
found = find(method: 'POST', path: '/foo/bar', version: '2.3')
found.endpoint.should be(endpoint_2)
found.version.should eq('2.3')
end

it 'finds the correct version of the endpoint' do
found = find(method: 'POST', path: '/foo/bar', version: '2.7')
found.version.should eq('2.7')
end

it 'returns NoDefinitionFound if it cannot find a matching route' do
result = find(method: 'POST', path: '/goo/bar', version: '2.7')
result.should be(DefinitionFinder::NoDefinitionFound)
end

it 'returns nil if the endpoint does not have a matching version' do
result = find(method: 'POST', path: '/foo/bar', version: '13.7')
result.should be(DefinitionFinder::NoDefinitionFound)
end

it 'handles route params properly' do
found = find(method: 'GET', path: '/users/17/overview', version: '1.3')
found.endpoint.should be(endpoint_1)
end

[:method, :path, :version].each do |key|
it "raises a helpful error if you do not include #{key.inspect} in the options" do
options = { method: 'POST', path: '/foo/bar', version: '2.3' }
options.delete(key)
expect { find(options) }.to raise_error(/key not found.*#{key}/)
end
end
end
end

describe Configuration do
let(:config) { Configuration.new }

Expand Down Expand Up @@ -51,6 +109,14 @@ module Interpol
config.endpoint_definition_files = Dir["#{dir}/*.yml"]
endpoints1.should_not equal(config.endpoints)
end

it 'returns a blank array if no definition files have been set' do
config.endpoints.should eq([])
end

it 'provides a method to easily find an endpoint definition' do
config.endpoints.should respond_to(:find_definition)
end
end

describe "#api_version" do
Expand Down

0 comments on commit f109617

Please sign in to comment.