First checkin of the Python XPCOM bindings.

git-svn-id: svn://10.0.0.236/trunk@87331 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
markh%activestate.com
2001-02-19 05:24:45 +00:00
parent 0b610ca389
commit abe83923e1
70 changed files with 13648 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
test_com_exceptions
** Unhandled exception calling 'int8 do_short(in int16, inout int16, out int16, out retval int16);'
** Returning nsresult of NS_ERROR_FAILURE
** Unhandled exception calling 'int8 do_unsigned_short(in uint16, inout uint16, out uint16, out retval uint16);'
** Returning nsresult of NS_ERROR_FAILURE
** Unhandled exception calling 'int8 do_unsigned_long_long(in uint64, inout uint64, out uint64, out retval uint64);'
** Returning nsresult of NS_ERROR_FAILURE
The xpcom exception tests passed

View File

@@ -0,0 +1,7 @@
test_comfile
Open as string test worked.
Open as URL test worked.
File test using buffers worked.
Local file read test worked.
Read the correct data.
Chunks read the correct data.

View File

@@ -0,0 +1,4 @@
test_components
The interfaces object appeared to work!
The classes object appeared to work!
The ID function appeared to work!

View File

@@ -0,0 +1,2 @@
test_isupports_primitives
The nsISupports primitive interface tests appeared to work

View File

@@ -0,0 +1,9 @@
test_misc
Running all tests - use '-h' to see command-line options...
The netscape sample worked!
Enumerated all the ContractIDs
xpcom object hashing tests seemed to work
Dumping every interface I can find - please wait
(verbosity is turned off, so Im not actually going to print them)
Finished dumping all the interfaces.
The IID tests seemed to work

View File

@@ -0,0 +1 @@
test_streams

View File

@@ -0,0 +1,4 @@
test_test_component
Testing the Python.TestComponent component
The Python test component worked!
Javascript could successfully use the Python test component.

View File

@@ -0,0 +1,2 @@
test_weakreferences
Weak-reference tests appear to have worked!

View File

@@ -0,0 +1,18 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
# regrtest.py
#
# The Regression Tests for the xpcom package.
import os
import sys
import test.regrtest # The standard Python test suite.
path = os.path.abspath(os.path.split(sys.argv[0])[0])
tests = []
for arg in sys.argv[1:]:
if arg[0] not in "-/":
tests.append(arg)
tests = tests or test.regrtest.findtests(path, [])
test.regrtest.main(tests, path)

View File

@@ -0,0 +1,70 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
# Test pyxpcom exception.
from xpcom import components, nsError, ServerException, COMException
from xpcom.server import WrapObject
class PythonFailingComponent:
# Re-use the test interface for this test.
_com_interfaces_ = components.interfaces.nsIPythonTestInterfaceExtra
def do_boolean(self, p1, p2):
# This should cause the caller to see a "silent" NS_ERROR_FAILURE exception.
raise ServerException()
def do_octet(self, p1, p2):
# This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
def do_short(self, p1, p2):
# This should cause the caller to see a "debug" NS_ERROR_FAILURE exception.
raise COMException(nsError.NS_ERROR_NOT_IMPLEMENTED)
def do_unsigned_short(self, p1, p2):
# This should cause the caller to see a "debug" NS_ERROR_FAILURE exception.
raise "Foo"
def do_long(self, p1, p2):
# This should cause the caller to see a "silent" NS_ERROR_FAILURE exception.
raise ServerException
def do_unsigned_long(self, p1, p2):
# This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
raise ServerException, nsError.NS_ERROR_NOT_IMPLEMENTED
def do_long_long(self, p1, p2):
# This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
raise ServerException, (nsError.NS_ERROR_NOT_IMPLEMENTED, "testing")
def do_unsigned_long_long(self, p1, p2):
# Report of a crash in this case - test it!
raise ServerException, "A bad exception param"
def _testit(expected_errno, func, *args):
try:
apply(func, args)
except COMException, what:
if what.errno != expected_errno:
raise
def test():
# For the benefit of the test suite, we print some reassuring messages.
import sys
sys.__stderr__.write("***** NOTE: Three tracebacks below this is normal\n")
ob = WrapObject( PythonFailingComponent(), components.interfaces.nsIPythonTestInterfaceExtra)
_testit(nsError.NS_ERROR_FAILURE, ob.do_boolean, 0, 0)
_testit(nsError.NS_ERROR_NOT_IMPLEMENTED, ob.do_octet, 0, 0)
_testit(nsError.NS_ERROR_FAILURE, ob.do_short, 0, 0)
_testit(nsError.NS_ERROR_FAILURE, ob.do_unsigned_short, 0, 0)
_testit(nsError.NS_ERROR_FAILURE, ob.do_long, 0, 0)
_testit(nsError.NS_ERROR_NOT_IMPLEMENTED, ob.do_unsigned_long, 0, 0)
_testit(nsError.NS_ERROR_NOT_IMPLEMENTED, ob.do_long_long, 0, 0)
_testit(nsError.NS_ERROR_FAILURE, ob.do_unsigned_long_long, 0, 0)
print "The xpcom exception tests passed"
# For the benefit of the test suite, some more reassuring messages.
sys.__stderr__.write("***** NOTE: Three tracebacks printed above this is normal\n")
sys.__stderr__.write("***** It is testing the Python XPCOM Exception semantics\n")
test()

View File

@@ -0,0 +1,7 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
"""Test the xpcom.file module."""
# Called "test_comfile" as Python has a standard test called test_file :-(
import xpcom.file
xpcom.file._TestAll()

View File

@@ -0,0 +1,149 @@
<!-- Copyright (c) 2000-2001 ActiveState Tool Corporation. -->
<!-- See the file LICENSE.txt for licensing information. -->
<center><b><font size=+2>Python Component Sample</font></b>
<p>
<br>
Last modified
<script>
document.write(document.lastModified);
</script>
</center>
<p>XPConnect allows JavaScript
to transparantly access and manipulate XPCOM objects;
<p>Big Deal, I hear you say! But it also works for Python!!!
<p>
This sample demonstrates accessing a XPCOM object through XPConnect.
The JavaScript executed when this page loads creates an instance
of the Python object by
using the <tt>Components</tt> object, then accesses it through
the <a href="py_test_component.idl">nsISample</a> interface by calling <tt>QueryInterface</tt>:
<br>
<pre>
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["component://mozilla/sample/sample-world"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsISample);
</pre>
<p>
The buttons on the form are connected to JavaScript event handlers which
call the methods defined in Python
<p><b><a name="Compiling">Compiling the idl</b>
<p>The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac)
is compiled at build time (except on Mac) thus
you will have to build mozilla in order to test this out. If you
have already built mozilla then the compiler will be located at <tt>mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe</tt>.
<p>Once you have the XPIDL compiler enter the following command at your
prompt:
<br><tt>D:\whereever\xpcom\test\test_component>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I
d:\mozilla\dist\idl -m typelib py_test_component.idl</tt>. You must then copy the generated .xpt file
to the mozilla component directory.
<p>The <tt>-I d:\mozilla\dist\idl</tt> points the compiler to the folder
containing the other idl files, needed because nsISample.idl inherits from
nsISupports.idl. The <tt>-m typelib</tt> instruction tells the compiler
to build the .XPT typelib file.</tt>.
<p>
For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl
compiler page</a>.
<p><b>Running the sample</b>
<p><b>NOTE: This doesnt work for me - I get an access denied error using XPConnect!</b>
<p>Using Mozilla, load this file. Pay attention
to the console when clicking "write".
<!-- XXX keep in sync with stuff in pre tag below -->
<script>
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["Python.TestComponent"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsIPythonTestInterface);
dump("sample = " + sample + "\n");
function get()
{
var field = document.getElementById('Value');
field.value = sample.str_value;
}
function set()
{
var field = document.getElementById('Value');
sample.str_value = field.value;
}
function poke()
{
var field = document.getElementById('Value');
sample.poke(field.value);
}
function write()
{
sample.writeValue("here is what I'm writing: ");
}
</script>
<p>
<form name="form">
<input type="button" value="Get" onclick="get();">
<input type="button" value="Set" onclick="set();">
<input type="button" value="Poke" onclick="poke();">
<input type="text" id="Value">
<input type="button" value="Write" onclick="write();">
<form>
<hr>
<p>
JavaScript and form source:
<!-- XXX keep in sync with actual script -->
<pre>
&lt;script&gt;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["component://Python.TestComponent"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsIPythonTestInterface);
dump("sample = " + sample + "\n");
function get()
{
var field = document.getElementById('Value');
field.value = sample.str_value;
}
function set()
{
var field = document.getElementById('Value');
sample.str_value = field.value;
}
function poke()
{
var field = document.getElementById('Value');
sample.poke(field.value);
}
function write()
{
sample.writeValue("here is what I'm writing: ");
}
&lt;/script&gt;
&lt;form name=&quot;form&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Get&quot; onclick=&quot;get();&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Set&quot; onclick=&quot;set();&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Poke&quot; onclick=&quot;poke();&quot;&gt;
&lt;input type=&quot;text&quot; id=&quot;Value&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;Write&quot; onclick=&quot;write();&quot;&gt;
&lt;form>
</pre>

View File

@@ -0,0 +1,183 @@
/* Copyright (c) 2000-2001 ActiveState Tool Corporation.
See the file LICENSE.txt for licensing information. */
// NOTE: This is a TEST interface, not a DEMO interface :-)
// We try to get as many data-types etc exposed, meaning this
// doesnt really make a good demo of a "simple component"
#include "nsISupports.idl"
[scriptable, uuid(1ECAED4F-E4D5-4ee7-ABF0-7D72AE1441D7)]
interface nsIPythonTestInterface : nsISupports
{
// Some constants for us to test - one for every type supported by xpidl
const short One = 1;
const long Two = 2;
const long MinusOne = -1;
const long BigLong = 0x7FFFFFFF;
const long BigULong = 0xFFFFFFFF;
// Declare every type supported as an attribute.
attribute boolean boolean_value; // PRBool
attribute octet octet_value; // PRUint8
attribute short short_value; // PRInt16
attribute unsigned short ushort_value; // PRUint16
attribute long long_value; // PRInt32
attribute unsigned long ulong_value; // PRUint32
attribute long long long_long_value; // PRInt64
attribute unsigned long long ulong_long_value; // PRUint64
attribute float float_value; // float
attribute double double_value; // double
attribute char char_value; // char
attribute wchar wchar_value; // PRUnichar
attribute string string_value; // char *
attribute wstring wstring_value; // PRUnichar*
attribute nsIIDRef iid_value; // an IID
attribute nsIPythonTestInterface interface_value; // A specific interface
attribute nsISupports isupports_value; // A generic interface
// Declare every type supported as a method with an "in", "in/out" and "out" params
boolean do_boolean(in boolean p1, inout boolean p2, out boolean p3);
octet do_octet(in octet p1, inout octet p2, out octet p3);
short do_short(in short p1, inout short p2, out short p3);
unsigned short do_unsigned_short(in unsigned short p1, inout unsigned short p2, out unsigned short p3);
long do_long(in long p1, inout long p2, out long p3);
unsigned long do_unsigned_long(in unsigned long p1, inout unsigned long p2, out unsigned long p3);
long long do_long_long(in long long p1, inout long long p2, out long long p3);
unsigned long long do_unsigned_long_long(in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3);
float do_float(in float p1, inout float p2, out float p3);
double do_double(in double p1, inout double p2, out double p3);
char do_char(in char p1, inout char p2, out char p3);
wchar do_wchar(in wchar p1, inout wchar p2, out wchar p3);
string do_string(in string p1, inout string p2, out string p3);
wstring do_wstring(in wstring p1, inout wstring p2, out wstring p3);
nsIIDRef do_nsIIDRef(in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3);
nsIPythonTestInterface do_nsIPythonTestInterface(in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3);
nsISupports do_nsISupports(in nsISupports p1, inout nsISupports p2, out nsISupports p3);
void do_nsISupportsIs(in nsIIDRef iid, [iid_is(iid),retval] out nsQIResult result);
// Do I really need these??
// void do_nsISupportsIs2(inout nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
// void do_nsISupportsIs3(out nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
// void do_nsISupportsIs4(out nsIIDRef iid, [iid_is(iid)] out nsQIResult result);
};
// Another interface - we use another interface purely for testing purposes -
// We ensure that the entire interface hierarcy is available correctly.
[scriptable, uuid(B38D1538-FE92-42c3-831F-285242EDEEA4)]
interface nsIPythonTestInterfaceExtra : nsIPythonTestInterface
{
// These were copied from the XPCOM test 'xpctest.idl'
// (and a few extras added)
void MultiplyEachItemInIntegerArray(
in PRInt32 val,
in PRUint32 count,
[array, size_is(count)] inout PRInt32 valueArray);
void MultiplyEachItemInIntegerArrayAndAppend(
in PRInt32 val,
inout PRUint32 count,
[array, size_is(count)] inout PRInt32 valueArray);
// Note that this method shares a single "size_is" between 2 params!
void CompareStringArrays([array, size_is(count)] in string arr1,
[array, size_is(count)] in string arr2,
in unsigned long count,
[retval] out short result);
void DoubleStringArray(inout PRUint32 count,
[array, size_is(count)] inout string valueArray);
void ReverseStringArray(in PRUint32 count,
[array, size_is(count)] inout string valueArray);
// One count, one inout array.
void DoubleString(inout PRUint32 count,
[size_is(count)] inout string str);
// One in count and in array, plus out count and out array
void DoubleString2(in PRUint32 in_count, [size_is(in_count)] in string in_str,
out PRUint32 out_count, [size_is(out_count)] out string out_str);
// As per DoubleString2, but out string also marked retval
void DoubleString3(in PRUint32 in_count, [size_is(in_count)] in string in_str,
out PRUint32 out_count, [size_is(out_count), retval] out string out_str);
// One in array, one out array, one share inout count.
void DoubleString4([size_is(count)] in string in_str, inout PRUint32 count, [size_is(count)] out string out_str);
// UpString defines the count as only "in" - meaning the result must be the same size
void UpString(in PRUint32 count,
[size_is(count)] inout string str);
// UpString2 defines count as only "in", and a string as only "out"
void UpString2(in PRUint32 count,
[size_is(count)] in string in_str,
[size_is(count)]out string out_str);
// Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
void GetFixedString(in PRUint32 count, [size_is(count)]out string out_str);
void DoubleWideString(inout PRUint32 count,
[size_is(count)] inout wstring str);
void DoubleWideString2(in PRUint32 in_count, [size_is(in_count)] in wstring in_str,
out PRUint32 out_count, [size_is(out_count)] out wstring out_str);
void DoubleWideString3(in PRUint32 in_count, [size_is(in_count)] in wstring in_str,
out PRUint32 out_count, [size_is(out_count), retval] out wstring out_str);
void DoubleWideString4([size_is(count)] in wstring in_str, inout PRUint32 count, [size_is(count)] out wstring out_str);
// UpWideString defines the count as only "in" - meaning the result must be the same size
void UpWideString(in PRUint32 count,
[size_is(count)] inout wstring str);
// UpWideString2 defines count as only "in", and a string as only "out"
void UpWideString2(in PRUint32 count,
[size_is(count)] in wstring in_str,
[size_is(count)]out wstring out_str);
// Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
void GetFixedWideString(in PRUint32 count, [size_is(count)]out string out_str);
void GetStrings(out PRUint32 count,
[retval, array, size_is(count)] out string str);
void UpOctetArray(inout PRUint32 count,
[array, size_is(count)] inout PRUint8 data);
void UpOctetArray2(inout PRUint32 count,
[array, size_is(count)] inout PRUint8 data);
// Arrays of interfaces
void CheckInterfaceArray(in PRUint32 count,
[array, size_is(count)] in nsISupports data,
[retval] out PRBool all_non_null);
void GetInterfaceArray(out PRUint32 count,
[array, size_is(count)] out nsISupports data);
void ExtendInterfaceArray(inout PRUint32 count,
[array, size_is(count)] inout nsISupports data);
// Arrays of IIDs
void CheckIIDArray(in PRUint32 count,
[array, size_is(count)] in nsIIDRef data,
[retval] out PRBool all_mine);
void GetIIDArray(out PRUint32 count,
[array, size_is(count)] out nsIIDRef data);
void ExtendIIDArray(inout PRUint32 count,
[array, size_is(count)] inout nsIIDRef data);
// More specific tests.
// Test our count param can be shared as an "in" param.
void SumArrays(in PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]in PRInt32 array2, [retval]out PRInt32 result);
// Test our count param can be shared as an "out" param.
void GetArrays(out PRUint32 count, [array, size_is(count)]out PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
// Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
void GetFixedArray(in PRUint32 count, [array, size_is(count)]out PRInt32 array1);
// Test our "in" count param can be shared as one "in", plus one "out" param.
void CopyArray(in PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
// Test our "in-out" count param can be shared as one "in", plus one "out" param.
void CopyAndDoubleArray(inout PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
// Test our "in-out" count param can be shared as one "in", plus one "in-out" param.
void AppendArray(inout PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]inout PRInt32 array2);
};
// DOM String support is a "recent" (01/2001) addition to XPCOM. These test
// have their own interface for no real good reason ;-)
[scriptable, uuid(657ae651-a973-4818-8c06-f4b948b3d758)]
interface nsIPythonTestInterfaceDOMStrings : nsIPythonTestInterfaceExtra
{
DOMString GetDOMStringResult();
void GetDOMStringOut([retval] out DOMString s);
PRUint32 GetDOMStringLength(in DOMString s);
PRUint32 GetDOMStringRefLength(in DOMStringRef s);
PRUint32 GetDOMStringPtrLength(in DOMStringPtr s);
void ConcatDOMStrings(in DOMString s1, in DOMString s2, out DOMString ret);
attribute DOMString domstring_value;
readonly attribute DOMString domstring_value_ro;
};

View File

@@ -0,0 +1,344 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
# NOTE: This is a TEST interface, not a DEMO interface :-)
# We try to get as many data-types etc exposed, meaning this
# doesnt really make a good demo of a "simple component"
from xpcom import components, verbose
class PythonTestComponent:
# Note we only list the "child" interface, not our intermediate interfaces
# (which we must, by definition, also support)
_com_interfaces_ = components.interfaces.nsIPythonTestInterfaceDOMStrings
_reg_clsid_ = "{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}"
_reg_contractid_ = "Python.TestComponent"
def __init__(self):
self.boolean_value = 1
self.octet_value = 2
self.short_value = 3
self.ushort_value = 4
self.long_value = 5
self.ulong_value = 6
self.long_long_value = 7
self.ulong_long_value = 8
self.float_value = 9.0
self.double_value = 10.0
self.char_value = "a"
self.wchar_value = "b"
self.string_value = "cee"
self.wstring_value = "dee"
self.iid_value = self._reg_clsid_
self.interface_value = None
self.isupports_value = None
self.domstring_value = "dom"
def __del__(self):
if verbose:
print "Python.TestComponent: __del__ method called - object is destructing"
def do_boolean(self, p1, p2):
# boolean do_boolean(in boolean p1, inout boolean p2, out boolean p3);
ret = p1 ^ p2
return ret, not ret, ret
def do_octet(self, p1, p2):
# octet do_octet(in octet p1, inout octet p2, out octet p3);
return p1+p2, p1-p2, p1*p2
def do_short(self, p1, p2):
# short do_short(in short p1, inout short p2, out short p3);
return p1+p2, p1-p2, p1*p2
def do_unsigned_short(self, p1, p2):
# unsigned short do_unsigned_short(in unsigned short p1, inout unsigned short p2, out unsigned short p3);
return p1+p2, p1-p2, p1*p2
def do_long(self, p1, p2):
# long do_long(in long p1, inout long p2, out long p3);
return p1+p2, p1-p2, p1*p2
def do_unsigned_long(self, p1, p2):
# unsigned long do_unsigned_long(in unsigned long p1, inout unsigned long p2, out unsigned long p3);
return p1+p2, p1-p2, p1*p2
def do_long_long(self, p1, p2):
# long long do_long_long(in long long p1, inout long long p2, out long long p3);
return p1+p2, p1-p2, p1*p2
def do_unsigned_long_long(self, p1, p2):
# unsigned long long do_unsigned_long_long(in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3);
return p1+p2, p1-p2, p1*p2
def do_float(self, p1, p2):
# float do_float(in float p1, inout float p2, out float p3);
return p1+p2, p1-p2, p1*p2
def do_double(self, p1, p2):
# double do_double(in double p1, inout double p2, out double p3);
return p1+p2, p1-p2, p1*p2
def do_char(self, p1, p2):
# char do_char(in char p1, inout char p2, out char p3);
return chr(ord(p1)+ord(p2)), p2, p1
def do_wchar(self, p1, p2):
# wchar do_wchar(in wchar p1, inout wchar p2, out wchar p3);
return chr(ord(p1)+ord(p2)), p2, p1
def do_string(self, p1, p2):
# string do_string(in string p1, inout string p2, out string p3);
ret = ""
if p1 is not None: ret = ret + p1
if p2 is not None: ret = ret + p2
return ret, p1, p2
def do_wstring(self, p1, p2):
# wstring do_wstring(in wstring p1, inout wstring p2, out wstring p3);
ret = u""
if p1 is not None: ret = ret + p1
if p2 is not None: ret = ret + p2
return ret, p1, p2
def do_nsIIDRef(self, p1, p2):
# nsIIDRef do_nsIIDRef(in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3);
return p1, self._reg_clsid_, p2
def do_nsIPythonTestInterface(self, p1, p2):
# nsIPythonTestInterface do_nsIPythonTestInterface(in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3);
return p2, p1, self
def do_nsISupports(self, p1, p2):
# nsISupports do_nsISupports(in nsISupports p1, inout nsISupports p2, out nsISupports p3);
return self, p1, p2
def do_nsISupportsIs(self, iid):
# void do_nsISupportsIs(in nsIIDRef iid, [iid_is(iid),retval] out nsQIResult result)
# Note the framework does the QI etc on us, so there is no real point me doing it.
# (However, user code _should_ do the QI - otherwise any errors are deemed "internal" (as they
# are raised by the C++ framework), and therefore logged to the console, etc.
# A user QI allows the user to fail gracefully, whatever gracefully means for them!
return self
# Do I really need these??
## def do_nsISupportsIs2(self, iid, interface):
## # void do_nsISupportsIs2(inout nsIIDRef iid, [iid_is(iid),retval] inout nsQIResult result);
## return iid, interface
## def do_nsISupportsIs3(self, interface):
## # void do_nsISupportsIs3(out nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
## return self._com_interfaces_, interface
## def do_nsISupportsIs4(self):
## # void do_nsISupportsIs4(out nsIIDRef iid, [iid_is(iid)] out nsQIResult result);
## return self._com_interfaces_, self
# Methods from the nsIPythonTestInterfaceExtra interface
#
def MultiplyEachItemInIntegerArray(self, val, valueArray):
# void MultiplyEachItemInIntegerArray(
# in PRInt32 val,
# in PRUint32 count,
# [array, size_is(count)] inout PRInt32 valueArray);
# NOTE - the "sizeis" params are never passed to or returned from Python!
results = []
for item in valueArray:
results.append(item * val)
return results
def MultiplyEachItemInIntegerArrayAndAppend(self, val, valueArray):
#void MultiplyEachItemInIntegerArrayAndAppend(
# in PRInt32 val,
# inout PRUint32 count,
# [array, size_is(count)] inout PRInt32 valueArray);
results = valueArray[:]
for item in valueArray:
results.append(item * val)
return results
def DoubleStringArray(self, valueArray):
# void DoubleStringArray(inout PRUint32 count,
# [array, size_is(count)] inout string valueArray);
results = []
for item in valueArray:
results.append(item * 2)
return results
def ReverseStringArray(self, valueArray):
# void ReverseStringArray(in PRUint32 count,
# [array, size_is(count)] inout string valueArray);
valueArray.reverse()
return valueArray
# Note that this method shares a single "size_is" between 2 params!
def CompareStringArrays(self, ar1, ar2):
# void CompareStringArrays([array, size_is(count)] in string arr1,
# [array, size_is(count)] in string arr2,
# in unsigned long count,
# [retval] out short result);
return cmp(ar1, ar2)
def DoubleString(self, val):
# void DoubleString(inout PRUint32 count,
# [size_is(count)] inout string str);
return val * 2
def DoubleString2(self, val):
# void DoubleString2(in PRUint32 in_count, [size_is(in_count)] in string in_str,
# out PRUint32 out_count, [size_is(out_count)] out string out_str);
return val * 2
def DoubleString3(self, val):
# void DoubleString3(in PRUint32 in_count, [size_is(in_count)] in string in_str,
# out PRUint32 out_count, [size_is(out_count), retval] string out_str);
return val * 2
def DoubleString4(self, val):
# void DoubleString4([size_is(count)] in string in_str, inout PRUint32 count, [size_is(count)] out string out_str);
return val * 2
def UpString(self, val):
# // UpString defines the count as only "in" - meaning the result must be the same size
# void UpString(in PRUint32 count,
# [size_is(count)] inout string str);
return val.upper()
UpString2 = UpString
# // UpString2 defines count as only "in", and a string as only "out"
# void UpString2(in PRUint32 count,
# [size_is(count)] inout string in_str,
# [size_is(count)]out string out_str);
def GetFixedString(self, count):
# void GetFixedString(in PRUint32 count, [size_is(count)out string out_str);
return "A" * count
# DoubleWideString functions are identical to DoubleString, except use wide chars!
def DoubleWideString(self, val):
return val * 2
def DoubleWideString2(self, val):
return val * 2
def DoubleWideString3(self, val):
return val * 2
def DoubleWideString4(self, val):
return val * 2
def UpWideString(self, val):
return val.upper()
UpWideString2 = UpWideString
# Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
def GetFixedWideString(self, count):
# void GetFixedWideString(in PRUint32 count, [size_is(count)out string out_str);
return u"A" * count
def GetStrings(self):
# void GetStrings(out PRUint32 count,
# [retval, array, size_is(count)] out string str);
return "Hello from the Python test component".split()
# Some tests for our special "PRUint8" support.
def UpOctetArray( self, data ):
# void UpOctetArray(inout PRUint32 count,
# [array, size_is(count)] inout PRUint8 data);
return data.upper()
def UpOctetArray2( self, data ):
# void UpOctetArray2(inout PRUint32 count,
# [array, size_is(count)] inout PRUint8 data);
data = data.upper()
# This time we return a list of integers.
return map( ord, data )
# Arrays of interfaces
def CheckInterfaceArray(self, interfaces):
# void CheckInterfaceArray(in PRUint32 count,
# [array, size_is(count)] in nsISupports data,
# [retval] out PRBool all_non_null);
ret = 1
for i in interfaces:
if i is None:
ret = 0
break
return ret
def GetInterfaceArray(self):
# void GetInterfaceArray(out PRUint32 count,
# [array, size_is(count)] out nsISupports data);
return self, self, self, None
def ExtendInterfaceArray(self, data):
# void ExtendInterfaceArray(inout PRUint32 count,
# [array, size_is(count)] inout nsISupports data);
return data * 2
# Arrays of IIDs
def CheckIIDArray(self, data):
# void CheckIIDArray(in PRUint32 count,
# [array, size_is(count)] in nsIIDRef data,
# [retval] out PRBool all_mine);
ret = 1
for i in data:
if i!= self._com_interfaces_ and i != self._reg_clsid_:
ret = 0
break
return ret
def GetIIDArray(self):
# void GetIIDArray(out PRUint32 count,
# [array, size_is(count)] out nsIIDRef data);
return self._com_interfaces_, self._reg_clsid_
def ExtendIIDArray(self, data):
# void ExtendIIDArray(inout PRUint32 count,
# [array, size_is(count)] inout nsIIDRef data);
return data * 2
# Test our count param can be shared as an "in" param.
def SumArrays(self, array1, array2):
# void SumArrays(in PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]in array2, [retval]result);
if len(array1)!=len(array2):
print "SumArrays - not expecting different lengths!"
result = 0
for i in array1:
result = result + i
for i in array2:
result = result+i
return result
# Test our count param can be shared as an "out" param.
def GetArrays(self):
# void GetArrays(out PRUint32 count, [array, size_is(count)]out array1, [array, size_is(count)]out array2);
return (1,2,3), (4,5,6)
# Test we can get an "out" array with an "in" size
def GetFixedArray(self, size):
# void GetFixedArray(in PRUint32 count, [array, size_is(count)]out PRInt32 array1]);
return 0 * size
# Test our "in" count param can be shared as one "in", plus one "out" param.
def CopyArray(self, array1):
# void CopyArray(in PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]out array2);
return array1
# Test our "in-out" count param can be shared as one "in", plus one "out" param.
def CopyAndDoubleArray(self, array):
# void CopyAndDoubleArray(inout PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]out array2);
return array + array
# Test our "in-out" count param can be shared as one "in", plus one "in-out" param.
def AppendArray(self, array1, array2):
# void AppendArray(inout PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]inout array2);
rc = array1
if array2 is not None:
rc.extend(array2)
return rc
# Some tests for the "new" (Feb-2001) DOMString type.
def GetDOMStringResult( self ):
# Result: DOMString &
return "A DOM String"
def GetDOMStringOut( self ):
# Result: DOMString &
return "Another DOM String"
def GetDOMStringLength( self, param0 ):
# Result: uint32
# In: param0: DOMString &
return len(param0)
def GetDOMStringRefLength( self, param0 ):
# Result: uint32
# In: param0: DOMString &
return len(param0)
def GetDOMStringPtrLength( self, param0 ):
# Result: uint32
# In: param0: DOMString *
return len(param0)
def ConcatDOMStrings( self, param0, param1 ):
# Result: void - None
# In: param0: DOMString &
# In: param1: DOMString &
# Out: DOMString &
return param0 + param1
def get_domstring_value( self ):
# Result: DOMString &
return self.domstring_value
def set_domstring_value( self, param0 ):
# Result: void - None
# In: param0: DOMString &
self.domstring_value = param0
def get_domstring_value_ro( self ):
# Result: DOMString &
return self.domstring_value

View File

@@ -0,0 +1,78 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
"""Tests the "xpcom.components" object.
"""
import xpcom.components
if not __debug__:
raise RuntimeError, "This test uses assert, so must be run in debug mode"
def test_interfaces():
"Test the xpcom.components.interfaces object"
iid = xpcom.components.interfaces.nsISupports
assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
iid = xpcom.components.interfaces['nsISupports']
assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
# Test dictionary semantics
num_fetched = num_nsisupports = 0
for name, iid in xpcom.components.interfaces.items():
num_fetched = num_fetched + 1
if name == "nsISupports":
num_nsisupports = num_nsisupports + 1
assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
assert xpcom.components.interfaces[name] == iid
# Check all the lengths match.
assert len(xpcom.components.interfaces.keys()) == len(xpcom.components.interfaces.values()) == \
len(xpcom.components.interfaces.items()) == len(xpcom.components.interfaces) == \
num_fetched, "The collection lengths were wrong"
if num_nsisupports != 1:
print "Didnt find exactly 1 nsiSupports!"
print "The interfaces object appeared to work!"
def test_classes():
# Need a well-known contractID here?
prog_id = "@mozilla.org/filelocator;1"
clsid = xpcom.components.ID("{78043e01-e603-11d2-915f-f08a208628fc}")
# Check we can create the instance (dont check we can do anything with it tho!)
klass = xpcom.components.classes[prog_id]
instance = klass.createInstance()
# Test dictionary semantics
num_fetched = num_mine = 0
for name, klass in xpcom.components.classes.items():
num_fetched = num_fetched + 1
if name == prog_id:
if klass.clsid != clsid:
print "Eeek - didn't get the correct IID - got", klass.clsid
num_mine = num_mine + 1
# xpcom appears to add charset info to the contractid!?
# assert xpcom.components.classes[name].contractid == prog_id, "Expected '%s', got '%s'" % (prog_id, xpcom.components.classes[name].contractid)
# Check all the lengths match.
if len(xpcom.components.classes.keys()) == len(xpcom.components.classes.values()) == \
len(xpcom.components.classes.items()) == len(xpcom.components.classes) == \
num_fetched:
pass
else:
raise RuntimeError, "The collection lengths were wrong"
if num_fetched <= 0:
raise RuntimeError, "Didnt get any classes!!!"
if num_mine != 1:
raise RuntimeError, "Didnt find exactly 1 of my contractid! (%d)" % (num_mine,)
print "The classes object appeared to work!"
def test_id():
id = xpcom.components.ID(str(xpcom._xpcom.IID_nsISupports))
assert id == xpcom._xpcom.IID_nsISupports
print "The ID function appeared to work!"
# regrtest doesnt like if __name__=='__main__' blocks - it fails when running as a test!
test_interfaces()
test_classes()
test_id()

View File

@@ -0,0 +1,116 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
# Test our support for the interfaces defined in nsISupportsPrimitives.idl
#
# The framework supports nsISupportsString and nsISupportsWString, but
# only if our class doesnt provide explicit support.
from xpcom import components
class NoSupportsString:
_com_interfaces_ = [components.interfaces.nsISupports]
pass
class ImplicitSupportsString:
_com_interfaces_ = [components.interfaces.nsISupports]
def __str__(self):
return "<MyImplicitStrObject>"
class ExplicitSupportsString:
_com_interfaces_ = [components.interfaces.nsISupports, components.interfaces.nsISupportsString]
# __str__ will be ignored by XPCOM, as we have _explicit_ support.
def __str__(self):
return "<MyImplicitStrObject>"
# This is the one that will be used.
def toString(self):
return "<MyExplicitStrObject>"
class ImplicitSupportsInt:
_com_interfaces_ = [components.interfaces.nsISupports]
def __int__(self):
return 99
class ExplicitSupportsInt:
_com_interfaces_ = [components.interfaces.nsISupportsPRInt32]
def get_data(self):
return 99
class ImplicitSupportsLong:
_com_interfaces_ = [components.interfaces.nsISupports]
def __long__(self):
return 99L
class ExplicitSupportsLong:
_com_interfaces_ = [components.interfaces.nsISupportsPRInt64]
def get_data(self):
return 99
class ExplicitSupportsFloat:
_com_interfaces_ = [components.interfaces.nsISupportsDouble]
def get_data(self):
return 99.99
class ImplicitSupportsFloat:
_com_interfaces_ = [components.interfaces.nsISupports]
def __float__(self):
return 99.99
def test():
import xpcom.server, xpcom.client
ob = xpcom.server.WrapObject( NoSupportsString(), components.interfaces.nsISupports)
if not str(ob).startswith("<XPCOM interface"):
raise RuntimeError, "Wrong str() value: %s" % (ob,)
ob = xpcom.server.WrapObject( ImplicitSupportsString(), components.interfaces.nsISupports)
if str(ob) != "<MyImplicitStrObject>":
raise RuntimeError, "Wrong str() value: %s" % (ob,)
ob = xpcom.server.WrapObject( ExplicitSupportsString(), components.interfaces.nsISupports)
if str(ob) != "<MyExplicitStrObject>":
raise RuntimeError, "Wrong str() value: %s" % (ob,)
# Try our conversions.
try:
int(ob)
raise RuntimeError, "Expected to get a ValueError converting this COM object to an int"
except ValueError:
pass
ob = xpcom.server.WrapObject( ExplicitSupportsInt(), components.interfaces.nsISupports)
if int(ob) != 99:
raise RuntimeError, "Bad value: %s" % (int(ob),)
if float(ob) != 99.0:
raise RuntimeError, "Bad value: %s" % (float(ob),)
ob = xpcom.server.WrapObject( ImplicitSupportsInt(), components.interfaces.nsISupports)
if int(ob) != 99:
raise RuntimeError, "Bad value: %s" % (int(ob),)
if float(ob) != 99.0:
raise RuntimeError, "Bad value: %s" % (float(ob),)
ob = xpcom.server.WrapObject( ExplicitSupportsLong(), components.interfaces.nsISupports)
if long(ob) != 99 or not repr(long(ob)).endswith("L"):
raise RuntimeError, "Bad value: %s" % (repr(long(ob)),)
if float(ob) != 99.0:
raise RuntimeError, "Bad value: %s" % (float(ob),)
ob = xpcom.server.WrapObject( ImplicitSupportsLong(), components.interfaces.nsISupports)
if long(ob) != 99 or not repr(long(ob)).endswith("L"):
raise RuntimeError, "Bad value: %s" % (repr(long(ob)),)
if float(ob) != 99.0:
raise RuntimeError, "Bad value: %s" % (float(ob),)
ob = xpcom.server.WrapObject( ExplicitSupportsFloat(), components.interfaces.nsISupports)
if float(ob) != 99.99:
raise RuntimeError, "Bad value: %s" % (float(ob),)
if int(ob) != 99:
raise RuntimeError, "Bad value: %s" % (int(ob),)
ob = xpcom.server.WrapObject( ImplicitSupportsFloat(), components.interfaces.nsISupports)
if float(ob) != 99.99:
raise RuntimeError, "Bad value: %s" % (float(ob),)
if int(ob) != 99:
raise RuntimeError, "Bad value: %s" % (int(ob),)
print "The nsISupports primitive interface tests appeared to work"
test()

View File

@@ -0,0 +1,171 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
import xpcom
import xpcom.client
import xpcom._xpcom
import xpcom.components
import string
import traceback, getopt, sys
verbose_level = 0
def DumpEveryInterfaceUnderTheSun():
"Dump every interface under the sun!"
import xpcom, xpcom.xpt, xpcom._xpcom
iim = xpcom._xpcom.XPTI_GetInterfaceInfoManager()
print "Dumping every interface I can find - please wait"
if verbose_level == 0:
print "(verbosity is turned off, so Im not actually going to print them)"
enum = iim.EnumerateInterfaces()
rc = enum.First()
num = 0
while rc==0:
item = enum.CurrentItem(xpcom._xpcom.IID_nsIInterfaceInfo)
try:
iid = item.GetIID()
except xpcom.Exception:
if verbose_level:
print "Can't dump", item
continue # Dont bother dumping this.
interface = xpcom.xpt.Interface(iid)
num = num + 1
text = interface.Describe()
if verbose_level:
print text
rc = enum.Next()
if num < 200:
print "Only found", num, "interfaces - this seems unusually low!"
print "Finished dumping all the interfaces."
def EnumContractIDs():
"""Enumerate all the ContractIDs registered"""
cm = xpcom._xpcom.NS_GetGlobalComponentManager()
enum = cm.EnumerateContractIDs()
rc = enum.First()
n = 0
while rc == 0:
n = n + 1
if verbose_level:
print "ContractID:", enum.CurrentItem()
rc = enum.Next()
if n < 200:
print "Only found", n, "ContractIDs - this seems unusually low!"
print "Enumerated all the ContractIDs"
def TestSampleComponent():
"""Test the standard Netscape 'sample' sample"""
# contractid = "mozilla.jssample.1" # the JS version
contractid = "@mozilla.org/sample;1" # The C++ version.
c = xpcom.components.classes[contractid].createInstance() \
.queryInterface(xpcom.components.interfaces.nsISample)
assert c.value == "initial value"
c.value = "new value"
assert c.value == "new value"
c.poke("poked value")
assert c.value == "poked value"
c.writeValue("Python just poked:")
print "The netscape sample worked!"
def TestHash():
"Test that hashing COM objects works"
d = {}
contractid = "@mozilla.org/sample;1" # The C++ version.
c = xpcom.components.classes[contractid].createInstance() \
.queryInterface(xpcom.components.interfaces.nsISample)
d[c] = None
if not d.has_key(c):
raise RuntimeError, "Can't get the exact same object back!"
if not d.has_key(c.queryInterface(xpcom.components.interfaces.nsISupports)):
raise RuntimeError, "Can't get back as nsISupports"
# And the same in reverse - stick an nsISupports in, and make sure an explicit interface comes back.
d = {}
contractid = "@mozilla.org/sample;1" # The C++ version.
c = xpcom.components.classes[contractid].createInstance() \
.queryInterface(xpcom.components.interfaces.nsISupports)
d[c] = None
if not d.has_key(c):
raise RuntimeError, "Can't get the exact same object back!"
if not d.has_key(c.queryInterface(xpcom.components.interfaces.nsISample)):
raise RuntimeError, "Can't get back as nsISupports"
print "xpcom object hashing tests seemed to work"
def TestIIDs():
"Do some basic IID semantic tests."
iid_str = "{7ee4bdc6-cb53-42c1-a9e4-616b8e012aba}"
IID = xpcom._xpcom.IID
assert IID(iid_str)==IID(iid_str), "IIDs with identical strings dont compare!"
assert hash(IID(iid_str))==hash(IID(iid_str)), "IIDs with identical strings dont have identical hashes!"
assert IID(iid_str)==IID(iid_str.upper()), "IIDs with case-different strings dont compare!"
assert hash(IID(iid_str))==hash(IID(iid_str.upper())), "IIDs with case-different strings dont have identical hashes!"
# If the above work, this shoud too, but WTF
dict = {}
dict[IID(iid_str)] = None
assert dict.has_key(IID(iid_str))
assert dict.has_key(IID(iid_str.upper()))
print "The IID tests seemed to work"
def usage(tests):
import os
print "Usage: %s [-v] [Test ...]" % os.path.basename(sys.argv[0])
print " -v : Verbose - print more information"
print "where Test is one of:"
for t in tests:
print t.__name__,":", t.__doc__
print
print "If not tests are specified, all tests are run"
sys.exit(1)
def main():
tests = []
args = []
for ob in globals().values():
if type(ob)==type(main) and ob.__doc__:
tests.append(ob)
if __name__ == '__main__': # Only process args when not running under the test suite!
opts, args = getopt.getopt(sys.argv[1:], "hv")
for opt, val in opts:
if opt=="-h":
usage(tests)
if opt=="-v":
global verbose_level
verbose_level = verbose_level + 1
if len(args)==0:
print "Running all tests - use '-h' to see command-line options..."
dotests = tests
else:
dotests = []
for arg in args:
for t in tests:
if t.__name__==arg:
dotests.append(t)
break
else:
print "Test '%s' unknown - skipping" % arg
if not len(dotests):
print "Nothing to do!"
usage(tests)
for test in dotests:
try:
test()
except:
print "Test %s failed" % test.__name__
traceback.print_exc()
# regrtest doesnt like if __name__=='__main__' blocks - it fails when running as a test!
main()
if __name__=='__main__':
# We can only afford to shutdown if we are truly running as the main script.
# (xpcom can't handle shutdown/init pairs)
xpcom._xpcom.NS_ShutdownXPCOM()
ni = xpcom._xpcom._GetInterfaceCount()
ng = xpcom._xpcom._GetGatewayCount()
if ni or ng:
print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)

View File

@@ -0,0 +1,86 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
import xpcom
from xpcom import _xpcom, components, COMException, ServerException, nsError
from StringIO import StringIO
test_data = "abcdefeghijklmnopqrstuvwxyz"
class koTestSimpleStreamBase:
_com_interfaces_ = [components.interfaces.nsIInputStream]
# We avoid registering this object - see comments in get_test_inout_? below.
def __init__(self):
self.data=StringIO(test_data)
def close( self ):
pass
def available( self ):
return self.data.len-self.data.pos
def readStr( self, amount):
return self.data.read(amount)
read=readStr
def get_observer( self ):
raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
def set_observer( self, param0 ):
raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
# This class has "nonBlocking" as an attribute.
class koTestSimpleStream1(koTestSimpleStreamBase):
nonBlocking=0
# This class has "nonBlocking" as getter/setters.
class koTestSimpleStream2(koTestSimpleStreamBase):
def __init__(self):
koTestSimpleStreamBase.__init__(self)
self.isNonBlocking = 0
def get_nonBlocking(self):
return self.isNonBlocking
def get_test_input_1():
# We use a couple of internal hacks here that mean we can avoid having the object
# registered. This code means that we are still working over the xpcom boundaries, tho
# (and the point of this test is not the registration, etc).
import xpcom.server, xpcom.client
ob = xpcom.server.WrapObject( koTestSimpleStream1(), _xpcom.IID_nsISupports)
ob = xpcom.client.Component(ob, components.interfaces.nsIInputStream)
return ob
def get_test_input_2():
# We use a couple of internal hacks here that mean we can avoid having the object
# registered. This code means that we are still working over the xpcom boundaries, tho
# (and the point of this test is not the registration, etc).
import xpcom.server, xpcom.client
ob = xpcom.server.WrapObject( koTestSimpleStream2(), _xpcom.IID_nsISupports)
ob = xpcom.client.Component(ob, components.interfaces.nsIInputStream)
return ob
def test_input(myStream):
if myStream.read(5) != test_data[:5]:
raise "Read the wrong data!"
if myStream.read(0) != '':
raise "Read the wrong emtpy data!"
if myStream.read(5) != test_data[5:10]:
raise "Read the wrong data after an empty read!"
if myStream.read(-1) != test_data[10:]:
raise "Couldnt read the rest of the data"
if myStream.nonBlocking:
raise "Expected default to be blocking"
try:
myStream.observer = None
raise "Shouldnt get here!"
except COMException, details:
if details.errno != nsError.NS_ERROR_NOT_IMPLEMENTED:
raise "Unexpected COM exception: %s (%r)" % (details, details)
if __name__=='__main__':
test_input( get_test_input_1() )
test_input( get_test_input_2() )
print "The stream tests worked!"

View File

@@ -0,0 +1,80 @@
/* Javascript code calling the Python test interface. */
function MakeTestInterface()
{
var clazz = Components.classes["Python.TestComponent"];
var iface = Components.interfaces.nsIPythonTestInterfaceDOMStrings;
return new clazz(iface);
}
var c = new MakeTestInterface();
if (c.boolean_value != 1)
throw("boolean_value has wrong initial value");
c.boolean_value = false;
if (c.boolean_value != false)
throw("boolean_value has wrong new value");
// Python's own test does thorough testing of all numeric types
// Wont bother from here!
if (c.char_value != 'a')
throw("char_value has wrong initial value");
c.char_value = 'b';
if (c.char_value != 'b')
throw("char_value has wrong new value");
if (c.wchar_value != 'b')
throw("wchar_value has wrong initial value");
c.wchar_value = 'c';
if (c.wchar_value != 'c')
throw("wchar_value has wrong new value");
if (c.string_value != 'cee')
throw("string_value has wrong initial value");
c.string_value = 'dee';
if (c.string_value != 'dee')
throw("string_value has wrong new value");
if (c.wstring_value != 'dee')
throw("wstring_value has wrong initial value");
c.wstring_value = 'eee';
if (c.wstring_value != 'eee')
throw("wstring_value has wrong new value");
if (c.domstring_value != 'dom')
throw("domstring_value has wrong initial value");
c.domstring_value = 'New value';
if (c.domstring_value != 'New value')
throw("domstring_value has wrong new value");
var v = new Object();
v.value = "Hello"
var l = new Object();
l.value = v.value.length;
c.DoubleString(l, v);
if ( v.value != "HelloHello")
throw("Could not double the string!");
var v = new Object();
v.value = "Hello"
var l = new Object();
l.value = v.value.length;
c.DoubleWideString(l, v);
if ( v.value != "HelloHello")
throw("Could not double the wide string!");
// Some basic array tests
var v = new Array()
v[0] = 1;
v[2] = 2;
v[3] = 3;
var v2 = new Array()
v2[0] = 4;
v2[2] = 5;
v2[3] = 6;
if (c.SumArrays(v.length, v, v2) != 21)
throw("Could not sum an array of integers!");
print("javascript successfully tested the Python test component.");

View File

@@ -0,0 +1,435 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
import sys, os
import xpcom.components
import xpcom._xpcom
import xpcom.nsError
num_errors = 0
component_iid = xpcom.components.ID("{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}")
new_iid = xpcom.components.ID("{2AF747D3-ECBC-457b-9AF9-5C5D80EDC360}")
contractid = "Python.TestComponent"
really_big_string = "This is really repetitive!" * 10000
really_big_wstring = u"This is really repetitive!" * 10000
def print_error(error):
print error
global num_errors
num_errors = num_errors + 1
def _test_value(what, got, expecting):
ok = got == expecting
if type(got)==type(expecting)==type(0.0):
ok = abs(got-expecting) < 0.001
if not ok:
print_error("*** Error %s - got '%r', but expecting '%r'" % (what, got, expecting))
def test_attribute(ob, attr_name, expected_init, new_value, new_value_really = None):
if xpcom.verbose:
print "Testing attribute %s" % (attr_name,)
if new_value_really is None:
new_value_really = new_value # Handy for eg bools - set a BOOL to 2, you still get back 1!
_test_value( "getting initial attribute value (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
setattr(ob, attr_name, new_value)
_test_value( "getting new attribute value (%s)" % (attr_name,), getattr(ob, attr_name), new_value_really)
# And set it back to the expected init.
setattr(ob, attr_name, expected_init)
_test_value( "getting back initial attribute value after change (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
def test_attribute_failure(ob, attr_name, new_value, expected_exception):
try:
setattr(ob, attr_name, new_value)
print_error("*** Setting attribute '%s' to '%r' didnt yield an exception!" % (attr_name, new_value) )
except:
exc_typ = sys.exc_info()[0]
ok = issubclass(exc_typ, expected_exception)
if not ok:
print_error("*** Wrong exception setting '%s' to '%r'- got '%s: %s', expected '%s'" % (attr_name, new_value, exc_typ, exc_val, expected_exception))
def test_method(method, args, expected_results):
if xpcom.verbose:
print "Testing %s%s" % (method.__name__, `args`)
ret = method(*args)
if ret != expected_results:
print_error("calling method %s - expected %s, but got %s" % (method.__name__, expected_results, ret))
def test_int_method(meth):
test_method(meth, (0,0), (0,0,0))
test_method(meth, (1,1), (2,0,1))
test_method(meth, (5,2), (7,3,10))
# test_method(meth, (2,5), (7,-3,10))
def test_constant(ob, cname, val):
v = getattr(ob, cname)
if v != val:
print_error("Bad value for constant '%s' - got '%r'" % (cname, v))
try:
setattr(ob, cname, 0)
print_error("The object allowed us to set the constant '%s'" % (cname,))
except AttributeError:
pass
def test_base_interface(c):
test_attribute(c, "boolean_value", 1, 0)
test_attribute(c, "boolean_value", 1, -1, 1) # Set a bool to anything, you should always get back 0 or 1
test_attribute(c, "boolean_value", 1, 4, 1) # Set a bool to anything, you should always get back 0 or 1
test_attribute(c, "boolean_value", 1, "1", 1) # This works by virtual of PyNumber_Int - not sure I agree, but...
test_attribute_failure(c, "boolean_value", "boo", ValueError)
test_attribute_failure(c, "boolean_value", test_base_interface, TypeError)
test_attribute(c, "octet_value", 2, 5)
test_attribute(c, "octet_value", 2, 0)
test_attribute(c, "octet_value", 2, 128) # octet is unsigned 8 bit
test_attribute(c, "octet_value", 2, 255) # octet is unsigned 8 bit
test_attribute(c, "octet_value", 2, -1, 255) # octet is unsigned 8 bit
test_attribute_failure(c, "octet_value", "boo", ValueError)
test_attribute(c, "short_value", 3, 10)
test_attribute(c, "short_value", 3, -1) # 16 bit signed
test_attribute(c, "short_value", 3, 0xFFFF, -1) # 16 bit signed
test_attribute(c, "short_value", 3, 0L)
test_attribute(c, "short_value", 3, 1L)
test_attribute(c, "short_value", 3, -1L)
test_attribute(c, "short_value", 3, 0xFFFFL, -1)
test_attribute_failure(c, "short_value", "boo", ValueError)
test_attribute(c, "ushort_value", 4, 5)
test_attribute(c, "ushort_value", 4, 0)
test_attribute(c, "ushort_value", 4, -1, 0xFFFF) # 16 bit signed
test_attribute(c, "ushort_value", 4, 0xFFFF) # 16 bit signed
test_attribute(c, "ushort_value", 4, 0L)
test_attribute(c, "ushort_value", 4, 1L)
test_attribute(c, "ushort_value", 4, -1L, 0xFFFF)
test_attribute_failure(c, "ushort_value", "boo", ValueError)
test_attribute(c, "long_value", 5, 7)
test_attribute(c, "long_value", 5, 0)
test_attribute(c, "long_value", 5, 0xFFFFFFFF, -1) # 32 bit signed.
test_attribute(c, "long_value", 5, -1) # 32 bit signed.
test_attribute(c, "long_value", 5, 0L)
test_attribute(c, "long_value", 5, 1L)
test_attribute(c, "long_value", 5, -1L)
test_attribute_failure(c, "long_value", 0xFFFFL * 0xFFFF, OverflowError) # long int too long to convert
test_attribute_failure(c, "long_value", "boo", ValueError)
test_attribute(c, "ulong_value", 6, 7)
test_attribute(c, "ulong_value", 6, 0)
test_attribute(c, "ulong_value", 6, 0xFFFFFFFF) # 32 bit signed.
test_attribute_failure(c, "ulong_value", "boo", ValueError)
test_attribute(c, "long_long_value", 7, 8)
test_attribute(c, "long_long_value", 7, 0)
test_attribute(c, "long_long_value", 7, -1)
test_attribute(c, "long_long_value", 7, 0xFFFF)
test_attribute(c, "long_long_value", 7, 0xFFFFL * 2)
test_attribute_failure(c, "long_long_value", 0xFFFFL * 0xFFFF * 0xFFFF * 0xFFFF, OverflowError) # long int too long to convert
test_attribute_failure(c, "long_long_value", "boo", ValueError)
test_attribute(c, "ulong_long_value", 8, 9)
test_attribute(c, "ulong_long_value", 8, 0)
test_attribute_failure(c, "ulong_long_value", "boo", ValueError)
test_attribute_failure(c, "ulong_long_value", -1, OverflowError) # can't convert negative value to unsigned long)
test_attribute(c, "float_value", 9.0, 10.2)
test_attribute(c, "float_value", 9.0, 0)
test_attribute(c, "float_value", 9.0, -1)
test_attribute(c, "float_value", 9.0, 1L)
test_attribute_failure(c, "float_value", "boo", ValueError)
test_attribute(c, "double_value", 10.0, 9.0)
test_attribute(c, "double_value", 10.0, 0)
test_attribute(c, "double_value", 10.0, -1)
test_attribute(c, "double_value", 10.0, 1L)
test_attribute_failure(c, "double_value", "boo", ValueError)
test_attribute(c, "char_value", "a", "b")
test_attribute(c, "char_value", "a", "\0")
test_attribute_failure(c, "char_value", "xy", ValueError)
test_attribute(c, "char_value", "a", u"c")
test_attribute(c, "char_value", "a", u"\0")
test_attribute_failure(c, "char_value", u"xy", ValueError)
test_attribute(c, "wchar_value", "b", "a")
test_attribute(c, "wchar_value", "b", "\0")
test_attribute_failure(c, "wchar_value", "hi", ValueError)
test_attribute(c, "wchar_value", "b", u"a")
test_attribute(c, "wchar_value", "b", u"\0")
test_attribute_failure(c, "wchar_value", u"hi", ValueError)
test_attribute(c, "string_value", "cee", "dee")
test_attribute(c, "string_value", "cee", "a null >\0<", "a null >") # strings are NULL terminated!!
test_attribute(c, "string_value", "cee", "")
test_attribute(c, "string_value", "cee", u"dee")
test_attribute(c, "string_value", "cee", u"a null >\0<", "a null >") # strings are NULL terminated!!
test_attribute(c, "string_value", "cee", u"")
test_attribute(c, "wstring_value", "dee", "cee")
test_attribute(c, "wstring_value", "dee", "a null >\0<", "a null >") # strings are NULL terminated!!
test_attribute(c, "wstring_value", "dee", "")
test_attribute(c, "wstring_value", "dee", really_big_string)
test_attribute(c, "wstring_value", "dee", u"cee")
test_attribute(c, "wstring_value", "dee", u"a null >\0<", "a null >") # strings are NULL terminated!!
test_attribute(c, "wstring_value", "dee", u"")
test_attribute(c, "wstring_value", "dee", really_big_wstring)
test_attribute(c, "iid_value", component_iid, new_iid)
test_attribute(c, "iid_value", component_iid, str(new_iid), new_iid)
test_attribute(c, "iid_value", component_iid, xpcom._xpcom.IID(new_iid))
test_attribute_failure(c, "no_attribute", "boo", AttributeError)
test_attribute(c, "interface_value", None, c)
test_attribute_failure(c, "interface_value", 2, TypeError)
test_attribute(c, "isupports_value", None, c)
# The methods
test_method(c.do_boolean, (0,1), (1,0,1))
test_method(c.do_boolean, (1,0), (1,0,1))
test_method(c.do_boolean, (1,1), (0,1,0))
test_int_method(c.do_octet)
test_int_method(c.do_short)
test_int_method(c.do_unsigned_short)
test_int_method(c.do_long)
test_int_method(c.do_unsigned_long)
test_int_method(c.do_long_long)
test_int_method(c.do_unsigned_long)
test_int_method(c.do_float)
test_int_method(c.do_double)
test_method(c.do_char, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
test_method(c.do_char, ("A", "\0"), ("A", "\0","A") )
test_method(c.do_wchar, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
test_method(c.do_wchar, ("A", "\0"), ("A", "\0","A") )
test_method(c.do_string, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
test_method(c.do_string, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
test_method(c.do_string, (None, u"Python"), ("Python", None, "Python") )
test_method(c.do_string, (None, really_big_string), (really_big_string, None, really_big_string) )
test_method(c.do_string, (None, really_big_wstring), (really_big_string, None, really_big_string) )
test_method(c.do_wstring, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
test_method(c.do_wstring, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
test_method(c.do_string, (None, really_big_wstring), (really_big_wstring, None, really_big_wstring) )
test_method(c.do_string, (None, really_big_string), (really_big_wstring, None, really_big_wstring) )
test_method(c.do_nsIIDRef, (component_iid, new_iid), (component_iid, component_iid, new_iid))
test_method(c.do_nsIIDRef, (new_iid, component_iid), (new_iid, component_iid, component_iid))
test_method(c.do_nsIPythonTestInterface, (None, None), (None, None, c))
test_method(c.do_nsIPythonTestInterface, (c, c), (c, c, c))
test_method(c.do_nsISupports, (None, None), (c, None, None))
test_method(c.do_nsISupports, (c,c), (c, c, c))
test_method(c.do_nsISupportsIs, (xpcom._xpcom.IID_nsISupports,), c)
test_method(c.do_nsISupportsIs, (xpcom.components.interfaces.nsIPythonTestInterface,), c)
## test_method(c.do_nsISupportsIs2, (xpcom.components.interfaces.nsIPythonTestInterface,c), (xpcom.components.interfaces.nsIPythonTestInterface,c))
## test_method(c.do_nsISupportsIs3, (c,), (xpcom.components.interfaces.nsIPythonTestInterface,c))
## test_method(c.do_nsISupportsIs4, (), (xpcom.components.interfaces.nsIPythonTestInterface,c))
# Test the constants.
test_constant(c, "One", 1)
test_constant(c, "Two", 2)
test_constant(c, "MinusOne", -1)
test_constant(c, "BigLong", 0x7FFFFFFF)
test_constant(c, "BigULong", 0xFFFFFFFF)
# Test the components.Interfaces semantics
i = xpcom.components.interfaces.nsIPythonTestInterface
test_constant(i, "One", 1)
test_constant(i, "Two", 2)
test_constant(i, "MinusOne", -1)
test_constant(i, "BigLong", 0x7FFFFFFF)
test_constant(i, "BigULong", 0xFFFFFFFF)
def test_derived_interface(c):
val = "Hello\0there"
expected = val * 2
test_method(c.DoubleString, (val,), expected)
test_method(c.DoubleString2, (val,), expected)
test_method(c.DoubleString3, (val,), expected)
test_method(c.DoubleString4, (val,), expected)
test_method(c.UpString, (val,), val.upper())
test_method(c.UpString2, (val,), val.upper())
test_method(c.GetFixedString, (20,), "A"*20)
val = u"Hello\0there"
expected = val * 2
test_method(c.DoubleWideString, (val,), expected)
test_method(c.DoubleWideString2, (val,), expected)
test_method(c.DoubleWideString3, (val,), expected)
test_method(c.DoubleWideString4, (val,), expected)
test_method(c.UpWideString, (val,), val.upper())
test_method(c.UpWideString2, (val,), val.upper())
test_method(c.GetFixedWideString, (20,), u"A"*20)
items = [1,2,3,4,5]
test_method(c.MultiplyEachItemInIntegerArray, (3, items,), map(lambda i:i*3, items))
test_method(c.MultiplyEachItemInIntegerArrayAndAppend, (3, items), items + map(lambda i:i*3, items))
items = "Hello from Python".split()
expected = map( lambda x: x*2, items)
test_method(c.DoubleStringArray, (items,), expected)
test_method(c.CompareStringArrays, (items, items), cmp(items, items))
# Can we pass lists and tuples correctly?
test_method(c.CompareStringArrays, (items, tuple(items)), cmp(items, items))
items2 = ["Not", "the", "same"]
test_method(c.CompareStringArrays, (items, items2), cmp(items, items2))
expected = items[:]
expected.reverse()
test_method(c.ReverseStringArray, (items,), expected)
expected = "Hello from the Python test component".split()
test_method(c.GetStrings, (), expected)
val = "Hello\0there"
test_method(c.UpOctetArray, (val,), val.upper())
test_method(c.UpOctetArray2, (val,), val.upper())
test_method(c.CheckInterfaceArray, ((c, c),), 1)
test_method(c.CheckInterfaceArray, ((c, None),), 0)
test_method(c.CheckInterfaceArray, ((),), 1)
test_method(c.GetInterfaceArray, (), [c,c,c, None])
test_method(c.ExtendInterfaceArray, ((c,c,c, None),), [c,c,c,None,c,c,c,None] )
expected = [xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings, xpcom.components.classes[contractid].clsid]
test_method(c.GetIIDArray, (), expected)
val = [xpcom.components.interfaces.nsIPythonTestInterfaceExtra, xpcom.components.classes[contractid].clsid]
expected = val * 2
test_method(c.ExtendIIDArray, (val,), expected)
test_method(c.GetArrays, (), ( [1,2,3], [4,5,6] ) )
test_method(c.CopyArray, ([1,2,3],), [1,2,3] )
test_method(c.CopyAndDoubleArray, ([1,2,3],), [1,2,3,1,2,3] )
test_method(c.AppendArray, ([1,2,3],), [1,2,3])
test_method(c.AppendArray, ([1,2,3],[4,5,6]), [1,2,3,4,5,6])
c = c.queryInterface(xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings)
test_method(c.GetDOMStringResult, (), "A DOM String")
test_method(c.GetDOMStringOut, (), "Another DOM String")
val = "Hello there"
test_method(c.GetDOMStringLength, (val,), len(val))
test_method(c.GetDOMStringRefLength, (val,), len(val))
test_method(c.GetDOMStringPtrLength, (val,), len(val))
test_method(c.ConcatDOMStrings, (val,val), val+val)
test_attribute(c, "domstring_value", "dom", "new dom")
if c.domstring_value_ro != "dom":
print "Read-only DOMString not currect - got", c.domstring_ro
try:
c.dom_string_ro = "new dom"
print "Managed to set a readonly attribute - eek!"
except AttributeError:
pass
except:
print "Unexpected exception when setting readonly attribute: %s: %s" % (sys.exc_info()[0], sys.exc_info()[1])
if c.domstring_value_ro != "dom":
print "Read-only DOMString not correct after failed set attempt - got", c.domstring_ro
def do_test_failures():
c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
try:
ret = c.do_nsISupportsIs( xpcom._xpcom.IID_nsIInterfaceInfoManager )
print "*** got", ret, "***"
raise RuntimeError, "We worked when using an IID we dont support!?!"
except xpcom.Exception, details:
if details.errno != xpcom.nsError.NS_ERROR_NO_INTERFACE:
raise RuntimeError, "Wrong COM exception type: %r" % (details,)
def test_failures():
# This extra stack-frame ensures Python cleans up sys.last_traceback etc
do_test_failures()
def test_all():
c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterface)
test_base_interface(c)
# Now create an instance using the derived IID, and test that.
c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
test_base_interface(c)
test_derived_interface(c)
test_failures()
try:
from sys import gettotalrefcount
except ImportError:
# Not a Debug build - assume no references (can't be leaks then :-)
def gettotalrefcount():
return 0
def test_from_js():
# Ensure we can find the js test script - same dir as this!
# Assume the path of sys.argv[0] is where we can find the js test code.
# (Running under the regression test is a little painful)
script_dir = os.path.split(sys.argv[0])[0]
fname = os.path.join( script_dir, "test_test_component.js")
if not os.path.isfile(fname):
raise RuntimeError, "Can not find '%s'" % (fname,)
# Note we _dont_ pump the test output out, as debug "xpcshell" spews
# extra debug info that will cause our output comparison to fail.
try:
data = os.popen('xpcshell "' + fname + '"').readlines()
good = 0
for line in data:
if line.strip() == "javascript successfully tested the Python test component.":
good = 1
if good:
print "Javascript could successfully use the Python test component."
else:
print "** The javascript test appeared to fail! Test output follows **"
print "".join(data)
print "** End of javascript test output **"
except os.error, why:
print "Error executing the javascript test program:", why
def doit(num_loops = -1):
if "-v" in sys.argv: # Hack the verbose flag for the server
xpcom.verbose = 1
# Do the test lots of times - can help shake-out ref-count bugs.
print "Testing the Python.TestComponent component"
if num_loops == -1: num_loops = 10
for i in xrange(num_loops):
test_all()
if i==0:
# First loop is likely to "leak" as we cache things.
# Leaking after that is a problem.
num_refs = gettotalrefcount()
if num_errors:
break
lost = gettotalrefcount() - num_refs
# Sometimes we get spurious counts off by 1 or 2.
# This can't indicate a real leak, as we have looped
# more than twice!
if abs(lost)>2:
print "*** Lost %d references" % (lost,)
if num_errors:
print "There were", num_errors, "errors testing the Python component :-("
else:
print "The Python test component worked!"
# regrtest doesnt like if __name__=='__main__' blocks - it fails when running as a test!
num_iters = -1
if __name__=='__main__' and len(sys.argv) > 1:
num_iters = int(sys.argv[1])
doit(num_iters)
test_from_js()
if __name__=='__main__':
# But we can only do this if _not_ testing - otherwise we
# screw up any tests that want to run later.
xpcom._xpcom.NS_ShutdownXPCOM()
ni = xpcom._xpcom._GetInterfaceCount()
ng = xpcom._xpcom._GetGatewayCount()
if ni or ng:
print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)

View File

@@ -0,0 +1,52 @@
# Copyright (c) 2000-2001 ActiveState Tool Corporation.
# See the file LICENSE.txt for licensing information.
# test_weakreferences.py - Test our weak reference implementation.
from xpcom import components, _xpcom
import xpcom.server, xpcom.client
num_alive = 0
class koTestSimple:
_com_interfaces_ = [components.interfaces.nsIInputStream]
def __init__(self):
global num_alive
num_alive += 1
def __del__(self):
global num_alive
num_alive -= 1
def close( self ):
pass
def test():
ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsIInputStream)
if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
# Check we can create a weak reference to our object.
wr = xpcom.client.WeakReference(ob)
if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
# Check we can call methods via the weak reference.
if wr() is None: raise RuntimeError, "Our weak-reference is returning None before it should!"
wr().close()
ob = None # This should kill the object.
if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
# Now a test that we can get a _new_ interface from the weak reference - ie,
# an IID the real object has never previously been queried for
# (this behaviour previously caused a bug - never again ;-)
ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsISupports)
if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
wr = xpcom.client.WeakReference(ob, components.interfaces.nsIInputStream)
if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
wr() # This would die once upon a time ;-)
ob = None # This should kill the object.
if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
test()
print "Weak-reference tests appear to have worked!"