tor-browser

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

test_interfacemixin.py (14010B)


      1 import WebIDL
      2 
      3 
      4 def WebIDLTest(parser, harness):
      5    parser.parse("interface mixin Foo { };")
      6    results = parser.finish()
      7    harness.ok(True, "Empty interface mixin parsed without error.")
      8    harness.check(len(results), 1, "Should be one production")
      9    harness.ok(
     10        isinstance(results[0], WebIDL.IDLInterfaceMixin),
     11        "Should be an IDLInterfaceMixin",
     12    )
     13    mixin = results[0]
     14    harness.check(
     15        mixin.identifier.QName(), "::Foo", "Interface mixin has the right QName"
     16    )
     17    harness.check(mixin.identifier.name, "Foo", "Interface mixin has the right name")
     18 
     19    parser = parser.reset()
     20    parser.parse(
     21        """
     22        interface mixin QNameBase {
     23            const long foo = 3;
     24        };
     25    """
     26    )
     27    results = parser.finish()
     28    harness.check(len(results), 1, "Should be one productions")
     29    harness.ok(
     30        isinstance(results[0], WebIDL.IDLInterfaceMixin),
     31        "Should be an IDLInterfaceMixin",
     32    )
     33    harness.check(len(results[0].members), 1, "Expect 1 productions")
     34    mixin = results[0]
     35    harness.check(
     36        mixin.members[0].identifier.QName(),
     37        "::QNameBase::foo",
     38        "Member has the right QName",
     39    )
     40 
     41    parser = parser.reset()
     42    parser.parse(
     43        """
     44        interface mixin A {
     45            readonly attribute boolean x;
     46            undefined foo();
     47        };
     48        partial interface mixin A {
     49            readonly attribute boolean y;
     50            undefined foo(long arg);
     51        };
     52    """
     53    )
     54    results = parser.finish()
     55    harness.check(
     56        len(results), 2, "Should have two results with partial interface mixin"
     57    )
     58    mixin = results[0]
     59    harness.check(
     60        len(mixin.members), 3, "Should have three members with partial interface mixin"
     61    )
     62    harness.check(
     63        mixin.members[0].identifier.name,
     64        "x",
     65        "First member should be x with partial interface mixin",
     66    )
     67    harness.check(
     68        mixin.members[1].identifier.name,
     69        "foo",
     70        "Second member should be foo with partial interface mixin",
     71    )
     72    harness.check(
     73        len(mixin.members[1].signatures()),
     74        2,
     75        "Should have two foo signatures with partial interface mixin",
     76    )
     77    harness.check(
     78        mixin.members[2].identifier.name,
     79        "y",
     80        "Third member should be y with partial interface mixin",
     81    )
     82 
     83    parser = parser.reset()
     84    parser.parse(
     85        """
     86        partial interface mixin A {
     87            readonly attribute boolean y;
     88            undefined foo(long arg);
     89        };
     90        interface mixin A {
     91            readonly attribute boolean x;
     92            undefined foo();
     93        };
     94    """
     95    )
     96    results = parser.finish()
     97    harness.check(
     98        len(results), 2, "Should have two results with reversed partial interface mixin"
     99    )
    100    mixin = results[1]
    101    harness.check(
    102        len(mixin.members),
    103        3,
    104        "Should have three members with reversed partial interface mixin",
    105    )
    106    harness.check(
    107        mixin.members[0].identifier.name,
    108        "x",
    109        "First member should be x with reversed partial interface mixin",
    110    )
    111    harness.check(
    112        mixin.members[1].identifier.name,
    113        "foo",
    114        "Second member should be foo with reversed partial interface mixin",
    115    )
    116    harness.check(
    117        len(mixin.members[1].signatures()),
    118        2,
    119        "Should have two foo signatures with reversed partial interface mixin",
    120    )
    121    harness.check(
    122        mixin.members[2].identifier.name,
    123        "y",
    124        "Third member should be y with reversed partial interface mixin",
    125    )
    126 
    127    parser = parser.reset()
    128    parser.parse(
    129        """
    130        interface Interface {};
    131        interface mixin Mixin {
    132            attribute short x;
    133        };
    134        Interface includes Mixin;
    135    """
    136    )
    137    results = parser.finish()
    138    iface = results[0]
    139    harness.check(len(iface.members), 1, "Should merge members from mixins")
    140    harness.check(
    141        iface.members[0].identifier.name, "x", "Should merge members from mixins"
    142    )
    143 
    144    parser = parser.reset()
    145    threw = False
    146    try:
    147        parser.parse(
    148            """
    149            interface mixin A {
    150                readonly attribute boolean x;
    151            };
    152            interface mixin A {
    153                readonly attribute boolean y;
    154            };
    155        """
    156        )
    157        results = parser.finish()
    158    except WebIDL.WebIDLError:
    159        threw = True
    160    harness.ok(
    161        threw, "Should not allow two non-partial interface mixins with the same name"
    162    )
    163 
    164    parser = parser.reset()
    165    threw = False
    166    try:
    167        parser.parse(
    168            """
    169            partial interface mixin A {
    170                readonly attribute boolean x;
    171            };
    172            partial interface mixin A {
    173                readonly attribute boolean y;
    174            };
    175        """
    176        )
    177        results = parser.finish()
    178    except WebIDL.WebIDLError:
    179        threw = True
    180    harness.ok(threw, "Must have a non-partial interface mixin for a given name")
    181 
    182    parser = parser.reset()
    183    threw = False
    184    try:
    185        parser.parse(
    186            """
    187            dictionary A {
    188                boolean x;
    189            };
    190            partial interface mixin A {
    191                readonly attribute boolean y;
    192            };
    193        """
    194        )
    195        results = parser.finish()
    196    except WebIDL.WebIDLError:
    197        threw = True
    198    harness.ok(
    199        threw,
    200        "Should not allow a name collision between partial interface "
    201        "mixin and other object",
    202    )
    203 
    204    parser = parser.reset()
    205    threw = False
    206    try:
    207        parser.parse(
    208            """
    209            dictionary A {
    210                boolean x;
    211            };
    212            interface mixin A {
    213                readonly attribute boolean y;
    214            };
    215        """
    216        )
    217        results = parser.finish()
    218    except WebIDL.WebIDLError:
    219        threw = True
    220    harness.ok(
    221        threw,
    222        "Should not allow a name collision between interface mixin and other object",
    223    )
    224 
    225    parser = parser.reset()
    226    threw = False
    227    try:
    228        parser.parse(
    229            """
    230            interface mixin A {
    231                readonly attribute boolean x;
    232            };
    233            interface A;
    234        """
    235        )
    236        results = parser.finish()
    237    except WebIDL.WebIDLError:
    238        threw = True
    239    harness.ok(
    240        threw,
    241        "Should not allow a name collision between external interface "
    242        "and interface mixin",
    243    )
    244 
    245    parser = parser.reset()
    246    threw = False
    247    try:
    248        parser.parse(
    249            """
    250            [SomeRandomAnnotation]
    251            interface mixin A {
    252                readonly attribute boolean y;
    253            };
    254        """
    255        )
    256        results = parser.finish()
    257    except WebIDL.WebIDLError:
    258        threw = True
    259    harness.ok(
    260        threw, "Should not allow unknown extended attributes on interface mixins"
    261    )
    262 
    263    parser = parser.reset()
    264    threw = False
    265    try:
    266        parser.parse(
    267            """
    268            interface mixin A {
    269                getter double (DOMString propertyName);
    270            };
    271        """
    272        )
    273        results = parser.finish()
    274    except WebIDL.WebIDLError:
    275        threw = True
    276    harness.ok(threw, "Should not allow getters on interface mixins")
    277 
    278    parser = parser.reset()
    279    threw = False
    280    try:
    281        parser.parse(
    282            """
    283            interface mixin A {
    284                setter undefined (DOMString propertyName, double propertyValue);
    285            };
    286        """
    287        )
    288        results = parser.finish()
    289    except WebIDL.WebIDLError:
    290        threw = True
    291    harness.ok(threw, "Should not allow setters on interface mixins")
    292 
    293    parser = parser.reset()
    294    threw = False
    295    try:
    296        parser.parse(
    297            """
    298            interface mixin A {
    299                deleter undefined (DOMString propertyName);
    300            };
    301        """
    302        )
    303        results = parser.finish()
    304    except WebIDL.WebIDLError:
    305        threw = True
    306    harness.ok(threw, "Should not allow deleters on interface mixins")
    307 
    308    parser = parser.reset()
    309    threw = False
    310    try:
    311        parser.parse(
    312            """
    313            interface mixin A {
    314                legacycaller double compute(double x);
    315            };
    316        """
    317        )
    318        results = parser.finish()
    319    except WebIDL.WebIDLError:
    320        threw = True
    321    harness.ok(threw, "Should not allow legacycallers on interface mixins")
    322 
    323    parser = parser.reset()
    324    threw = False
    325    try:
    326        parser.parse(
    327            """
    328            interface mixin A {
    329                inherit attribute x;
    330            };
    331        """
    332        )
    333        results = parser.finish()
    334    except WebIDL.WebIDLError:
    335        threw = True
    336    harness.ok(threw, "Should not allow inherited attribute on interface mixins")
    337 
    338    parser = parser.reset()
    339    threw = False
    340    try:
    341        parser.parse(
    342            """
    343            interface Interface {};
    344            interface NotMixin {
    345                attribute short x;
    346            };
    347            Interface includes NotMixin;
    348        """
    349        )
    350        results = parser.finish()
    351    except WebIDL.WebIDLError:
    352        threw = True
    353    harness.ok(threw, "Should fail if the right side does not point an interface mixin")
    354 
    355    parser = parser.reset()
    356    threw = False
    357    try:
    358        parser.parse(
    359            """
    360            interface mixin NotInterface {};
    361            interface mixin Mixin {
    362                attribute short x;
    363            };
    364            NotInterface includes Mixin;
    365        """
    366        )
    367        results = parser.finish()
    368    except WebIDL.WebIDLError:
    369        threw = True
    370    harness.ok(threw, "Should fail if the left side does not point an interface")
    371 
    372    parser = parser.reset()
    373    threw = False
    374    try:
    375        parser.parse(
    376            """
    377            interface mixin Mixin {
    378                iterable<DOMString>;
    379            };
    380        """
    381        )
    382        results = parser.finish()
    383    except WebIDL.WebIDLError:
    384        threw = True
    385    harness.ok(threw, "Should fail if an interface mixin includes iterable")
    386 
    387    parser = parser.reset()
    388    threw = False
    389    try:
    390        parser.parse(
    391            """
    392            interface mixin Mixin {
    393                setlike<DOMString>;
    394            };
    395        """
    396        )
    397        results = parser.finish()
    398    except WebIDL.WebIDLError:
    399        threw = True
    400    harness.ok(threw, "Should fail if an interface mixin includes setlike")
    401 
    402    parser = parser.reset()
    403    threw = False
    404    try:
    405        parser.parse(
    406            """
    407            interface mixin Mixin {
    408                maplike<DOMString, DOMString>;
    409            };
    410        """
    411        )
    412        results = parser.finish()
    413    except WebIDL.WebIDLError:
    414        threw = True
    415    harness.ok(threw, "Should fail if an interface mixin includes maplike")
    416 
    417    parser = parser.reset()
    418    threw = False
    419    try:
    420        parser.parse(
    421            """
    422            interface Interface {
    423                attribute short attr;
    424            };
    425            interface mixin Mixin {
    426                attribute short attr;
    427            };
    428            Interface includes Mixin;
    429        """
    430        )
    431        results = parser.finish()
    432    except WebIDL.WebIDLError:
    433        threw = True
    434    harness.ok(
    435        threw, "Should fail if the included mixin interface has duplicated member"
    436    )
    437 
    438    parser = parser.reset()
    439    threw = False
    440    try:
    441        parser.parse(
    442            """
    443            interface Interface {};
    444            interface mixin Mixin1 {
    445                attribute short attr;
    446            };
    447            interface mixin Mixin2 {
    448                attribute short attr;
    449            };
    450            Interface includes Mixin1;
    451            Interface includes Mixin2;
    452        """
    453        )
    454        results = parser.finish()
    455    except WebIDL.WebIDLError:
    456        threw = True
    457    harness.ok(
    458        threw, "Should fail if the included mixin interfaces have duplicated member"
    459    )
    460 
    461    parser = parser.reset()
    462    parser.parse(
    463        """
    464        [Global=Window, Exposed=Window] interface Window {};
    465        [Global=Worker, Exposed=Worker] interface Worker {};
    466        [Exposed=Window]
    467        interface Base {};
    468        interface mixin Mixin {
    469            Base returnSelf();
    470        };
    471        Base includes Mixin;
    472    """
    473    )
    474    results = parser.finish()
    475    base = results[2]
    476    attr = base.members[0]
    477    harness.check(
    478        attr.exposureSet,
    479        set(["Window"]),
    480        "Should expose on globals where the base interfaces are exposed",
    481    )
    482 
    483    parser = parser.reset()
    484    parser.parse(
    485        """
    486        [Global=Window, Exposed=Window] interface Window {};
    487        [Global=Worker, Exposed=Worker] interface Worker {};
    488        [Exposed=Window]
    489        interface Base {};
    490        [Exposed=Window]
    491        interface mixin Mixin {
    492            attribute short a;
    493        };
    494        Base includes Mixin;
    495    """
    496    )
    497    results = parser.finish()
    498    base = results[2]
    499    attr = base.members[0]
    500    harness.check(
    501        attr.exposureSet, set(["Window"]), "Should follow [Exposed] on interface mixin"
    502    )
    503 
    504    parser = parser.reset()
    505    parser.parse(
    506        """
    507        [Global=Window, Exposed=Window] interface Window {};
    508        [Global=Worker, Exposed=Worker] interface Worker {};
    509        [Exposed=Window]
    510        interface Base1 {};
    511        [Exposed=Worker]
    512        interface Base2 {};
    513        interface mixin Mixin {
    514            attribute short a;
    515        };
    516        Base1 includes Mixin;
    517        Base2 includes Mixin;
    518    """
    519    )
    520    results = parser.finish()
    521    base = results[2]
    522    attr = base.members[0]
    523    harness.check(
    524        attr.exposureSet,
    525        set(["Window", "Worker"]),
    526        "Should expose on all globals where including interfaces are exposed",
    527    )
    528    base = results[3]
    529    attr = base.members[0]
    530    harness.check(
    531        attr.exposureSet,
    532        set(["Window", "Worker"]),
    533        "Should expose on all globals where including interfaces are exposed",
    534    )