How to test modular Sinatra apps with Rack::Test

Ruby posted 2 months ago by christian

Let’s say you have this in your config.ru:

   1  run Rack::URLMap.new \
   2    "/" => HomeController.new,
   3    "/user" => UserController.new

and you want to test both / and /user at the same time.

The solution is to return an instance of Rack::Builder instead of, for example, HomeController, which this snippet does by reading config.ru and evaluating it:

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

The code was found on the internets.

Tagged sinatra, rack::test, urlmap

How to create a JSONP cross-domain webservice with Sinatra and Ruby

Ruby posted 4 months ago by christian

Your Sinatra app:

   1  get '/' do
   2      callback = params.delete('callback') # jsonp
   3      json = {'your' => 'data'}.to_json
   4  
   5      if callback
   6        content_type :js
   7        response = "#{callback}(#{json})" 
   8      else
   9        content_type :json
  10        response = json
  11      end
  12      response
  13    end

Your HTML:

   1  <script type="text/javascript">
   2      function parseResponse(json) {
   3      // Do something with the data
   4      }
   5      </script>
   6      <script type="text/javascript" src="http://xxx.com/?callback=parseResponse"></script>

You can also do the same with jQuery:

   1  $.ajax({
   2      type: 'get',
   3      url: '/',
   4      dataType: 'jsonp',
   5      success: function(data) {
   6        parseResponse(data);
   7      }
   8  })

Tagged json, jsonp, sinatra, jquery

How to fix "can't activate rack (= 0.9.1, runtime), already activated rack-1.0.0"

Ruby posted about 1 year ago by christian

The current version of Sinatra (0.9.2) requires Rack version 0.9.1:

   1  require 'rubygems'
   2  gem "rack", "0.9.1"
   3  require 'sinatra'

Tagged sinatra, rack

My Sinatra+Capistrano+Capinatra deployment recipe

Ruby posted about 1 year ago by christian

   1  require 'capistrano/version'
   2  require 'rubygems'
   3  require 'capinatra'
   4  load 'deploy' if respond_to?(:namespace) # cap2 differentiator
   5  
   6  # set an app_class if you're using the more recent style of creating
   7  # Sinatra apps, where app_class would be the name of your subclass
   8  # of Sinatra::Base. if you're just requiring 'sinatra' and using the
   9  # more traditional DSL style of Sinatra, then comment this line out.
  10  set :app_class, 'xxx'
  11  
  12  # standard settings
  13  set :app_file, "xxx.rb"
  14  set :application, "xxx"
  15  set :domain, "xxx.com"
  16  role :app, domain
  17  role :web, domain
  18  role :db,  domain, :primary => true
  19  
  20  set :ssh_options, { :forward_agent => true }
  21  
  22  #set :use_sudo, false
  23  
  24  # environment settings
  25  set :user, "xxx"
  26  set :group, "www-data"
  27  set :deploy_to, "/var/www/#{application}"
  28  set :deploy_via, :copy #:remote_cache
  29  default_run_options[:pty] = true
  30  
  31  # scm settings
  32  set :repository, "git@xxx.com:xxx.git"
  33  #set :repository, "file:///home/git/repositories/xxx.git"
  34  set :scm, "git"
  35  set :branch, "master"
  36  set :git_enable_submodules, 1
  37  
  38  # where the apache vhost will be generated
  39  set :apache_vhost_dir, "/etc/apache2/sites-enabled/"
  40  
  41  namespace :deploy do
  42    task :restart do
  43      run "touch #{current_path}/tmp/restart.txt"
  44    end
  45  end

Tagged capistrano, sinatra, capinatra

Testing sessions with Sinatra and Rack::Test

Ruby posted about 1 year ago by christian

You need support for testing sessions when, for example, testing authentication. The only way I’ve managed to get sessions to work with Sinatra and Rack::Test is by going through the whole stack, in other words calling the authentication controller as shown here:

   1  @user = Factory(:user) # create a dummy user
   2  User.expects(:authenticate).with(any_parameters).returns(@user) # make authenticate return the dummy user
   3  post "/sign-in", {:email => @user.email, :password => @user.password} # login to the application and set a session variable.

After this the session populated and we’re logged in when accessing the application again:

   1  post "/articles", {:title => 'Sessions suck', :body => '...'}

On a side note, there are two ways of specifying sessions that used to work, but which no longer work with Sinatra 1.0:

   1  get '/', :env => { :session => {:abc => 'adf'} }
   2  get '/', {}, :session => {:abc => 'adf'}
   3  get '/', {}, "rack.session" => {:abc => 'adf'}

The session is always empty.

There are many discussions about sessions and Rack::Test, but not one of them has a solution that works for me:

Tagged session, test, sinatra, rack, cookie, rack::test, mocha