Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / dom / bindings / parser / tests / test_interface_maplikesetlikeiterable.py
blob6ad15edeaa69d8d44dfa6c15574960cb0e145548
1 import WebIDL
4 def WebIDLTest(parser, harness):
5 def shouldPass(prefix, iface, expectedMembers, numProductions=1):
6 p = parser.reset()
7 p.parse(iface)
8 results = p.finish()
9 harness.check(
10 len(results),
11 numProductions,
12 "%s - Should have production count %d" % (prefix, numProductions),
14 harness.ok(
15 isinstance(results[0], WebIDL.IDLInterface),
16 "%s - Should be an IDLInterface" % (prefix),
18 # Make a copy, since we plan to modify it
19 expectedMembers = list(expectedMembers)
20 for m in results[0].members:
21 name = m.identifier.name
22 if m.isMethod() and m.isStatic():
23 # None of the expected members are static methods, so ignore those.
24 harness.ok(True, "%s - %s - Should be a %s" % (prefix, name, type(m)))
25 elif (name, type(m)) in expectedMembers:
26 harness.ok(True, "%s - %s - Should be a %s" % (prefix, name, type(m)))
27 expectedMembers.remove((name, type(m)))
28 else:
29 harness.ok(
30 False,
31 "%s - %s - Unknown symbol of type %s" % (prefix, name, type(m)),
33 # A bit of a hoop because we can't generate the error string if we pass
34 if len(expectedMembers) == 0:
35 harness.ok(True, "Found all the members")
36 else:
37 harness.ok(
38 False,
39 "Expected member not found: %s of type %s"
40 % (expectedMembers[0][0], expectedMembers[0][1]),
42 return results
44 def shouldFail(prefix, iface):
45 try:
46 p = parser.reset()
47 p.parse(iface)
48 p.finish()
49 harness.ok(False, prefix + " - Interface passed when should've failed")
50 except WebIDL.WebIDLError:
51 harness.ok(True, prefix + " - Interface failed as expected")
52 except Exception as e:
53 harness.ok(
54 False,
55 prefix
56 + " - Interface failed but not as a WebIDLError exception: %s" % e,
59 iterableMembers = [
60 (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values", "forEach"]
62 setROMembers = (
63 [(x, WebIDL.IDLMethod) for x in ["has"]]
64 + [("__setlike", WebIDL.IDLMaplikeOrSetlike)]
65 + iterableMembers
67 setROMembers.extend([("size", WebIDL.IDLAttribute)])
68 setRWMembers = [
69 (x, WebIDL.IDLMethod) for x in ["add", "clear", "delete"]
70 ] + setROMembers
71 mapROMembers = (
72 [(x, WebIDL.IDLMethod) for x in ["get", "has"]]
73 + [("__maplike", WebIDL.IDLMaplikeOrSetlike)]
74 + iterableMembers
76 mapROMembers.extend([("size", WebIDL.IDLAttribute)])
77 mapRWMembers = [
78 (x, WebIDL.IDLMethod) for x in ["set", "clear", "delete"]
79 ] + mapROMembers
81 # OK, now that we've used iterableMembers to set up the above, append
82 # __iterable to it for the iterable<> case.
83 iterableMembers.append(("__iterable", WebIDL.IDLIterable))
85 asyncIterableMembers = [
86 (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values"]
88 asyncIterableMembers.append(("__iterable", WebIDL.IDLAsyncIterable))
90 valueIterableMembers = [("__iterable", WebIDL.IDLIterable)]
91 valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod))
92 valueIterableMembers.append(("length", WebIDL.IDLAttribute))
94 valueAsyncIterableMembers = [("__iterable", WebIDL.IDLAsyncIterable)]
95 valueAsyncIterableMembers.append(("values", WebIDL.IDLMethod))
97 disallowedIterableNames = [
98 ("keys", WebIDL.IDLMethod),
99 ("entries", WebIDL.IDLMethod),
100 ("values", WebIDL.IDLMethod),
102 disallowedMemberNames = [
103 ("forEach", WebIDL.IDLMethod),
104 ("has", WebIDL.IDLMethod),
105 ("size", WebIDL.IDLAttribute),
106 ] + disallowedIterableNames
107 mapDisallowedMemberNames = [("get", WebIDL.IDLMethod)] + disallowedMemberNames
108 disallowedNonMethodNames = [
109 ("clear", WebIDL.IDLMethod),
110 ("delete", WebIDL.IDLMethod),
112 mapDisallowedNonMethodNames = [("set", WebIDL.IDLMethod)] + disallowedNonMethodNames
113 setDisallowedNonMethodNames = [("add", WebIDL.IDLMethod)] + disallowedNonMethodNames
114 unrelatedMembers = [
115 ("unrelatedAttribute", WebIDL.IDLAttribute),
116 ("unrelatedMethod", WebIDL.IDLMethod),
120 # Simple Usage Tests
123 shouldPass(
124 "Iterable (key only)",
126 interface Foo1 {
127 iterable<long>;
128 readonly attribute unsigned long length;
129 getter long(unsigned long index);
130 attribute long unrelatedAttribute;
131 long unrelatedMethod();
133 """,
134 valueIterableMembers + unrelatedMembers,
137 shouldPass(
138 "Iterable (key only) inheriting from parent",
140 interface Foo1 : Foo2 {
141 iterable<long>;
142 readonly attribute unsigned long length;
143 getter long(unsigned long index);
145 interface Foo2 {
146 attribute long unrelatedAttribute;
147 long unrelatedMethod();
149 """,
150 valueIterableMembers,
151 numProductions=2,
154 shouldPass(
155 "Iterable (key and value)",
157 interface Foo1 {
158 iterable<long, long>;
159 attribute long unrelatedAttribute;
160 long unrelatedMethod();
162 """,
163 iterableMembers + unrelatedMembers,
164 # numProductions == 2 because of the generated iterator iface,
165 numProductions=2,
168 shouldPass(
169 "Iterable (key and value) inheriting from parent",
171 interface Foo1 : Foo2 {
172 iterable<long, long>;
174 interface Foo2 {
175 attribute long unrelatedAttribute;
176 long unrelatedMethod();
178 """,
179 iterableMembers,
180 # numProductions == 3 because of the generated iterator iface,
181 numProductions=3,
184 shouldPass(
185 "Async iterable (key only)",
187 interface Foo1 {
188 async iterable<long>;
189 attribute long unrelatedAttribute;
190 long unrelatedMethod();
192 """,
193 valueAsyncIterableMembers + unrelatedMembers,
194 # numProductions == 2 because of the generated iterator iface,
195 numProductions=2,
198 shouldPass(
199 "Async iterable (key only) inheriting from parent",
201 interface Foo1 : Foo2 {
202 async iterable<long>;
204 interface Foo2 {
205 attribute long unrelatedAttribute;
206 long unrelatedMethod();
208 """,
209 valueAsyncIterableMembers,
210 # numProductions == 3 because of the generated iterator iface,
211 numProductions=3,
214 shouldPass(
215 "Async iterable with argument (key only)",
217 interface Foo1 {
218 async iterable<long>(optional long foo);
219 attribute long unrelatedAttribute;
220 long unrelatedMethod();
222 """,
223 valueAsyncIterableMembers + unrelatedMembers,
224 # numProductions == 2 because of the generated iterator iface,
225 numProductions=2,
228 shouldPass(
229 "Async iterable (key and value)",
231 interface Foo1 {
232 async iterable<long, long>;
233 attribute long unrelatedAttribute;
234 long unrelatedMethod();
236 """,
237 asyncIterableMembers + unrelatedMembers,
238 # numProductions == 2 because of the generated iterator iface,
239 numProductions=2,
242 shouldPass(
243 "Async iterable (key and value) inheriting from parent",
245 interface Foo1 : Foo2 {
246 async iterable<long, long>;
248 interface Foo2 {
249 attribute long unrelatedAttribute;
250 long unrelatedMethod();
252 """,
253 asyncIterableMembers,
254 # numProductions == 3 because of the generated iterator iface,
255 numProductions=3,
258 shouldPass(
259 "Async iterable with argument (key and value)",
261 interface Foo1 {
262 async iterable<long, long>(optional long foo);
263 attribute long unrelatedAttribute;
264 long unrelatedMethod();
266 """,
267 asyncIterableMembers + unrelatedMembers,
268 # numProductions == 2 because of the generated iterator iface,
269 numProductions=2,
272 shouldPass(
273 "Maplike (readwrite)",
275 interface Foo1 {
276 maplike<long, long>;
277 attribute long unrelatedAttribute;
278 long unrelatedMethod();
280 """,
281 mapRWMembers + unrelatedMembers,
284 shouldPass(
285 "Maplike (readwrite) inheriting from parent",
287 interface Foo1 : Foo2 {
288 maplike<long, long>;
290 interface Foo2 {
291 attribute long unrelatedAttribute;
292 long unrelatedMethod();
294 """,
295 mapRWMembers,
296 numProductions=2,
299 shouldPass(
300 "Maplike (readwrite)",
302 interface Foo1 {
303 maplike<long, long>;
304 attribute long unrelatedAttribute;
305 long unrelatedMethod();
307 """,
308 mapRWMembers + unrelatedMembers,
311 shouldPass(
312 "Maplike (readwrite) inheriting from parent",
314 interface Foo1 : Foo2 {
315 maplike<long, long>;
317 interface Foo2 {
318 attribute long unrelatedAttribute;
319 long unrelatedMethod();
321 """,
322 mapRWMembers,
323 numProductions=2,
326 shouldPass(
327 "Maplike (readonly)",
329 interface Foo1 {
330 readonly maplike<long, long>;
331 attribute long unrelatedAttribute;
332 long unrelatedMethod();
334 """,
335 mapROMembers + unrelatedMembers,
338 shouldPass(
339 "Maplike (readonly) inheriting from parent",
341 interface Foo1 : Foo2 {
342 readonly maplike<long, long>;
344 interface Foo2 {
345 attribute long unrelatedAttribute;
346 long unrelatedMethod();
348 """,
349 mapROMembers,
350 numProductions=2,
353 shouldPass(
354 "Setlike (readwrite)",
356 interface Foo1 {
357 setlike<long>;
358 attribute long unrelatedAttribute;
359 long unrelatedMethod();
361 """,
362 setRWMembers + unrelatedMembers,
365 shouldPass(
366 "Setlike (readwrite) inheriting from parent",
368 interface Foo1 : Foo2 {
369 setlike<long>;
371 interface Foo2 {
372 attribute long unrelatedAttribute;
373 long unrelatedMethod();
375 """,
376 setRWMembers,
377 numProductions=2,
380 shouldPass(
381 "Setlike (readonly)",
383 interface Foo1 {
384 readonly setlike<long>;
385 attribute long unrelatedAttribute;
386 long unrelatedMethod();
388 """,
389 setROMembers + unrelatedMembers,
392 shouldPass(
393 "Setlike (readonly) inheriting from parent",
395 interface Foo1 : Foo2 {
396 readonly setlike<long>;
398 interface Foo2 {
399 attribute long unrelatedAttribute;
400 long unrelatedMethod();
402 """,
403 setROMembers,
404 numProductions=2,
407 shouldPass(
408 "Inheritance of maplike/setlike",
410 interface Foo1 {
411 maplike<long, long>;
413 interface Foo2 : Foo1 {
415 """,
416 mapRWMembers,
417 numProductions=2,
420 shouldFail(
421 "JS Implemented maplike interface",
423 [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"]
424 interface Foo1 {
425 constructor();
426 setlike<long>;
428 """,
431 shouldFail(
432 "JS Implemented maplike interface",
434 [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"]
435 interface Foo1 {
436 constructor();
437 maplike<long, long>;
439 """,
443 # Multiple maplike/setlike tests
446 shouldFail(
447 "Two maplike/setlikes on same interface",
449 interface Foo1 {
450 setlike<long>;
451 maplike<long, long>;
453 """,
456 shouldFail(
457 "Two iterable/setlikes on same interface",
459 interface Foo1 {
460 iterable<long>;
461 maplike<long, long>;
463 """,
466 shouldFail(
467 "Two iterables on same interface",
469 interface Foo1 {
470 iterable<long>;
471 iterable<long, long>;
473 """,
476 shouldFail(
477 "Two iterables on same interface",
479 interface Foo1 {
480 iterable<long>;
481 async iterable<long>;
483 """,
486 shouldFail(
487 "Two iterables on same interface",
489 interface Foo1 {
490 async iterable<long>;
491 async iterable<long, long>;
493 """,
496 shouldFail(
497 "Async iterable with non-optional arguments",
499 interface Foo1 {
500 async iterable<long>(long foo);
502 """,
505 shouldFail(
506 "Async iterable with non-optional arguments",
508 interface Foo1 {
509 async iterable<long>(optional long foo, long bar);
511 """,
514 shouldFail(
515 "Async iterable with non-optional arguments",
517 interface Foo1 {
518 async iterable<long, long>(long foo);
520 """,
523 shouldFail(
524 "Two maplike/setlikes in partials",
526 interface Foo1 {
527 maplike<long, long>;
529 partial interface Foo1 {
530 setlike<long>;
532 """,
535 shouldFail(
536 "Conflicting maplike/setlikes across inheritance",
538 interface Foo1 {
539 maplike<long, long>;
541 interface Foo2 : Foo1 {
542 setlike<long>;
544 """,
547 shouldFail(
548 "Conflicting maplike/iterable across inheritance",
550 interface Foo1 {
551 maplike<long, long>;
553 interface Foo2 : Foo1 {
554 iterable<long>;
556 """,
559 shouldFail(
560 "Conflicting maplike/setlikes across multistep inheritance",
562 interface Foo1 {
563 maplike<long, long>;
565 interface Foo2 : Foo1 {
567 interface Foo3 : Foo2 {
568 setlike<long>;
570 """,
574 # Member name collision tests
577 def testConflictingMembers(
578 likeMember, conflict, expectedMembers, methodPasses, numProductions=1
581 Tests for maplike/setlike member generation against conflicting member
582 names. If methodPasses is True, this means we expect the interface to
583 pass in the case of method shadowing, and expectedMembers should be the
584 list of interface members to check against on the passing interface.
587 (conflictName, conflictType) = conflict
588 if methodPasses:
589 shouldPass(
590 "Conflicting method: %s and %s" % (likeMember, conflictName),
592 interface Foo1 {
594 [Throws]
595 undefined %s(long test1, double test2, double test3);
598 % (likeMember, conflictName),
599 expectedMembers,
601 else:
602 shouldFail(
603 "Conflicting method: %s and %s" % (likeMember, conflictName),
605 interface Foo1 {
607 [Throws]
608 undefined %s(long test1, double test2, double test3);
611 % (likeMember, conflictName),
613 # Inherited conflicting methods should ALWAYS fail
614 shouldFail(
615 "Conflicting inherited method: %s and %s" % (likeMember, conflictName),
617 interface Foo1 {
618 undefined %s(long test1, double test2, double test3);
620 interface Foo2 : Foo1 {
624 % (conflictName, likeMember),
626 if conflictType == WebIDL.IDLAttribute:
627 shouldFail(
628 "Conflicting static method: %s and %s" % (likeMember, conflictName),
630 interface Foo1 {
632 static undefined %s(long test1, double test2, double test3);
635 % (likeMember, conflictName),
637 else:
638 shouldPass(
639 "Conflicting static method: %s and %s" % (likeMember, conflictName),
641 interface Foo1 {
643 static undefined %s(long test1, double test2, double test3);
646 % (likeMember, conflictName),
647 expectedMembers,
648 numProductions=numProductions,
650 shouldFail(
651 "Conflicting attribute: %s and %s" % (likeMember, conflictName),
653 interface Foo1 {
655 attribute double %s;
658 % (likeMember, conflictName),
660 shouldFail(
661 "Conflicting const: %s and %s" % (likeMember, conflictName),
663 interface Foo1 {
665 const double %s = 0;
668 % (likeMember, conflictName),
670 shouldFail(
671 "Conflicting static attribute: %s and %s" % (likeMember, conflictName),
673 interface Foo1 {
675 static attribute long %s;
678 % (likeMember, conflictName),
681 for member in disallowedIterableNames:
682 testConflictingMembers(
683 "iterable<long, long>", member, iterableMembers, False, numProductions=2
685 for member in mapDisallowedMemberNames:
686 testConflictingMembers("maplike<long, long>", member, mapRWMembers, False)
687 for member in disallowedMemberNames:
688 testConflictingMembers("setlike<long>", member, setRWMembers, False)
689 for member in mapDisallowedNonMethodNames:
690 testConflictingMembers("maplike<long, long>", member, mapRWMembers, True)
691 for member in setDisallowedNonMethodNames:
692 testConflictingMembers("setlike<long>", member, setRWMembers, True)
694 shouldPass(
695 "Inheritance of maplike/setlike with child member collision",
697 interface Foo1 {
698 maplike<long, long>;
700 interface Foo2 : Foo1 {
701 undefined entries();
703 """,
704 mapRWMembers,
705 numProductions=2,
708 shouldPass(
709 "Inheritance of multi-level maplike/setlike with child member collision",
711 interface Foo1 {
712 maplike<long, long>;
714 interface Foo2 : Foo1 {
716 interface Foo3 : Foo2 {
717 undefined entries();
719 """,
720 mapRWMembers,
721 numProductions=3,
724 shouldFail(
725 "Maplike interface with mixin member collision",
727 interface Foo1 {
728 maplike<long, long>;
730 interface mixin Foo2 {
731 undefined entries();
733 Foo1 includes Foo2;
734 """,
737 shouldPass(
738 "Inherited Maplike interface with consequential interface member collision",
740 interface Foo1 {
741 maplike<long, long>;
743 interface mixin Foo2 {
744 undefined entries();
746 interface Foo3 : Foo1 {
748 Foo3 includes Foo2;
749 """,
750 mapRWMembers,
751 numProductions=4,
754 shouldFail(
755 "Inheritance of name collision with child maplike/setlike",
757 interface Foo1 {
758 undefined entries();
760 interface Foo2 : Foo1 {
761 maplike<long, long>;
763 """,
766 shouldFail(
767 "Inheritance of multi-level name collision with child maplike/setlike",
769 interface Foo1 {
770 undefined entries();
772 interface Foo2 : Foo1 {
774 interface Foo3 : Foo2 {
775 maplike<long, long>;
777 """,
780 shouldPass(
781 "Inheritance of attribute collision with parent maplike/setlike",
783 interface Foo1 {
784 maplike<long, long>;
786 interface Foo2 : Foo1 {
787 attribute double size;
789 """,
790 mapRWMembers,
791 numProductions=2,
794 shouldPass(
795 "Inheritance of multi-level attribute collision with parent maplike/setlike",
797 interface Foo1 {
798 maplike<long, long>;
800 interface Foo2 : Foo1 {
802 interface Foo3 : Foo2 {
803 attribute double size;
805 """,
806 mapRWMembers,
807 numProductions=3,
810 shouldFail(
811 "Inheritance of attribute collision with child maplike/setlike",
813 interface Foo1 {
814 attribute double size;
816 interface Foo2 : Foo1 {
817 maplike<long, long>;
819 """,
822 shouldFail(
823 "Inheritance of multi-level attribute collision with child maplike/setlike",
825 interface Foo1 {
826 attribute double size;
828 interface Foo2 : Foo1 {
830 interface Foo3 : Foo2 {
831 maplike<long, long>;
833 """,
836 shouldFail(
837 "Inheritance of attribute/rw function collision with child maplike/setlike",
839 interface Foo1 {
840 attribute double set;
842 interface Foo2 : Foo1 {
843 maplike<long, long>;
845 """,
848 shouldFail(
849 "Inheritance of const/rw function collision with child maplike/setlike",
851 interface Foo1 {
852 const double set = 0;
854 interface Foo2 : Foo1 {
855 maplike<long, long>;
857 """,
860 shouldPass(
861 "Inheritance of rw function with same name in child maplike/setlike",
863 interface Foo1 {
864 maplike<long, long>;
866 interface Foo2 : Foo1 {
867 undefined clear();
869 """,
870 mapRWMembers,
871 numProductions=2,
874 shouldFail(
875 "Inheritance of unforgeable attribute collision with child maplike/setlike",
877 interface Foo1 {
878 [LegacyUnforgeable]
879 attribute double size;
881 interface Foo2 : Foo1 {
882 maplike<long, long>;
884 """,
887 shouldFail(
888 "Inheritance of multi-level unforgeable attribute collision with child maplike/setlike",
890 interface Foo1 {
891 [LegacyUnforgeable]
892 attribute double size;
894 interface Foo2 : Foo1 {
896 interface Foo3 : Foo2 {
897 maplike<long, long>;
899 """,
902 shouldPass(
903 "Interface with readonly allowable overrides",
905 interface Foo1 {
906 readonly setlike<long>;
907 readonly attribute boolean clear;
909 """,
910 setROMembers + [("clear", WebIDL.IDLAttribute)],
913 r = shouldPass(
914 "Check proper override of clear/delete/set",
916 interface Foo1 {
917 maplike<long, long>;
918 long clear(long a, long b, double c, double d);
919 long set(long a, long b, double c, double d);
920 long delete(long a, long b, double c, double d);
922 """,
923 mapRWMembers,
926 for m in r[0].members:
927 if m.identifier.name in ["clear", "set", "delete"]:
928 harness.ok(m.isMethod(), "%s should be a method" % m.identifier.name)
929 harness.check(
930 m.maxArgCount, 4, "%s should have 4 arguments" % m.identifier.name
932 harness.ok(
933 not m.isMaplikeOrSetlikeOrIterableMethod(),
934 "%s should not be a maplike/setlike function" % m.identifier.name,
937 tests = [
938 ("maplike", " maplike<long, long>;"),
939 ("setlike", " readonly setlike<long>;"),
940 ("iterable", " iterable<long>;"),
941 ("iterable", " async iterable<long, long>;"),
944 for name, line in tests:
945 parser = parser.reset()
946 lines = [
947 "interface Foo {",
948 line,
949 " readonly attribute unsigned long length;",
950 " getter long(unsigned long index);",
951 "};",
953 parser.parse("\n".join(lines))
954 results = parser.finish()
956 p = results[0].members[0]
958 harness.check(p.identifier.name, "__" + name, "Correct name")
960 colno = line.find(name)
962 loc_lines = str(p.identifier.location).split("\n")
964 harness.check(loc_lines[1], line, "Second line shows the input")
965 harness.check(
966 loc_lines[2],
967 " " * colno + "^",
968 "Correct column pointer in location string",