def test_weaving(self): import testbed from testbed import echo class Dupper(object): def _after_echo(self, method, result, exc_value): if not exc_value: return result * 2 def _after_rien(self, method, result, exc_value): return result + 1 def _after_method(self, method, result, exc_value): return result weave(Dupper, self.testbed) self.assertEquals(20, testbed.echo(10)) self.assertEquals(2, testbed.rien()) module, args, kwargs = testbed.method(1, 2, 3, a=1) self.assertEquals(args, (1, 2, 3)) self.assertEquals(kwargs, {'a': 1}) self.assertEquals(testbed, module) # Unfortunately is quite difficult to replace standing references. Is # possible by keeping the old func_code function and replacing # func_code directly, but is difficult to get right and I don't need # it. self.assertEquals(10, echo(10)) # After the test, since other may require normal echo behavior, let's # restore it testbed.echo = echo
def test_whole_weaving(self): class Foobar(object): def echo(self, what): return what class Aspect(object): @classmethod def _before_weave(cls, target): print('Weaving {target} with {aspect}'.format(target=target.__name__, aspect=cls.__name__)) def _before_echo(self, method): print('Echoing....') def _after_echo(self, method, result, exc): print('...echoed') if exc: raise StopExceptionChain return result def injected(self, who): return self.echo(who) weave(Aspect, Foobar) f = Foobar() self.assertEquals(10, f.echo(10))