dom/bindings/parser/tests/test_union.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 import WebIDL
     2 import itertools
     3 import string
     5 # We'd like to use itertools.chain but it's 2.6 or higher.
     6 def chain(*iterables):
     7     # chain('ABC', 'DEF') --> A B C D E F
     8     for it in iterables:
     9         for element in it:
    10             yield element
    12 # We'd like to use itertools.combinations but it's 2.6 or higher.
    13 def combinations(iterable, r):
    14     # combinations('ABCD', 2) --> AB AC AD BC BD CD
    15     # combinations(range(4), 3) --> 012 013 023 123
    16     pool = tuple(iterable)
    17     n = len(pool)
    18     if r > n:
    19         return
    20     indices = range(r)
    21     yield tuple(pool[i] for i in indices)
    22     while True:
    23         for i in reversed(range(r)):
    24             if indices[i] != i + n - r:
    25                 break
    26         else:
    27             return
    28         indices[i] += 1
    29         for j in range(i+1, r):
    30             indices[j] = indices[j-1] + 1
    31         yield tuple(pool[i] for i in indices)
    33 # We'd like to use itertools.combinations_with_replacement but it's 2.7 or
    34 # higher.
    35 def combinations_with_replacement(iterable, r):
    36     # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
    37     pool = tuple(iterable)
    38     n = len(pool)
    39     if not n and r:
    40         return
    41     indices = [0] * r
    42     yield tuple(pool[i] for i in indices)
    43     while True:
    44         for i in reversed(range(r)):
    45             if indices[i] != n - 1:
    46                 break
    47         else:
    48             return
    49         indices[i:] = [indices[i] + 1] * (r - i)
    50         yield tuple(pool[i] for i in indices)
    52 def WebIDLTest(parser, harness):
    53     types = ["float",
    54              "double",
    55              "short",
    56              "unsigned short",
    57              "long",
    58              "unsigned long",
    59              "long long",
    60              "unsigned long long",
    61              "boolean",
    62              "byte",
    63              "octet",
    64              "DOMString",
    65              "ByteString",
    66              #"sequence<float>",
    67              "object",
    68              "ArrayBuffer",
    69              #"Date",
    70              "TestInterface1",
    71              "TestInterface2"]
    73     testPre = """
    74         interface TestInterface1 {
    75         };
    76         interface TestInterface2 {
    77         };
    78         """
    80     interface = testPre + """
    81         interface PrepareForTest {
    82         """
    83     for (i, type) in enumerate(types):
    84         interface += string.Template("""
    85           readonly attribute ${type} attr${i};
    86         """).substitute(i=i, type=type)
    87     interface += """
    88         };
    89         """
    91     parser.parse(interface)
    92     results = parser.finish()
    94     iface = results[2]
    96     parser = parser.reset()
    98     def typesAreDistinguishable(t):
    99         return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
   100     def typesAreNotDistinguishable(t):
   101         return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
   102     def unionTypeName(t):
   103         if len(t) > 2:
   104             t[0:2] = [unionTypeName(t[0:2])]
   105         return "(" + " or ".join(t) + ")"
   107     # typeCombinations is an iterable of tuples containing the name of the type
   108     # as a string and the parsed IDL type.
   109     def unionTypes(typeCombinations, predicate):
   110         for c in typeCombinations:
   111             if predicate(t[1] for t in c):
   112                 yield unionTypeName([t[0] for t in c])
   114     # We limit invalid union types with a union member type to the subset of 3
   115     # types with one invalid combination.
   116     # typeCombinations is an iterable of tuples containing the name of the type
   117     # as a string and the parsed IDL type.
   118     def invalidUnionWithUnion(typeCombinations):
   119         for c in typeCombinations:
   120             if (typesAreNotDistinguishable((c[0][1], c[1][1])) and
   121                 typesAreDistinguishable((c[1][1], c[2][1])) and
   122                 typesAreDistinguishable((c[0][1], c[2][1]))):
   123                 yield unionTypeName([t[0] for t in c])
   125     # Create a list of tuples containing the name of the type as a string and
   126     # the parsed IDL type.
   127     types = zip(types, (a.type for a in iface.members))
   129     validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable),
   130                             unionTypes(combinations(types, 3), typesAreDistinguishable))
   131     invalidUnionTypes = chain(unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable),
   132                               invalidUnionWithUnion(combinations(types, 3)))
   133     interface = testPre + """
   134         interface TestUnion {
   135         """
   136     for (i, type) in enumerate(validUnionTypes):
   137         interface += string.Template("""
   138           void method${i}(${type} arg);
   139           ${type} returnMethod${i}();
   140           attribute ${type} attr${i};
   141           void arrayMethod${i}(${type}[] arg);
   142           ${type}[] arrayReturnMethod${i}();
   143           attribute ${type}[] arrayAttr${i};
   144           void optionalMethod${i}(${type}? arg);
   145         """).substitute(i=i, type=type)
   146     interface += """
   147         };
   148         """
   149     parser.parse(interface)
   150     results = parser.finish()
   152     parser = parser.reset()
   154     for invalid in invalidUnionTypes:
   155         interface = testPre + string.Template("""
   156             interface TestUnion {
   157               void method(${type} arg);
   158             };
   159         """).substitute(type=invalid)
   161         threw = False
   162         try:
   163             parser.parse(interface)
   164             results = parser.finish()
   165         except:
   166             threw = True
   168         harness.ok(threw, "Should have thrown.")
   170         parser = parser.reset()

mercurial