diff --git a/comtypes/test/test_dispifc_records.py b/comtypes/test/test_dispifc_records.py index 8c289fa1..db0f9d3d 100644 --- a/comtypes/test/test_dispifc_records.py +++ b/comtypes/test/test_dispifc_records.py @@ -86,5 +86,72 @@ def test_record(self): self.assertEqual(rec.needs_clarification, nc) +@unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.") +class Test_Dual(unittest.TestCase): + EXPECTED_INITED_QUESTIONS = "The meaning of life, the universe and everything?" + + def _create_dualifc(self) -> "ComtypesCppTestSrvLib.IDualRecordParamTest": + # Explicitely ask for the dispinterface of the component. + return CreateObject( + "Comtypes.DispIfcParamTests", + clsctx=CLSCTX_LOCAL_SERVER, + interface=ComtypesCppTestSrvLib.IDualRecordParamTest, + ) + + def test_byref(self): + dualifc = self._create_dualifc() + # Passing a record by reference to a method that has declared the parameter + # as [in, out] we expect modifications of the record on the server side to + # also change the record on the client side. + test_record = ComtypesCppTestSrvLib.StructRecordParamTest() + self.assertEqual(test_record.question, None) + self.assertEqual(test_record.answer, 0) + self.assertEqual(test_record.needs_clarification, False) + dualifc.InitRecord(byref(test_record)) + self.assertEqual(test_record.question, self.EXPECTED_INITED_QUESTIONS) + self.assertEqual(test_record.answer, 42) + self.assertEqual(test_record.needs_clarification, True) + + def test_pointer(self): + dualifc = self._create_dualifc() + # Passing a record pointer to a method that has declared the parameter + # as [in, out] we expect modifications of the record on the server side to + # also change the record on the client side. + test_record = ComtypesCppTestSrvLib.StructRecordParamTest() + self.assertEqual(test_record.question, None) + self.assertEqual(test_record.answer, 0) + self.assertEqual(test_record.needs_clarification, False) + dualifc.InitRecord(pointer(test_record)) + self.assertEqual(test_record.question, self.EXPECTED_INITED_QUESTIONS) + self.assertEqual(test_record.answer, 42) + self.assertEqual(test_record.needs_clarification, True) + + def test_record(self): + # Passing a record to a method that has declared the parameter just as [in] + # we expect modifications of the record on the server side NOT to change + # the record on the client side. + # We also need to test if the record gets properly passed to the method on + # the server side. For this, the 'VerifyRecord' method returns 'True' if + # all record fields have values equivalent to the initialization values + # provided by 'InitRecord'. + inited_record = ComtypesCppTestSrvLib.StructRecordParamTest() + inited_record.question = self.EXPECTED_INITED_QUESTIONS + inited_record.answer = 42 + inited_record.needs_clarification = True + for rec, expected, (q, a, nc) in [ + (inited_record, True, (self.EXPECTED_INITED_QUESTIONS, 42, True)), + # Also perform the inverted test. For this, create a blank record. + (ComtypesCppTestSrvLib.StructRecordParamTest(), False, (None, 0, False)), + ]: + with self.subTest(expected=expected, q=q, a=a, nc=nc): + # Perform the check on initialization values. + self.assertEqual(self._create_dualifc().VerifyRecord(rec), expected) + self.assertEqual(rec.question, q) + # Check if the 'answer' field is unchanged although the method + # modifies this field on the server side. + self.assertEqual(rec.answer, a) + self.assertEqual(rec.needs_clarification, nc) + + if __name__ == "__main__": unittest.main()