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
|
# frozen_string_literal: true
require "spec_helper"
class Parent
include Memoizable
def foo
@foo_call_count ||= 0
@foo_call_count += 1
end
memoize :foo
attr_reader :foo_call_count
end
class Child < Parent
def foo
@child_foo_call_count ||= 0
@child_foo_call_count += 1
super + 100
end
memoize :foo
attr_reader :child_foo_call_count
end
RSpec.describe Child do
subject(:child) { described_class.new }
before do
child.foo
end
it "allows subclass to override and memoize a parent memoized method" do
expect(child.foo).to eq(101)
end
it "memoizes the child method" do
expect(child.child_foo_call_count).to eq(1)
end
it "memoizes the parent method" do
expect(child.foo_call_count).to eq(1)
end
it "stores the parent memoized value under its own cache key" do
cache = child.instance_variable_get(:@_memoized_method_cache)
memory = cache.instance_variable_get(:@memory)
expect(memory[[Parent, :foo]]).to eq(1)
end
it "stores the child memoized value under its own cache key" do
cache = child.instance_variable_get(:@_memoized_method_cache)
memory = cache.instance_variable_get(:@memory)
expect(memory[[described_class, :foo]]).to eq(101)
end
it "reuses parent memoized value when child cache is cleared" do
child.instance_variable_get(:@_memoized_method_cache).delete([described_class, :foo])
child.foo
expect(child.foo_call_count).to eq(1)
end
it "recomputes child value when child cache is cleared" do
child.instance_variable_get(:@_memoized_method_cache).delete([described_class, :foo])
child.foo
expect(child.child_foo_call_count).to eq(2)
end
end
|