test/memoist_test.rb in memoist-0.15.0 vs test/memoist_test.rb in memoist-0.16.0
- old
+ new
@@ -1,12 +1,10 @@
require 'test_helper'
require 'memoist'
class MemoistTest < Minitest::Test
-
class CallCounter
-
def initialize
@calls = {}
end
def call(method_name)
@@ -15,11 +13,10 @@
end
def count(method_name)
@calls[method_name] ||= 0
end
-
end
class Person
extend Memoist
@@ -47,21 +44,21 @@
@counter.count(:age)
end
def name
@counter.call(:name)
- "Josh"
+ 'Josh'
end
def name?
@counter.call(:name?)
true
end
memoize :name?
- def update(name)
- "Joshua"
+ def update(_name)
+ 'Joshua'
end
memoize :update
def age
@counter.call(:age)
@@ -78,11 +75,11 @@
def sleep_calls
@counter.count(:sleep)
end
- def update_attributes(options = {})
+ def update_attributes(_options = {})
@counter.call(:update_attributes)
true
end
memoize :update_attributes
@@ -99,26 +96,26 @@
private
def is_developer?
@counter.call(:is_developer?)
- "Yes"
+ 'Yes'
end
memoize :is_developer?
end
class Student < Person
def name
@counter.call(:student_name)
"Student #{super}"
end
- memoize :name, :identifier => :student
+ memoize :name, identifier: :student
end
class Teacher < Person
def seniority
- "very_senior"
+ 'very_senior'
end
memoize :seniority
end
class Company
@@ -127,11 +124,11 @@
@name_calls = 0
end
def name
@name_calls += 1
- "37signals"
+ '37signals'
end
end
module Rates
extend Memoist
@@ -179,20 +176,72 @@
@count += 1
end
memoize :counter
end
+ class Book
+ extend Memoist
+ STATUSES = %w[new used].freeze
+ CLASSIFICATION = %w[fiction nonfiction].freeze
+ GENRES = %w[humor romance reference sci-fi classic philosophy].freeze
+
+ attr_reader :title, :author
+ def initialize(title, author)
+ @title = title
+ @author = author
+ end
+
+ def full_title
+ "#{@title} by #{@author}"
+ end
+ memoize :full_title
+
+ class << self
+ extend Memoist
+
+ def all_types
+ STATUSES.product(CLASSIFICATION).product(GENRES).collect(&:flatten)
+ end
+ memoize :all_types
+ end
+ end
+
+ class Abb
+ extend Memoist
+
+ def run(*_args)
+ flush_cache if respond_to?(:flush_cache)
+ execute
+ end
+
+ def execute
+ some_method
+ end
+
+ def some_method
+ # Override this
+ end
+ end
+
+ class Bbb < Abb
+ def some_method
+ :foo
+ end
+ memoize :some_method
+ end
+
def setup
@person = Person.new
@calculator = Calculator.new
+ @book = Book.new('My Life', "Brian 'Fudge' Turmuck")
end
def test_memoization
- assert_equal "Josh", @person.name
+ assert_equal 'Josh', @person.name
assert_equal 1, @person.name_calls
- 3.times { assert_equal "Josh", @person.name }
+ 3.times { assert_equal 'Josh', @person.name }
assert_equal 1, @person.name_calls
end
def test_memoize_with_optional_arguments
assert_equal 4, @person.sleep(4)
@@ -204,17 +253,17 @@
3.times { assert_equal 4, @person.sleep(4, :reload) }
assert_equal 4, @person.sleep_calls
end
def test_memoize_with_options_hash
- assert_equal true, @person.update_attributes(:age => 21, :name => 'James')
+ assert_equal true, @person.update_attributes(age: 21, name: 'James')
assert_equal 1, @person.update_attributes_calls
- 3.times { assert_equal true, @person.update_attributes(:age => 21, :name => 'James') }
+ 3.times { assert_equal true, @person.update_attributes(age: 21, name: 'James') }
assert_equal 1, @person.update_attributes_calls
- 3.times { assert_equal true, @person.update_attributes({:age => 21, :name => 'James'}, :reload) }
+ 3.times { assert_equal true, @person.update_attributes({ age: 21, name: 'James' }, :reload) }
assert_equal 4, @person.update_attributes_calls
end
def test_memoization_with_punctuation
assert_equal true, @person.name?
@@ -229,14 +278,14 @@
3.times { assert_equal true, @person.name? }
assert_equal 2, @person.name_query_calls
end
def test_memoization_with_nil_value
- assert_equal nil, @person.age
+ assert_nil @person.age
assert_equal 1, @person.age_calls
- 3.times { assert_equal nil, @person.age }
+ 3.times { assert_nil @person.age }
assert_equal 1, @person.age_calls
end
def test_reloadable
assert_equal 1, @calculator.counter
@@ -254,10 +303,37 @@
assert_equal false, @calculator.instance_variable_defined?(:@_memoized_counter)
assert_equal 2, @calculator.counter
end
+ def test_class_flush_cache
+ @book.memoize_all
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
+
+ Book.memoize_all
+ assert_instance_of Array, Book.instance_variable_get(:@_memoized_all_types)
+ Book.flush_cache
+ assert_equal false, Book.instance_variable_defined?(:@_memoized_all_types)
+ end
+
+ def test_class_flush_cache_preserves_instances
+ @book.memoize_all
+ Book.memoize_all
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
+
+ Book.flush_cache
+ assert_equal false, Book.instance_variable_defined?(:@_memoized_all_types)
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
+ end
+
+ def test_flush_cache_in_child_class
+ x = Bbb.new
+
+ # This should not throw error
+ x.run
+ end
+
def test_unmemoize_all
assert_equal 1, @calculator.counter
assert_equal true, @calculator.instance_variable_defined?(:@_memoized_counter)
assert @calculator.instance_variable_get(:@_memoized_counter)
@@ -270,44 +346,44 @@
def test_all_memoized_structs
# Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
# Student < Person memoize :name, :identifier => :student
# Teacher < Person memoize :seniority
- expected = %w(age is_developer? memoize_protected_test name name? sleep update update_attributes)
+ expected = %w[age is_developer? memoize_protected_test name name? sleep update update_attributes]
structs = Person.all_memoized_structs
assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
- assert_equal "@_memoized_name", structs.detect {|s| s.memoized_method == :name }.ivar
+ assert_equal '@_memoized_name', structs.detect { |s| s.memoized_method == :name }.ivar
# Same expected methods
structs = Student.all_memoized_structs
assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
- assert_equal "@_memoized_student_name", structs.detect {|s| s.memoized_method == :name }.ivar
+ assert_equal '@_memoized_student_name', structs.detect { |s| s.memoized_method == :name }.ivar
- expected = (expected << "seniority").sort
+ expected = (expected << 'seniority').sort
structs = Teacher.all_memoized_structs
assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
- assert_equal "@_memoized_name", structs.detect {|s| s.memoized_method == :name }.ivar
+ assert_equal '@_memoized_name', structs.detect { |s| s.memoized_method == :name }.ivar
end
def test_unmemoize_all_subclasses
# Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
# Student < Person memoize :name, :identifier => :student
# Teacher < Person memoize :seniority
teacher = Teacher.new
- assert_equal "Josh", teacher.name
- assert_equal "Josh", teacher.instance_variable_get(:@_memoized_name)
- assert_equal "very_senior", teacher.seniority
- assert_equal "very_senior", teacher.instance_variable_get(:@_memoized_seniority)
+ assert_equal 'Josh', teacher.name
+ assert_equal 'Josh', teacher.instance_variable_get(:@_memoized_name)
+ assert_equal 'very_senior', teacher.seniority
+ assert_equal 'very_senior', teacher.instance_variable_get(:@_memoized_seniority)
teacher.unmemoize_all
assert_equal false, teacher.instance_variable_defined?(:@_memoized_name)
assert_equal false, teacher.instance_variable_defined?(:@_memoized_seniority)
student = Student.new
- assert_equal "Student Josh", student.name
- assert_equal "Student Josh", student.instance_variable_get(:@_memoized_student_name)
+ assert_equal 'Student Josh', student.name
+ assert_equal 'Student Josh', student.instance_variable_get(:@_memoized_student_name)
assert_equal false, student.instance_variable_defined?(:@_memoized_seniority)
student.unmemoize_all
assert_equal false, @calculator.instance_variable_defined?(:@_memoized_student_name)
end
@@ -323,31 +399,41 @@
# Teacher < Person memoize :seniority
teacher = Teacher.new
teacher.memoize_all
- assert_equal "very_senior", teacher.instance_variable_get(:@_memoized_seniority)
- assert_equal "Josh", teacher.instance_variable_get(:@_memoized_name)
+ assert_equal 'very_senior', teacher.instance_variable_get(:@_memoized_seniority)
+ assert_equal 'Josh', teacher.instance_variable_get(:@_memoized_name)
student = Student.new
student.memoize_all
- assert_equal "Student Josh", student.instance_variable_get(:@_memoized_student_name)
- assert_equal "Student Josh", student.name
+ assert_equal 'Student Josh', student.instance_variable_get(:@_memoized_student_name)
+ assert_equal 'Student Josh', student.name
assert_equal false, student.instance_variable_defined?(:@_memoized_seniority)
end
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
+ def test_memoization_class_variables
+ @book.memoize_all
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.instance_variable_get(:@_memoized_full_title)
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
+
+ Book.memoize_all
+ assert_instance_of Array, Book.instance_variable_get(:@_memoized_all_types)
+ assert_equal 24, Book.all_types.count
+ end
+
def test_memoized_is_not_affected_by_freeze
@person.freeze
- assert_equal "Josh", @person.name
- assert_equal "Joshua", @person.update("Joshua")
+ assert_equal 'Josh', @person.name
+ assert_equal 'Joshua', @person.update('Joshua')
end
def test_memoization_with_args
assert_equal 55, @calculator.fib(10)
assert_equal 11, @calculator.fib_calls
@@ -370,13 +456,13 @@
def test_object_memoization
[Company.new, Company.new, Company.new].each do |company|
company.extend Memoist
company.memoize :name
- assert_equal "37signals", company.name
+ assert_equal '37signals', company.name
assert_equal 1, company.name_calls
- assert_equal "37signals", company.name
+ assert_equal '37signals', company.name
assert_equal 1, company.name_calls
end
end
def test_memoized_module_methods
@@ -403,29 +489,29 @@
def test_double_memoization_with_identifier
# Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
# Student < Person memoize :name, :identifier => :student
# Teacher < Person memoize :seniority
- Person.memoize :name, :identifier => :again
+ Person.memoize :name, identifier: :again
p = Person.new
- assert_equal "Josh", p.name
+ assert_equal 'Josh', p.name
assert p.instance_variable_get(:@_memoized_again_name)
# HACK: tl;dr: Don't memoize classes in test that are used elsewhere.
# Calling Person.memoize :name, :identifier => :again pollutes Person
# and descendents since we cache the memoized method structures.
# This populates those structs, verifies Person is polluted, resets the
# structs, cleans up cached memoized_methods
Student.all_memoized_structs
Person.all_memoized_structs
Teacher.all_memoized_structs
- assert Person.memoized_methods.any? { |m| m.ivar == "@_memoized_again_name" }
+ assert Person.memoized_methods.any? { |m| m.ivar == '@_memoized_again_name' }
- [Student, Teacher, Person].each { |obj| obj.clear_structs }
- assert Person.memoized_methods.reject! { |m| m.ivar == "@_memoized_again_name" }
- assert_nil Student.memoized_methods.reject! { |m| m.ivar == "@_memoized_again_name" }
- assert_nil Teacher.memoized_methods.reject! { |m| m.ivar == "@_memoized_again_name" }
+ [Student, Teacher, Person].each(&:clear_structs)
+ assert Person.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
+ assert_nil Student.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
+ assert_nil Teacher.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
end
def test_memoization_with_a_subclass
student = Student.new
student.name
@@ -434,30 +520,31 @@
assert_equal 1, student.name_calls
end
def test_memoization_is_chainable
klass = Class.new do
- def foo; "bar"; end
+ def foo
+ 'bar'
+ end
end
klass.extend Memoist
chainable = klass.memoize :foo
assert_equal :foo, chainable
end
def test_protected_method_memoization
person = Person.new
assert_raises(NoMethodError) { person.memoize_protected_test }
- assert_equal "protected", person.send(:memoize_protected_test)
+ assert_equal 'protected', person.send(:memoize_protected_test)
end
def test_private_method_memoization
person = Person.new
assert_raises(NoMethodError) { person.is_developer? }
- assert_equal "Yes", person.send(: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 'Yes', person.send(:is_developer?)
assert_equal 1, person.is_developer_calls
end
-
end