Back to index

enigmail  1.4.3
runtests.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # Copyright 2010,2011 Mozilla Foundation. All rights reserved.
00003 #
00004 # Redistribution and use in source and binary forms, with or without
00005 # modification, are permitted provided that the following conditions are
00006 # met:
00007 #
00008 #   1. Redistributions of source code must retain the above copyright
00009 #      notice, this list of conditions and the following disclaimer.
00010 #
00011 #   2. Redistributions in binary form must reproduce the above copyright
00012 #      notice, this list of conditions and the following disclaimer in
00013 #      the documentation and/or other materials provided with the
00014 #      distribution.
00015 #
00016 # THIS SOFTWARE IS PROVIDED BY THE MOZILLA FOUNDATION ``AS IS'' AND ANY
00017 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00019 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE MOZILLA FOUNDATION OR
00020 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00021 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00022 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00023 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00024 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00026 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 #
00028 # The views and conclusions contained in the software and documentation
00029 # are those of the authors and should not be interpreted as representing
00030 # official policies, either expressed or implied, of the Mozilla
00031 # Foundation.
00032 
00033 import difflib
00034 import os
00035 import shutil
00036 from StringIO import StringIO
00037 import subprocess
00038 import sys
00039 import tempfile
00040 import unittest
00041 import xpt
00042 
00043 def get_output(bin, file):
00044     p = subprocess.Popen([bin, file], stdout=subprocess.PIPE)
00045     stdout, _ = p.communicate()
00046     return stdout
00047 
00048 if "MOZILLA_OBJDIR" in os.environ:
00049     class CheckXPTDump(unittest.TestCase):
00050         def test_xpt_dump_diffs(self):
00051             MOZILLA_OBJDIR = os.environ["MOZILLA_OBJDIR"]
00052             xptdump = os.path.abspath(os.path.join(MOZILLA_OBJDIR,
00053                                                    "dist", "bin", "xpt_dump"))
00054             components = os.path.abspath(os.path.join(MOZILLA_OBJDIR,
00055                                                    "dist", "bin", "components"))
00056             for f in os.listdir(components):
00057                 if not f.endswith(".xpt"):
00058                     continue
00059                 fullpath = os.path.join(components, f)
00060                 # read a Typelib and dump it to a string
00061                 t = xpt.Typelib.read(fullpath)
00062                 self.assert_(t is not None)
00063                 outf = StringIO()
00064                 t.dump(outf)
00065                 out = outf.getvalue()
00066                 # now run xpt_dump on it
00067                 out2 = get_output(xptdump, fullpath)
00068                 if out != out2:
00069                     print "diff %s" % f
00070                     for line in difflib.unified_diff(out2.split("\n"), out.split("\n"), lineterm=""):
00071                         print line
00072                 self.assert_(out == out2, "xpt_dump output should be identical for %s" % f)
00073 
00074 class TestIIDString(unittest.TestCase):
00075     def test_iid_str_roundtrip(self):
00076         iid_str = "11223344-5566-7788-9900-aabbccddeeff"
00077         iid = xpt.Typelib.string_to_iid(iid_str)
00078         self.assertEqual(iid_str, xpt.Typelib.iid_to_string(iid))
00079 
00080     def test_iid_roundtrip(self):
00081         iid = "\x11\x22\x33\x44\x55\x66\x77\x88\x99\x00\xaa\xbb\xcc\xdd\xee\xff"
00082         iid_str = xpt.Typelib.iid_to_string(iid)
00083         self.assertEqual(iid, xpt.Typelib.string_to_iid(iid_str))
00084 
00085 class TypelibCompareMixin:
00086     def assertEqualTypelibs(self, t1, t2):
00087         self.assert_(t1 is not None, "Should not be None")
00088         self.assert_(t2 is not None, "Should not be None")
00089         self.assertEqual(t1.version, t2.version, "Versions should be equal")
00090         self.assertEqual(len(t1.interfaces), len(t2.interfaces),
00091                          "Number of interfaces should be equal")
00092         for i, j in zip(t1.interfaces, t2.interfaces):
00093             self.assertEqualInterfaces(i, j)
00094 
00095     def assertEqualInterfaces(self, i1, i2):
00096         self.assert_(i1 is not None, "Should not be None")
00097         self.assert_(i2 is not None, "Should not be None")
00098         self.assertEqual(i1.name, i2.name, "Names should be equal")
00099         self.assertEqual(i1.iid, i2.iid, "IIDs should be equal")
00100         self.assertEqual(i1.namespace, i2.namespace,
00101                          "Namespaces should be equal")
00102         self.assertEqual(i1.resolved, i2.resolved,
00103                          "Resolved status should be equal")
00104         if i1.resolved:
00105             if i1.parent or i2.parent:
00106                 # Can't test exact equality, probably different objects
00107                 self.assertEqualInterfaces(i1.parent, i2.parent)
00108             self.assertEqual(len(i1.methods), len(i2.methods))
00109             for m, n in zip(i1.methods, i2.methods):
00110                 self.assertEqualMethods(m, n)
00111             self.assertEqual(len(i1.constants), len(i2.constants))
00112             for c, d in zip(i1.constants, i2.constants):
00113                 self.assertEqualConstants(c, d)
00114             self.assertEqual(i1.scriptable, i2.scriptable,
00115                              "Scriptable status should be equal")
00116             self.assertEqual(i1.function, i2.function,
00117                              "Function status should be equal")
00118 
00119     def assertEqualMethods(self, m1, m2):
00120         self.assert_(m1 is not None, "Should not be None")
00121         self.assert_(m2 is not None, "Should not be None")
00122         self.assertEqual(m1.name, m2.name, "Names should be equal")
00123         self.assertEqual(m1.getter, m2.getter, "Getter flag should be equal")
00124         self.assertEqual(m1.setter, m2.setter, "Setter flag should be equal")
00125         self.assertEqual(m1.notxpcom, m2.notxpcom,
00126                          "notxpcom flag should be equal")
00127         self.assertEqual(m1.constructor, m2.constructor,
00128                          "constructor flag should be equal")
00129         self.assertEqual(m1.hidden, m2.hidden, "hidden flag should be equal")
00130         self.assertEqual(m1.optargc, m2.optargc, "optargc flag should be equal")
00131         self.assertEqual(m1.implicit_jscontext, m2.implicit_jscontext,
00132                          "implicit_jscontext flag should be equal")
00133         for p1, p2 in zip(m1.params, m2.params):
00134             self.assertEqualParams(p1, p2)
00135         self.assertEqualParams(m1.result, m2.result)
00136         
00137     def assertEqualConstants(self, c1, c2):
00138         self.assert_(c1 is not None, "Should not be None")
00139         self.assert_(c2 is not None, "Should not be None")
00140         self.assertEqual(c1.name, c2.name)
00141         self.assertEqual(c1.value, c2.value)
00142         self.assertEqualTypes(c1.type, c2.type)
00143 
00144     def assertEqualParams(self, p1, p2):
00145         self.assert_(p1 is not None, "Should not be None")
00146         self.assert_(p2 is not None, "Should not be None")
00147         self.assertEqualTypes(p1.type, p2.type)
00148         self.assertEqual(p1.in_, p2.in_)
00149         self.assertEqual(p1.out, p2.out)
00150         self.assertEqual(p1.retval, p2.retval)
00151         self.assertEqual(p1.shared, p2.shared)
00152         self.assertEqual(p1.dipper, p2.dipper)
00153         self.assertEqual(p1.optional, p2.optional)
00154         
00155     def assertEqualTypes(self, t1, t2):
00156         self.assert_(t1 is not None, "Should not be None")
00157         self.assert_(t2 is not None, "Should not be None")
00158         self.assertEqual(type(t1), type(t2), "type types should be equal")
00159         self.assertEqual(t1.pointer, t2.pointer,
00160                          "pointer flag should be equal for %s and %s" % (t1, t2))
00161         self.assertEqual(t1.reference, t2.reference)
00162         if isinstance(t1, xpt.SimpleType):
00163             self.assertEqual(t1.tag, t2.tag)
00164         elif isinstance(t1, xpt.InterfaceType):
00165             self.assertEqualInterfaces(t1.iface, t2.iface)
00166         elif isinstance(t1, xpt.InterfaceIsType):
00167             self.assertEqual(t1.param_index, t2.param_index)
00168         elif isinstance(t1, xpt.ArrayType):
00169             self.assertEqualTypes(t1.element_type, t2.element_type)
00170             self.assertEqual(t1.size_is_arg_num, t2.size_is_arg_num)
00171             self.assertEqual(t1.length_is_arg_num, t2.length_is_arg_num)
00172         elif isinstance(t1, xpt.StringWithSizeType) or isinstance(t1, xpt.WideStringWithSizeType):
00173             self.assertEqual(t1.size_is_arg_num, t2.size_is_arg_num)
00174             self.assertEqual(t1.length_is_arg_num, t2.length_is_arg_num)
00175 
00176 #TODO: test flags in various combinations
00177 class TestTypelibRoundtrip(unittest.TestCase, TypelibCompareMixin):
00178     def checkRoundtrip(self, t):
00179         fd, f = tempfile.mkstemp()
00180         os.close(fd)
00181         t.write(f)
00182         t2 = xpt.Typelib.read(f)
00183         os.remove(f)
00184         self.assert_(t2 is not None)
00185         self.assertEqualTypelibs(t, t2)
00186         
00187     def test_simple(self):
00188         t = xpt.Typelib()
00189         # add an unresolved interface
00190         t.interfaces.append(xpt.Interface("IFoo"))
00191         self.checkRoundtrip(t)
00192         
00193         t = xpt.Typelib()
00194         # add an unresolved interface with an IID
00195         t.interfaces.append(xpt.Interface("IBar", "11223344-5566-7788-9900-aabbccddeeff"))
00196         self.checkRoundtrip(t)
00197 
00198     def test_parent(self):
00199         """
00200         Test that an interface's parent property is correctly serialized
00201         and deserialized.
00202 
00203         """
00204         t = xpt.Typelib()
00205         pi = xpt.Interface("IParent")
00206         t.interfaces.append(pi)
00207         t.interfaces.append(xpt.Interface("IChild", iid="11223344-5566-7788-9900-aabbccddeeff",
00208                                           parent=pi, resolved=True))
00209         self.checkRoundtrip(t)
00210 
00211     def test_ifaceFlags(self):
00212         """
00213         Test that an interface's flags are correctly serialized
00214         and deserialized.
00215 
00216         """
00217         t = xpt.Typelib()
00218         t.interfaces.append(xpt.Interface("IFlags", iid="11223344-5566-7788-9900-aabbccddeeff",
00219                                           resolved=True,
00220                                           scriptable=True,
00221                                           function=True))
00222         self.checkRoundtrip(t)
00223 
00224     def test_constants(self):
00225         c = xpt.Constant("X", xpt.SimpleType(xpt.Type.Tags.uint32),
00226                          0xF000F000)
00227         i = xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00228                           constants=[c])
00229         t = xpt.Typelib(interfaces=[i])
00230         self.checkRoundtrip(t)
00231         # tack on some more constants
00232         i.constants.append(xpt.Constant("Y",
00233                                         xpt.SimpleType(xpt.Type.Tags.int16),
00234                                         -30000))
00235         i.constants.append(xpt.Constant("Z",
00236                                         xpt.SimpleType(xpt.Type.Tags.uint16),
00237                                         0xB0B0))
00238         i.constants.append(xpt.Constant("A",
00239                                         xpt.SimpleType(xpt.Type.Tags.int32),
00240                                         -1000000))
00241         self.checkRoundtrip(t)
00242 
00243     def test_methods(self):
00244         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00245         m = xpt.Method("Bar", p)
00246         i = xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00247                           methods=[m])
00248         t = xpt.Typelib(interfaces=[i])
00249         self.checkRoundtrip(t)
00250         # add some more methods
00251         i.methods.append(xpt.Method("One", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00252                                     params=[
00253                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int64)),
00254                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.float, pointer=True))
00255                                         ]))
00256         self.checkRoundtrip(t)
00257         # test some other types (should really be more thorough)
00258         i.methods.append(xpt.Method("Two", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00259                                     params=[
00260                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.UTF8String, pointer=True)),
00261                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.wchar_t_ptr, pointer=True))
00262                                         ]))
00263         self.checkRoundtrip(t)
00264         # add a method with an InterfaceType argument
00265         bar = xpt.Interface("IBar")
00266         t.interfaces.append(bar)
00267         i.methods.append(xpt.Method("IFaceMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00268                                     params=[
00269                                         xpt.Param(xpt.InterfaceType(bar))
00270                                         ]))
00271         self.checkRoundtrip(t)
00272 
00273         # add a method with an InterfaceIsType argument
00274         i.methods.append(xpt.Method("IFaceIsMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
00275                                     params=[
00276                                         xpt.Param(xpt.InterfaceIsType(1)),
00277                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.nsIID))
00278                                         ]))
00279         self.checkRoundtrip(t)
00280 
00281         # add a method with an ArrayType argument
00282         i.methods.append(xpt.Method("ArrayMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
00283                                     params=[
00284                                         xpt.Param(xpt.ArrayType(
00285                                             xpt.SimpleType(xpt.Type.Tags.int32),
00286                                             1, 2)),
00287                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00288                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00289                                         ]))
00290         self.checkRoundtrip(t)
00291         
00292         # add a method with a StringWithSize and WideStringWithSize arguments
00293         i.methods.append(xpt.Method("StringWithSizeMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
00294                                     params=[
00295                                         xpt.Param(xpt.StringWithSizeType(
00296                                             1, 2)),
00297                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00298                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00299                                         xpt.Param(xpt.WideStringWithSizeType(
00300                                             4, 5)),
00301                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00302                                         xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
00303                                         ]))
00304         self.checkRoundtrip(t)
00305 
00306 class TestInterfaceCmp(unittest.TestCase):
00307     def test_unresolvedName(self):
00308         """
00309         Test comparison function on xpt.Interface by name.
00310         
00311         """
00312         i1 = xpt.Interface("ABC")
00313         i2 = xpt.Interface("DEF")
00314         self.assert_(i1 < i2)
00315         self.assert_(i1 != i2)
00316 
00317     def test_unresolvedEqual(self):
00318         """
00319         Test comparison function on xpt.Interface with equal names and IIDs.
00320         
00321         """
00322         i1 = xpt.Interface("ABC")
00323         i2 = xpt.Interface("ABC")
00324         self.assert_(i1 == i2)
00325 
00326     def test_unresolvedIID(self):
00327         """
00328         Test comparison function on xpt.Interface with different IIDs.
00329         
00330         """
00331         # IIDs sort before names
00332         i1 = xpt.Interface("ABC", iid="22334411-5566-7788-9900-aabbccddeeff")
00333         i2 = xpt.Interface("DEF", iid="11223344-5566-7788-9900-aabbccddeeff")
00334         self.assert_(i2 < i1)
00335         self.assert_(i2 != i1)
00336 
00337     def test_unresolvedResolved(self):
00338         """
00339         Test comparison function on xpt.Interface with interfaces with
00340         identical names and IIDs but different resolved status.
00341         
00342         """
00343         i1 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff")
00344         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00345         m = xpt.Method("Bar", p)
00346         i2 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
00347                            methods=[m])
00348         self.assert_(i2 < i1)
00349         self.assert_(i2 != i1)
00350 
00351     def test_resolvedIdentical(self):
00352         """
00353         Test comparison function on xpt.Interface with interfaces with
00354         identical names and IIDs, both of which are resolved.
00355         
00356         """
00357         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00358         m = xpt.Method("Bar", p)
00359         i1 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
00360                            methods=[m])
00361         i2 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
00362                            methods=[m])
00363         self.assert_(i2 == i1)
00364 
00365 class TestTypelibMerge(unittest.TestCase):
00366     def test_mergeDifferent(self):
00367         """
00368         Test that merging two typelibs with completely different interfaces
00369         produces the correctly merged typelib.
00370         
00371         """
00372         t1 = xpt.Typelib()
00373         # add an unresolved interface
00374         t1.interfaces.append(xpt.Interface("IFoo"))
00375         t2 = xpt.Typelib()
00376         # add an unresolved interface
00377         t2.interfaces.append(xpt.Interface("IBar"))
00378         t1.merge(t2)
00379         
00380         self.assertEqual(2, len(t1.interfaces))
00381         # Interfaces should wind up sorted
00382         self.assertEqual("IBar", t1.interfaces[0].name)
00383         self.assertEqual("IFoo", t1.interfaces[1].name)
00384 
00385         # Add some IID values
00386         t1 = xpt.Typelib()
00387         # add an unresolved interface
00388         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00389         t2 = xpt.Typelib()
00390         # add an unresolved interface
00391         t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
00392         t1.merge(t2)
00393         
00394         self.assertEqual(2, len(t1.interfaces))
00395         # Interfaces should wind up sorted
00396         self.assertEqual("IFoo", t1.interfaces[0].name)
00397         self.assertEqual("IBar", t1.interfaces[1].name)
00398 
00399     def test_mergeConflict(self):
00400         """
00401         Test that merging two typelibs with conflicting interface definitions
00402         raises an error.
00403         
00404         """
00405         # Same names, different IIDs
00406         t1 = xpt.Typelib()
00407         # add an unresolved interface
00408         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00409         t2 = xpt.Typelib()
00410         # add an unresolved interface, same name different IID
00411         t2.interfaces.append(xpt.Interface("IFoo", iid="44332211-6655-8877-0099-aabbccddeeff"))
00412         self.assertRaises(xpt.DataError, t1.merge, t2)
00413 
00414         # Same IIDs, different names
00415         t1 = xpt.Typelib()
00416         # add an unresolved interface
00417         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00418         t2 = xpt.Typelib()
00419         # add an unresolved interface, same IID different name
00420         t2.interfaces.append(xpt.Interface("IBar", iid="11223344-5566-7788-9900-aabbccddeeff"))
00421         self.assertRaises(xpt.DataError, t1.merge, t2)
00422 
00423     def test_mergeUnresolvedIID(self):
00424         """
00425         Test that merging a typelib with an unresolved definition of
00426         an interface that's also unresolved in this typelib, but one
00427         has a valid IID copies the IID value to the resulting typelib.
00428 
00429         """
00430         # Unresolved in both, but t1 has an IID value
00431         t1 = xpt.Typelib()
00432         # add an unresolved interface with a valid IID
00433         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00434         t2 = xpt.Typelib()
00435         # add an unresolved interface, no IID
00436         t2.interfaces.append(xpt.Interface("IFoo"))
00437         t1.merge(t2)
00438         
00439         self.assertEqual(1, len(t1.interfaces))
00440         self.assertEqual("IFoo", t1.interfaces[0].name)
00441         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
00442         # Unresolved in both, but t2 has an IID value
00443         t1 = xpt.Typelib()
00444         # add an unresolved interface, no IID
00445         t1.interfaces.append(xpt.Interface("IFoo"))
00446         t2 = xpt.Typelib()
00447         # add an unresolved interface with a valid IID
00448         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00449         t1.merge(t2)
00450         
00451         self.assertEqual(1, len(t1.interfaces))
00452         self.assertEqual("IFoo", t1.interfaces[0].name)
00453         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
00454 
00455     def test_mergeResolvedUnresolved(self):
00456         """
00457         Test that merging two typelibs, one of which contains an unresolved
00458         reference to an interface, and the other of which contains a
00459         resolved reference to the same interface results in keeping the
00460         resolved reference.
00461 
00462         """
00463         # t1 has an unresolved interface, t2 has a resolved version
00464         t1 = xpt.Typelib()
00465         # add an unresolved interface
00466         t1.interfaces.append(xpt.Interface("IFoo"))
00467         t2 = xpt.Typelib()
00468         # add a resolved interface
00469         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00470         m = xpt.Method("Bar", p)
00471         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00472                                            methods=[m]))
00473         t1.merge(t2)
00474         
00475         self.assertEqual(1, len(t1.interfaces))
00476         self.assertEqual("IFoo", t1.interfaces[0].name)
00477         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
00478         self.assert_(t1.interfaces[0].resolved)
00479         self.assertEqual(1, len(t1.interfaces[0].methods))
00480         self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
00481 
00482         # t1 has a resolved interface, t2 has an unresolved version
00483         t1 = xpt.Typelib()
00484         # add a resolved interface
00485         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00486         m = xpt.Method("Bar", p)
00487         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00488                                            methods=[m]))
00489         t2 = xpt.Typelib()
00490         # add an unresolved interface
00491         t2.interfaces.append(xpt.Interface("IFoo"))
00492         t1.merge(t2)
00493         
00494         self.assertEqual(1, len(t1.interfaces))
00495         self.assertEqual("IFoo", t1.interfaces[0].name)
00496         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
00497         self.assert_(t1.interfaces[0].resolved)
00498         self.assertEqual(1, len(t1.interfaces[0].methods))
00499         self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
00500 
00501     def test_mergeReplaceParents(self):
00502         """
00503         Test that merging an interface results in other interfaces' parent
00504         member being updated properly.
00505 
00506         """
00507         # t1 has an unresolved interface, t2 has a resolved version,
00508         # but t1 also has another interface whose parent is the unresolved
00509         # interface.
00510         t1 = xpt.Typelib()
00511         # add an unresolved interface
00512         pi = xpt.Interface("IFoo")
00513         t1.interfaces.append(pi)
00514         # add a child of the unresolved interface
00515         t1.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
00516                                            resolved=True, parent=pi))
00517         t2 = xpt.Typelib()
00518         # add a resolved interface
00519         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00520         m = xpt.Method("Bar", p)
00521         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00522                                            methods=[m]))
00523         t1.merge(t2)
00524         
00525         self.assertEqual(2, len(t1.interfaces))
00526         self.assertEqual("IChild", t1.interfaces[0].name)
00527         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00528         self.assertEqual("IFoo", t1.interfaces[1].name)
00529         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00530         self.assert_(t1.interfaces[0].resolved)
00531         # Ensure that IChild's parent has been updated
00532         self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
00533         self.assert_(t1.interfaces[0].parent.resolved)
00534 
00535         # t1 has a resolved interface, t2 has an unresolved version,
00536         # but t2 also has another interface whose parent is the unresolved
00537         # interface.
00538         t1 = xpt.Typelib()
00539         # add a resolved interface
00540         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00541         m = xpt.Method("Bar", p)
00542         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00543                                            methods=[m]))
00544         t2 = xpt.Typelib()
00545         # add an unresolved interface
00546         pi = xpt.Interface("IFoo")
00547         t2.interfaces.append(pi)
00548         # add a child of the unresolved interface
00549         t2.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
00550                                            resolved=True, parent=pi))
00551         t1.merge(t2)
00552         
00553         self.assertEqual(2, len(t1.interfaces))
00554         self.assertEqual("IChild", t1.interfaces[0].name)
00555         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00556         self.assertEqual("IFoo", t1.interfaces[1].name)
00557         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00558         self.assert_(t1.interfaces[0].resolved)
00559         # Ensure that IChild's parent has been updated
00560         self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
00561         self.assert_(t1.interfaces[0].parent.resolved)
00562 
00563     def test_mergeReplaceRetval(self):
00564         """
00565         Test that merging an interface correctly updates InterfaceType
00566         return values on methods of other interfaces.
00567 
00568         """
00569         # t1 has an unresolved interface and an interface that uses the
00570         # unresolved interface as a return value from a method. t2
00571         # has a resolved version of the unresolved interface.
00572         t1 = xpt.Typelib()
00573         # add an unresolved interface
00574         i = xpt.Interface("IFoo")
00575         t1.interfaces.append(i)
00576         # add an interface that uses the unresolved interface
00577         # as a return value in a method.
00578         p = xpt.Param(xpt.InterfaceType(i))
00579         m = xpt.Method("ReturnIface", p)
00580         t1.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
00581                                            methods=[m]))
00582         t2 = xpt.Typelib()
00583         # add a resolved interface
00584         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00585         m = xpt.Method("Bar", p)
00586         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00587                                            methods=[m]))
00588         t1.merge(t2)
00589         
00590         self.assertEqual(2, len(t1.interfaces))
00591         self.assertEqual("IRetval", t1.interfaces[0].name)
00592         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00593         self.assertEqual("IFoo", t1.interfaces[1].name)
00594         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00595         self.assert_(t1.interfaces[1].resolved)
00596         # Ensure that IRetval's method's return value type has been updated.
00597         self.assertEqual(1, len(t1.interfaces[0].methods))
00598         self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
00599         self.assertEqual(t1.interfaces[1],
00600                          t1.interfaces[0].methods[0].result.type.iface)
00601 
00602         # t1 has a resolved interface. t2 has an unresolved version and
00603         # an interface that uses the unresolved interface as a return value
00604         # from a method.
00605         t1 = xpt.Typelib()
00606         # add a resolved interface
00607         p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00608         m = xpt.Method("Bar", p)
00609         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00610                                            methods=[m]))
00611         t2 = xpt.Typelib()
00612         # add an unresolved interface
00613         i = xpt.Interface("IFoo")
00614         t2.interfaces.append(i)
00615         # add an interface that uses the unresolved interface
00616         # as a return value in a method.
00617         p = xpt.Param(xpt.InterfaceType(i))
00618         m = xpt.Method("ReturnIface", p)
00619         t2.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
00620                                            methods=[m]))
00621         t1.merge(t2)
00622         
00623         self.assertEqual(2, len(t1.interfaces))
00624         self.assertEqual("IRetval", t1.interfaces[0].name)
00625         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00626         self.assertEqual("IFoo", t1.interfaces[1].name)
00627         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00628         self.assert_(t1.interfaces[1].resolved)
00629         # Ensure that IRetval's method's return value type has been updated.
00630         self.assertEqual(1, len(t1.interfaces[0].methods))
00631         self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
00632         self.assertEqual(t1.interfaces[1],
00633                          t1.interfaces[0].methods[0].result.type.iface)
00634 
00635     def test_mergeReplaceParams(self):
00636         """
00637         Test that merging an interface correctly updates InterfaceType
00638         params on methods of other interfaces.
00639 
00640         """
00641         # t1 has an unresolved interface and an interface that uses the
00642         # unresolved interface as a param value in a method. t2
00643         # has a resolved version of the unresolved interface.
00644         t1 = xpt.Typelib()
00645         # add an unresolved interface
00646         i = xpt.Interface("IFoo")
00647         t1.interfaces.append(i)
00648         # add an interface that uses the unresolved interface
00649         # as a param value in a method.
00650         vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00651         p = xpt.Param(xpt.InterfaceType(i))
00652         m = xpt.Method("IfaceParam", vp, params=[p])
00653         t1.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
00654                                            methods=[m]))
00655         t2 = xpt.Typelib()
00656         # add a resolved interface
00657         m = xpt.Method("Bar", vp)
00658         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00659                                            methods=[m]))
00660         t1.merge(t2)
00661         
00662         self.assertEqual(2, len(t1.interfaces))
00663         self.assertEqual("IParam", t1.interfaces[0].name)
00664         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00665         self.assertEqual("IFoo", t1.interfaces[1].name)
00666         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00667         self.assert_(t1.interfaces[1].resolved)
00668         # Ensure that IRetval's method's param type has been updated.
00669         self.assertEqual(1, len(t1.interfaces[0].methods))
00670         self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
00671         self.assertEqual(t1.interfaces[1],
00672                          t1.interfaces[0].methods[0].params[0].type.iface)
00673 
00674         # t1 has a resolved interface. t2 has an unresolved version
00675         # and an interface that uses the unresolved interface as a
00676         # param value in a method.
00677         t1 = xpt.Typelib()
00678         # add a resolved interface
00679         m = xpt.Method("Bar", vp)
00680         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00681                                            methods=[m]))
00682         t2 = xpt.Typelib()
00683         # add an unresolved interface
00684         i = xpt.Interface("IFoo")
00685         t2.interfaces.append(i)
00686         # add an interface that uses the unresolved interface
00687         # as a param value in a method.
00688         vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00689         p = xpt.Param(xpt.InterfaceType(i))
00690         m = xpt.Method("IfaceParam", vp, params=[p])
00691         t2.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
00692                                            methods=[m]))
00693         t1.merge(t2)
00694         
00695         self.assertEqual(2, len(t1.interfaces))
00696         self.assertEqual("IParam", t1.interfaces[0].name)
00697         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00698         self.assertEqual("IFoo", t1.interfaces[1].name)
00699         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00700         self.assert_(t1.interfaces[1].resolved)
00701         # Ensure that IRetval's method's param type has been updated.
00702         self.assertEqual(1, len(t1.interfaces[0].methods))
00703         self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
00704         self.assertEqual(t1.interfaces[1],
00705                          t1.interfaces[0].methods[0].params[0].type.iface)
00706 
00707 
00708     def test_mergeReplaceArrayTypeParams(self):
00709         """
00710         Test that merging an interface correctly updates ArrayType
00711         params whose element_type is an InterfaceType on methods
00712         of other interfaces.
00713 
00714         """
00715         # t1 has an unresolved interface and an interface that uses the
00716         # unresolved interface as a type in an ArrayType in a parameter
00717         # of a method. t2 has a resolved version of the unresolved interface.
00718         t1 = xpt.Typelib()
00719         # add an unresolved interface
00720         i = xpt.Interface("IFoo")
00721         t1.interfaces.append(i)
00722         # add an interface that uses the unresolved interface
00723         # as a type in an ArrayType in a param value in a method.
00724         vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
00725         intp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32))
00726         p = xpt.Param(xpt.ArrayType(xpt.InterfaceType(i), 1, 2))
00727         m = xpt.Method("ArrayIfaceParam", vp, params=[p, intp, intp])
00728         t1.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
00729                                            methods=[m]))
00730         t2 = xpt.Typelib()
00731         # add a resolved interface
00732         m = xpt.Method("Bar", vp)
00733         t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
00734                                            methods=[m]))
00735         t1.merge(t2)
00736         
00737         self.assertEqual(2, len(t1.interfaces))
00738         self.assertEqual("IParam", t1.interfaces[0].name)
00739         self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
00740         self.assertEqual("IFoo", t1.interfaces[1].name)
00741         self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
00742         self.assert_(t1.interfaces[1].resolved)
00743         # Ensure that IRetval's method's param type has been updated.
00744         self.assertEqual(1, len(t1.interfaces[0].methods))
00745         self.assert_(t1.interfaces[0].methods[0].params[0].type.element_type.iface.resolved)
00746         self.assertEqual(t1.interfaces[1],
00747                          t1.interfaces[0].methods[0].params[0].type.element_type.iface)
00748 
00749 class TestXPTLink(unittest.TestCase):
00750     def setUp(self):
00751         self.tempdir = tempfile.mkdtemp()
00752 
00753     def tearDown(self):
00754         shutil.rmtree(self.tempdir, True)
00755 
00756     def gettempfile(self):
00757         fd, f = tempfile.mkstemp(dir=self.tempdir)
00758         os.close(fd)
00759         return f
00760 
00761     def test_xpt_link(self):
00762         """
00763         Test the xpt_link method.
00764         
00765         """
00766         t1 = xpt.Typelib()
00767         # add an unresolved interface
00768         t1.interfaces.append(xpt.Interface("IFoo"))
00769         f1 = self.gettempfile()
00770         t1.write(f1)
00771 
00772         t2 = xpt.Typelib()
00773         # add an unresolved interface
00774         t2.interfaces.append(xpt.Interface("IBar"))
00775         f2 = self.gettempfile()
00776         t2.write(f2)
00777 
00778         f3 = self.gettempfile()
00779         xpt.xpt_link(f3, [f1, f2])
00780         t3 = xpt.Typelib.read(f3)
00781         
00782         self.assertEqual(2, len(t3.interfaces))
00783         # Interfaces should wind up sorted
00784         self.assertEqual("IBar", t3.interfaces[0].name)
00785         self.assertEqual("IFoo", t3.interfaces[1].name)
00786 
00787         # Add some IID values
00788         t1 = xpt.Typelib()
00789         # add an unresolved interface
00790         t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
00791         f1 = self.gettempfile()
00792         t1.write(f1)
00793 
00794         t2 = xpt.Typelib()
00795         # add an unresolved interface
00796         t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
00797         f2 = self.gettempfile()
00798         t2.write(f2)
00799 
00800         f3 = self.gettempfile()
00801         xpt.xpt_link(f3, [f1, f2])
00802         t3 = xpt.Typelib.read(f3)
00803         
00804         self.assertEqual(2, len(t3.interfaces))
00805         # Interfaces should wind up sorted
00806         self.assertEqual("IFoo", t3.interfaces[0].name)
00807         self.assertEqual("IBar", t3.interfaces[1].name)
00808 
00809 if __name__ == '__main__':
00810     unittest.main()