# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Python XPCOM language bindings.
#
# The Initial Developer of the Original Code is
# ActiveState Tool Corp.
# Portions created by the Initial Developer are Copyright (C) 2000, 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mark Hammond <MarkH@ActiveState.com> (original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
try:
import gc
except ImportError:
gc = None
# Exception raised when a -ve integer is converted to an unsigned C integer
# (via an extension module). This changed in Python 2.2
else:
print error
global num_errors
if not ok:
print "Testing attribute %s" % (attr_name,)
if new_value_really is None:
_test_value( "getting initial attribute value (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
_test_value( "getting new attribute value (%s)" % (attr_name,), getattr(ob, attr_name), new_value_really)
# And set it back to the expected init.
_test_value( "getting back initial attribute value after change (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
val = "a null >\0<"
if is_dumb_sz:
else:
val = u"a null >\0<"
if is_dumb_sz:
else:
if not ascii_only:
try:
print_error("*** Setting attribute '%s' to '%r' didnt yield an exception!" % (attr_name, new_value) )
except:
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))
if ret != expected_results:
print_error("calling method %s - expected %r, but got %r" % (method.__name__, expected_results, ret))
# test_method(meth, (2,5), (7,-3,10))
if v != val:
try:
except AttributeError:
pass
def test_base_interface(c):
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, "long_value", 0xFFFFL * 0xFFFF, OverflowError) # long int too long to convert
test_attribute_failure(c, "long_long_value", 0xFFFFL * 0xFFFF * 0xFFFF * 0xFFFF, OverflowError) # long int too long to convert
test_attribute_failure(c, "ulong_long_value", -1, UnsignedMismatchException) # can't convert negative value to unsigned long)
# Test a string already encoded gets through correctly.
test_attribute(c, "utf8string_value", "utf8string", extended_unicode_string.encode("utf8"), extended_unicode_string)
# This will fail internal string representation :( Test we don't crash
try:
print_error("strings with chars > 128 appear to have stopped failing?")
except UnicodeError:
pass
test_attribute(c, "interface_value", None, c)
test_attribute(c, "isupports_value", None, c)
# The methods
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_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_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_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 the components.Interfaces semantics
val = "Hello\0there"
val = u"Hello\0there"
test_method(c.MultiplyEachItemInIntegerArrayAndAppend, (3, items), items + map(lambda i:i*3, items))
# Can we pass lists and tuples correctly?
val = "Hello\0there"
# Passing Unicode objects here used to cause us grief.
test_method(c.CopyInterfaceArray, ((c, c),), [c,c])
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]
val = [xpcom.components.interfaces.nsIPythonTestInterfaceExtra, xpcom.components.classes[contractid].clsid]
test_method(c.CopyVariant, (None,), None)
test_method(c.CopyVariant, (c,), c)
test_method(c.CopyVariant, ((c,c),), [c,c])
test_method(c.AppendVariant, (None, None), None)
test_method(c.SumVariants, ([],), None)
# Array's dont expose their interface, so we are unable to auto-wrap
# variant arrays, as they aren't aware if the IID of the array
if not test_flat:
# NULL DOM strings don't work yet.
# test_method(c.GetDOMStringResult, (-1,), None)
# test_method(c.GetDOMStringOut, (-1,), None)
val = "Hello there"
if c.domstring_value_ro != "dom":
print "Read-only DOMString not correct - 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():
try:
raise RuntimeError, "We worked when using an IID we dont support!?!"
def test_failures():
# This extra stack-frame ensures Python cleans up sys.last_traceback etc
def test_all():
# Now create an instance using the derived IID, and test that.
# Now create an instance and test interface flattening.
# We had a bug where a "set" of an attribute before a "get" failed.
# Don't let it happen again :)
c.boolean_value = 0
# This name is used in exceptions etc - make sure we got it from nsIClassInfo OK.
assert c._object_name_ == "Python.TestComponent"
try:
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)
# Note we _dont_ pump the test output out, as debug "xpcshell" spews
# extra debug info that will cause our output comparison to fail.
good = 0
good = 1
if not good:
print "** The javascript test appeared to fail! Test output follows **"
print "** End of javascript test output **"
raise RuntimeError, "test failed"
# Do the test lots of times - can help shake-out ref-count bugs.
test_all()
if i==0:
# First loop is likely to "leak" as we cache things.
# Leaking after that is a problem.
if gc is not None:
mem_usage = getmemusage()
if num_errors:
break
if gc is not None:
# Sometimes we get spurious counts off by 1 or 2.
# This can't indicate a real leak, as we have looped
# more than twice!
print "*** Lost %d references" % (lost,)
# sleep to allow the OS to recover
# working set size is fickle, and when we were leaking strings, this test
# would report a leak of 100MB. So we allow a 3MB buffer - but even this
# may still occasionally report spurious warnings. If you are really
# worried, bump the counter to a huge value, and if there is a leak it will
# show.
if mem_lost > 3000000:
def suite():
if __name__=='__main__':
print "Testing the Python.TestComponent component"
print "The Python test component worked."
print "JS successfully used our Python test component."