Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 113 lines (95 sloc) 2.682 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
require 'sinatra/base'
require 'test/unit'

module Sinatra::Test
  include Rack::Utils

  attr_reader :app, :request, :response

  def mock_app(base=Sinatra::Base, &block)
    @app = Sinatra.new(base, &block)
  end

  undef request if method_defined?(:request)

  def request(verb, path, *args)
    fail "@app not set - cannot make request" if @app.nil?
    @request = Rack::MockRequest.new(@app)
    opts, input =
      case args.size
      when 2 # input, env
        input, env = args
        if input.kind_of?(Hash) # params, env
          [env, param_string(input)]
        else
          [env, input]
        end
      when 1 # params
        if (data = args.first).kind_of?(Hash)
          env = (data.delete(:env) || {})
          [env, param_string(data)]
        else
          [{}, data]
        end
      when 0
        [{}, '']
      else
        raise ArgumentError, "zero, one, or two arguments expected"
      end
    opts = rack_opts(opts)
    opts[:input] ||= input
    yield @request if block_given?
    @response = @request.request(verb, path, opts)
  end

  def get(path, *args, &b) ; request('GET', path, *args, &b) ; end
  def head(path, *args, &b) ; request('HEAD', path, *args, &b) ; end
  def post(path, *args, &b) ; request('POST', path, *args, &b) ; end
  def put(path, *args, &b) ; request('PUT', path, *args, &b) ; end
  def delete(path, *args, &b) ; request('DELETE', path, *args, &b) ; end

  def follow!
    request 'GET', @response.location
  end

  def should
    @response.should
  end

  def body
    @response.body
  end

  def status
    @response.status
  end

  RACK_OPT_NAMES = {
    :accept => "HTTP_ACCEPT",
    :agent => "HTTP_USER_AGENT",
    :host => "HTTP_HOST",
    :session => "HTTP_COOKIE",
    :cookies => "HTTP_COOKIE",
    :content_type => "CONTENT_TYPE"
  }

  def rack_opts(opts)
    opts.inject({}) do |hash,(key,val)|
      key = RACK_OPT_NAMES[key] || key
      hash[key] = val
      hash
    end
  end

  def env_for(opts={})
    opts = rack_opts(opts)
    Rack::MockRequest.env_for(opts)
  end

  def param_string(hash)
    hash.map { |pair| pair.map{|v|escape(v)}.join('=') }.join('&')
  end

  if defined? Sinatra::Compat
    # Deprecated. Use: "get" instead of "get_it".
    %w(get head post put delete).each do |verb|
      alias_method "#{verb}_it", verb
      remove_method verb
    end

    include Sinatra::Delegator

    # Deprecated. Tests no longer delegate missing methods to the
    # mock response. Use: @response
    def method_missing(name, *args, &block)
      if @response && @response.respond_to?(name)
        @response.send(name, *args, &block)
      else
        super
      end
    end
  end
end
Something went wrong with that request. Please try again.