testIterators.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # Some raw iter tests. Some "high-level" iterator tests can be found in
  2. # testvb.py and testOutlook.py
  3. import sys
  4. import unittest
  5. from win32com.client.gencache import EnsureDispatch
  6. from win32com.client import Dispatch
  7. import win32com.server.util
  8. import win32com.test.util
  9. import pythoncom
  10. def yield_iter(iter):
  11. while 1:
  12. yield next(iter)
  13. class _BaseTestCase(win32com.test.util.TestCase):
  14. def test_enumvariant_vb(self):
  15. ob, iter = self.iter_factory()
  16. got=[]
  17. for v in iter:
  18. got.append(v)
  19. self.assertEquals(got, self.expected_data)
  20. def test_yield(self):
  21. ob, i = self.iter_factory()
  22. got=[]
  23. for v in yield_iter(iter(i)):
  24. got.append(v)
  25. self.assertEquals(got, self.expected_data)
  26. def _do_test_nonenum(self, object):
  27. try:
  28. for i in object:
  29. pass
  30. self.fail("Could iterate over a non-iterable object")
  31. except TypeError:
  32. pass # this is expected.
  33. self.assertRaises(TypeError, iter, object)
  34. self.assertRaises(AttributeError, getattr, object, "next")
  35. def test_nonenum_wrapper(self):
  36. # Check our raw PyIDispatch
  37. ob = self.object._oleobj_
  38. try:
  39. for i in ob:
  40. pass
  41. self.fail("Could iterate over a non-iterable object")
  42. except TypeError:
  43. pass # this is expected.
  44. self.assertRaises(TypeError, iter, ob)
  45. self.assertRaises(AttributeError, getattr, ob, "next")
  46. # And our Dispatch wrapper
  47. ob = self.object
  48. try:
  49. for i in ob:
  50. pass
  51. self.fail("Could iterate over a non-iterable object")
  52. except TypeError:
  53. pass # this is expected.
  54. # Note that as our object may be dynamic, we *do* have a __getitem__
  55. # method, meaning we *can* call iter() on the object. In this case
  56. # actual iteration is what fails.
  57. # So either the 'iter(); will raise a type error, or an attempt to
  58. # fetch it
  59. try:
  60. next(iter(ob))
  61. self.fail("Expected a TypeError fetching this iterator")
  62. except TypeError:
  63. pass
  64. # And it should never have a 'next' method
  65. self.assertRaises(AttributeError, getattr, ob, "next")
  66. class VBTestCase(_BaseTestCase):
  67. def setUp(self):
  68. def factory():
  69. # Our VB test harness exposes a property with IEnumVariant.
  70. ob = self.object.EnumerableCollectionProperty
  71. for i in self.expected_data:
  72. ob.Add(i)
  73. # Get the raw IEnumVARIANT.
  74. invkind = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
  75. iter = ob._oleobj_.InvokeTypes(pythoncom.DISPID_NEWENUM,0,invkind,(13, 10),())
  76. return ob, iter.QueryInterface(pythoncom.IID_IEnumVARIANT)
  77. # We *need* generated dispatch semantics, so dynamic __getitem__ etc
  78. # don't get in the way of our tests.
  79. self.object = EnsureDispatch("PyCOMVBTest.Tester")
  80. self.expected_data = [1, "Two", "3"]
  81. self.iter_factory = factory
  82. def tearDown(self):
  83. self.object = None
  84. # Test our client semantics, but using a wrapped Python list object.
  85. # This has the effect of re-using our client specific tests, but in this
  86. # case is exercising the server side.
  87. class SomeObject:
  88. _public_methods_ = ["GetCollection"]
  89. def __init__(self, data):
  90. self.data = data
  91. def GetCollection(self):
  92. return win32com.server.util.NewCollection(self.data)
  93. class WrappedPythonCOMServerTestCase(_BaseTestCase):
  94. def setUp(self):
  95. def factory():
  96. ob = self.object.GetCollection()
  97. flags = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
  98. enum = ob._oleobj_.Invoke(pythoncom.DISPID_NEWENUM, 0, flags, 1)
  99. return ob, enum.QueryInterface(pythoncom.IID_IEnumVARIANT)
  100. self.expected_data = [1,'Two',3]
  101. sv = win32com.server.util.wrap(SomeObject(self.expected_data))
  102. self.object = Dispatch(sv)
  103. self.iter_factory = factory
  104. def tearDown(self):
  105. self.object = None
  106. def suite():
  107. # We dont want our base class run
  108. suite = unittest.TestSuite()
  109. for item in globals().values():
  110. if type(item)==type(unittest.TestCase) and \
  111. issubclass(item, unittest.TestCase) and \
  112. item != _BaseTestCase:
  113. suite.addTest(unittest.makeSuite(item))
  114. return suite
  115. if __name__=='__main__':
  116. unittest.main(argv=sys.argv + ['suite'])