Skip to content

Commit

Permalink
add let().
Browse files Browse the repository at this point in the history
  • Loading branch information
sumeet committed Apr 23, 2012
1 parent b2622b0 commit a919298
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
28 changes: 28 additions & 0 deletions test/test_case_test.py
@@ -1,8 +1,11 @@
import itertools

from testify import TestCase from testify import TestCase
from testify import assert_equal from testify import assert_equal
from testify import class_setup from testify import class_setup
from testify import class_setup_teardown from testify import class_setup_teardown
from testify import class_teardown from testify import class_teardown
from testify import let
from testify import run from testify import run
from testify import setup from testify import setup
from testify import setup_teardown from testify import setup_teardown
Expand Down Expand Up @@ -245,5 +248,30 @@ def test_method_1(self):
def test_method_2(self): def test_method_2(self):
pass pass


class LetTest(TestCase):

@let
def counter(self):
return itertools.count(0)

def test_first_call_is_not_cached(self):
assert_equal(self.counter.next(), 0)

def test_subsequent_calls_are_cached(self):
assert_equal(self.counter.next(), 0)
assert_equal(self.counter.next(), 1)

class LetWithLambdaTest(TestCase):

counter = let(lambda self: itertools.count(0))

def test_first_call_is_not_cached(self):
assert_equal(self.counter.next(), 0)

def test_subsequent_calls_are_cached(self):
assert_equal(self.counter.next(), 0)
assert_equal(self.counter.next(), 1)


if __name__ == '__main__': if __name__ == '__main__':
run() run()
3 changes: 2 additions & 1 deletion testify/__init__.py
Expand Up @@ -42,7 +42,8 @@
class_teardown, class_teardown,
setup_teardown, setup_teardown,
class_setup_teardown, class_setup_teardown,
suite) suite,
let)


from utils import turtle from utils import turtle


Expand Down
30 changes: 30 additions & 0 deletions testify/test_case.py
Expand Up @@ -470,3 +470,33 @@ def fixture_method(func):


setup_teardown = __fixture_decorator_factory('setup_teardown') setup_teardown = __fixture_decorator_factory('setup_teardown')
class_setup_teardown = __fixture_decorator_factory('class_setup_teardown') class_setup_teardown = __fixture_decorator_factory('class_setup_teardown')

class let(object):
"""Decorator that creates a lazy-evaluated helper property. The value is
cached across multiple calls in the same test, but not across multiple
tests.
"""

class _unsaved(object): pass

def __init__(self, func):
self._func = func
self._result = self._unsaved

def __get__(self, test_case, cls):
if test_case is None:
return self
if self._result is self._unsaved:
self._save_result(self._func(test_case))
self._register_reset_after_test_completion(test_case)
return self._result

def _save_result(self, result):
self._result = result

def _register_reset_after_test_completion(self, test_case):
test_case.register_callback(TestCase.EVENT_ON_COMPLETE_TEST_METHOD,
lambda _: self._reset_value())

def _reset_value(self):
self._result = self._unsaved

0 comments on commit a919298

Please sign in to comment.