tor-browser

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

test_method.py (12610B)


      1 import WebIDL
      2 
      3 
      4 def WebIDLTest(parser, harness):
      5    parser.parse(
      6        """
      7        interface TestMethods {
      8          undefined basic();
      9          static undefined basicStatic();
     10          undefined basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
     11          boolean basicBoolean();
     12          static boolean basicStaticBoolean();
     13          boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
     14          undefined optionalArg(optional byte? arg1, optional sequence<byte> arg2);
     15          undefined variadicArg(byte?... arg1);
     16          object getObject();
     17          undefined setObject(object arg1);
     18          undefined setAny(any arg1);
     19          float doFloats(float arg1);
     20        };
     21    """
     22    )
     23 
     24    results = parser.finish()
     25 
     26    harness.ok(True, "TestMethods interface parsed without error.")
     27    harness.check(len(results), 1, "Should be one production.")
     28    iface = results[0]
     29    harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface")
     30    harness.check(
     31        iface.identifier.QName(), "::TestMethods", "Interface has the right QName"
     32    )
     33    harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
     34    harness.check(len(iface.members), 12, "Expect 12 members")
     35 
     36    methods = iface.members
     37 
     38    def checkArgument(argument, QName, name, type, optional, variadic):
     39        harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument")
     40        harness.check(
     41            argument.identifier.QName(), QName, "Argument has the right QName"
     42        )
     43        harness.check(argument.identifier.name, name, "Argument has the right name")
     44        harness.check(str(argument.type), type, "Argument has the right return type")
     45        harness.check(
     46            argument.optional, optional, "Argument has the right optional value"
     47        )
     48        harness.check(
     49            argument.variadic, variadic, "Argument has the right variadic value"
     50        )
     51 
     52    def checkMethod(
     53        method,
     54        QName,
     55        name,
     56        signatures,
     57        static=False,
     58        getter=False,
     59        setter=False,
     60        deleter=False,
     61        legacycaller=False,
     62        stringifier=False,
     63    ):
     64        harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod")
     65        harness.ok(method.isMethod(), "Method is a method")
     66        harness.ok(not method.isAttr(), "Method is not an attr")
     67        harness.ok(not method.isConst(), "Method is not a const")
     68        harness.check(method.identifier.QName(), QName, "Method has the right QName")
     69        harness.check(method.identifier.name, name, "Method has the right name")
     70        harness.check(method.isStatic(), static, "Method has the correct static value")
     71        harness.check(method.isGetter(), getter, "Method has the correct getter value")
     72        harness.check(method.isSetter(), setter, "Method has the correct setter value")
     73        harness.check(
     74            method.isDeleter(), deleter, "Method has the correct deleter value"
     75        )
     76        harness.check(
     77            method.isLegacycaller(),
     78            legacycaller,
     79            "Method has the correct legacycaller value",
     80        )
     81        harness.check(
     82            method.isStringifier(),
     83            stringifier,
     84            "Method has the correct stringifier value",
     85        )
     86        harness.check(
     87            len(method.signatures()),
     88            len(signatures),
     89            "Method has the correct number of signatures",
     90        )
     91 
     92        sigpairs = zip(method.signatures(), signatures)
     93        for gotSignature, expectedSignature in sigpairs:
     94            (gotRetType, gotArgs) = gotSignature
     95            (expectedRetType, expectedArgs) = expectedSignature
     96 
     97            harness.check(
     98                str(gotRetType), expectedRetType, "Method has the expected return type."
     99            )
    100 
    101            for i in range(0, len(gotArgs)):
    102                (QName, name, type, optional, variadic) = expectedArgs[i]
    103                checkArgument(gotArgs[i], QName, name, type, optional, variadic)
    104 
    105    checkMethod(methods[0], "::TestMethods::basic", "basic", [("Undefined", [])])
    106    checkMethod(
    107        methods[1],
    108        "::TestMethods::basicStatic",
    109        "basicStatic",
    110        [("Undefined", [])],
    111        static=True,
    112    )
    113    checkMethod(
    114        methods[2],
    115        "::TestMethods::basicWithSimpleArgs",
    116        "basicWithSimpleArgs",
    117        [
    118            (
    119                "Undefined",
    120                [
    121                    (
    122                        "::TestMethods::basicWithSimpleArgs::arg1",
    123                        "arg1",
    124                        "Boolean",
    125                        False,
    126                        False,
    127                    ),
    128                    (
    129                        "::TestMethods::basicWithSimpleArgs::arg2",
    130                        "arg2",
    131                        "Byte",
    132                        False,
    133                        False,
    134                    ),
    135                    (
    136                        "::TestMethods::basicWithSimpleArgs::arg3",
    137                        "arg3",
    138                        "UnsignedLong",
    139                        False,
    140                        False,
    141                    ),
    142                ],
    143            )
    144        ],
    145    )
    146    checkMethod(
    147        methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])]
    148    )
    149    checkMethod(
    150        methods[4],
    151        "::TestMethods::basicStaticBoolean",
    152        "basicStaticBoolean",
    153        [("Boolean", [])],
    154        static=True,
    155    )
    156    checkMethod(
    157        methods[5],
    158        "::TestMethods::basicBooleanWithSimpleArgs",
    159        "basicBooleanWithSimpleArgs",
    160        [
    161            (
    162                "Boolean",
    163                [
    164                    (
    165                        "::TestMethods::basicBooleanWithSimpleArgs::arg1",
    166                        "arg1",
    167                        "Boolean",
    168                        False,
    169                        False,
    170                    ),
    171                    (
    172                        "::TestMethods::basicBooleanWithSimpleArgs::arg2",
    173                        "arg2",
    174                        "Byte",
    175                        False,
    176                        False,
    177                    ),
    178                    (
    179                        "::TestMethods::basicBooleanWithSimpleArgs::arg3",
    180                        "arg3",
    181                        "UnsignedLong",
    182                        False,
    183                        False,
    184                    ),
    185                ],
    186            )
    187        ],
    188    )
    189    checkMethod(
    190        methods[6],
    191        "::TestMethods::optionalArg",
    192        "optionalArg",
    193        [
    194            (
    195                "Undefined",
    196                [
    197                    (
    198                        "::TestMethods::optionalArg::arg1",
    199                        "arg1",
    200                        "ByteOrNull",
    201                        True,
    202                        False,
    203                    ),
    204                    (
    205                        "::TestMethods::optionalArg::arg2",
    206                        "arg2",
    207                        "ByteSequence",
    208                        True,
    209                        False,
    210                    ),
    211                ],
    212            )
    213        ],
    214    )
    215    checkMethod(
    216        methods[7],
    217        "::TestMethods::variadicArg",
    218        "variadicArg",
    219        [
    220            (
    221                "Undefined",
    222                [
    223                    (
    224                        "::TestMethods::variadicArg::arg1",
    225                        "arg1",
    226                        "ByteOrNull",
    227                        True,
    228                        True,
    229                    )
    230                ],
    231            )
    232        ],
    233    )
    234    checkMethod(methods[8], "::TestMethods::getObject", "getObject", [("Object", [])])
    235    checkMethod(
    236        methods[9],
    237        "::TestMethods::setObject",
    238        "setObject",
    239        [
    240            (
    241                "Undefined",
    242                [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)],
    243            )
    244        ],
    245    )
    246    checkMethod(
    247        methods[10],
    248        "::TestMethods::setAny",
    249        "setAny",
    250        [("Undefined", [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])],
    251    )
    252    checkMethod(
    253        methods[11],
    254        "::TestMethods::doFloats",
    255        "doFloats",
    256        [("Float", [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])],
    257    )
    258 
    259    parser = parser.reset()
    260    threw = False
    261    try:
    262        parser.parse(
    263            """
    264          interface A {
    265            undefined foo(optional float bar = 1);
    266          };
    267        """
    268        )
    269        results = parser.finish()
    270    except WebIDL.WebIDLError:
    271        threw = True
    272    harness.ok(not threw, "Should allow integer to float type corecion")
    273 
    274    parser = parser.reset()
    275    threw = False
    276    try:
    277        parser.parse(
    278            """
    279          interface A {
    280            [GetterThrows] undefined foo();
    281          };
    282        """
    283        )
    284        results = parser.finish()
    285    except WebIDL.WebIDLError:
    286        threw = True
    287    harness.ok(threw, "Should not allow [GetterThrows] on methods")
    288 
    289    parser = parser.reset()
    290    threw = False
    291    try:
    292        parser.parse(
    293            """
    294          interface A {
    295            [SetterThrows] undefined foo();
    296          };
    297        """
    298        )
    299        results = parser.finish()
    300    except WebIDL.WebIDLError:
    301        threw = True
    302    harness.ok(threw, "Should not allow [SetterThrows] on methods")
    303 
    304    parser = parser.reset()
    305    threw = False
    306    try:
    307        parser.parse(
    308            """
    309          interface A {
    310            [Throw] undefined foo();
    311          };
    312        """
    313        )
    314        results = parser.finish()
    315    except WebIDL.WebIDLError:
    316        threw = True
    317    harness.ok(threw, "Should spell [Throws] correctly on methods")
    318 
    319    parser = parser.reset()
    320    threw = False
    321    try:
    322        parser.parse(
    323            """
    324          interface A {
    325            undefined __noSuchMethod__();
    326          };
    327        """
    328        )
    329        results = parser.finish()
    330    except WebIDL.WebIDLError:
    331        threw = True
    332    harness.ok(threw, "Should not allow __noSuchMethod__ methods")
    333 
    334    parser = parser.reset()
    335    threw = False
    336    try:
    337        parser.parse(
    338            """
    339          interface A {
    340            [Throws, LenientFloat]
    341            undefined foo(float myFloat);
    342            [Throws]
    343            undefined foo();
    344          };
    345        """
    346        )
    347        results = parser.finish()
    348    except WebIDL.WebIDLError:
    349        threw = True
    350    harness.ok(not threw, "Should allow LenientFloat to be only in a specific overload")
    351 
    352    parser = parser.reset()
    353    parser.parse(
    354        """
    355      interface A {
    356        [Throws]
    357        undefined foo();
    358        [Throws, LenientFloat]
    359        undefined foo(float myFloat);
    360      };
    361    """
    362    )
    363    results = parser.finish()
    364    iface = results[0]
    365    methods = iface.members
    366    lenientFloat = methods[0].getExtendedAttribute("LenientFloat")
    367    harness.ok(
    368        lenientFloat is not None,
    369        "LenientFloat in overloads must be added to the method",
    370    )
    371 
    372    parser = parser.reset()
    373    threw = False
    374    try:
    375        parser.parse(
    376            """
    377          interface A {
    378            [Throws, LenientFloat]
    379            undefined foo(float myFloat);
    380            [Throws]
    381            undefined foo(float myFloat, float yourFloat);
    382          };
    383        """
    384        )
    385        results = parser.finish()
    386    except WebIDL.WebIDLError:
    387        threw = True
    388    harness.ok(
    389        threw,
    390        "Should prevent overloads from getting different restricted float behavior",
    391    )
    392 
    393    parser = parser.reset()
    394    threw = False
    395    try:
    396        parser.parse(
    397            """
    398          interface A {
    399            [Throws]
    400            undefined foo(float myFloat, float yourFloat);
    401            [Throws, LenientFloat]
    402            undefined foo(float myFloat);
    403          };
    404        """
    405        )
    406        results = parser.finish()
    407    except WebIDL.WebIDLError:
    408        threw = True
    409    harness.ok(
    410        threw,
    411        "Should prevent overloads from getting different restricted float behavior (2)",
    412    )
    413 
    414    parser = parser.reset()
    415    threw = False
    416    try:
    417        parser.parse(
    418            """
    419          interface A {
    420            [Throws, LenientFloat]
    421            undefined foo(float myFloat);
    422            [Throws, LenientFloat]
    423            undefined foo(short myShort);
    424          };
    425        """
    426        )
    427        results = parser.finish()
    428    except WebIDL.WebIDLError:
    429        threw = True
    430    harness.ok(threw, "Should prevent overloads from getting redundant [LenientFloat]")