dom/bindings/parser/tests/test_nullable_equivalency.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/bindings/parser/tests/test_nullable_equivalency.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,125 @@
     1.4 +import WebIDL
     1.5 +
     1.6 +def WebIDLTest(parser, harness):
     1.7 +    parser.parse("""
     1.8 +        interface TestNullableEquivalency1 {
     1.9 +          attribute long  a;
    1.10 +          attribute long? b;
    1.11 +        };
    1.12 +
    1.13 +        interface TestNullableEquivalency2 {
    1.14 +          attribute ArrayBuffer  a;
    1.15 +          attribute ArrayBuffer? b;
    1.16 +        };
    1.17 +
    1.18 +        /* Can't have dictionary-valued attributes, so can't test that here */
    1.19 +
    1.20 +        enum TestNullableEquivalency4Enum {
    1.21 +          "Foo",
    1.22 +          "Bar"
    1.23 +        };
    1.24 +
    1.25 +        interface TestNullableEquivalency4 {
    1.26 +          attribute TestNullableEquivalency4Enum  a;
    1.27 +          attribute TestNullableEquivalency4Enum? b;
    1.28 +        };
    1.29 +
    1.30 +        interface TestNullableEquivalency5 {
    1.31 +          attribute TestNullableEquivalency4  a;
    1.32 +          attribute TestNullableEquivalency4? b;
    1.33 +        };
    1.34 +
    1.35 +        interface TestNullableEquivalency6 {
    1.36 +          attribute boolean  a;
    1.37 +          attribute boolean? b;
    1.38 +        };
    1.39 +
    1.40 +        interface TestNullableEquivalency7 {
    1.41 +          attribute DOMString  a;
    1.42 +          attribute DOMString? b;
    1.43 +        };
    1.44 +
    1.45 +        interface TestNullableEquivalency8 {
    1.46 +          attribute float  a;
    1.47 +          attribute float? b;
    1.48 +        };
    1.49 +
    1.50 +        interface TestNullableEquivalency9 {
    1.51 +          attribute double  a;
    1.52 +          attribute double? b;
    1.53 +        };
    1.54 +
    1.55 +        interface TestNullableEquivalency10 {
    1.56 +          attribute object  a;
    1.57 +          attribute object? b;
    1.58 +        };
    1.59 +
    1.60 +        interface TestNullableEquivalency11 {
    1.61 +          attribute double[]  a;
    1.62 +          attribute double[]? b;
    1.63 +        };
    1.64 +
    1.65 +        interface TestNullableEquivalency12 {
    1.66 +          attribute TestNullableEquivalency9[]  a;
    1.67 +          attribute TestNullableEquivalency9[]? b;
    1.68 +        };
    1.69 +    """)
    1.70 +
    1.71 +    for decl in parser.finish():
    1.72 +        if decl.isInterface():
    1.73 +            checkEquivalent(decl, harness)
    1.74 +
    1.75 +def checkEquivalent(iface, harness):
    1.76 +    type1 = iface.members[0].type
    1.77 +    type2 = iface.members[1].type
    1.78 +
    1.79 +    harness.check(type1.nullable(), False, 'attr1 should not be nullable')
    1.80 +    harness.check(type2.nullable(), True, 'attr2 should be nullable')
    1.81 +
    1.82 +    # We don't know about type1, but type2, the nullable type, definitely
    1.83 +    # shouldn't be builtin.
    1.84 +    harness.check(type2.builtin, False, 'attr2 should not be builtin')
    1.85 +
    1.86 +    # Ensure that all attributes of type2 match those in type1, except for:
    1.87 +    #  - names on an ignore list,
    1.88 +    #  - names beginning with '_',
    1.89 +    #  - functions which throw when called with no args, and
    1.90 +    #  - class-level non-callables ("static variables").
    1.91 +    #
    1.92 +    # Yes, this is an ugly, fragile hack.  But it finds bugs...
    1.93 +    for attr in dir(type1):
    1.94 +        if attr.startswith('_') or \
    1.95 +           attr in ['nullable', 'builtin', 'filename', 'location',
    1.96 +                    'inner', 'QName', 'getDeps'] or \
    1.97 +           (hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
    1.98 +            continue
    1.99 +
   1.100 +        a1 = getattr(type1, attr)
   1.101 +
   1.102 +        if callable(a1):
   1.103 +            try:
   1.104 +                v1 = a1()
   1.105 +            except:
   1.106 +                # Can't call a1 with no args, so skip this attriute.
   1.107 +                continue
   1.108 +
   1.109 +            try:
   1.110 +                a2 = getattr(type2, attr)
   1.111 +            except:
   1.112 +                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
   1.113 +                continue
   1.114 +
   1.115 +            if not callable(a2):
   1.116 +                harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface))
   1.117 +                continue
   1.118 +
   1.119 +            v2 = a2()
   1.120 +            harness.check(v2, v1, '%s method return value' % attr)
   1.121 +        else:
   1.122 +            try:
   1.123 +                a2 = getattr(type2, attr)
   1.124 +            except:
   1.125 +                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
   1.126 +                continue
   1.127 +
   1.128 +            harness.check(a2, a1, '%s attribute should match' % attr)

mercurial