views:

511

answers:

3

I'm building out a medium-sized application using Sinatra and all was well when I had a single app.rb file and I followed Aslak's guidance up on Github:

http://wiki.github.com/aslakhellesoy/cucumber/sinatra

As the app grew a bit larger and the app.rb file started to bulge, I refactored out a lot of of the bits into "middleware" style modules using Sinatra::Base, mapping things using a rack-up file (config.ru) etc.

The app works nicely - but my specs blew up as there was no more app.rb file for webrat to run against (as defined in the link above).

I've tried to find examples on how to work this - and I think I'm just not used to the internal guts of Cuke just yet as I can't find a single way to have it cover all the apps. I tried just pointing to "config.ru" instead of app.rb - but that doesn't work.

What I ended up doing - which is completely hackish - is to have a separate app.rb file in my support directory, which has all the requires stuff so I can at least test the model stuff. I can also specify routes in there - but that's not at all what I want to do.

So - the question is: how can I get Cucumber to properly work with the modular app approach?

+2  A: 

Update to include dealing with multiple Sinatra apps

Require the file where your app comes together and change

  def app
    Sinatra::Application
  end

to

 def app
    Rack::Builder.new do
      map '/a' { run MyAppA }
      map '/b' { run MyAppB }
    end
  end

and just test the app proper.

eg, if you define middleware in your config.ru that you want to test, maybe move loading those into your app's definition.

BaroqueBobcat
That makes sense - but I have 3 apps - that's the part I'm struggling with.
Rob Conery
You could wrap your apps in a Rack::Builder instance.
BaroqueBobcat
You're a star - very close... but it pushed me in the right direction and thank you. I'll add the code below :)
Rob Conery
+1  A: 

Thanks to Mr. BaroqueBobcat - the answer now, of course, seems so damn obvious :). Here's the env.rb (/features/support/env.rb):

require 'sinatra'
require 'test/unit'
require 'spec/expectations'
require 'rack/test'
require 'webrat'
require 'app1'
require 'app2'
require 'app3'

Webrat.configure do |config|
  config.mode = :rack
end

class MyWorld
  require 'test/unit'

  set :environment, :test

  include Rack::Test::Methods
  include Webrat::Methods
  include Webrat::Matchers

  Webrat::Methods.delegate_to_session :response_code, :response_body, :response

  def app
    Rack::Builder.new do
      map '/' do
        run App1 #important - this is the class name
      end
      map '/app1' do
        run App2
      end
      map '/app2' do
        run App3
      end
    end
  end
end

World do
  MyWorld.new

end
Rob Conery
A: 

https://gist.github.com/28d510d9fc25710192bc

def app
  eval "Rack::Builder.new {( " + File.read(File.dirname(__FILE__) + '/../config.ru') + "\n )}"
end
Tim Connor