leakTest.py
4.4 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import sys
from win32com.axscript.server.error import Exception
from win32com.axscript import axscript
from win32com.axscript.server import axsite
import pythoncom
from win32com.server import util, connect
import win32com.server.policy
class MySite(axsite.AXSite):
def OnScriptError(self, error):
exc = error.GetExceptionInfo()
context, line, char = error.GetSourcePosition()
print " >Exception:", exc[1]
try:
st = error.GetSourceLineText()
except pythoncom.com_error:
st = None
if st is None: st = ""
text = st + "\n" + (" " * (char-1)) + "^" + "\n" + exc[2]
for line in text.splitlines():
print " >" + line
class MyCollection(util.Collection):
def _NewEnum(self):
print "Making new Enumerator"
return util.Collection._NewEnum(self)
class Test:
_public_methods_ = [ 'echo' ]
_public_attrs_ = ['collection', 'verbose']
def __init__(self):
self.verbose = 0
self.collection = util.wrap( MyCollection( [1,'Two',3] ))
self.last = ""
# self._connect_server_ = TestConnectServer(self)
def echo(self, *args):
self.last = ''.join(map(str, args))
if self.verbose:
for arg in args:
print arg,
print
# self._connect_server_.Broadcast(last)
#### Connections currently wont work, as there is no way for the engine to
#### know what events we support. We need typeinfo support.
IID_ITestEvents = pythoncom.MakeIID("{8EB72F90-0D44-11d1-9C4B-00AA00125A98}")
class TestConnectServer(connect.ConnectableServer):
_connect_interfaces_ = [IID_ITestEvents]
# The single public method that the client can call on us
# (ie, as a normal COM server, this exposes just this single method.
def __init__(self, object):
self.object = object
def Broadcast(self,arg):
# Simply broadcast a notification.
self._BroadcastNotify(self.NotifyDoneIt, (arg,))
def NotifyDoneIt(self, interface, arg):
interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1, arg)
VBScript = """\
prop = "Property Value"
sub hello(arg1)
test.echo arg1
end sub
sub testcollection
test.verbose = 1
for each item in test.collection
test.echo "Collection item is", item
next
end sub
"""
if sys.version_info < (3,):
PyScript = """print "PyScript is being parsed..."\n"""
else:
PyScript = """print("PyScript is being parsed...")\n"""
PyScript += """\
prop = "Property Value"
def hello(arg1):
test.echo(arg1)
pass
def testcollection():
test.verbose = 1
# test.collection[1] = "New one"
for item in test.collection:
test.echo("Collection item is", item)
pass
"""
ErrScript = """\
bad code for everyone!
"""
def TestEngine(engineName, code, bShouldWork = 1):
echoer = Test()
model = {
'test' : util.wrap(echoer),
}
site = MySite(model)
engine = site._AddEngine(engineName)
engine.AddCode(code, axscript.SCRIPTTEXT_ISPERSISTENT)
try:
engine.Start()
finally:
if not bShouldWork:
engine.Close()
return
doTestEngine(engine, echoer)
# re-transition the engine back to the UNINITIALIZED state, a-la ASP.
engine.eScript.SetScriptState(axscript.SCRIPTSTATE_UNINITIALIZED)
engine.eScript.SetScriptSite(util.wrap(site))
print "restarting"
engine.Start()
# all done!
engine.Close()
def doTestEngine(engine, echoer):
# Now call into the scripts IDispatch
from win32com.client.dynamic import Dispatch
ob = Dispatch(engine.GetScriptDispatch())
try:
ob.hello("Goober")
except pythoncom.com_error, exc:
print "***** Calling 'hello' failed", exc
return
if echoer.last != "Goober":
print "***** Function call didnt set value correctly", repr(echoer.last)
if str(ob.prop) != "Property Value":
print "***** Property Value not correct - ", repr(ob.prop)
ob.testcollection()
# Now make sure my engines can evaluate stuff.
result = engine.eParse.ParseScriptText("1+1", None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION)
if result != 2:
print "Engine could not evaluate '1+1' - said the result was", result
def dotestall():
for i in xrange(10):
TestEngine("Python", PyScript)
print sys.gettotalrefcount()
## print "Testing Exceptions"
## try:
## TestEngine("Python", ErrScript, 0)
## except pythoncom.com_error:
## pass
def testall():
dotestall()
pythoncom.CoUninitialize()
print "AXScript Host worked correctly - %d/%d COM objects left alive." % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
if __name__ == '__main__':
testall()