Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 372 lines (294 sloc) 8.385 kb
33245a9 @matthewrudy make the tests work
authored
1 require 'test_helper'
b5bbbd0 @matthewrudy rename to memoist
authored
2 require 'memoist'
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
3
9b95ec6 @matthewrudy upgrade dev dependencies
authored
4 class MemoistTest < Minitest::Test
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
5
6 class CallCounter
7
8 def initialize
9 @calls = {}
10 end
11
12 def call(method_name)
13 @calls[method_name] ||= 0
14 @calls[method_name] += 1
15 end
16
17 def count(method_name)
18 @calls[method_name] ||= 0
19 end
20
21 end
22
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
23 class Person
b5bbbd0 @matthewrudy rename to memoist
authored
24 extend Memoist
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
25
26 def initialize
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
27 @counter = CallCounter.new
28 end
29
30 def name_calls
31 @counter.count(:name)
32 end
33
34 def student_name_calls
35 @counter.count(:student_name)
36 end
37
38 def name_query_calls
39 @counter.count(:name?)
40 end
41
42 def is_developer_calls
43 @counter.count(:is_developer?)
44 end
45
46 def age_calls
47 @counter.count(:age)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
48 end
49
50 def name
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
51 @counter.call(:name)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
52 "Josh"
53 end
54
55 def name?
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
56 @counter.call(:name?)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
57 true
58 end
59 memoize :name?
60
61 def update(name)
62 "Joshua"
63 end
64 memoize :update
65
66 def age
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
67 @counter.call(:age)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
68 nil
69 end
70
71 memoize :name, :age
72
051c56c Call abs on arity when extracting reload
Brady Love and Johnneylee Jack Rollins authored
73 def sleep(hours = 8)
74 @counter.call(:sleep)
75 hours
76 end
77 memoize :sleep
78
79 def sleep_calls
80 @counter.count(:sleep)
81 end
82
83 def update_attributes(options = {})
84 @counter.call(:update_attributes)
85 true
86 end
87 memoize :update_attributes
88
89 def update_attributes_calls
90 @counter.count(:update_attributes)
91 end
92
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
93 protected
94
95 def memoize_protected_test
96 'protected'
97 end
98 memoize :memoize_protected_test
99
100 private
101
102 def is_developer?
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
103 @counter.call(:is_developer?)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
104 "Yes"
105 end
106 memoize :is_developer?
107 end
108
a10c075 @matthewrudy add an optional identifier to memoize
authored
109 class Student < Person
110 def name
2e947e6 @matthewrudy The Person tests don't rely on instance variables
authored
111 @counter.call(:student_name)
a10c075 @matthewrudy add an optional identifier to memoize
authored
112 "Student #{super}"
113 end
114 memoize :name, :identifier => :student
115 end
116
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
117 class Company
118 attr_reader :name_calls
119 def initialize
120 @name_calls = 0
121 end
122
123 def name
124 @name_calls += 1
125 "37signals"
126 end
127 end
128
129 module Rates
b5bbbd0 @matthewrudy rename to memoist
authored
130 extend Memoist
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
131
132 attr_reader :sales_tax_calls
133 def sales_tax(price)
134 @sales_tax_calls ||= 0
135 @sales_tax_calls += 1
136 price * 0.1025
137 end
138 memoize :sales_tax
139 end
140
141 class Calculator
b5bbbd0 @matthewrudy rename to memoist
authored
142 extend Memoist
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
143 include Rates
144
145 attr_reader :fib_calls
146 def initialize
147 @fib_calls = 0
148 end
149
150 def fib(n)
151 @fib_calls += 1
152
153 if n == 0 || n == 1
154 n
155 else
156 fib(n - 1) + fib(n - 2)
157 end
158 end
159 memoize :fib
160
161 def add_or_subtract(i, j, add)
162 if add
163 i + j
164 else
165 i - j
166 end
167 end
168 memoize :add_or_subtract
169
170 def counter
171 @count ||= 0
172 @count += 1
173 end
174 memoize :counter
175 end
176
177 def setup
178 @person = Person.new
179 @calculator = Calculator.new
180 end
181
182 def test_memoization
183 assert_equal "Josh", @person.name
184 assert_equal 1, @person.name_calls
185
186 3.times { assert_equal "Josh", @person.name }
187 assert_equal 1, @person.name_calls
188 end
189
051c56c Call abs on arity when extracting reload
Brady Love and Johnneylee Jack Rollins authored
190 def test_memoize_with_optional_arguments
191 assert_equal 4, @person.sleep(4)
192 assert_equal 1, @person.sleep_calls
193
194 3.times { assert_equal 4, @person.sleep(4) }
195 assert_equal 1, @person.sleep_calls
196
197 3.times { assert_equal 4, @person.sleep(4, :reload) }
198 assert_equal 4, @person.sleep_calls
199 end
200
201 def test_memoize_with_options_hash
202 assert_equal true, @person.update_attributes(:age => 21, :name => 'James')
203 assert_equal 1, @person.update_attributes_calls
204
205 3.times { assert_equal true, @person.update_attributes(:age => 21, :name => 'James') }
206 assert_equal 1, @person.update_attributes_calls
207
208 3.times { assert_equal true, @person.update_attributes({:age => 21, :name => 'James'}, :reload) }
209 assert_equal 4, @person.update_attributes_calls
210 end
211
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
212 def test_memoization_with_punctuation
213 assert_equal true, @person.name?
214
97ba3b1 @matthewrudy use minitest for compatability with ruby-head
authored
215 @person.memoize_all
216 @person.unmemoize_all
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
217 end
218
219 def test_memoization_flush_with_punctuation
220 assert_equal true, @person.name?
221 @person.flush_cache(:name?)
222 3.times { assert_equal true, @person.name? }
223 assert_equal 2, @person.name_query_calls
224 end
225
226 def test_memoization_with_nil_value
227 assert_equal nil, @person.age
228 assert_equal 1, @person.age_calls
229
230 3.times { assert_equal nil, @person.age }
231 assert_equal 1, @person.age_calls
232 end
233
234 def test_reloadable
235 assert_equal 1, @calculator.counter
236 assert_equal 2, @calculator.counter(:reload)
237 assert_equal 2, @calculator.counter
238 assert_equal 3, @calculator.counter(true)
239 assert_equal 3, @calculator.counter
240 end
241
242 def test_flush_cache
243 assert_equal 1, @calculator.counter
244
8ce1a78 @matthewrudy use remove_instance_variable
authored
245 assert @calculator.instance_variable_get(:@_memoized_counter)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
246 @calculator.flush_cache(:counter)
8ce1a78 @matthewrudy use remove_instance_variable
authored
247 assert_nil @calculator.instance_variable_get(:@_memoized_counter)
248 assert !@calculator.instance_variable_defined?(:@_memoized_counter)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
249
250 assert_equal 2, @calculator.counter
251 end
252
253 def test_unmemoize_all
254 assert_equal 1, @calculator.counter
255
8ce1a78 @matthewrudy use remove_instance_variable
authored
256 assert @calculator.instance_variable_get(:@_memoized_counter)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
257 @calculator.unmemoize_all
8ce1a78 @matthewrudy use remove_instance_variable
authored
258 assert_nil @calculator.instance_variable_get(:@_memoized_counter)
259 assert !@calculator.instance_variable_defined?(:@_memoized_counter)
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
260
261 assert_equal 2, @calculator.counter
262 end
263
264 def test_memoize_all
265 @calculator.memoize_all
266 assert @calculator.instance_variable_defined?(:@_memoized_counter)
267 end
268
269 def test_memoization_cache_is_different_for_each_instance
270 assert_equal 1, @calculator.counter
271 assert_equal 2, @calculator.counter(:reload)
272 assert_equal 1, Calculator.new.counter
273 end
274
275 def test_memoized_is_not_affected_by_freeze
276 @person.freeze
277 assert_equal "Josh", @person.name
278 assert_equal "Joshua", @person.update("Joshua")
279 end
280
281 def test_memoization_with_args
282 assert_equal 55, @calculator.fib(10)
283 assert_equal 11, @calculator.fib_calls
284 end
285
286 def test_reloadable_with_args
287 assert_equal 55, @calculator.fib(10)
288 assert_equal 11, @calculator.fib_calls
289 assert_equal 55, @calculator.fib(10, :reload)
290 assert_equal 12, @calculator.fib_calls
291 assert_equal 55, @calculator.fib(10, true)
292 assert_equal 13, @calculator.fib_calls
293 end
294
295 def test_memoization_with_boolean_arg
296 assert_equal 4, @calculator.add_or_subtract(2, 2, true)
297 assert_equal 2, @calculator.add_or_subtract(4, 2, false)
298 end
299
300 def test_object_memoization
301 [Company.new, Company.new, Company.new].each do |company|
b5bbbd0 @matthewrudy rename to memoist
authored
302 company.extend Memoist
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
303 company.memoize :name
304
305 assert_equal "37signals", company.name
306 assert_equal 1, company.name_calls
307 assert_equal "37signals", company.name
308 assert_equal 1, company.name_calls
309 end
310 end
311
312 def test_memoized_module_methods
313 assert_equal 1.025, @calculator.sales_tax(10)
314 assert_equal 1, @calculator.sales_tax_calls
315 assert_equal 1.025, @calculator.sales_tax(10)
316 assert_equal 1, @calculator.sales_tax_calls
317 assert_equal 2.5625, @calculator.sales_tax(25)
318 assert_equal 2, @calculator.sales_tax_calls
319 end
320
321 def test_object_memoized_module_methods
322 company = Company.new
323 company.extend(Rates)
324
325 assert_equal 1.025, company.sales_tax(10)
326 assert_equal 1, company.sales_tax_calls
327 assert_equal 1.025, company.sales_tax(10)
328 assert_equal 1, company.sales_tax_calls
329 assert_equal 2.5625, company.sales_tax(25)
330 assert_equal 2, company.sales_tax_calls
331 end
332
a10c075 @matthewrudy add an optional identifier to memoize
authored
333 def test_double_memoization_with_identifier
97ba3b1 @matthewrudy use minitest for compatability with ruby-head
authored
334 Person.memoize :name, :identifier => :again
a10c075 @matthewrudy add an optional identifier to memoize
authored
335 end
336
337 def test_memoization_with_a_subclass
338 student = Student.new
339 student.name
340 student.name
341 assert_equal 1, student.student_name_calls
342 assert_equal 1, student.name_calls
343 end
344
4c98b82 @matthewrudy we can chain together memoize with private
authored
345 def test_memoization_is_chainable
346 klass = Class.new do
347 def foo; "bar"; end
348 end
349 klass.extend Memoist
350 chainable = klass.memoize :foo
351 assert_equal :foo, chainable
352 end
353
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
354 def test_protected_method_memoization
355 person = Person.new
356
97ba3b1 @matthewrudy use minitest for compatability with ruby-head
authored
357 assert_raises(NoMethodError) { person.memoize_protected_test }
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
358 assert_equal "protected", person.send(:memoize_protected_test)
359 end
360
361 def test_private_method_memoization
362 person = Person.new
363
97ba3b1 @matthewrudy use minitest for compatability with ruby-head
authored
364 assert_raises(NoMethodError) { person.is_developer? }
7a5352d @matthewrudy copy ActiveSupport::Memoizable as is
authored
365 assert_equal "Yes", person.send(:is_developer?)
366 assert_equal 1, person.is_developer_calls
367 assert_equal "Yes", person.send(:is_developer?)
368 assert_equal 1, person.is_developer_calls
369 end
370
8ce1a78 @matthewrudy use remove_instance_variable
authored
371 end
Something went wrong with that request. Please try again.