tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_nullable_equivalency.py (4191B)


      1 import WebIDL
      2 
      3 
      4 def WebIDLTest(parser, harness):
      5    parser.parse(
      6        """
      7        interface TestNullableEquivalency1 {
      8          attribute long  a;
      9          attribute long? b;
     10        };
     11 
     12        interface TestNullableEquivalency2 {
     13          attribute ArrayBuffer  a;
     14          attribute ArrayBuffer? b;
     15        };
     16 
     17        /* Can't have dictionary-valued attributes, so can't test that here */
     18 
     19        enum TestNullableEquivalency4Enum {
     20          "Foo",
     21          "Bar"
     22        };
     23 
     24        interface TestNullableEquivalency4 {
     25          attribute TestNullableEquivalency4Enum  a;
     26          attribute TestNullableEquivalency4Enum? b;
     27        };
     28 
     29        interface TestNullableEquivalency5 {
     30          attribute TestNullableEquivalency4  a;
     31          attribute TestNullableEquivalency4? b;
     32        };
     33 
     34        interface TestNullableEquivalency6 {
     35          attribute boolean  a;
     36          attribute boolean? b;
     37        };
     38 
     39        interface TestNullableEquivalency7 {
     40          attribute DOMString  a;
     41          attribute DOMString? b;
     42        };
     43 
     44        interface TestNullableEquivalency8 {
     45          attribute float  a;
     46          attribute float? b;
     47        };
     48 
     49        interface TestNullableEquivalency9 {
     50          attribute double  a;
     51          attribute double? b;
     52        };
     53 
     54        interface TestNullableEquivalency10 {
     55          attribute object  a;
     56          attribute object? b;
     57        };
     58    """
     59    )
     60 
     61    for decl in parser.finish():
     62        if decl.isInterface():
     63            checkEquivalent(decl, harness)
     64 
     65 
     66 def checkEquivalent(iface, harness):
     67    type1 = iface.members[0].type
     68    type2 = iface.members[1].type
     69 
     70    harness.check(type1.nullable(), False, "attr1 should not be nullable")
     71    harness.check(type2.nullable(), True, "attr2 should be nullable")
     72 
     73    # We don't know about type1, but type2, the nullable type, definitely
     74    # shouldn't be builtin.
     75    harness.check(type2.builtin, False, "attr2 should not be builtin")
     76 
     77    # Ensure that all attributes of type2 match those in type1, except for:
     78    #  - names on an ignore list,
     79    #  - names beginning with '_',
     80    #  - functions which throw when called with no args, and
     81    #  - class-level non-callables ("static variables").
     82    #
     83    # Yes, this is an ugly, fragile hack.  But it finds bugs...
     84    for attr in dir(type1):
     85        if (
     86            attr.startswith("_")
     87            or attr
     88            in [
     89                "nullable",
     90                "builtin",
     91                "filename",
     92                "location",
     93                "inner",
     94                "QName",
     95                "getDeps",
     96                "name",
     97                "prettyName",
     98            ]
     99            or (hasattr(type(type1), attr) and not callable(getattr(type1, attr)))
    100        ):
    101            continue
    102 
    103        a1 = getattr(type1, attr)
    104 
    105        if callable(a1):
    106            try:
    107                v1 = a1()
    108            except AssertionError:
    109                # Various methods assert that they're called on objects of
    110                # the right type, skip them if the assert fails.
    111                continue
    112            except TypeError:
    113                # a1 requires positional arguments, so skip this attribute.
    114                continue
    115 
    116            try:
    117                a2 = getattr(type2, attr)
    118            except WebIDL.WebIDLError:
    119                harness.ok(
    120                    False,
    121                    "Missing %s attribute on type %s in %s" % (attr, type2, iface),
    122                )
    123                continue
    124 
    125            if not callable(a2):
    126                harness.ok(
    127                    False,
    128                    "%s attribute on type %s in %s wasn't callable"
    129                    % (attr, type2, iface),
    130                )
    131                continue
    132 
    133            v2 = a2()
    134            harness.check(v2, v1, "%s method return value" % attr)
    135        else:
    136            try:
    137                a2 = getattr(type2, attr)
    138            except WebIDL.WebIDLError:
    139                harness.ok(
    140                    False,
    141                    "Missing %s attribute on type %s in %s" % (attr, type2, iface),
    142                )
    143                continue
    144 
    145            harness.check(a2, a1, "%s attribute should match" % attr)