import pychrysalide from chrysacase import ChrysalideTestCase from pychrysalide.arch import ArchOperand from pychrysalide.glibext import HashableObject, StringBuilder class TestOperand(ChrysalideTestCase): """TestCase for arch.ArchOperand.""" def testAbstractClass(self): """Forbid operand class instance.""" with self.assertRaisesRegex(RuntimeError, 'pychrysalide.arch.ArchOperand is an abstract class'): pc = ArchOperand() def testStringBuilderMethodsOverriding(self): """Override the StringBuilder interface provided by native implementations.""" class MyOperand(ArchOperand, StringBuilder): def __init__(self): super().__init__(self) def _to_string(self, flags=0): return 'my-op' op = MyOperand() self.assertEqual(op.to_string(), 'my-op') self.assertEqual(str(op), 'my-op') self.assertEqual(f'{op}', 'my-op') def testHashableObjectMethods(self): """Test the HashableObject methods implemantation for operands.""" # Pas d'implementation de particulière de HashableObject, # c'est donc la définition d'implémentation d'ArchOperand # qui s'applique. # Spécificité de l'implémentation GLib : hash 32 bits class DefaultHashableOperand(ArchOperand): pass def_op = DefaultHashableOperand() h = hash(def_op) self.assertEqual(0, h & ~0xffffffff) # Définition particulière de l'opérande, sur la base de # l'implémentation parente. class CustomHashableOperand(ArchOperand, HashableObject): def _hash(self): h = self.parent_hash() h &= ~0xffff return h cust_op = CustomHashableOperand() h = hash(cust_op) self.assertEqual(0, h & 0xffff) self.assertEqual(0, h & ~0xffffffff)