home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_win32com_test_testGatewayAddresses.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  5.0 KB  |  136 lines

  1. # The purpose of this test is to ensure that the gateways objects
  2. # do the right thing WRT COM rules about object identity etc.
  3.  
  4. # Also includes a basic test that we support inheritance correctly in
  5. # gateway interfaces.
  6.  
  7. # For our test, we create an object of type IID_IPersistStorage
  8. # This interface derives from IPersist.
  9. # Therefore, QI's for IID_IDispatch, IID_IUnknown, IID_IPersist and
  10. # IID_IPersistStorage should all return the same gateway object.
  11. #
  12. # In addition, the interface should only need to declare itself as
  13. # using the IPersistStorage interface, and as the gateway derives
  14. # from IPersist, it should automatically be available without declaration.
  15. #
  16. # We also create an object of type IID_I??, and perform a QI for it.
  17. # We then jump through a number of hoops, ensuring that the objects
  18. # returned by the QIs follow all the rules.
  19. #
  20. # Here is Gregs summary of the rules:
  21. # 1) the set of supported interfaces is static and unchanging
  22. # 2) symmetric: if you QI an interface for that interface, it succeeds
  23. # 3) reflexive: if you QI against A for B, the new pointer must succeed
  24. #   for a QI for A
  25. # 4) transitive: if you QI for B, then QI that for C, then QIÆing A for C
  26. #   must succeed
  27. #
  28. #
  29. # Note that 1) Requires cooperation of the Python programmer.  The rule to keep is:
  30. # "whenever you return an _object_ from _query_interface_(), you must return the
  31. # same object each time for a given IID.  Note that you must return the same
  32. # _wrapped_ object
  33. # you 
  34. # The rest are tested here.
  35.  
  36.  
  37. from win32com.server.util import wrap
  38. import pythoncom
  39. import string
  40. from util import CheckClean
  41.  
  42. numErrors = 0
  43.  
  44. # Check that the 2 objects both have identical COM pointers.
  45. def CheckSameCOMObject(ob1, ob2):
  46.     addr1 = string.split(repr(ob1))[6][:-1]
  47.     addr2 = string.split(repr(ob2))[6][:-1]
  48.     return addr1==addr2
  49.  
  50. # Check that the objects conform to COM identity rules.
  51. def CheckObjectIdentity(ob1, ob2):
  52.     u1 = ob1.QueryInterface(pythoncom.IID_IUnknown)
  53.     u2 = ob2.QueryInterface(pythoncom.IID_IUnknown)
  54.     return CheckSameCOMObject(u1, u2)
  55.  
  56. def FailObjectIdentity(ob1, ob2, when):
  57.     if not CheckObjectIdentity(ob1, ob2):
  58.         global numErrors
  59.         numErrors = numErrors + 1
  60.         print when, "are not identical (%s, %s)" % (`ob1`, `ob2`)
  61.  
  62.  
  63. class Dummy:
  64.     _public_methods_ = [] # We never attempt to make a call on this object.
  65.     _com_interfaces_ = [pythoncom.IID_IPersistStorage]
  66.  
  67. class Dummy2:
  68.     _public_methods_ = [] # We never attempt to make a call on this object.
  69.     _com_interfaces_ = [pythoncom.IID_IPersistStorage, pythoncom.IID_IExternalConnection]
  70.  
  71. class DeletgatedDummy:
  72.     _public_methods_ = []
  73.  
  74. class Dummy3:
  75.     _public_methods_ = [] # We never attempt to make a call on this object.
  76.     _com_interfaces_ = [pythoncom.IID_IPersistStorage]
  77.     def _query_interface_(self, iid):
  78.         if iid==pythoncom.IID_IExternalConnection:
  79.             # This will NEVER work - can only wrap the object once!
  80.             return wrap(DelegatedDummy())
  81.  
  82. def TestGatewayInheritance():    
  83.     # By default, wrap() creates and discards a temporary object.
  84.     # This is not necessary, but just the current implementation of wrap.
  85.     # As the object is correctly discarded, it doesnt affect this test.
  86.     o = wrap(Dummy(), pythoncom.IID_IPersistStorage)
  87.     o2 = o.QueryInterface(pythoncom.IID_IUnknown)
  88.     FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IUnknown")
  89.  
  90.     o3 = o2.QueryInterface(pythoncom.IID_IDispatch)
  91.  
  92.     FailObjectIdentity(o2, o3, "IID_IUnknown->IID_IDispatch")
  93.     FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IDispatch")
  94.  
  95.     o4 = o3.QueryInterface(pythoncom.IID_IPersistStorage)
  96.     FailObjectIdentity(o, o4, "IID_IPersistStorage->IID_IPersistStorage(2)")
  97.     FailObjectIdentity(o2, o4, "IID_IUnknown->IID_IPersistStorage(2)")
  98.     FailObjectIdentity(o3, o4, "IID_IDispatch->IID_IPersistStorage(2)")
  99.  
  100.  
  101.     o5 = o4.QueryInterface(pythoncom.IID_IPersist)
  102.     FailObjectIdentity(o, o5, "IID_IPersistStorage->IID_IPersist")
  103.     FailObjectIdentity(o2, o5, "IID_IUnknown->IID_IPersist")
  104.     FailObjectIdentity(o3, o5, "IID_IDispatch->IID_IPersist")
  105.     FailObjectIdentity(o4, o5, "IID_IPersistStorage(2)->IID_IPersist")
  106.     
  107. def TestMultiInterface():
  108.     o = wrap(Dummy2(), pythoncom.IID_IPersistStorage)
  109.     o2 = o.QueryInterface(pythoncom.IID_IExternalConnection)
  110.  
  111.     FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IExternalConnection")
  112.  
  113.     # Make the same QI again, to make sure it is stable.
  114.     o22 = o.QueryInterface(pythoncom.IID_IExternalConnection)
  115.     FailObjectIdentity(o, o22, "IID_IPersistStorage->IID_IExternalConnection")
  116.     FailObjectIdentity(o2, o22, "IID_IPersistStorage->IID_IExternalConnection (stability)")
  117.  
  118.     o3 = o2.QueryInterface(pythoncom.IID_IPersistStorage)
  119.     FailObjectIdentity(o2, o3, "IID_IExternalConnection->IID_IPersistStorage")
  120.     FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IExternalConnection->IID_IPersistStorage")
  121.  
  122.  
  123. def test():
  124.     TestGatewayInheritance()
  125.     TestMultiInterface()
  126.     if numErrors==0:
  127.         print "Worked ok"
  128.     else:
  129.         print "There were", numErrors, "errors."
  130.  
  131.     
  132. if __name__=='__main__':
  133.     test()
  134.     CheckClean()
  135.  
  136.