async def test_operator_neg(self): a = var(2) res = -a self.assertEqual(ev(res), -2) a @= -5 self.assertEqual(ev(res), 5)
async def test_exception_propagation(self): a = var(None) b = var() res = my_sum(a=a, b=b) self.assertIsNotNone(ev_exception(res)) with self.assertRaisesRegex(Exception, r'.*b.*'): ev(res)
async def test_not_initialized(self): not_initialized = var() res = process_positive_num(not_initialized) with self.assertRaises(ArgEvalError) as cm: ev(res) self.assertIsInstance(cm.exception.__cause__, NotInitializedError)
async def test_operator_add(self): a = var(2) b = const(5) res = a + b self.assertEqual(ev(res), 7) a @= 6 self.assertEqual(ev(res), 11) # 6+5
async def test_var_changes(self): a = var(2) b = var(5) res = my_sum(a=a, b=b) a @= 6 self.assertEqual(ev(res), 11) # 6+5 b @= 3 self.assertEqual(ev(res), 9) # 6+3
async def test_operator_assign_add(self): a = var(2) res = a + 5 self.assertEqual(ev(res), 7) a += 3 self.assertEqual(ev(a), 5) self.assertEqual(ev(res), 10)
async def test_not_none(self): a = var(None) with self.assertRaises(EvalError): res = process_positive_num(a) res2 = process_positive_num(not_none(a)) with self.assertRaises(ArgEvalError): ev(res2)
async def test_with_const_arg(self): global some_observable res = func_with_default(5) self.assertTrue(isinstance(res, Observable)) self.assertEqual(1, called_times2) self.assertEqual(8, ev(res)) self.assertEqual(1, called_times2) some_observable @= 100 ev(res) self.assertEqual(2, called_times2) self.assertEqual(105, ev(res))
async def test_operator_cmp(self): a = var(2) b = var(5) a_greater = a > b self.assertFalse(ev(a_greater)) a @= 5 self.assertFalse(ev(a_greater)) a @= 6 self.assertTrue(ev(a_greater))
async def test_operator_var_index(self): a = var() b = var() res = a[b] b @= 2 a @= [1, 2, 3] self.assertEqual(ev(res), 3) b @= 0 self.assertEqual(ev(res), 1)
async def test_lambda_validator(self): a = var(-1) with self.assertRaises(EvalError) as cm: res = process_positive_num(a) self.assertIsInstance(cm.exception.__cause__, AssertionError) res2 = process_positive_num(validate_arg(a, lambda x: x > 0)) with self.assertRaises(ArgEvalError) as cm: ev(res2) self.assertIsInstance(cm.exception.__cause__, ValidationError)
async def test_1(self): global some_observable a = var(5) b = var(3) res = pass_args(a, b) self.assertTrue(isinstance(res, Observable)) self.assertEqual(8, ev(res)) self.assertEqual(1, called_times2) a @= 10 self.assertEqual(8, ev(res)) self.assertEqual(1, called_times2) b @= 100 self.assertEqual(110, ev(res)) self.assertEqual(2, called_times2)
async def test_operator_getitem_setitem_delitem(self): a = var() res = a[1] with self.assertRaises(ArgEvalError): ev(res) a @= [1, 2, 3] self.assertEqual(ev(res), 2) a[1] = 'hej' self.assertEqual(ev(res), 'hej') del a[1] self.assertEqual(ev(res), 3)
async def test_exception_propagation(self): b = var() res = sum_with_yield(2, b=b) self.assertIsInstance(res, Observable) gc.collect() self.assertIsNotNone(ev_exception(res)) self.assertEqual(0, inside) with self.assertRaisesRegex(Exception, r'.*b.*'): ev(res) b @= 5 await asyncio.sleep(0.1) gc.collect() self.assertIsNone(ev_exception(res)) self.assertEqual(7, ev(res)) self.assertEqual(1, inside)
async def test_with_raw(self): res = sum_with_yield(2, 5) # in this case we must return something that finalizes the function when destroyed self.assertIsInstance(res, Observable) self.assertEqual(ev(res), 7) self.assertEqual(inside, 1) del res await asyncio.sleep(0.5) gc.collect() self.assertEqual(inside, 0)
async def test_a(self): b = var(5) res = sum_with_yield(2, b=b) self.assertIsInstance(res, Observable) self.assertEqual(ev(res), 7) gc.collect() self.assertEqual(inside, 1) b @= (1) print("w1") self.assertEqual(ev(res), 3) self.assertEqual(inside, 1) # await res.dispose() del b gc.collect() # weak_res = weakref.ref(res) # print(gc.get_referrers(res)) del res gc.collect() await asyncio.sleep(0.5) self.assertEqual(inside, 0) print("finished)")
async def test_vars(self): global called_times called_times = 0 a = var(None) res = inc_called_times(a) ev(res) self.assertEqual(1, called_times) a @= 55 await asyncio.sleep(0.1) ev(res) self.assertEqual(2, called_times) some_observable.__notifier__.notify() await asyncio.sleep(1) ev(res) self.assertEqual(3, called_times) some_observable.__notifier__.notify() await asyncio.sleep(1) ev(res) self.assertEqual(4, called_times)
async def test_operator_getitem_and_exception(self): a = var(('a', 'b')) res = a[1] self.assertEqual(ev(res), 'b') a @= ('A', 'B', 'C') self.assertEqual(ev(res), 'B') a @= ('A', ) with self.assertRaises(EvalError): ev(res) a @= 5 with self.assertRaises(EvalError): ev(res) # check if it works again a @= (1, 2, 3) self.assertEqual(ev(res), 2)
async def test_operator_mul_numpy(self): import numpy as np a = var(2) b = np.array([1, 2]) res = a * b assert_array_equal(ev(res), np.array([2, 4]))
async def test_var_var(self): a = var(2) b = var(5) res = my_sum(a=a, b=b) self.assertIsInstance(res, Observable) self.assertEqual(ev(res), 7)
async def test_var_val_keyword(self): a = var(2) res = my_sum(a=a, b=5) self.assertIsInstance(res, Observable) self.assertEqual(ev(res), 7)
async def test_var_val_positional(self): a = var(2) res = my_sum(a, 5) self.assertIsInstance(res, Observable) self.assertEqual(ev(res), 7)
def pass_args(a, b): global called_times2 called_times2 += 1 return ev(a) + b