class Apib::MockServer

Rack compatible mock server from an API Blueprint document.

Example:

require "apib/mock_server"
require "webmock"
base_url = "http://test.com"
blueprint = Rails.root.join("api-blueprints", "my.apib").read
app = Apib::MockServer.new(base_url, blueprint)
WebMock::StubRegistry.instance.register_request_stub(
  WebMock::RequestStub.new(:any, /#{base_url}/)
).to_rack(app)

Constants

VERSION

Public Class Methods

new(base_url, blueprint) click to toggle source
# File lib/apib/mock_server.rb, line 20
def initialize(base_url, blueprint)
  @mocks = {}
  ast(blueprint).resource_groups.flat_map(&:resources).each do |resource|
    uri_template = Addressable::Template.new(base_url.to_s +
                                             resource.uri_template)
    @mocks[uri_template] = resource.actions.map { |a| [a.method, a] }.to_h
  end
end

Public Instance Methods

call(env) click to toggle source
# File lib/apib/mock_server.rb, line 29
def call(env)
  request = Rack::Request.new(env)
  action = match(request)
  return [404, {}, []] unless action
  responses(action).first || [500, {}, []]
end
headers(response) click to toggle source
# File lib/apib/mock_server.rb, line 47
def headers(response)
  response.headers.collection.map { |h| [h[:name], h[:value]] }.to_h
end
match(request) click to toggle source
# File lib/apib/mock_server.rb, line 36
def match(request)
  template = @mocks.keys.find { |uri| uri.match(request.url) }
  @mocks[template][request.request_method] if template
end
responses(action) click to toggle source
# File lib/apib/mock_server.rb, line 41
def responses(action)
  action.examples.flat_map(&:responses).map do |response|
    [response.name.to_i, headers(response), [response.body]]
  end
end

Private Instance Methods

ast(blueprint) click to toggle source
# File lib/apib/mock_server.rb, line 53
def ast(blueprint)
  RedSnow.parse(blueprint.is_a?(IO) ? blueprint.read : blueprint).ast
end