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
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
class ExpensiveClass
attr_writer :x, :y
include DirtyMemoize
def initialize
@a=nil
@b=nil
@x='x'
@y='y'
end
def set_a(aa)
@a=aa
end
def compute
@a=@x
@b=@y
end
def a
"@a=#{@a}"
end
def b
"@b=#{@b}"
end
dirty_writer :x, :y
dirty_memoize :a, :b
end
class ExpensiveClass2 < ExpensiveClass
DIRTY_COMPUTE=:compute2
def compute2
@a=@x+".2"
end
end
describe DirtyMemoize, "extended object" do
before do
@ec=ExpensiveClass.new
end
subject { @ec }
context "when instanciated" do
it { should be_dirty}
it "should initialize with number of computation to 0" do
@ec.compute_count.should==0
end
it "read inmediatly the correct value" do
@ec.a.should=='@a=x'
end
end
context "when reads 'dirty' attributes " do
before do
@ec.a
end
it 'call compute' do
@ec.compute_count.should==1
end
it{ should_not be_dirty}
it "call compute once and only once" do
5.times {@ec.a}
@ec.compute_count.should==1
end
end
context "calls dirty writers before dirty getter" do
before do
@ec.x="cache"
end
it { should be_dirty}
it "doesn't compute anything" do
@ec.compute_count.should==0
end
it "doesn't change internal variables" do
@ec.instance_variable_get("@a").should be_nil
end
end
describe "when calls dirty getter after call dirty writer" do
before do
@ec.x="cache"
@ec.a
end
it { @ec.should_not be_dirty}
it "calls compute only once" do
@ec.compute_count.should==1
end
it "set value of internal variable" do
@ec.instance_variable_get("@a").should=='cache'
end
it 'set getter method with a different value' do
@ec.a.should=='@a=cache'
end
end
describe "uses cache" do
before do
@ec.x='cache'
@ec.a
@ec.set_a('not_cache')
end
it "changing internal doesn't start compute" do
@ec.compute_count.should==1
end
it {should_not be_dirty}
it "doesn't change cache value" do
@ec.a.should=='@a=cache'
end
describe "when cleaning cache" do
before do
@ec.clean_cache
end
it {@ec.should be_dirty}
it "doesn't call compute" do
@ec.compute_count.should==1
end
describe "when get dirty attribute" do
it "returns correct value and call compute again" do
@ec.a.should=='@a=cache'
@ec.compute_count.should==2
end
end
end
end
describe "could call other computation method" do
it "using DIRTY_COMPUTER" do
@ec2=ExpensiveClass2.new
@ec2.x='cache'
@ec2.a.should=='@a=cache.2'
@ec2.compute_count.should==1
end
end
end
|