def test_object_deletion(self): """ Checks that Connectors do not inhibit clean object deletion. """ # deletion without explicit garbage collection gc.collect() rel = sumpf.modules.RelabelSignal() rel.SetSignal(sumpf.Signal()) del rel self.assertEqual(gc.collect(), 0) # sumpf.collect_garbage sumpf.connect(self.obj1.GetValue, self.obj2.SetValue) sumpf.connect(self.obj2.GetText, self.obj1.SetText) sumpf.disconnect_all(self.obj1) gc.collect() current_instance_count = ExampleClass.instance_count sumpf.destroy_connectors(self.obj1) del self.obj1 gc.collect() if ExampleClass.instance_count != current_instance_count - 1: for o in gc.garbage: if isinstance(o, ExampleClass): collected = sumpf.collect_garbage() self.assertIsInstance(collected, int) # sumpf.collect_garbage shall return the integer number of collected items self.assertEqual(gc.garbage, []) # garbage collection should have removed all garbage return self.fail("The object has neither been deleted, nor has it been marked as garbage")
def test_disconnect_all(self): """ Tests if the disconnect_all function works as expected. """ sumpf.connect(self.obj1.GetValue, self.obj2.Trigger) sumpf.connect(self.obj1.GetText, self.obj2.Trigger) sumpf.disconnect_all(self.obj2.Trigger) self.obj2.triggered = False self.obj1.SetValue(1) self.obj1.SetText("1") self.assertFalse(self.obj2.triggered) # disconnect_all should have removed all connections to GetTriggered sumpf.connect(self.obj1.GetValue, self.obj2.Trigger) sumpf.connect(self.obj1.GetText, self.obj2.Trigger) sumpf.connect(self.obj1.GetValue, self.obj2.SetValue) sumpf.connect(self.obj1.GetValue2, self.obj2.SetValueNoUpdate) sumpf.connect(self.obj2.GetValue, self.obj1.SetValueNoUpdate) sumpf.connect(self.obj1.GetValue, self.obj2.AddItemNoReplace) sumpf.connect(self.obj1.GetValue2, self.obj2.AddItemNoReplace) sumpf.disconnect_all(self.obj2) self.obj2.SetValue(3) self.assertEqual(self.obj1.GetValue(), 2) # disconnect_all should have removed the connection from obj2.GetValue to obj1.SetValueNoUpdate self.obj2.SetText("3") self.obj2.triggered = False self.obj1.SetValue(2) self.obj1.SetText("2") self.assertEqual(self.obj2.GetValue(), 3) # disconnect_all should have removed all connections to obj2 self.assertEqual(self.obj2.GetText(), "3") # disconnect_all should have removed all connections to obj2 self.assertFalse(self.obj2.triggered) # disconnect_all should have removed all connections to obj2 self.assertEqual(set(self.obj2.GetItems()), set()) # disconnect_all should have removed all connections to obj2
def test_duplicate_calculation(self): """ Tests if duplicate calculation in forked chains is avoided. """ sumpf.connect(self.obj1.GetValue, self.obj2.SetValue) sumpf.connect(self.obj1.GetValue, self.obj2.SetValue2) sumpf.connect(self.obj2.GetValue, self.obj1.SetValueNoUpdate) self.obj2.history = [] self.obj1.SetValue(1) self.assertEqual(self.obj2.history, [1]) # the value should have been calculated only once sumpf.deactivate_output(self.obj1) self.obj2.history = [] self.obj1.SetValue(2) sumpf.activate_output(self.obj1) self.assertEqual(self.obj2.history, [2]) # the value should have been calculated only once after reactivating outputs sumpf.disconnect_all(self.obj1) sumpf.connect(self.obj1.GetValue, self.obj2.AddItemNoReplace) sumpf.connect(self.obj1.GetValue2, self.obj2.AddItemNoReplace) sumpf.connect(self.obj2.GetItems, self.obj1.TakeList) self.obj2.history = [] self.obj1.SetValue2(3) self.assertEqual(self.obj2.history, [[3, 6]]) # the list should have been calculated only once
def Destroy(self): sumpf.disconnect_all(self.__input) sumpf.disconnect_all(self.__inversion)
def test_connection_observers(testcase, inputs, noinputs, output): """ A function to test if an OutputConnector is affected by the correct inputs. @param testcase: the TestCase instance which shall raise an error if something is not as expected @param inputs: the inputs that shall affect the output @param noinputs: the inputs that shall not affect the output @param output: the output that shall be affected """ try: # deep testing of connector dependencies class ConnectionTester(object): def __init__(self): self.triggered = False @sumpf.Trigger() def Trigger(self): self.triggered = True def Untrigger(self): result = self.triggered self.triggered = False return result def call_input_connector(connector): c = connector if isinstance(connector, sumpf.internal.ConnectorProxy): c = connector.GetConnector() if isinstance(c, sumpf.internal.TypedConnector): if c.GetType() in [int, float, complex]: try: c(c.GetType()(2.0)) # try passing an even, non-zero value except ValueError: try: c(c.GetType()(0.7)) # try passing a value between 0.0 and 1.0 except ValueError: try: c(c.GetType()(1.0)) # try passing one except ValueError: c(c.GetType()(0.0)) # try passing zero elif not issubclass(c.GetType(), str) and issubclass(c.GetType(), collections.Iterable): try: c(c.GetType()([1, 2])) # pass an iterable with two integers with ascending value to avoid raising errors except IndexError: c(c.GetType()([0])) # if an IndexError is raised, pass an iterable with the index that most likely exists else: try: c(c.GetType()()) except ValueError: raise TypeError("Skip to shallow testing") else: c() ct = ConnectionTester() sumpf.connect(output, ct.Trigger) for i in inputs: call_input_connector(i) testcase.assertTrue(ct.Untrigger()) for i in noinputs: call_input_connector(i) testcase.assertFalse(ct.Untrigger()) sumpf.disconnect_all(ct) except TypeError: # shallow testing of connector dependencies, when automatic creation of # test parameters fails o = output if isinstance(output, sumpf.internal.ConnectorProxy): o = output.GetConnector() for i in inputs: testcase.assertIn(o, i.GetObservers()) for i in noinputs: testcase.assertNotIn(o, i.GetObservers())