PyXR

c:\python24\lib\site-packages\win32 \ com \ test \ testvb.py



0001 # Test code for a VB Program.
0002 #
0003 # This requires the PythonCOM VB Test Harness.
0004 #
0005 
0006 import winerror
0007 import pythoncom, win32com.client, win32com.client.dynamic, win32com.client.gencache
0008 from win32com.server.util import NewCollection, wrap
0009 import string
0010 import util
0011 
0012 importMsg = """\
0013 **** VB Test harness is not installed ***
0014   This test requires a VB test program to be built and installed
0015   on this PC.
0016 """
0017 
0018 ### NOTE: VB SUCKS!
0019 ### If you delete the DLL built by VB, then reopen VB
0020 ### to rebuild the DLL, it loses the IID of the object!!!
0021 ### So I will try to avoid this in the future :-)
0022 
0023 # Import the type library for the test module.
0024 try:
0025     win32com.client.gencache.EnsureDispatch("PyCOMVBTest.Tester")
0026 except pythoncom.com_error:
0027     raise RuntimeError, importMsg
0028 
0029 import traceback
0030 
0031 # for debugging
0032 useDispatcher = None
0033 ##  import win32com.server.dispatcher
0034 ##  useDispatcher = win32com.server.dispatcher.DefaultDebugDispatcher
0035 
0036 error = "VB Test Error"
0037 
0038 # Set up a COM object that VB will do some callbacks on.  This is used
0039 # to test byref params for gateway IDispatch.
0040 class TestObject:
0041     _public_methods_ = ["CallbackVoidOneByRef","CallbackResultOneByRef", "CallbackVoidTwoByRef",
0042                                         "CallbackString","CallbackResultOneByRefButReturnNone",
0043                                         "CallbackVoidOneByRefButReturnNone",
0044                                         "CallbackArrayResult", "CallbackArrayResultOneArrayByRef",
0045                                         "CallbackArrayResultWrongSize"
0046                                        ]
0047     def CallbackVoidOneByRef(self, intVal):
0048         return intVal + 1
0049     def CallbackResultOneByRef(self, intVal):
0050         return intVal, intVal + 1
0051     def CallbackVoidTwoByRef(self, int1, int2):
0052         return int1+int2, int1-int2
0053     def CallbackString(self, strVal):
0054         return 0, strVal + " has visited Python"
0055     def CallbackArrayResult(self, arrayVal):
0056         ret = []
0057         for i in arrayVal:
0058             ret.append(i+1)
0059         # returning as a list forces it be processed as a single result
0060         # (rather than a tuple, where it may be interpreted as
0061         # multiple results for byref unpacking)
0062         return ret
0063     def CallbackArrayResultWrongSize(self, arrayVal):
0064         return list(arrayVal[:-1])
0065     def CallbackArrayResultOneArrayByRef(self, arrayVal):
0066         ret = []
0067         for i in arrayVal:
0068             ret.append(i+1)
0069         # See above for list processing.
0070         return list(arrayVal), ret
0071 
0072     def CallbackResultOneByRefButReturnNone(self, intVal):
0073         return
0074     def CallbackVoidOneByRefButReturnNone(self, intVal):
0075         return
0076 
0077 def TestVB( vbtest, bUseGenerated ):
0078     vbtest.LongProperty = -1
0079     if vbtest.LongProperty != -1:
0080         raise error, "Could not set the long property correctly."
0081     vbtest.IntProperty = 10
0082     if vbtest.IntProperty != 10:
0083         raise error, "Could not set the integer property correctly."
0084     vbtest.VariantProperty = 10
0085     if vbtest.VariantProperty != 10:
0086         raise error, "Could not set the variant integer property correctly."
0087     vbtest.StringProperty = "Hello from Python"
0088     if vbtest.StringProperty != "Hello from Python":
0089         raise error, "Could not set the string property correctly."
0090     vbtest.VariantProperty = "Hello from Python"
0091     if vbtest.VariantProperty != "Hello from Python":
0092         raise error, "Could not set the variant string property correctly."
0093     vbtest.VariantProperty = (1.0, 2.0, 3.0)
0094     if vbtest.VariantProperty != (1.0, 2.0, 3.0):
0095         raise error, "Could not set the variant property to an array of floats correctly - '%s'." % (vbtest.VariantProperty,)
0096 
0097     TestArrays(vbtest, bUseGenerated)
0098     TestStructs(vbtest)
0099     TestCollections(vbtest)
0100 
0101     assert vbtest.TakeByValObject(vbtest)==vbtest
0102 
0103     # Python doesnt support PUTREF properties without a typeref
0104     # (although we could)
0105     if bUseGenerated:
0106         ob = vbtest.TakeByRefObject(vbtest)
0107         assert ob[0]==vbtest and ob[1]==vbtest
0108 
0109         # A property that only has PUTREF defined.
0110         vbtest.VariantPutref = vbtest
0111         if vbtest.VariantPutref._oleobj_!= vbtest._oleobj_:
0112             raise error, "Could not set the VariantPutref property correctly."
0113         # Cant test further types for this VariantPutref, as only
0114         # COM objects can be stored ByRef.
0115 
0116         # A "set" type property - only works for generated.
0117         # VB recognizes a collection via a few "private" interfaces that we
0118         # could later build support in for.
0119 #               vbtest.CollectionProperty = NewCollection((1,2,"3", "Four"))
0120 #               if vbtest.CollectionProperty != (1,2,"3", "Four"):
0121 #                       raise error, "Could not set the Collection property correctly - got back " + str(vbtest.CollectionProperty)
0122 
0123         # These are sub's that have a single byref param
0124         # Result should be just the byref.
0125         if vbtest.IncrementIntegerParam(1) != 2:
0126             raise error, "Could not pass an integer byref"
0127 
0128 # Sigh - we cant have *both* "ommited byref" and optional args
0129 # We really have to opt that args nominated as optional work as optional
0130 # rather than simply all byrefs working as optional.
0131 #               if vbtest.IncrementIntegerParam() != 1:
0132 #                       raise error, "Could not pass an omitted integer byref"
0133 
0134         if vbtest.IncrementVariantParam(1) != 2:
0135             raise error, "Could not pass an int VARIANT byref:"+str(vbtest.IncrementVariantParam(1))
0136 
0137         if vbtest.IncrementVariantParam(1.5) != 2.5:
0138             raise error, "Could not pass a float VARIANT byref"
0139 
0140         # Can't test IncrementVariantParam with the param omitted as it
0141         # it not declared in the VB code as "Optional"
0142         callback_ob = wrap(TestObject(), useDispatcher = useDispatcher)
0143         vbtest.DoSomeCallbacks(callback_ob)
0144 
0145     ret = vbtest.PassIntByVal(1)
0146     if ret != 2:
0147         raise error, "Could not increment the integer - "+str(ret)
0148 
0149     TestVBInterface(vbtest)
0150     # Python doesnt support byrefs without some sort of generated support.
0151     if bUseGenerated:
0152         # This is a VB function that takes a single byref
0153         # Hence 2 return values - function and byref.
0154         ret = vbtest.PassIntByRef(1)
0155         if ret != (1,2):
0156             raise error, "Could not increment the integer - "+str(ret)
0157         # Check you can leave a byref arg blank.
0158 # see above
0159 #               ret = vbtest.PassIntByRef()
0160 #               if ret != (0,1):
0161 #                       raise error, "Could not increment the integer with default arg- "+str(ret)
0162 
0163 def _DoTestCollection(vbtest, col_name, expected):
0164     # It sucks that some objects allow "Count()", but others "Count"
0165     def _getcount(ob):
0166         r = getattr(ob, "Count")
0167         if type(r)!=type(0):
0168             return r()
0169         return r
0170     c = getattr(vbtest, col_name)
0171     check = []
0172     for item in c:
0173         check.append(item)
0174     if check != list(expected):
0175         raise error, "Collection %s didn't have %r (had %r)" % (col_name, expected, check)
0176     # Just looping over the collection again works (ie, is restartable)
0177     check = []
0178     for item in c:
0179         check.append(item)
0180     if check != list(expected):
0181         raise error, "Collection 2nd time around %s didn't have %r (had %r)" % (col_name, expected, check)
0182     # Check we can get it via iter()
0183     i = iter(getattr(vbtest, col_name))
0184     check = []
0185     for item in i:
0186         check.append(item)
0187     if check != list(expected):
0188         raise error, "Collection iterator %s didn't have %r 2nd time around (had %r)" % (col_name, expected, check)
0189     # but an iterator is not restartable
0190     check = []
0191     for item in i:
0192         check.append(item)
0193     if check != []:
0194         raise error, "2nd time around Collection iterator %s wasn't empty (had %r)" % (col_name, check)
0195 
0196     # Check len()==Count()
0197     c = getattr(vbtest, col_name)
0198     if len(c) != _getcount(c):
0199         raise error, "Collection %s __len__(%r) wasn't==Count(%r)" % (col_name, len(c), _getcount(c))
0200     # Check we can do it with zero based indexing.
0201     c = getattr(vbtest, col_name)
0202     check = []
0203     for i in range(_getcount(c)):
0204         check.append(c[i])
0205     if check != list(expected):
0206         raise error, "Collection %s didn't have %r (had %r)" % (col_name, expected, check)
0207 
0208     # Check we can do it with our old "Skip/Next" methods.
0209     c = getattr(vbtest, col_name)._NewEnum()
0210     check = []
0211     while 1:
0212         n = c.Next()
0213         if not n:
0214             break
0215         check.append(n[0])
0216     if check != list(expected):
0217         raise error, "Collection %s didn't have %r (had %r)" % (col_name, expected, check)
0218 
0219 def TestCollections(vbtest):
0220     _DoTestCollection(vbtest, "CollectionProperty", [1,"Two", "3"])
0221     # zero based indexing works for simple VB collections.
0222     if vbtest.CollectionProperty[0] != 1:
0223         raise error, "The CollectionProperty[0] element was not the default value"
0224 
0225     _DoTestCollection(vbtest, "EnumerableCollectionProperty", [])
0226     vbtest.EnumerableCollectionProperty.Add(1)
0227     vbtest.EnumerableCollectionProperty.Add("Two")
0228     vbtest.EnumerableCollectionProperty.Add("3")
0229     _DoTestCollection(vbtest, "EnumerableCollectionProperty", [1,"Two", "3"])
0230 
0231 def _DoTestArray(vbtest, data, expected_exception = None):
0232     try:
0233         vbtest.ArrayProperty = data
0234         if expected_exception is not None:
0235             raise error, "Expected '%s'" % expected_exception
0236     except expected_exception:
0237         return
0238     got = vbtest.ArrayProperty
0239     if got != data:
0240         raise error, \
0241               "Could not set the array data correctly - got %r, expected %r" \
0242               % (got, data)
0243 
0244 def TestArrays(vbtest, bUseGenerated):
0245     # Try and use a safe array (note that the VB code has this declared as a VARIANT
0246     # and I cant work out how to force it to use native arrays!
0247     # (NOTE Python will convert incoming arrays to tuples, so we pass a tuple, even tho
0248     # a list works fine - just makes it easier for us to compare the result!
0249     # Empty array
0250     _DoTestArray(vbtest, ())
0251     # Empty child array
0252     _DoTestArray(vbtest, ((), ()))
0253     # ints
0254     _DoTestArray(vbtest, tuple(range(1,100)))
0255     # Floats
0256     _DoTestArray(vbtest, (1.0, 2.0, 3.0))
0257     # Strings.
0258     _DoTestArray(vbtest, tuple(string.split("Hello from Python")))
0259     # Date and Time?
0260     # COM objects.
0261     _DoTestArray(vbtest, (vbtest, vbtest))
0262     # Mixed
0263     _DoTestArray(vbtest, (1, 2.0, "3"))
0264     # Array alements containing other arrays
0265     _DoTestArray(vbtest, (1,(vbtest, vbtest),("3","4")))
0266     # Multi-dimensional
0267     _DoTestArray(vbtest, (( (1,2,3), (4,5,6) )))
0268     _DoTestArray(vbtest, (( (vbtest,vbtest,vbtest), (vbtest,vbtest,vbtest) )))
0269     # Another dimension!
0270     arrayData = ( ((1,2),(3,4),(5,6)), ((7,8),(9,10),(11,12)) )
0271     arrayData = ( ((vbtest,vbtest),(vbtest,vbtest),(vbtest,vbtest)),
0272                   ((vbtest,vbtest),(vbtest,vbtest),(vbtest,vbtest)) )
0273     _DoTestArray(vbtest, arrayData)
0274 
0275     # Check that when a '__getitem__ that fails' object is the first item
0276     # in the structure, we don't mistake it for a sequence.
0277     _DoTestArray(vbtest, (vbtest, 2.0, "3"))
0278     _DoTestArray(vbtest, (1, 2.0, vbtest))
0279 
0280     # Pass arbitrarily sized arrays - these used to fail, but thanks to 
0281     # Stefan Schukat, they now work!
0282     expected_exception = None
0283     arrayData = ( ((1,2,1),(3,4),(5,6)), ((7,8),(9,10),(11,12)) )
0284     _DoTestArray(vbtest, arrayData, expected_exception)
0285     arrayData = ( ((vbtest,vbtest),), ((vbtest,),))
0286     _DoTestArray(vbtest, arrayData, expected_exception)
0287     # Pass bad data - last item wrong size
0288     arrayData = ( ((1,2),(3,4),(5,6,8)), ((7,8),(9,10),(11,12)) )
0289     _DoTestArray(vbtest, arrayData, expected_exception)
0290     
0291     # byref safearray results with incorrect size.
0292     callback_ob = wrap(TestObject(), useDispatcher = useDispatcher)
0293     print "** Expecting a 'ValueError' exception to be printed next:"
0294     try:
0295         vbtest.DoCallbackSafeArraySizeFail(callback_ob)
0296     except pythoncom.com_error, (hr, msg, exc, arg):
0297         assert exc[1] == "Python COM Server Internal Error", "Didnt get the correct exception - '%s'" % (exc,)
0298         
0299     if bUseGenerated:
0300         # This one is a bit strange!  The array param is "ByRef", as VB insists.
0301         # The function itself also _returns_ the arram param.
0302         # Therefore, Python sees _2_ result values - one for the result,
0303         # and one for the byref.
0304         testData = string.split("Mark was here")
0305         resultData, byRefParam = vbtest.PassSAFEARRAY(testData)
0306         # Un unicode everything (only 1.5.2)
0307         try:
0308             unicode
0309         except NameError : # No builtin named Unicode!
0310             resultData = map(str, resultData)
0311             byRefParam = map(str, byRefParam)
0312         if testData != list(resultData):
0313             raise error, "The safe array data was not what we expected - got " + str(resultData)
0314         if testData != list(byRefParam):
0315             raise error, "The safe array data was not what we expected - got " + str(byRefParam)
0316         testData = [1.0, 2.0, 3.0]
0317         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
0318         assert testData == list(byRefParam)
0319         assert testData == list(resultData)
0320         testData = ["hi", "from", "Python"]
0321         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
0322         assert testData == list(byRefParam), "Expected '%s', got '%s'" % (testData, list(byRefParam))
0323         assert testData == list(resultData), "Expected '%s', got '%s'" % (testData, list(resultData))
0324         # This time, instead of an explicit str() for 1.5, we just
0325         # pass Unicode, so the result should compare equal
0326         testData = [1, 2.0, pythoncom.Unicode("3")]
0327         resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
0328         assert testData == list(byRefParam)
0329         assert testData == list(resultData)
0330     print "Array tests passed"
0331 
0332 def TestStructs(vbtest):
0333     try:
0334         vbtest.IntProperty = "One"
0335         raise error, "Should have failed by now"
0336     except pythoncom.com_error, (hr, desc, exc, argErr):
0337         if hr != winerror.DISP_E_TYPEMISMATCH:
0338             raise error, "Expected DISP_E_TYPEMISMATCH"
0339 
0340     s = vbtest.StructProperty
0341     if s.int_val != 99 or str(s.str_val) != "hello":
0342         raise error, "The struct value was not correct"
0343     s.str_val = "Hi from Python"
0344     s.int_val = 11
0345     if s.int_val != 11 or str(s.str_val) != "Hi from Python":
0346         raise error, "The struct value didnt persist!"
0347 
0348     if s.sub_val.int_val != 66 or str(s.sub_val.str_val) != "sub hello":
0349         raise error, "The sub-struct value was not correct"
0350     sub = s.sub_val
0351     sub.int_val = 22
0352     if sub.int_val != 22:
0353         print sub.int_val
0354         raise error, "The sub-struct value didnt persist!"
0355 
0356     if s.sub_val.int_val != 22:
0357         print s.sub_val.int_val
0358         raise error, "The sub-struct value (re-fetched) didnt persist!"
0359 
0360     if s.sub_val.array_val[0].int_val != 0 or str(s.sub_val.array_val[0].str_val) != "zero":
0361         print s.sub_val.array_val[0].int_val
0362         raise error, "The array element wasnt correct"
0363     s.sub_val.array_val[0].int_val = 99
0364     s.sub_val.array_val[1].int_val = 66
0365     if s.sub_val.array_val[0].int_val != 99 or \
0366        s.sub_val.array_val[1].int_val != 66:
0367         print s.sub_val.array_val[0].int_val
0368         raise error, "The array element didnt persist."
0369     # Now pass the struct back to VB
0370     vbtest.StructProperty = s
0371     # And get it back again
0372     s = vbtest.StructProperty
0373     if s.int_val != 11 or str(s.str_val) != "Hi from Python":
0374         raise error, "After sending to VB, the struct value didnt persist!"
0375     if s.sub_val.array_val[0].int_val != 99:
0376         raise error, "After sending to VB, the struct array value didnt persist!"
0377 
0378     # Now do some object equality tests.
0379     assert s==s
0380     assert s != s.sub_val
0381     import copy
0382     s2 = copy.copy(s)
0383     assert s is not s2
0384     assert s == s2
0385     s2.int_val = 123
0386     assert s != s2
0387     # Make sure everything works with functions
0388     s2 = vbtest.GetStructFunc()
0389     assert s==s2
0390     vbtest.SetStructSub(s2)
0391 
0392     # Create a new structure, and set its elements.
0393     s = win32com.client.Record("VBStruct", vbtest)
0394     assert s.int_val == 0, "new struct inst initialized correctly!"
0395     s.int_val = -1
0396     vbtest.SetStructSub(s)
0397     assert vbtest.GetStructFunc().int_val == -1, "new struct didnt make the round trip!"
0398     # Finally, test stand-alone structure arrays.
0399     s_array = vbtest.StructArrayProperty
0400     assert s_array is None, "Expected None from the uninitialized VB array"
0401     vbtest.MakeStructArrayProperty(3)
0402     s_array = vbtest.StructArrayProperty
0403     assert len(s_array)==3
0404     for i in range(len(s_array)):
0405         assert s_array[i].int_val == i
0406         assert s_array[i].sub_val.int_val == i
0407         assert s_array[i].sub_val.array_val[0].int_val == i
0408         assert s_array[i].sub_val.array_val[1].int_val == i+1
0409         assert s_array[i].sub_val.array_val[2].int_val == i+2
0410 
0411     # Some error type checks.
0412     try:
0413         s.bad_attribute
0414         raise RuntimeError, "Could get a bad attribute"
0415     except AttributeError:
0416         pass
0417     m = s.__members__
0418     assert m[0]=="int_val" and m[1]=="str_val" and m[2]=="ob_val" and m[3]=="sub_val"
0419 
0420     # NOTE - a COM error is _not_ acceptable here!
0421     print "Struct/Record tests passed"
0422 
0423 def TestVBInterface(ob):
0424     t = ob.GetInterfaceTester(2)
0425     if t.getn() != 2:
0426         raise error, "Initial value wrong"
0427     t.setn(3)
0428     if t.getn() != 3:
0429         raise error, "New value wrong"
0430 
0431 def DoTestAll():
0432     o = win32com.client.Dispatch("PyCOMVBTest.Tester")
0433     TestVB(o,1)
0434 
0435     o = win32com.client.dynamic.DumbDispatch("PyCOMVBTest.Tester")
0436     TestVB(o,0)
0437 
0438 def TestAll():
0439     if not __debug__:
0440         raise RuntimeError, "This must be run in debug mode - we use assert!"
0441     try:
0442         DoTestAll()
0443         print "All tests appear to have worked!"
0444     except:
0445         print "TestAll() failed!!"
0446         traceback.print_exc()
0447 
0448 # Make this test run under our test suite to leak tests etc work
0449 def suite():
0450     import unittest
0451     test = util.CapturingFunctionTestCase(TestAll, description="VB tests")
0452     suite = unittest.TestSuite()
0453     suite.addTest(test)
0454     return suite
0455 
0456 if __name__=='__main__':
0457     util.testmain()
0458 

Generated by PyXR 0.9.4
SourceForge.net Logo