class BasicFlockTestCase(unittest.TestCase): """ Tests of the basic operations of a flock """ def setUp(self): super().setUp() self.flock = FlockDict() def test_simple_values(self): """ Test that simple(non-dict, non-callable) values are stored and retrieved transparently. """ assert len(self.flock) == 0 self.flock[3] = 3 assert self.flock[3] == 3 assert len(self.flock) == 1 self.flock["Shepherd"] = "Mary" assert len(self.flock) == 2 self.assertEqual(self.flock["Shepherd"], "Mary") self.flock["Management"] = ["Mary", "Joshua", "Isaac"] assert len(self.flock) == 3 self.assertEqual(self.flock["Management"], ["Mary", "Joshua", "Isaac"]) self.flock["Shepherd"] = "John" self.assertEqual(self.flock["Shepherd"], "John") assert "Shepherd" in self.flock assert 'missing' not in self.flock del self.flock["Shepherd"] assert "Shepherd" not in self.flock def test_simple_dict(self): """ Test that nested dicts still look like dicts. """ self.flock["Management"] = {"Mary": {"lambs": 1, "size": 'little'}} assert self.flock["Management"]["Mary"]['lambs'] == 1 assert self.flock["Management"]["Mary"]['size'] == 'little' def test_simple_closure(self): """ Test that simple closures are stored without mangling and evaluated on retrieval """ self.flock["lamb"] = lambda: "little" self.assertEqual(self.flock["lamb"], "little") def test_callable_with_arguments(self): """ Test that callables with arguments are passed transparently and never called """ self.flock["func"] = lambda x, y: x + y self.assertEqual(self.flock["func"](1, 2), 3) def test2(x, y): assert False self.flock["test2"] = test2 assert test2 == self.flock["test2"] # Testing that this is not called def test_error(self): self.flock["bad"] = lambda: 1 / 0 assert 'bad' in self.flock with raises(FlockException) as exc_info: self.flock.pop('bad') assert isinstance(exc_info.value.__cause__, ZeroDivisionError) with raises(FlockException) as exc_info: assert self.flock['bad'] != ( lambda: 1 / 0), "This should not be called at all as the exception should be raised" assert isinstance(exc_info.value.__cause__, ZeroDivisionError) with raises(FlockException) as exc_info: self.flock.shear() assert isinstance(exc_info.value.__cause__, ZeroDivisionError) error = self.flock.shear(record_errors=True)['bad'] assert isinstance(error, FlockException) assert isinstance(error.__cause__, ZeroDivisionError) def test_shear(self): """ Test trivial shear operation """ self.flock[3] = 15 assert not self.flock.check() sheared = self.flock.shear() assert len(sheared) == 1 assert isinstance(sheared, dict) assert sheared[3] == 15 self.flock['cat'] = lambda: 'Abbey' assert not self.flock.check() sheared = self.flock.shear() assert len(sheared) == 2 assert isinstance(sheared, dict) assert sheared['cat'] == 'Abbey' assert sheared[3] == 15 assert self.flock.dataset() == {'cat':'Abbey',3:15} assert len(self.flock.ruleset()) == 0 assert not self.flock.ruleset() def test_consistent_shear(self): t = toggle() self.flock['toggle'] = t self.flock['toggle2'] = t self.flock.update({x: lambda: self.flock['toggle'] for x in range(5)}) sheared = self.flock.shear() self.assertEqual(sheared['toggle'], not sheared['toggle2']) self.assertEqual([sheared['toggle']] * 5, [sheared[x] for x in range(5)]) assert len(self.flock.dataset()) == 0 assert not self.flock.dataset() assert len(self.flock.ruleset()) == 7 assert all(isinstance(x, FunctionType) for x in self.flock.ruleset().values())