Skip to content

Commit

Permalink
Create a builder for generating the application
Browse files Browse the repository at this point in the history
Pull together the models we loaded earlier and a sinatra application
with the generate action methods registered to create the full
application.
  • Loading branch information
vanstee committed Jul 2, 2012
1 parent 50583d4 commit 4bd9a23
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions hovercraft.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
gem.version = Hovercraft::VERSION

gem.add_dependency 'sinatra-activerecord'
gem.add_dependency 'rack-contrib'

gem.add_development_dependency 'rspec'
gem.add_development_dependency 'pry'
Expand Down
39 changes: 39 additions & 0 deletions lib/hovercraft/builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'hovercraft/loader'
require 'hovercraft/actions'
require 'sinatra/base'
require 'rack/contrib'
require 'forwardable'

module Hovercraft
class Builder
extend Forwardable

def_delegator :@loader, :with_each_model

def initialize
@loader = Loader.new
end

def application
application = Sinatra.new
application = configure(application)
application = generate_routes(application)
application
end

def configure(application)
application.register(Hovercraft::Actions)
application.use(Rack::PostBodyContentTypeParser)
application
end

def generate_routes(application)
with_each_model do |model_class, model_name, plural_model_name|
application.methods.grep(/generate/).each do |action|

This comment has been minimized.

Copy link
@aubreyrhodes

aubreyrhodes Jul 10, 2012

Ah, this is cool. I hadn't actually seen this pattern before. It might make sense to document the application class to mention that all of the generate methods need the same signature in case you ever add one in the future.

This comment has been minimized.

Copy link
@vanstee

vanstee Jul 10, 2012

Owner

Not a bad idea. While this is nifty it's probably too magical. I should probably just define all the methods to load or just call all the ones defined in the mixin.

application.send(action, model_class, model_name, plural_model_name)
end
end
application
end
end
end
60 changes: 60 additions & 0 deletions spec/hovercraft/builder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'hovercraft/builder'

describe Hovercraft::Builder do
let(:model) { stub(name: 'Robot') }
let(:models) { Array.new(3) { model } }
let(:params) { models.map { |m| [m, 'robot', 'robots'] } }

before do
subject.stub(:with_each_model).
and_yield(*params[0]).
and_yield(*params[1]).
and_yield(*params[2])
end

describe '#application' do
it 'creates a sinatra application' do
subject.application.ancestors.should include(Sinatra::Base)
end

it 'configures the application' do
subject.should_receive(:configure)

subject.application
end

it 'generates routes for the application' do
subject.should_receive(:generate_routes)

subject.application
end
end

describe '#configure' do
let(:application) { stub(register: nil, use: nil) }

it 'registers the methods to generate actions' do
application.should_receive(:register).with(Hovercraft::Actions)

subject.configure(application)
end

it 'uses a post body parsing middleware' do
application.should_receive(:use).with(Rack::PostBodyContentTypeParser)

subject.configure(application)
end
end

describe '#generate_routes' do
let(:application) { stub }

it 'calls all generate methods for each model' do
[:index, :create, :show, :update, :destroy].each do |action|
application.should_receive("generate_#{action}").exactly(3).times
end

subject.generate_routes(application)
end
end
end

0 comments on commit 4bd9a23

Please sign in to comment.