Пример #1
0
def test_external_access():

    rc = Context()
    rc.new_value(a=1)
    rc.new_expression('b', lambda env: env.a + 1)
    rc.new_observer('c', lambda env: env.b + 1)

    b = rc['b'].get_value()
    assert b is 2
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 0

    rc.run()
    assert rc['c'].value is 3
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1

    rc = Context()
    rc.new_value(a=1)
    rc.new_expression('b', lambda env: env.a + 1)
    rc.new_observer('c', lambda env: env.b + 1)

    b = rc['b'].get_value()
    assert b is 2
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 0

    rc.set_value(a=2)
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 0

    raises(Exception, rc.get_value, 'c')
Пример #2
0
def test_isolation_works():

    rc = Context()
    rc.new_value(x=1, y=10)
    rc.new_expression('b', lambda env: env.y + 100)
    rc.new_observer('c', lambda env: env.x + env[:].y + env[:].b)
    rc.new_observer('d', lambda env: env.x + env[:].y + env.b)

    rc.run()
    assert rc['c'].value is 121
    assert rc['c'].exec_count is 1
    assert rc['d'].value is 121
    assert rc['d'].exec_count is 1

    rc.set_value(x=2)
    assert rc['c'].value is 122
    assert rc['c'].exec_count is 2
    assert rc['d'].value is 122
    assert rc['d'].exec_count is 2

    rc.set_value(y=20)
    assert rc['c'].value is 122
    assert rc['c'].exec_count is 2
    assert rc['d'].value is 142
    assert rc['d'].exec_count is 3

    rc.set_value(x=3)
    assert rc['c'].value is 143
    assert rc['c'].exec_count is 3
    assert rc['d'].value is 143
    assert rc['d'].exec_count is 4
Пример #3
0
def test_order_of_evaluation():

    rc = Context()
    rc.new_value(a=1)
    rc.new_expression('b', lambda env: env.a + 5)
    rc.new_observer('c', lambda env: env.a * env.b)

    rc.run()
    assert rc['c'].value is 6
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1

    rc.set_value(a=2)
    assert rc['c'].value is 14
    assert rc['b'].exec_count is 2
    assert rc['c'].exec_count is 2

    rc = Context()
    rc.new_value(a=1)
    rc.new_expression('b', lambda env: env.a + 5)
    rc.new_observer('c', lambda env: env.b * env.a)

    rc.run()
    assert rc['c'].value is 6
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1

    rc.set_value(a=2)
    assert rc['c'].value is 14
    assert rc['b'].exec_count is 2
    assert rc['c'].exec_count is 2
Пример #4
0
def test_memoize_and_safe_mode():

    def b1(env):
        if len(env.a) > 0:
            env.a.pop()
        return env.a

    rc = Context(safe=True)
    rc.new_value(a=[1, 2, 3])
    rc.new_expression(b=b1)
    rc.memoize('b')
    rc.new_observer('c', lambda env: env.b)

    raises(Exception, rc.memoize, 'a')
    raises(Exception, rc.memoize, 'c')
    rc.memoize(rc['b'], False)
    assert not rc['b'].memoized
    rc.memoize('b', True)
    assert rc['b'].memoized

    rc.run()
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 4
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.set_value(a=[1, 2, 3])
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 5
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.set_value(a=[1, 2])
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 6
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.safe = False

    rc.set_value(a=[1, 2, 3])
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 7
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.set_value(a=[1])
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 8
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.set_value(a=[10, 20])
    assert rc['b'].exec_count is 5
    assert rc['c'].exec_count is 9
    assert len(rc['b'].value) is 1
    assert len(rc['c'].value) is 1
Пример #5
0
def test_observer_suspending():

    rc = Context()
    rc.new_value(v=1)
    rc.new_expression('a', lambda env: env.v)
    rc.new_observer('b', lambda env: env.a)

    raises(Exception, rc.suspend, 'v')
    raises(Exception, rc.suspend, 'a')
    raises(Exception, rc.resume, 'v')
    raises(Exception, rc.resume, 'a')
    rc.suspend('b')
    rc.run()
    assert rc['a'].exec_count is 1
    assert rc['b'].exec_count is 1

    rc.resume('b')
    rc.run()
    assert rc['a'].exec_count is 1
    assert rc['b'].exec_count is 1

    rc.suspend('b')
    assert not rc['b'].invalidated
    rc.set_value(v=2)
    assert rc['b'].invalidated
    assert rc['a'].exec_count is 1
    assert rc['b'].exec_count is 1

    rc['b'].resume()
    rc.set_value(v=2.5)
    rc['b'].suspend()
    rc.run()
    assert rc['a'].exec_count is 2
    assert rc['b'].exec_count is 2

    rc.set_value(v=3)
    assert rc['a'].exec_count is 2
    assert rc['b'].exec_count is 2

    assert rc['b'].invalidated
    rc.set_value(v=4)
    rc['b'].resume()
    rc.run()
    assert rc['a'].exec_count is 3
    assert rc['b'].exec_count is 3
    assert not rc['b'].invalidated

    rc.suspend('b')
    rc.set_value(v=5)
    rc.resume('b', run=True)
    assert rc['a'].exec_count is 4
    assert rc['b'].exec_count is 4
Пример #6
0
def test_overreactivity_1():

    rc = Context()
    rc.new_value(v=1)
    rc.new_expression('a', lambda env: env.v)
    rc.new_expression('b', lambda env: env.a + env.v)
    rc.new_observer('c', lambda env: env.b)

    rc.run()
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1

    rc.set_value(v=11)
    assert rc['b'].exec_count is 2
    assert rc['c'].exec_count is 2
Пример #7
0
def test_write_then_read():

    def b(env):
        env.a = env[:].a - 1
        return env.a

    rc = Context()
    rc.new_value(a=3)
    rc.new_expression(b=b)
    rc.new_observer('c', lambda env: env.b)

    rc.run()
    assert rc['c'].exec_count is 1

    rc.set_value(a=10)
    assert rc['c'].exec_count is 2
Пример #8
0
def test_undefined_key():

    try:
        raise UndefinedKey('a')
    except UndefinedKey as e:
        assert e.name == 'a'

    rc = Context()
    rc.new_expression('b', lambda env: env.a + 1)
    rc.new_observer('c', lambda env: env.b + 1)
    raises(Exception, lambda: rc['a'])

    rc.run()
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1

    rc.new_value(a=1)
    assert rc['b'].exec_count is 2
    assert rc['c'].exec_count is 2
    assert rc['c'].value is 3
Пример #9
0
def test_overreactivity_2():

    rc = Context()
    rc.new_value(a=1)
    rc.new_expression('b', lambda env: env.a + 5)
    rc.new_observer('c', lambda env: env.b * env.a)
    rc.new_observer('d', lambda env: env.b * env.a)

    rc.run()
    assert rc['c'].value is 6
    assert rc['d'].value is 6
    assert rc['b'].exec_count is 1
    assert rc['c'].exec_count is 1
    assert rc['d'].exec_count is 1

    rc.set_value(a=2)
    assert rc['c'].value is 14
    assert rc['d'].value is 14
    assert rc['b'].exec_count is 2
    assert rc['c'].exec_count is 2
    assert rc['d'].exec_count is 2
Пример #10
0
class TestRecursion(object):

    def setup(self):
        self.rc = Context()
        self.rc.new_value(a=3)
        self.rc.new_observer('c', lambda env: env.b)

    def fn_circular(self, env):
        if env.a is 0:
            return 0
        env.a -= 1
        return env.a

    def fn_recursive(self, env):
        if env.a is 0:
            return 0
        env.a -= 1
        return env.b

    def fn_nonreactive(self, env):
        if self.a is 0:
            return 0
        self.a -= 1
        return env.b

    def test_circular_references(self):
        self.rc.new_expression(b=self.fn_circular)
        self.rc.run()
        assert self.rc['c'].exec_count is 4
        self.rc.set_value(a=3)
        assert self.rc['c'].exec_count is 8

    def test_simple_recursion(self):
        self.rc.new_expression(b=self.fn_recursive)
        self.rc.run()
        assert self.rc['c'].exec_count is 2
        assert self.rc['b'].exec_count is 4

    def test_nonreactive_recursion(self):
        self.a = 3
        self.rc.new_expression(b=self.fn_nonreactive)
        self.rc.run()
        assert self.rc['b'].exec_count is 4
        assert self.rc['c'].value is 0

    def test_circular_observer_only(self):
        self.rc.new_value(b=0)
        self.rc.new_observer(d=self.fn_circular)
        self.rc.run()
        assert self.rc['d'].exec_count is 4
Пример #11
0
def test_safe_mode():

    def b1(env):
        if len(env.a) > 0:
            env.a.pop()
        return env.a

    rc = Context(safe=True)
    rc.new_value(a=[1, 2, 3])
    rc.new_expression(b=b1)
    rc.new_observer('c', lambda env: env.b)

    rc.run()
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 4
    assert len(rc['b'].value) is 0
    assert len(rc['c'].value) is 0

    rc.safe = False
    rc.set_value(a=[1, 2, 3])
    assert rc['b'].exec_count is 5
    assert rc['c'].exec_count is 5
    assert len(rc['b'].value) is 2
    assert len(rc['c'].value) is 2

    def b2(env):
        env.b1.pop()
        return env.a

    rc = Context(safe=True)
    rc.new_value(a=[1, 2, 3])
    rc.new_expression(b1=lambda env: list(env.a))
    rc.new_expression(b2=b2)
    rc.new_observer('c', lambda env: (env.b1, env.b2))

    raises(Exception, rc.run)

    rc = Context(safe=False)
    rc.new_value(a=[1, 2, 3])
    rc.new_expression(b1=lambda env: list(env.a))
    rc.new_expression(b2=b2)
    rc.new_observer('c', lambda env: (env.b1, env.b2))
    rc.run()
    assert rc['b1'].exec_count is 1
    assert rc['b2'].exec_count is 1
    assert rc['c'].exec_count is 1

    def b3(env):
        if len(env.a1) > 0:
            return env.a1.pop()
        return 0

    rc = Context(safe=True)
    a = [1, 2, 3]
    rc.new_value(a1=a, a2=a)
    rc.new_expression(b=b3)
    rc.new_observer('c', lambda env: env.b)
    rc.run()
    assert rc['b'].exec_count is 4
    assert rc['c'].exec_count is 4
    assert rc['b'].value is 0
    assert rc['c'].value is 0
    assert len(rc['a1'].value) is 0
    assert len(rc['a2'].value) is 0
    assert len(a) is 0

    a.extend([1, 2])
    rc.run()
    assert rc['b'].exec_count is 7
    assert rc['c'].exec_count is 7
    assert rc['b'].value is 0
    assert rc['c'].value is 0
    assert len(rc['a1'].value) is 0
    assert len(rc['a2'].value) is 0
    assert len(a) is 0