File: spec_lock.rb

package info (click to toggle)
ruby-rack 1.4.1-2.1%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,312 kB
  • sloc: ruby: 11,357; makefile: 2
file content (142 lines) | stat: -rw-r--r-- 3,716 bytes parent folder | download
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
require 'rack/lock'
require 'rack/mock'

class Lock
  attr_reader :synchronized

  def initialize
    @synchronized = false
  end

  def synchronize
    @synchronized = true
    yield
  end

  def lock
    @synchronized = true
  end

  def unlock
    @synchronized = false
  end
end

describe Rack::Lock do
  describe 'Proxy' do
    should 'delegate each' do
      lock     = Lock.new
      env      = Rack::MockRequest.env_for("/")
      response = Class.new {
        attr_accessor :close_called
        def initialize; @close_called = false; end
        def each; %w{ hi mom }.each { |x| yield x }; end
      }.new

      app = Rack::Lock.new(lambda { |inner_env| [200, {}, response] }, lock)
      response = app.call(env)[2]
      list = []
      response.each { |x| list << x }
      list.should.equal %w{ hi mom }
    end

    should 'delegate to_path' do
      lock = Lock.new
      env  = Rack::MockRequest.env_for("/")

      res = ['Hello World']
      def res.to_path ; "/tmp/hello.txt" ; end

      app = Rack::Lock.new(lambda { |inner_env| [200, {}, res] }, lock)
      body = app.call(env)[2]

      body.should.respond_to :to_path
      body.to_path.should.equal "/tmp/hello.txt"
    end

    should 'not delegate to_path if body does not implement it' do
      lock = Lock.new
      env  = Rack::MockRequest.env_for("/")

      res = ['Hello World']

      app = Rack::Lock.new(lambda { |inner_env| [200, {}, res] }, lock)
      body = app.call(env)[2]

      body.should.not.respond_to :to_path
    end
  end

  should 'call super on close' do
    lock     = Lock.new
    env      = Rack::MockRequest.env_for("/")
    response = Class.new {
      attr_accessor :close_called
      def initialize; @close_called = false; end
      def close; @close_called = true; end
    }.new

    app = Rack::Lock.new(lambda { |inner_env| [200, {}, response] }, lock)
    app.call(env)
    response.close_called.should.equal false
    response.close
    response.close_called.should.equal true
  end

  should "not unlock until body is closed" do
    lock     = Lock.new
    env      = Rack::MockRequest.env_for("/")
    response = Object.new
    app      = Rack::Lock.new(lambda { |inner_env| [200, {}, response] }, lock)
    lock.synchronized.should.equal false
    response = app.call(env)[2]
    lock.synchronized.should.equal true
    response.close
    lock.synchronized.should.equal false
  end

  should "return value from app" do
    lock = Lock.new
    env  = Rack::MockRequest.env_for("/")
    body = [200, {}, %w{ hi mom }]
    app  = Rack::Lock.new(lambda { |inner_env| body }, lock)
    app.call(env).should.equal body
  end

  should "call synchronize on lock" do
    lock = Lock.new
    env = Rack::MockRequest.env_for("/")
    app = Rack::Lock.new(lambda { |inner_env|
      [200, {}, %w{ a b c }]
    }, lock)
    lock.synchronized.should.equal false
    app.call(env)
    lock.synchronized.should.equal true
  end

  should "unlock if the app raises" do
    lock = Lock.new
    env = Rack::MockRequest.env_for("/")
    app = Rack::Lock.new(lambda { raise Exception }, lock)
    lambda { app.call(env) }.should.raise(Exception)
    lock.synchronized.should.equal false
  end

  should "set multithread flag to false" do
    app = Rack::Lock.new(lambda { |env|
      env['rack.multithread'].should.equal false
      [200, {}, %w{ a b c }]
    })
    app.call(Rack::MockRequest.env_for("/"))
  end

  should "reset original multithread flag when exiting lock" do
    app = Class.new(Rack::Lock) {
      def call(env)
        env['rack.multithread'].should.equal true
        super
      end
    }.new(lambda { |env| [200, {}, %w{ a b c }] })
    app.call(Rack::MockRequest.env_for("/"))
  end
end