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