1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activesupport/test/memoizable_test.rb

243 lines
5.5 KiB
Ruby
Raw Normal View History

require 'abstract_unit'
2009-04-13 19:56:04 -04:00
class MemoizableTest < ActiveSupport::TestCase
2008-11-22 18:19:19 -05:00
class Person
extend ActiveSupport::Memoizable
attr_reader :name_calls, :age_calls, :is_developer_calls
2008-11-22 18:19:19 -05:00
def initialize
@name_calls = 0
@age_calls = 0
@is_developer_calls = 0
2008-11-22 18:19:19 -05:00
end
2008-11-22 18:19:19 -05:00
def name
@name_calls += 1
"Josh"
end
2008-11-22 18:19:19 -05:00
def name?
true
end
memoize :name?
2008-11-22 18:19:19 -05:00
def update(name)
"Joshua"
end
memoize :update
2008-11-22 18:19:19 -05:00
def age
@age_calls += 1
nil
end
2008-11-22 18:19:19 -05:00
memoize :name, :age
private
def is_developer?
@is_developer_calls += 1
"Yes"
end
memoize :is_developer?
2008-11-22 18:19:19 -05:00
end
2008-11-22 18:19:19 -05:00
class Company
attr_reader :name_calls
def initialize
@name_calls = 0
end
2008-11-22 18:19:19 -05:00
def name
@name_calls += 1
"37signals"
end
2008-11-22 18:19:19 -05:00
end
2008-11-22 18:19:19 -05:00
module Rates
extend ActiveSupport::Memoizable
2008-11-22 18:19:19 -05:00
attr_reader :sales_tax_calls
def sales_tax(price)
@sales_tax_calls ||= 0
@sales_tax_calls += 1
price * 0.1025
end
memoize :sales_tax
end
2008-11-22 18:19:19 -05:00
class Calculator
extend ActiveSupport::Memoizable
include Rates
2008-11-22 18:19:19 -05:00
attr_reader :fib_calls
def initialize
@fib_calls = 0
end
def fib(n)
@fib_calls += 1
2008-11-22 18:19:19 -05:00
if n == 0 || n == 1
n
else
fib(n - 1) + fib(n - 2)
end
end
2008-11-22 18:19:19 -05:00
memoize :fib
2008-11-22 18:19:19 -05:00
def counter
@count ||= 0
@count += 1
end
2008-11-22 18:19:19 -05:00
memoize :counter
end
2008-11-22 18:19:19 -05:00
def setup
@person = Person.new
@calculator = Calculator.new
end
2008-11-22 18:19:19 -05:00
def test_memoization
assert_equal "Josh", @person.name
assert_equal 1, @person.name_calls
2008-11-22 18:19:19 -05:00
3.times { assert_equal "Josh", @person.name }
assert_equal 1, @person.name_calls
end
2008-11-22 18:19:19 -05:00
def test_memoization_with_punctuation
assert_equal true, @person.name?
assert_nothing_raised(NameError) do
@person.memoize_all
@person.unmemoize_all
end
2008-11-22 18:19:19 -05:00
end
2008-11-22 18:19:19 -05:00
def test_memoization_with_nil_value
assert_equal nil, @person.age
assert_equal 1, @person.age_calls
2008-11-22 18:19:19 -05:00
3.times { assert_equal nil, @person.age }
assert_equal 1, @person.age_calls
end
2008-11-22 18:19:19 -05:00
def test_reloadable
counter = @calculator.counter
assert_equal 1, @calculator.counter
assert_equal 2, @calculator.counter(:reload)
assert_equal 2, @calculator.counter
assert_equal 3, @calculator.counter(true)
assert_equal 3, @calculator.counter
end
def test_flush_cache
assert_equal 1, @calculator.counter
assert @calculator.instance_variable_get(:@_memoized_counter).any?
@calculator.flush_cache(:counter)
assert @calculator.instance_variable_get(:@_memoized_counter).empty?
assert_equal 2, @calculator.counter
end
2008-11-22 18:19:19 -05:00
def test_unmemoize_all
assert_equal 1, @calculator.counter
2008-08-13 20:22:38 -04:00
2008-11-22 18:19:19 -05:00
assert @calculator.instance_variable_get(:@_memoized_counter).any?
@calculator.unmemoize_all
assert @calculator.instance_variable_get(:@_memoized_counter).empty?
2008-08-13 20:22:38 -04:00
2008-11-22 18:19:19 -05:00
assert_equal 2, @calculator.counter
end
2008-08-13 20:22:38 -04:00
2008-11-22 18:19:19 -05:00
def test_memoize_all
@calculator.memoize_all
assert @calculator.instance_variable_defined?(:@_memoized_counter)
end
2008-08-13 20:22:38 -04:00
2008-11-22 18:19:19 -05:00
def test_memoization_cache_is_different_for_each_instance
assert_equal 1, @calculator.counter
assert_equal 2, @calculator.counter(:reload)
assert_equal 1, Calculator.new.counter
end
2008-11-22 18:19:19 -05:00
def test_memoized_is_not_affected_by_freeze
@person.freeze
assert_equal "Josh", @person.name
assert_equal "Joshua", @person.update("Joshua")
end
2008-11-22 18:19:19 -05:00
def test_memoization_with_args
assert_equal 55, @calculator.fib(10)
assert_equal 11, @calculator.fib_calls
end
2008-11-22 18:19:19 -05:00
def test_reloadable_with_args
assert_equal 55, @calculator.fib(10)
assert_equal 11, @calculator.fib_calls
assert_equal 55, @calculator.fib(10, :reload)
assert_equal 12, @calculator.fib_calls
assert_equal 55, @calculator.fib(10, true)
assert_equal 13, @calculator.fib_calls
end
2008-11-22 18:19:19 -05:00
def test_object_memoization
[Company.new, Company.new, Company.new].each do |company|
company.extend ActiveSupport::Memoizable
company.memoize :name
2008-11-22 18:19:19 -05:00
assert_equal "37signals", company.name
assert_equal 1, company.name_calls
assert_equal "37signals", company.name
assert_equal 1, company.name_calls
end
2008-11-22 18:19:19 -05:00
end
2008-11-22 18:19:19 -05:00
def test_memoized_module_methods
assert_equal 1.025, @calculator.sales_tax(10)
assert_equal 1, @calculator.sales_tax_calls
assert_equal 1.025, @calculator.sales_tax(10)
assert_equal 1, @calculator.sales_tax_calls
assert_equal 2.5625, @calculator.sales_tax(25)
assert_equal 2, @calculator.sales_tax_calls
end
2008-11-22 18:19:19 -05:00
def test_object_memoized_module_methods
company = Company.new
company.extend(Rates)
2008-11-22 18:19:19 -05:00
assert_equal 1.025, company.sales_tax(10)
assert_equal 1, company.sales_tax_calls
assert_equal 1.025, company.sales_tax(10)
assert_equal 1, company.sales_tax_calls
assert_equal 2.5625, company.sales_tax(25)
assert_equal 2, company.sales_tax_calls
end
2008-11-22 18:19:19 -05:00
def test_double_memoization
assert_raise(RuntimeError) { Person.memoize :name }
person = Person.new
person.extend ActiveSupport::Memoizable
assert_raise(RuntimeError) { person.memoize :name }
2008-11-22 18:19:19 -05:00
company = Company.new
company.extend ActiveSupport::Memoizable
company.memoize :name
assert_raise(RuntimeError) { company.memoize :name }
end
def test_private_method_memoization
person = Person.new
assert_raise(NoMethodError) { person.is_developer? }
assert_equal "Yes", person.send(:is_developer?)
assert_equal 1, person.is_developer_calls
assert_equal "Yes", person.send(:is_developer?)
assert_equal 1, person.is_developer_calls
end
end