Permalink
Browse files

Create a builder for generating the application

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...
1 parent 50583d4 commit 4bd9a23d9802a361a5fbc66614e853a370054946 @vanstee committed Jul 2, 2012
Showing with 100 additions and 0 deletions.
  1. +1 −0 hovercraft.gemspec
  2. +39 −0 lib/hovercraft/builder.rb
  3. +60 −0 spec/hovercraft/builder_spec.rb
View
@@ -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'
View
@@ -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|
@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.

@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
@@ -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.