From 087e8648a116285d83839b1c097e5636a8e0dd65 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Mon, 10 Apr 2017 16:11:29 +0100 Subject: [PATCH] Memoize tests --- tests/test_memoize.py | 317 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 tests/test_memoize.py diff --git a/tests/test_memoize.py b/tests/test_memoize.py new file mode 100644 index 000000000..4e7142328 --- /dev/null +++ b/tests/test_memoize.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python +# +# test_memoize.py - +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# + + +import numpy as np + +import fsl.utils.memoize as memoize + + +def test_memoize(): + + timesCalled = [0] + + def thefunc(*args, **kwargs): + timesCalled[0] += 1 + + if len(args) + len(kwargs) == 0: return 0 + elif len(args) == 1: return args[0] * 5 + else: return kwargs['value'] * 5 + + memoized = memoize.memoize(thefunc) + + + # No args + for i in range(5): + assert memoized() == 0 + assert timesCalled[0] == 1 + + # Positional args + for i in range(3): + for i in range(5): + assert memoized(i) == i * 5 + assert timesCalled[0] == 6 + + # Keyword arg + for i in range(3): + for i in range(5): + assert memoized(value=i) == i * 5 + assert timesCalled[0] == 6 + + +def test_memoizeMD5(): + timesCalled = [0] + + def thefunc(*args, **kwargs): + timesCalled[0] += 1 + if len(args) + len(kwargs) == 0: return 0 + elif len(args) == 1: return args[0] * 5 + else: return kwargs['value'] * 5 + + memoized = memoize.memoizeMD5(thefunc) + + # No args + for i in range(5): + assert memoized() == 0 + assert timesCalled[0] == 1 + + # Positional args + for i in range(3): + for i in range(5): + assert memoized(i) == i * 5 + assert timesCalled[0] == 6 + + # Keyword arg + for i in range(3): + for i in range(5): + assert memoized(value=i) == i * 5 + assert timesCalled[0] == 6 + + +def test_skipUnchanged(): + """ + """ + + timesCalled = { + 'key1' : 0, + 'key2' : 0, + 'key3' : 0, + } + + def setter(name, value): + timesCalled[name] = timesCalled[name] + 1 + + wrapped = memoize.skipUnchanged(setter) + + wrapped('key1', 11) + wrapped('key2', 12) + wrapped('key3', 13) + + assert timesCalled['key1'] == 1 + assert timesCalled['key2'] == 1 + assert timesCalled['key3'] == 1 + + wrapped('key1', 11) + wrapped('key2', 12) + wrapped('key3', 13) + + assert timesCalled['key1'] == 1 + assert timesCalled['key2'] == 1 + assert timesCalled['key3'] == 1 + + wrapped('key1', 14) + wrapped('key2', 15) + wrapped('key3', 16) + + assert timesCalled['key1'] == 2 + assert timesCalled['key2'] == 2 + assert timesCalled['key3'] == 2 + + wrapped('key1', 14) + wrapped('key2', 15) + wrapped('key3', 16) + + assert timesCalled['key1'] == 2 + assert timesCalled['key2'] == 2 + assert timesCalled['key3'] == 2 + + wrapped('key1', 11) + wrapped('key2', 12) + wrapped('key3', 13) + + assert timesCalled['key1'] == 3 + assert timesCalled['key2'] == 3 + assert timesCalled['key3'] == 3 + + wrapped('key1', np.array([11, 12])) + wrapped('key2', np.array([13, 14])) + wrapped('key3', np.array([15, 16])) + + assert timesCalled['key1'] == 4 + assert timesCalled['key2'] == 4 + assert timesCalled['key3'] == 4 + + wrapped('key1', np.array([12, 11])) + wrapped('key2', np.array([14, 13])) + wrapped('key3', np.array([16, 15])) + + assert timesCalled['key1'] == 5 + assert timesCalled['key2'] == 5 + assert timesCalled['key3'] == 5 + + wrapped('key1', np.array([12, 11])) + wrapped('key2', np.array([14, 13])) + wrapped('key3', np.array([16, 15])) + + assert timesCalled['key1'] == 5 + assert timesCalled['key2'] == 5 + assert timesCalled['key3'] == 5 + + +def test_Instanceify(): + + class Container(object): + + def __init__(self): + self.setter1Called = 0 + self.setter2Called = 0 + self.func1Called = 0 + self.func2Called = 0 + + @memoize.Instanceify(memoize.skipUnchanged) + def setter1(self, name, value): + self.setter1Called += 1 + + @memoize.Instanceify(memoize.skipUnchanged) + def setter2(self, name, value): + self.setter2Called += 1 + + @memoize.Instanceify(memoize.memoize) + def func1(self, arg): + self.func1Called += 1 + return arg * 2 + + @memoize.Instanceify(memoize.memoize) + def func2(self, arg): + self.func2Called += 1 + return arg * 4 + + def check(self, s1c, s2c, f1c, f2c): + assert self.setter1Called == s1c + assert self.setter2Called == s2c + assert self.func1Called == f1c + assert self.func2Called == f2c + + c1 = Container() + c2 = Container() + + # Call setter1 on one instance, + # make sure that the call counter + # only changes on that instance + for i in range(3): + c1.setter1('blob', 120) + c1.check(1, 0, 0, 0) + c2.check(0, 0, 0, 0) + + for i in range(3): + c1.setter1('blob', 150) + c1.check(2, 0, 0, 0) + c2.check(0, 0, 0, 0) + + for i in range(3): + c1.setter1('flob', 200) + c1.check(3, 0, 0, 0) + c2.check(0, 0, 0, 0) + + for i in range(3): + c1.setter1('flob', 180) + c1.check(4, 0, 0, 0) + c2.check(0, 0, 0, 0) + + for i in range(3): + c2.setter1('blob', 120) + c1.check(4, 0, 0, 0) + c2.check(1, 0, 0, 0) + + for i in range(3): + c2.setter1('blob', 150) + c1.check(4, 0, 0, 0) + c2.check(2, 0, 0, 0) + + for i in range(3): + c2.setter1('flob', 200) + c1.check(4, 0, 0, 0) + c2.check(3, 0, 0, 0) + + for i in range(3): + c2.setter1('flob', 180) + c1.check(4, 0, 0, 0) + c2.check(4, 0, 0, 0) + + # Call setter2 on one instance, + # ... + for i in range(3): + c1.setter2('blob', 120) + c1.check(4, 1, 0, 0) + c2.check(4, 0, 0, 0) + + for i in range(3): + c1.setter2('blob', 150) + c1.check(4, 2, 0, 0) + c2.check(4, 0, 0, 0) + + for i in range(3): + c1.setter2('flob', 200) + c1.check(4, 3, 0, 0) + c2.check(4, 0, 0, 0) + + for i in range(3): + c1.setter2('flob', 180) + c1.check(4, 4, 0, 0) + c2.check(4, 0, 0, 0) + + for i in range(3): + c2.setter2('blob', 120) + c1.check(4, 4, 0, 0) + c2.check(4, 1, 0, 0) + + for i in range(3): + c2.setter2('blob', 150) + c1.check(4, 4, 0, 0) + c2.check(4, 2, 0, 0) + + for i in range(3): + c2.setter2('flob', 200) + c1.check(4, 4, 0, 0) + c2.check(4, 3, 0, 0) + + for i in range(3): + c2.setter2('flob', 180) + c1.check(4, 4, 0, 0) + c2.check(4, 4, 0, 0) + + # Call func1 on one instance, + # ... + for i in range(3): + assert c1.func1(123) == 246 + c1.check(4, 4, 1, 0) + c2.check(4, 4, 0, 0) + + for i in range(3): + assert c1.func1(456) == 912 + c1.check(4, 4, 2, 0) + c2.check(4, 4, 0, 0) + + for i in range(3): + assert c2.func1(123) == 246 + c1.check(4, 4, 2, 0) + c2.check(4, 4, 1, 0) + + for i in range(3): + assert c2.func1(456) == 912 + c1.check(4, 4, 2, 0) + c2.check(4, 4, 2, 0) + + # Call func2 on one instance, + # ... + for i in range(3): + assert c1.func2(123) == 492 + c1.check(4, 4, 2, 1) + c2.check(4, 4, 2, 0) + + for i in range(3): + assert c1.func2(456) == 1824 + + for i in range(3): + assert c2.func2(123) == 492 + c1.check(4, 4, 2, 2) + c2.check(4, 4, 2, 1) + + for i in range(3): + assert c2.func2(456) == 1824 + c1.check(4, 4, 2, 2) + c2.check(4, 4, 2, 2) -- GitLab