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_testvb.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  12.5 KB  |  334 lines

  1. # Test code for a VB Program.
  2. #
  3. # This requires the PythonCOM VB Test Harness.
  4. #
  5.  
  6. import winerror
  7. import pythoncom, win32com.client, win32com.client.dynamic, win32com.client.gencache
  8. from win32com.server.util import NewCollection, wrap
  9. import string
  10.  
  11. importMsg = """\
  12. **** VB Test harness is not installed ***
  13.   This test requires a VB test program to be built and installed
  14.   on this PC.
  15. """
  16.  
  17. ### NOTE: VB SUCKS!
  18. ### If you delete the DLL built by VB, then reopen VB
  19. ### to rebuild the DLL, it loses the IID of the object!!!
  20. ### So I will try to avoid this in the future :-)
  21.  
  22. # Import the type library for the test module.
  23. try:
  24.     win32com.client.gencache.EnsureModule('{32C85CE8-0035-11D3-8546-204C4F4F5020}', 0, 5, 0)
  25. except pythoncom.com_error:
  26.     raise RuntimeError, importMsg
  27.  
  28. import traceback
  29.  
  30. error = "VB Test Error"
  31.  
  32. # Set up a COM object that VB will do some callbacks on.  This is used
  33. # to test byref params for gateway IDispatch.
  34. class TestObject:
  35.     _public_methods_ = ["CallbackVoidOneByRef","CallbackResultOneByRef", "CallbackVoidTwoByRef",
  36.                         "CallbackString","CallbackResultOneByRefButReturnNone",
  37.                         "CallbackVoidOneByRefButReturnNone",
  38.                         "CallbackArrayResult", "CallbackArrayResultOneArrayByRef",
  39.                         "CallbackArrayResultWrongSize"
  40.                        ]
  41.     def CallbackVoidOneByRef(self, intVal):
  42.         return intVal + 1
  43.     def CallbackResultOneByRef(self, intVal):
  44.         return intVal, intVal + 1
  45.     def CallbackVoidTwoByRef(self, int1, int2):
  46.         return int1+int2, int1-int2
  47.     def CallbackString(self, strVal):
  48.         return 0, strVal + " has visited Python"
  49.     def CallbackArrayResult(self, arrayVal):
  50.         ret = []
  51.         for i in arrayVal:
  52.             ret.append(i+1)
  53.         # returning as a list forces it be processed as a single result
  54.         # (rather than a tuple, where it may be interpreted as
  55.         # multiple results for byref unpacking)
  56.         return ret
  57.     def CallbackArrayResultWrongSize(self, arrayVal):
  58.         return list(arrayVal[:-1])
  59.     def CallbackArrayResultOneArrayByRef(self, arrayVal):
  60.         ret = []
  61.         for i in arrayVal:
  62.             ret.append(i+1)
  63.         # See above for list processing.
  64.         return list(arrayVal), ret
  65.     
  66.     def CallbackResultOneByRefButReturnNone(self, intVal):
  67.         return
  68.     def CallbackVoidOneByRefButReturnNone(self, intVal):
  69.         return
  70.  
  71. def TestVB( vbtest, bUseGenerated ):
  72.     vbtest.LongProperty = -1
  73.     if vbtest.LongProperty != -1:
  74.         raise error, "Could not set the long property correctly."
  75.     vbtest.IntProperty = 10
  76.     if vbtest.IntProperty != 10:
  77.         raise error, "Could not set the integer property correctly."
  78.     vbtest.VariantProperty = 10
  79.     if vbtest.VariantProperty != 10:
  80.         raise error, "Could not set the variant integer property correctly."
  81.     vbtest.StringProperty = "Hello from Python"
  82.     if vbtest.StringProperty != "Hello from Python":
  83.         raise error, "Could not set the string property correctly."
  84.     vbtest.VariantProperty = "Hello from Python"
  85.     if vbtest.VariantProperty != "Hello from Python":
  86.         raise error, "Could not set the variant string property correctly."
  87.     vbtest.VariantProperty = (1.0, 2.0, 3.0)
  88.     if vbtest.VariantProperty != (1.0, 2.0, 3.0):
  89.         raise error, "Could not set the variant property to an array of floats correctly - '%s'." % (vbtest.VariantProperty,)
  90.     
  91.  
  92.     # Try and use a safe array (note that the VB code has this declared as a VARIANT
  93.     # and I cant work out how to force it to use native arrays!
  94.     # (NOTE Python will convert incoming arrays to tuples, so we pass a tuple, even tho
  95.     # a list works fine - just makes it easier for us to compare the result!
  96.     arrayData = tuple(range(1,100))
  97.     vbtest.ArrayProperty = arrayData
  98.     if vbtest.ArrayProperty != arrayData:
  99.         raise error, "Could not set the array data correctly - got back " + str(vbtest.ArrayProperty)
  100.     # Floats
  101.     arrayData = (1.0, 2.0, 3.0)
  102.     vbtest.ArrayProperty = arrayData
  103.     assert vbtest.ArrayProperty == arrayData, "Could not set the array data correctly - got back '%s'" % (vbtest.ArrayProperty,)
  104.     # Strings.
  105.     arrayData = tuple(string.split("Hello from Python"))
  106.     vbtest.ArrayProperty = arrayData
  107.     assert vbtest.ArrayProperty == arrayData, "Could not set the array data correctly - got back '%s'" % (vbtest.ArrayProperty,)
  108.     # Date and Time?
  109.     # COM objects.
  110.     arrayData = (vbtest, vbtest)
  111.     vbtest.ArrayProperty = arrayData
  112.     assert vbtest.ArrayProperty == arrayData, "Could not set the array data correctly - got back '%s'" % (vbtest.ArrayProperty,)
  113.     # Mixed
  114.     arrayData = (1, 2.0, "3")
  115.     vbtest.ArrayProperty = arrayData
  116.     assert vbtest.ArrayProperty == arrayData, "Could not set the array data correctly - got back '%s'" % (vbtest.ArrayProperty,)
  117.  
  118.     TestStructs(vbtest)
  119.  
  120.     assert vbtest.TakeByValObject(vbtest)==vbtest
  121.  
  122.     # Python doesnt support PUTREF properties without a typeref
  123.     # (although we could)
  124.     if bUseGenerated:
  125.         ob = vbtest.TakeByRefObject(vbtest)
  126.         assert ob[0]==vbtest and ob[1]==vbtest
  127.  
  128.         # A property that only has PUTREF defined.
  129.         vbtest.VariantPutref = vbtest
  130.         if vbtest.VariantPutref._oleobj_!= vbtest._oleobj_:
  131.             raise error, "Could not set the VariantPutref property correctly."
  132.         # Cant test further types for this VariantPutref, as only
  133.         # COM objects can be stored ByRef.
  134.  
  135.         # A "set" type property - only works for generated.
  136.         print "Skipping CollectionProperty - how does VB recognize a collection object??"
  137. #        vbtest.CollectionProperty = NewCollection((1,2,"3", "Four"))
  138. #        if vbtest.CollectionProperty != (1,2,"3", "Four"):
  139. #            raise error, "Could not set the Collection property correctly - got back " + str(vbtest.CollectionProperty)
  140.  
  141.         # This one is a bit strange!  The array param is "ByRef", as VB insists.
  142.         # The function itself also _returns_ the arram param.
  143.         # Therefore, Python sees _2_ result values - one for the result,
  144.         # and one for the byref.
  145.         testData = string.split("Mark was here")
  146.         resultData, byRefParam = vbtest.PassSAFEARRAY(testData)
  147.         # Un unicode everything (only 1.5.2)
  148.         try:
  149.             unicode
  150.         except NameError : # No builtin named Unicode!
  151.             resultData = map(str, resultData)
  152.             byRefParam = map(str, byRefParam)
  153.         if testData != list(resultData):
  154.             raise error, "The safe array data was not what we expected - got " + str(resultData)
  155.         if testData != list(byRefParam):
  156.             raise error, "The safe array data was not what we expected - got " + str(byRefParam)
  157.         testData = [1.0, 2.0, 3.0]
  158.         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
  159.         assert testData == list(byRefParam)
  160.         assert testData == list(resultData)
  161.         testData = ["hi", "from", "Python"]
  162.         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
  163.         # Seamless Unicode only in 1.6!
  164.         try:
  165.             unicode
  166.         except NameError : # No builtin named Unicode!
  167.             byRefParam = map(str, byRefParam)
  168.             resultData = map(str, resultData)
  169.         assert testData == list(byRefParam), "Expected '%s', got '%s'" % (testData, list(byRefParam))
  170.         assert testData == list(resultData), "Expected '%s', got '%s'" % (testData, list(resultData))
  171.         # This time, instead of an explicit str() for 1.5, we just
  172.         # pass Unicode, so the result should compare equal
  173.         testData = [1, 2.0, pythoncom.Unicode("3")]
  174.         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
  175.         assert testData == list(byRefParam)
  176.         assert testData == list(resultData)
  177.  
  178.         # These are sub's that have a single byref param
  179.         # Result should be just the byref.
  180.         if vbtest.IncrementIntegerParam(1) != 2:
  181.             raise error, "Could not pass an integer byref"
  182.  
  183.         if vbtest.IncrementIntegerParam() != 1:
  184.             raise error, "Could not pass an omitted integer byref"
  185.  
  186.         if vbtest.IncrementVariantParam(1) != 2:
  187.             raise error, "Could not pass an int VARIANT byref:"+str(vbtest.IncrementVariantParam(1))
  188.  
  189.         if vbtest.IncrementVariantParam(1.5) != 2.5:
  190.             raise error, "Could not pass a float VARIANT byref"
  191.  
  192.         # Can't test IncrementVariantParam with the param omitted as it
  193.         # it not declared in the VB code as "Optional"
  194.         useDispatcher = None
  195. ##        import win32com.server.dispatcher
  196. ##        useDispatcher = win32com.server.dispatcher.DefaultDebugDispatcher
  197.         callback_ob = wrap(TestObject(), useDispatcher = useDispatcher)
  198.         vbtest.DoSomeCallbacks(callback_ob)
  199.  
  200.         # Check we fail gracefully for byref safearray results with incorrect size.
  201.         try:
  202.             vbtest.DoCallbackSafeArraySizeFail(callback_ob)
  203.         except pythoncom.com_error, (hr, msg, exc, arg):
  204.             assert exc[1] == "Python COM Server Internal Error", "Didnt get the correct exception - '%s'" % (exc,)
  205.  
  206.     ret = vbtest.PassIntByVal(1)
  207.     if ret != 2:
  208.         raise error, "Could not increment the integer - "+str(ret)
  209.  
  210.     # Python doesnt support byrefs without some sort of generated support.
  211.     if bUseGenerated:
  212.         # This is a VB function that takes a single byref
  213.         # Hence 2 return values - function and byref.
  214.         ret = vbtest.PassIntByRef(1)
  215.         if ret != (1,2):
  216.             raise error, "Could not increment the integer - "+str(ret)
  217.         # Check you can leave a byref arg blank.
  218.         ret = vbtest.PassIntByRef()
  219.         if ret != (0,1):
  220.             raise error, "Could not increment the integer with default arg- "+str(ret)
  221.  
  222. def TestStructs(vbtest):
  223.     try:
  224.         vbtest.IntProperty = "One"
  225.     except pythoncom.com_error, (hr, desc, exc, argErr):
  226.         if hr != winerror.DISP_E_TYPEMISMATCH:
  227.             raise error, "Expected DISP_E_TYPEMISMATCH"
  228.  
  229.     s = vbtest.StructProperty
  230.     if s.int_val != 99 or str(s.str_val) != "hello":
  231.         raise error, "The struct value was not correct"
  232.     s.str_val = "Hi from Python"
  233.     s.int_val = 11
  234.     if s.int_val != 11 or str(s.str_val) != "Hi from Python":
  235.         raise error, "The struct value didnt persist!"
  236.     
  237.     if s.sub_val.int_val != 66 or str(s.sub_val.str_val) != "sub hello":
  238.         raise error, "The sub-struct value was not correct"
  239.     sub = s.sub_val
  240.     sub.int_val = 22
  241.     if sub.int_val != 22:
  242.         print sub.int_val
  243.         raise error, "The sub-struct value didnt persist!"
  244.         
  245.     if s.sub_val.int_val != 22:
  246.         print s.sub_val.int_val
  247.         raise error, "The sub-struct value (re-fetched) didnt persist!"
  248.  
  249.     if s.sub_val.array_val[0].int_val != 0 or str(s.sub_val.array_val[0].str_val) != "zero":
  250.         print s.sub_val.array_val[0].int_val
  251.         raise error, "The array element wasnt correct"
  252.     s.sub_val.array_val[0].int_val = 99
  253.     s.sub_val.array_val[1].int_val = 66
  254.     if s.sub_val.array_val[0].int_val != 99 or \
  255.        s.sub_val.array_val[1].int_val != 66:
  256.         print s.sub_val.array_val[0].int_val
  257.         raise error, "The array element didnt persist."
  258.     # Now pass the struct back to VB
  259.     vbtest.StructProperty = s
  260.     # And get it back again
  261.     s = vbtest.StructProperty
  262.     if s.int_val != 11 or str(s.str_val) != "Hi from Python":
  263.         raise error, "After sending to VB, the struct value didnt persist!"
  264.     if s.sub_val.array_val[0].int_val != 99:
  265.         raise error, "After sending to VB, the struct array value didnt persist!"
  266.  
  267.     # Now do some object equality tests.
  268.     assert s==s
  269.     assert s != s.sub_val
  270.     import copy
  271.     s2 = copy.copy(s)
  272.     assert s is not s2
  273.     assert s == s2
  274.     s2.int_val = 123
  275.     assert s != s2
  276.     # Make sure everything works with functions
  277.     s2 = vbtest.GetStructFunc()
  278.     assert s==s2
  279.     vbtest.SetStructSub(s2)
  280.  
  281.     # Create a new structure, and set its elements.
  282.     s = win32com.client.Record("VBStruct", vbtest)
  283.     assert s.int_val == 0, "new struct inst initialized correctly!"
  284.     s.int_val = -1
  285.     vbtest.SetStructSub(s)
  286.     assert vbtest.GetStructFunc().int_val == -1, "new struct didnt make the round trip!"
  287.     # Finally, test stand-alone structure arrays.
  288.     s_array = vbtest.StructArrayProperty
  289.     assert s_array is None, "Expected None from the uninitialized VB array"
  290.     vbtest.MakeStructArrayProperty(3)
  291.     s_array = vbtest.StructArrayProperty
  292.     assert len(s_array)==3
  293.     for i in range(len(s_array)):
  294.         assert s_array[i].int_val == i
  295.         assert s_array[i].sub_val.int_val == i
  296.         assert s_array[i].sub_val.array_val[0].int_val == i
  297.         assert s_array[i].sub_val.array_val[1].int_val == i+1
  298.         assert s_array[i].sub_val.array_val[2].int_val == i+2
  299.  
  300.     # Some error type checks.
  301.     try:
  302.         s.bad_attribute
  303.         raise RuntimeError, "Could get a bad attribute"
  304.     except AttributeError:
  305.         pass
  306.     m = s.__members__
  307.     assert m[0]=="int_val" and m[1]=="str_val" and m[2]=="ob_val" and m[3]=="sub_val"
  308.         
  309.     # NOTE - a COM error is _not_ acceptable here!
  310.     print "Struct/Record tests passed"
  311.  
  312. def DoTestAll():
  313.     o = win32com.client.Dispatch("PyCOMVBTest.Tester")
  314.     TestVB(o,1)
  315.  
  316.     o = win32com.client.dynamic.DumbDispatch("PyCOMVBTest.Tester")
  317.     TestVB(o,0)
  318.         
  319. def TestAll():
  320.     if not __debug__:
  321.         raise RuntimeError, "This must be run in debug mode - we use assert!"
  322.     try:
  323.         DoTestAll()
  324.         print "All tests appear to have worked!"
  325.     except:
  326.         traceback.print_exc()
  327.  
  328. if __name__=='__main__':
  329.     from util import CheckClean
  330.     TestAll()
  331.     CheckClean()
  332.  
  333.     pythoncom.CoUninitialize()
  334.