Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 161 lines (136 sloc) 3.865 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
require File.expand_path('../helper', __FILE__)

class DelegatorTest < Test::Unit::TestCase
  class Mirror
    attr_reader :last_call
    def method_missing(*a, &b)
      @last_call = [*a.map(&:to_s)]
      @last_call << b if b
    end
  end

  def self.delegates(name)
    it "delegates #{name}" do
      m = mirror { send name }
      assert_equal [name.to_s], m.last_call
    end

    it "delegates #{name} with arguments" do
      m = mirror { send name, "foo", "bar" }
      assert_equal [name.to_s, "foo", "bar"], m.last_call
    end

    it "delegates #{name} with block" do
      block = proc { }
      m = mirror { send(name, &block) }
      assert_equal [name.to_s, block], m.last_call
    end
  end

  setup do
    @target_was = Sinatra::Delegator.target
  end

  def teardown
    Sinatra::Delegator.target = @target_was
  end

  def delegation_app(&block)
    mock_app { Sinatra::Delegator.target = self }
    delegate(&block)
  end

  def mirror(&block)
    mirror = Mirror.new
    Sinatra::Delegator.target = mirror
    delegate(&block)
  end

  def delegate(&block)
    assert Sinatra::Delegator.target != Sinatra::Application
    Object.new.extend(Sinatra::Delegator).instance_eval(&block) if block
    Sinatra::Delegator.target
  end

  def target
    Sinatra::Delegator.target
  end

  it 'defaults to Sinatra::Application as target' do
    assert_equal Sinatra::Application, Sinatra::Delegator.target
  end

  %w[get put post delete options patch link unlink].each do |verb|
    it "delegates #{verb} correctly" do
      delegation_app do
        send(verb, '/hello') { 'Hello World' }
      end

      request = Rack::MockRequest.new(@app)
      response = request.request(verb.upcase, '/hello', {})
      assert response.ok?
      assert_equal 'Hello World', response.body
    end
  end

  it "delegates head correctly" do
    delegation_app do
      head '/hello' do
        response['X-Hello'] = 'World!'
        'remove me'
      end
    end

    request = Rack::MockRequest.new(@app)
    response = request.request('HEAD', '/hello', {})
    assert response.ok?
    assert_equal 'World!', response['X-Hello']
    assert_equal '', response.body
  end

  it "registers extensions with the delegation target" do
    app, mixin = mirror, Module.new
    Sinatra.register mixin
    assert_equal ["register", mixin.to_s], app.last_call
  end

  it "registers helpers with the delegation target" do
    app, mixin = mirror, Module.new
    Sinatra.helpers mixin
    assert_equal ["helpers", mixin.to_s], app.last_call
  end

  it "registers middleware with the delegation target" do
    app, mixin = mirror, Module.new
    Sinatra.use mixin
    assert_equal ["use", mixin.to_s], app.last_call
  end

  it "should work with method_missing proxies for options" do
    mixin = Module.new do
      def respond_to?(method, *)
        method.to_sym == :options or super
      end

      def method_missing(method, *args, &block)
        return super unless method.to_sym == :options
        {:some => :option}
      end
    end

    value = nil
    mirror do
      extend mixin
      value = options
    end

    assert_equal({:some => :option}, value)
  end

  it "delegates crazy method names" do
    Sinatra::Delegator.delegate "foo:bar:"
    method = mirror { send "foo:bar:" }.last_call.first
    assert_equal "foo:bar:", method
  end

  delegates 'get'
  delegates 'patch'
  delegates 'put'
  delegates 'post'
  delegates 'delete'
  delegates 'head'
  delegates 'options'
  delegates 'template'
  delegates 'layout'
  delegates 'before'
  delegates 'after'
  delegates 'error'
  delegates 'not_found'
  delegates 'configure'
  delegates 'set'
  delegates 'mime_type'
  delegates 'enable'
  delegates 'disable'
  delegates 'use'
  delegates 'development?'
  delegates 'test?'
  delegates 'production?'
  delegates 'helpers'
  delegates 'settings'
end
Something went wrong with that request. Please try again.