Permalink
Browse files

Update identity map middleware.

Works with newer rack api of each and close.

Also, enables identity map for request and then disables, rather than
just always having it on.
  • Loading branch information...
1 parent 9f9a0a9 commit aaadd84c0a44dc672e7c07197ca122173fa48874 @jnunemaker jnunemaker committed Jul 9, 2012
Showing with 131 additions and 14 deletions.
  1. +23 −4 lib/mongo_mapper/middleware/identity_map.rb
  2. +108 −10 test/unit/test_identity_map_middleware.rb
@@ -1,16 +1,35 @@
module MongoMapper
module Middleware
class IdentityMap
+ class Body
+ def initialize(target, original)
+ @target = target
+ @original = original
+ end
+
+ def each(&block)
+ @target.each(&block)
+ end
+
+ def close
+ @target.close if @target.respond_to?(:close)
+ ensure
+ MongoMapper::Plugins::IdentityMap.enabled = @original
+ MongoMapper::Plugins::IdentityMap.clear
+ end
+ end
+
def initialize(app)
@app = app
end
def call(env)
MongoMapper::Plugins::IdentityMap.clear
- @app.call(env)
- ensure
- MongoMapper::Plugins::IdentityMap.clear
+ enabled = MongoMapper::Plugins::IdentityMap.enabled
+ MongoMapper::Plugins::IdentityMap.enabled = true
+ status, headers, body = @app.call(env)
+ [status, headers, Body.new(body, enabled)]
end
end
end
-end
+end
@@ -7,28 +7,126 @@ class IdentityMapMiddlewareTest < Test::Unit::TestCase
def app
@app ||= Rack::Builder.new do
use MongoMapper::Middleware::IdentityMap
+
map "/" do
run lambda {|env| [200, {}, []] }
end
+
map "/fail" do
run lambda {|env| raise "FAIL!" }
end
end.to_app
end
- context "with a successful request" do
- should "clear the identity map" do
- MongoMapper::Plugins::IdentityMap.expects(:clear).twice
- get '/'
+ context "" do
+ setup do
+ @enabled = MongoMapper::Plugins::IdentityMap.enabled
+ MongoMapper::Plugins::IdentityMap.enabled = false
end
- end
- context "when the request raises an error" do
- should "clear the identity map" do
- MongoMapper::Plugins::IdentityMap.expects(:clear).twice
- get '/fail' rescue nil
+ teardown do
+ MongoMapper::Plugins::IdentityMap.enabled = @enabled
end
- end
+ should "delegate" do
+ called = false
+ mw = MongoMapper::Middleware::IdentityMap.new lambda { |env|
+ called = true
+ [200, {}, nil]
+ }
+ mw.call({})
+ called.should be_true
+ end
+
+ should "enable identity map during delegation" do
+ mw = MongoMapper::Middleware::IdentityMap.new lambda { |env|
+ MongoMapper::Plugins::IdentityMap.should be_enabled
+ [200, {}, nil]
+ }
+ mw.call({})
+ end
+
+ class Enum < Struct.new(:iter)
+ def each(&b)
+ iter.call(&b)
+ end
+ end
+
+ should "enable IM for body each" do
+ mw = MongoMapper::Middleware::IdentityMap.new lambda { |env|
+ [200, {}, Enum.new(lambda { |&b|
+ MongoMapper::Plugins::IdentityMap.should be_enabled
+ b.call "hello"
+ })]
+ }
+ body = mw.call({}).last
+ body.each { |x| x.should eql('hello') }
+ end
+
+ should "disable IM after body close" do
+ mw = MongoMapper::Middleware::IdentityMap.new lambda { |env| [200, {}, []] }
+ body = mw.call({}).last
+ MongoMapper::Plugins::IdentityMap.should be_enabled
+ body.close
+ MongoMapper::Plugins::IdentityMap.should_not be_enabled
+ end
+
+ should "clear IM after body close" do
+ mw = MongoMapper::Middleware::IdentityMap.new lambda { |env| [200, {}, []] }
+ body = mw.call({}).last
+
+ MongoMapper::Plugins::IdentityMap.repository['hello'] = 'world'
+ MongoMapper::Plugins::IdentityMap.repository.should_not be_empty
+ body.close
+
+ MongoMapper::Plugins::IdentityMap.repository.should be_empty
+ end
+
+ context "with a successful request" do
+ should "clear the identity map" do
+ MongoMapper::Plugins::IdentityMap.expects(:clear).twice
+ get '/'
+ end
+ end
+
+ context "when the request raises an error" do
+ should "clear the identity map" do
+ MongoMapper::Plugins::IdentityMap.expects(:clear).once
+ get '/fail' rescue nil
+ end
+ end
+ end
end
+
+# class IdentityMapMiddlewareTest < Test::Unit::TestCase
+# include Rack::Test::Methods
+
+# def app
+# @app ||= Rack::Builder.new do
+# use MongoMapper::Middleware::IdentityMap
+# map "/" do
+# run lambda {|env| [200, {}, []] }
+# end
+# map "/fail" do
+# run lambda {|env| raise "FAIL!" }
+# end
+# end.to_app
+# end
+
+# context "with a successful request" do
+# should "clear the identity map" do
+# MongoMapper::Plugins::IdentityMap.expects(:clear).twice
+# get '/'
+# end
+# end
+
+# context "when the request raises an error" do
+# should "clear the identity map" do
+# MongoMapper::Plugins::IdentityMap.expects(:clear).twice
+# get '/fail' rescue nil
+# end
+# end
+
+
+# end

0 comments on commit aaadd84

Please sign in to comment.