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