diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /dom/bindings/parser/tests/test_union.py | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/bindings/parser/tests/test_union.py')
-rw-r--r-- | dom/bindings/parser/tests/test_union.py | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/dom/bindings/parser/tests/test_union.py b/dom/bindings/parser/tests/test_union.py new file mode 100644 index 0000000000..675e2d0264 --- /dev/null +++ b/dom/bindings/parser/tests/test_union.py @@ -0,0 +1,196 @@ +import string + +# We'd like to use itertools.chain but it's 2.6 or higher. + + +def chain(*iterables): + # chain('ABC', 'DEF') --> A B C D E F + for it in iterables: + for element in it: + yield element + + +# We'd like to use itertools.combinations but it's 2.6 or higher. +def combinations(iterable, r): + # combinations('ABCD', 2) --> AB AC AD BC BD CD + # combinations(range(4), 3) --> 012 013 023 123 + pool = tuple(iterable) + n = len(pool) + if r > n: + return + indices = list(range(r)) + yield tuple(pool[i] for i in indices) + while True: + for i in reversed(range(r)): + if indices[i] != i + n - r: + break + else: + return + indices[i] += 1 + for j in range(i + 1, r): + indices[j] = indices[j - 1] + 1 + yield tuple(pool[i] for i in indices) + + +# We'd like to use itertools.combinations_with_replacement but it's 2.7 or +# higher. +def combinations_with_replacement(iterable, r): + # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC + pool = tuple(iterable) + n = len(pool) + if not n and r: + return + indices = [0] * r + yield tuple(pool[i] for i in indices) + while True: + for i in reversed(range(r)): + if indices[i] != n - 1: + break + else: + return + indices[i:] = [indices[i] + 1] * (r - i) + yield tuple(pool[i] for i in indices) + + +def WebIDLTest(parser, harness): + types = [ + "float", + "double", + "short", + "unsigned short", + "long", + "unsigned long", + "long long", + "unsigned long long", + "boolean", + "byte", + "octet", + "DOMString", + "ByteString", + "USVString", + # "sequence<float>", + "object", + "ArrayBuffer", + # "Date", + "TestInterface1", + "TestInterface2", + ] + + testPre = """ + interface TestInterface1 { + }; + interface TestInterface2 { + }; + """ + + interface = ( + testPre + + """ + interface PrepareForTest { + """ + ) + for (i, type) in enumerate(types): + interface += string.Template( + """ + readonly attribute ${type} attr${i}; + """ + ).substitute(i=i, type=type) + interface += """ + }; + """ + + parser.parse(interface) + results = parser.finish() + + iface = results[2] + + parser = parser.reset() + + def typesAreDistinguishable(t): + return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) + + def typesAreNotDistinguishable(t): + return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) + + def unionTypeName(t): + if len(t) > 2: + t[0:2] = [unionTypeName(t[0:2])] + return "(" + " or ".join(t) + ")" + + # typeCombinations is an iterable of tuples containing the name of the type + # as a string and the parsed IDL type. + def unionTypes(typeCombinations, predicate): + for c in typeCombinations: + if predicate(t[1] for t in c): + yield unionTypeName([t[0] for t in c]) + + # We limit invalid union types with a union member type to the subset of 3 + # types with one invalid combination. + # typeCombinations is an iterable of tuples containing the name of the type + # as a string and the parsed IDL type. + def invalidUnionWithUnion(typeCombinations): + for c in typeCombinations: + if ( + typesAreNotDistinguishable((c[0][1], c[1][1])) + and typesAreDistinguishable((c[1][1], c[2][1])) + and typesAreDistinguishable((c[0][1], c[2][1])) + ): + yield unionTypeName([t[0] for t in c]) + + # Create a list of tuples containing the name of the type as a string and + # the parsed IDL type. + types = zip(types, (a.type for a in iface.members)) + + validUnionTypes = chain( + unionTypes(combinations(types, 2), typesAreDistinguishable), + unionTypes(combinations(types, 3), typesAreDistinguishable), + ) + invalidUnionTypes = chain( + unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable), + invalidUnionWithUnion(combinations(types, 3)), + ) + interface = ( + testPre + + """ + interface TestUnion { + """ + ) + for (i, type) in enumerate(validUnionTypes): + interface += string.Template( + """ + undefined method${i}(${type} arg); + ${type} returnMethod${i}(); + attribute ${type} attr${i}; + undefined optionalMethod${i}(${type}? arg); + """ + ).substitute(i=i, type=type) + interface += """ + }; + """ + parser.parse(interface) + results = parser.finish() + + parser = parser.reset() + + for invalid in invalidUnionTypes: + interface = ( + testPre + + string.Template( + """ + interface TestUnion { + undefined method(${type} arg); + }; + """ + ).substitute(type=invalid) + ) + + threw = False + try: + parser.parse(interface) + results = parser.finish() + except Exception: + threw = True + + harness.ok(threw, "Should have thrown.") + + parser = parser.reset() |