require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) describe "DataMapper::IdentityMap" do before(:all) do class Cow include DataMapper::Resource property :id, Integer, :key => true property :name, String end class Chicken include DataMapper::Resource property :name, String end class Pig include DataMapper::Resource property :id, Integer, :key => true property :composite, Integer, :key => true property :name, String end end it "should use a second level cache if created with on" it "should return nil on #get when it does not find the requested instance" do map = DataMapper::IdentityMap.new map.get([23]).should be_nil end it "should return an instance on #get when it finds the requested instance" do betsy = Cow.new({:id=>23,:name=>'Betsy'}) map = DataMapper::IdentityMap.new map.set(betsy.key, betsy) map.get([23]).should == betsy end it "should store an instance on #set" do betsy = Cow.new({:id=>23,:name=>'Betsy'}) map = DataMapper::IdentityMap.new map.set(betsy.key, betsy) map.get([23]).should == betsy end it "should store instances with composite keys on #set" do pig = Pig.new({:id=>1,:composite=>1,:name=> 'Pig'}) piggy = Pig.new({:id=>1,:composite=>2,:name=>'Piggy'}) map = DataMapper::IdentityMap.new map.set(pig.key, pig) map.set(piggy.key, piggy) map.get([1,1]).should == pig map.get([1,2]).should == piggy end it "should remove an instance on #delete" do betsy = Cow.new({:id=>23,:name=>'Betsy'}) map = DataMapper::IdentityMap.new map.set(betsy.key, betsy) map.delete([23]) map.get([23]).should be_nil end end describe "Second Level Caching" do before :all do @mock_class = Class.new do def get(key); raise NotImplementedError end def set(key, instance); raise NotImplementedError end def delete(key); raise NotImplementedError end end end it 'should expose a standard API' do cache = @mock_class.new cache.should respond_to(:get) cache.should respond_to(:set) cache.should respond_to(:delete) end it 'should provide values when the first level cache entry is empty' do cache = @mock_class.new key = %w[ test ] cache.should_receive(:get).with(key).and_return('resource') map = DataMapper::IdentityMap.new(cache) map.get(key).should == 'resource' end it 'should be set when the first level cache entry is set' do cache = @mock_class.new betsy = Cow.new(:id => 23, :name => 'Betsy') cache.should_receive(:set).with(betsy.key, betsy).and_return(betsy) map = DataMapper::IdentityMap.new(cache) map.set(betsy.key, betsy).should == betsy end it 'should be deleted when the first level cache entry is deleted' do cache = @mock_class.new betsy = Cow.new(:id => 23, :name => 'Betsy') cache.stub!(:set) cache.should_receive(:delete).with(betsy.key).and_return(betsy) map = DataMapper::IdentityMap.new(cache) map.set(betsy.key, betsy).should == betsy map.delete(betsy.key).should == betsy end it 'should not provide values when the first level cache entry is full' do cache = @mock_class.new betsy = Cow.new(:id => 23, :name => 'Betsy') cache.stub!(:set) cache.should_not_receive(:get) map = DataMapper::IdentityMap.new(cache) map.set(betsy.key, betsy).should == betsy map.get(betsy.key).should == betsy end end