コード例 #1
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testLessArgs(self) -> None:
        class C:
            def foo(self, _x, _y, **_kwargs):
                pass

        def after_2(x, y, *args, **kwargs):
            self.after_2_res = x, y

        def after_1(x, *args, **kwargs):
            self.after_1_res = x

        def after_0(*args, **kwargs):
            self.after_0_res = 0

        self.after_2_res = None
        self.after_1_res = None
        self.after_0_res = None

        c = C()

        After(c.foo, after_2)
        After(c.foo, after_1)
        After(c.foo, after_0)

        c.foo(10, 20, foo=1)
        assert self.after_2_res == (10, 20)
        assert self.after_1_res == 10
        assert self.after_0_res == 0
コード例 #2
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testDeadCallbackCleared(self) -> None:
        my_object = _MyClass()
        my_object.SetAlpha(0)
        my_object.SetBravo(0)
        self._value = []

        class B:
            def event(s, value):  # @NoSelf
                self._b_value = value

        class A:
            def event(s, obj, value):  # @NoSelf
                self._a_value = value

        a = A()
        b = B()

        self._a_value = None
        self._b_value = None

        # Test After/Remove with a callback and sender_as_parameter
        After(my_object.SetAlpha, a.event, sender_as_parameter=True)
        After(my_object.SetAlpha, b.event, sender_as_parameter=False)

        w = weakref.ref(a)
        my_object.SetAlpha(3)
        assert 3 == self._a_value
        assert 3 == self._b_value
        del a
        my_object.SetAlpha(4)
        assert 3 == self._a_value
        assert 4 == self._b_value
        assert w() is None
コード例 #3
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testOnClassMethod(self) -> None:
        class A:
            @classmethod
            def foo(cls):
                pass

        self.after_exec_class_method = 0

        def FooAfterClassMethod():
            self.after_exec_class_method += 1

        self.after_exec_self_method = 0

        def FooAfterSelfMethod():
            self.after_exec_self_method += 1

        After(A.foo, FooAfterClassMethod)

        a = A()
        After(a.foo, FooAfterSelfMethod)

        a.foo()
        assert 1 == self.after_exec_class_method
        assert 1 == self.after_exec_self_method

        Remove(A.foo, FooAfterClassMethod)
        a.foo()
        assert 1 == self.after_exec_class_method
        assert 2 == self.after_exec_self_method
コード例 #4
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testOnClassAndOnInstance1(self) -> None:
        vals = []

        def OnCall1(instance, val):
            vals.append(("call_instance", val))

        def OnCall2(val):
            vals.append(("call_class", val))

        After(Stub.call, OnCall1)
        s = Stub()
        After(s.call, OnCall2)

        s.call(True)
        assert [("call_instance", True), ("call_class", True)] == vals
コード例 #5
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testClassOverride(self) -> None:
        Before(C.foo, self.before)
        After(C.foo, self.after)

        self.a.foo(1)
        assert self.foo_called == (self.a, 1)
        assert self.after_called == (self.a, 1)
        assert self.after_count == 1
        assert self.before_called == (self.a, 1)
        assert self.before_count == 1

        self.b.foo(2)
        assert self.foo_called == (self.b, 2)
        assert self.after_called == (self.b, 2)
        assert self.after_count == 2
        assert self.before_called == (self.b, 2)
        assert self.before_count == 2

        assert Remove(C.foo, self.before)

        self.a.foo(3)
        assert self.foo_called == (self.a, 3)
        assert self.after_called == (self.a, 3)
        assert self.after_count == 3
        assert self.before_called == (self.b, 2)
        assert self.before_count == 2
コード例 #6
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testInstanceOverride(self) -> None:
        Before(self.a.foo, self.before)
        After(self.a.foo, self.after)

        self.a.foo(1)
        assert self.foo_called == (self.a, 1)
        assert self.after_called == (1, )
        assert self.before_called == (1, )
        assert self.after_count == 1
        assert self.before_count == 1

        self.b.foo(2)
        assert self.foo_called == (self.b, 2)
        assert self.after_called == (1, )
        assert self.before_called == (1, )
        assert self.after_count == 1
        assert self.before_count == 1

        assert Remove(self.a.foo, self.before) == True

        self.a.foo(2)
        assert self.foo_called == (self.a, 2)
        assert self.after_called == (2, )
        assert self.before_called == (1, )
        assert self.after_count == 2
        assert self.before_count == 1

        Before(self.a.foo, self.before)
        Before(self.a.foo,
               self.before)  # Registering twice has no effect the 2nd time

        self.a.foo(5)
        assert self.before_called == (5, )
        assert self.before_count == 2
コード例 #7
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testActionMethodDies(self) -> None:
        class A:
            def foo(self):
                pass

        def FooAfter():
            self.after_exec += 1

        self.after_exec = 0

        a = A()
        weak_a = weakref.ref(a)
        After(a.foo, FooAfter)
        a.foo()

        assert self.after_exec == 1

        del a

        # IMPORTANT: behaviour change. The description below is for the previous
        # behaviour. That is not true anymore (the circular reference is not kept anymore)

        # callback creates a circular reference; that's ok, because we want
        # to still be able to do "x = a.foo" and keep a strong reference to it

        assert weak_a() is None
コード例 #8
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testAfterBeforeHandleError(self) -> None:
        class C:
            def Method(self, x):
                return x * 2

        def AfterMethod(*args):
            self.after_called += 1
            raise RuntimeError

        def BeforeMethod(*args):
            self.before_called += 1
            raise RuntimeError

        self.before_called = 0
        self.after_called = 0

        c = C()
        Before(c.Method, BeforeMethod)
        After(c.Method, AfterMethod)

        # Now behavior changed and it will fail on first callback error
        with pytest.raises(RuntimeError):
            assert c.Method(10) == 20

        assert self.before_called == 1
        assert self.after_called == 0
コード例 #9
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testBoundMethodsRight(self) -> None:
        foo = self.a.foo
        foo = Before(foo, self.before)
        foo = After(foo, self.after)

        foo(10)
        assert self.before_count == 1
        assert self.after_count == 1
コード例 #10
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testBoundMethodsWrong(self) -> None:
        foo = self.a.foo
        Before(foo, self.before)
        After(foo, self.after)

        foo(10)
        assert 0 == self.before_count
        assert 0 == self.after_count
コード例 #11
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testSenderDies2(self) -> None:
        After(self.a.foo, self.after, True)
        self.a.foo(1)
        assert (self.a, 1) == self.after_called

        a = weakref.ref(self.a)
        self.after_called = None
        self.foo_called = None
        del self.a
        assert a() is None
コード例 #12
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testOnNullClass(self) -> None:
        class _MyNullSubClass(Null):
            def GetIstodraw(self):
                return True

        s = _MyNullSubClass()

        def AfterSetIstodraw():
            pass

        After(s.SetIstodraw, AfterSetIstodraw)
コード例 #13
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testOnClassAndOnInstance2(self) -> None:
        vals = []

        def OnCall1(instance, val):
            vals.append(("call_class", val))

        def OnCall2(val):
            vals.append(("call_instance", val))

        s = Stub()
        After(s.call, OnCall2)
        After(Stub.call, OnCall1)

        # Tricky thing here: because we added the callback in the class after we added it to the
        # instance, the callback on the instance cannot be rebound, thus, calling it on the instance
        # won't really trigger the callback on the class (not really what would be expected of the
        # after method, but I couldn't find a reasonable way to overcome that).
        # A solution could be keeping track of all callbacks and rebinding all existent ones in the
        # instances to the one in the class, but it seems overkill for such an odd situation.
        s.call(True)
        assert [("call_instance", True)] == vals
コード例 #14
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testAfterRegisterMultipleAndUnregisterOnce(self) -> None:
        class A:
            def foo(self):
                pass

        a = A()

        def FooAfter1():
            Remove(a.foo, FooAfter1)
            self.after_exec += 1

        def FooAfter2():
            self.after_exec += 1

        self.after_exec = 0
        After(a.foo, FooAfter1)
        After(a.foo, FooAfter2)
        a.foo()

        # it was iterating in the original after, so, this case
        # was only giving 1 result and not 2 as it should
        assert 2 == self.after_exec

        a.foo()
        assert 3 == self.after_exec
        a.foo()
        assert 4 == self.after_exec

        After(a.foo, FooAfter2)
        After(a.foo, FooAfter2)
        After(a.foo, FooAfter2)

        a.foo()
        assert 5 == self.after_exec

        Remove(a.foo, FooAfter2)
        a.foo()
        assert 5 == self.after_exec
コード例 #15
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testAfterRemove(self) -> None:

        my_object = _MyClass()
        my_object.SetAlpha(0)
        my_object.SetBravo(0)

        After(my_object.SetAlpha, my_object.SetBravo)

        my_object.SetAlpha(1)
        assert my_object.bravo == 1

        Remove(my_object.SetAlpha, my_object.SetBravo)

        my_object.SetAlpha(2)
        assert my_object.bravo == 1
コード例 #16
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def test_sender_as_parameter_after_and_before(self) -> None:
        self.zulu_calls = []

        def zulu_one(*args):
            self.zulu_calls.append((1, args))

        def zulu_too(*args):
            self.zulu_calls.append((2, args))

        Before(self.a.foo, zulu_one, sender_as_parameter=True)
        After(self.a.foo, zulu_too)

        assert self.zulu_calls == []
        self.a.foo(0)
        assert self.zulu_calls == [(1, (self.a, 0)), (2, (0, ))]
コード例 #17
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testWithCallable(self) -> None:
        class Stub:
            def call(self, _b):
                pass

        class Aux:
            def __call__(self, _b):
                self.called = True

        s = Stub()
        a = Aux()
        After(s.call, a)
        s.call(True)

        assert a.called
コード例 #18
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testAfterRemoveCallback(self) -> None:
        my_object = _MyClass()
        my_object.SetAlpha(0)
        my_object.SetBravo(0)

        # Test After/Remove with a callback
        event = Callback()
        After(my_object.SetAlpha, event)
        event.Register(my_object.SetBravo)

        my_object.SetAlpha(3)
        assert my_object.bravo == 3

        Remove(my_object.SetAlpha, event)

        my_object.SetAlpha(4)
        assert my_object.bravo == 3
コード例 #19
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testListMethodAsCallback(self, mocker) -> None:
        """
        This was based on a failure on
        souring20.core.model.multiple_simulation_runs._tests.test_multiple_simulation_runs.testNormalExecution
        which failed with "TypeError: cannot create weak reference to 'list' object"
        """
        vals: List[str] = []

        class Stub:
            def call(self, *args, **kwargs):
                pass

        s = Stub()
        After(s.call, vals.append)

        s.call("call_append")
        assert ["call_append"] == vals
コード例 #20
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
    def testAfterRemoveCallbackAndSenderAsParameter(self) -> None:
        my_object = _MyClass()
        my_object.SetAlpha(0)
        my_object.SetBravo(0)

        def event(obj_or_value, value):
            self._value = value

        # Test After/Remove with a callback and sender_as_parameter
        After(my_object.SetAlpha, event, sender_as_parameter=True)

        my_object.SetAlpha(3)

        assert 3 == self._value

        Remove(my_object.SetAlpha, event)

        my_object.SetAlpha(4)
        assert 3 == self._value
コード例 #21
0
ファイル: test_singleton.py プロジェクト: nicoddemus/oop-ext
def testSingletonOptimization() -> None:
    class MySingleton(Singleton):
        pass

    class MockClass:
        called = False

        def ObtainStack(self, *args, **kwargs):
            self.called = True

    obj = MockClass()
    After(MySingleton._ObtainStack, obj.ObtainStack)

    obj.called = False
    MySingleton.GetSingleton()
    assert obj.called

    obj.called = False
    MySingleton.GetSingleton()
    assert not obj.called
コード例 #22
0
def testCallbackAndInterfaces() -> None:
    """
    Tests if the interface "AssertImplements" works with "callbacked" methods.
    """
    @ImplementsInterface(_InterfM1)
    class My:
        def m1(self):
            ""

    def MyCallback():
        ""

    from oop_ext.foundation.callback import After

    o = My()
    AssertImplements(o, _InterfM1)

    After(o.m1, MyCallback)

    AssertImplements(o, _InterfM1)
    AssertImplements(o, _InterfM1)  # Not raises BadImplementationError
コード例 #23
0
ファイル: test_callback.py プロジェクト: nicoddemus/oop-ext
 def __init__(self):
     Before(self.SetFilename, GetWeakProxy(self._BeforeSetFilename))
     After(self.SetFilename, GetWeakProxy(self._AfterSetFilename))
     self.before = False
     self.after = False