• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { Selector, SelectorType, AttributeAction, IgnoreCaseMode } from "..";
2
3export const tests: [
4    selector: string,
5    expected: Selector[][],
6    message: string
7][] = [
8    // Tag names
9    [
10        "div",
11        [
12            [
13                {
14                    type: SelectorType.Tag,
15                    namespace: null,
16                    name: "div",
17                },
18            ],
19        ],
20        "simple tag",
21    ],
22    [
23        "*",
24        [
25            [
26                {
27                    type: SelectorType.Universal,
28                    namespace: null,
29                },
30            ],
31        ],
32        "universal",
33    ],
34
35    // Traversal
36    [
37        "div div",
38        [
39            [
40                {
41                    type: SelectorType.Tag,
42                    namespace: null,
43                    name: "div",
44                },
45                {
46                    type: SelectorType.Descendant,
47                },
48                {
49                    type: SelectorType.Tag,
50                    namespace: null,
51                    name: "div",
52                },
53            ],
54        ],
55        "descendant",
56    ],
57    [
58        "div\t \n \tdiv",
59        [
60            [
61                {
62                    type: SelectorType.Tag,
63                    namespace: null,
64                    name: "div",
65                },
66                {
67                    type: SelectorType.Descendant,
68                },
69                {
70                    type: SelectorType.Tag,
71                    namespace: null,
72                    name: "div",
73                },
74            ],
75        ],
76        "descendant /w whitespace",
77    ],
78    [
79        "div + div",
80        [
81            [
82                {
83                    type: SelectorType.Tag,
84                    namespace: null,
85                    name: "div",
86                },
87                {
88                    type: SelectorType.Adjacent,
89                },
90                {
91                    type: SelectorType.Tag,
92                    namespace: null,
93                    name: "div",
94                },
95            ],
96        ],
97        "adjacent",
98    ],
99    [
100        "div ~ div",
101        [
102            [
103                {
104                    type: SelectorType.Tag,
105                    namespace: null,
106                    name: "div",
107                },
108                {
109                    type: SelectorType.Sibling,
110                },
111                {
112                    type: SelectorType.Tag,
113                    namespace: null,
114                    name: "div",
115                },
116            ],
117        ],
118        "sibling",
119    ],
120    [
121        "p < div",
122        [
123            [
124                {
125                    type: SelectorType.Tag,
126                    namespace: null,
127                    name: "p",
128                },
129                {
130                    type: SelectorType.Parent,
131                },
132                {
133                    type: SelectorType.Tag,
134                    namespace: null,
135                    name: "div",
136                },
137            ],
138        ],
139        "parent",
140    ],
141
142    // Escaped whitespace
143    [
144        "#\\  > a ",
145        [
146            [
147                {
148                    type: SelectorType.Attribute,
149                    namespace: null,
150                    action: AttributeAction.Equals,
151                    name: "id",
152                    ignoreCase: IgnoreCaseMode.QuirksMode,
153                    value: " ",
154                },
155                {
156                    type: SelectorType.Child,
157                },
158                {
159                    type: SelectorType.Tag,
160                    namespace: null,
161                    name: "a",
162                },
163            ],
164        ],
165        "Space between escaped space and combinator",
166    ],
167    [
168        ".\\  ",
169        [
170            [
171                {
172                    type: SelectorType.Attribute,
173                    namespace: null,
174                    name: "class",
175                    action: AttributeAction.Element,
176                    ignoreCase: IgnoreCaseMode.QuirksMode,
177                    value: " ",
178                },
179            ],
180        ],
181        "Space after escaped space",
182    ],
183    [
184        ".m™²³",
185        [
186            [
187                {
188                    type: SelectorType.Attribute,
189                    namespace: null,
190                    name: "class",
191                    action: AttributeAction.Element,
192                    ignoreCase: IgnoreCaseMode.QuirksMode,
193                    value: "m™²³",
194                },
195            ],
196        ],
197        "Special charecters in selector",
198    ],
199    [
200        "\\61 ",
201        [
202            [
203                {
204                    type: SelectorType.Tag,
205                    namespace: null,
206                    name: "a",
207                },
208            ],
209        ],
210        "Numeric escape with space (BMP)",
211    ],
212    [
213        "\\1d306\\01d306",
214        [
215            [
216                {
217                    type: SelectorType.Tag,
218                    namespace: null,
219                    name: "\uD834\uDF06\uD834\uDF06",
220                },
221            ],
222        ],
223        "Numeric escape (outside BMP)",
224    ],
225    [
226        "#\\26 B",
227        [
228            [
229                {
230                    type: SelectorType.Attribute,
231                    namespace: null,
232                    action: AttributeAction.Equals,
233                    name: "id",
234                    ignoreCase: IgnoreCaseMode.QuirksMode,
235                    value: "&B",
236                },
237            ],
238        ],
239        "id selector with escape sequence",
240    ],
241
242    // Attributes
243    [
244        '[name^="foo["]',
245        [
246            [
247                {
248                    type: SelectorType.Attribute,
249                    namespace: null,
250                    name: "name",
251                    ignoreCase: IgnoreCaseMode.Unknown,
252                    action: AttributeAction.Start,
253                    value: "foo[",
254                },
255            ],
256        ],
257        "quoted attribute",
258    ],
259    [
260        '[name^="foo[bar]"]',
261        [
262            [
263                {
264                    type: SelectorType.Attribute,
265                    namespace: null,
266                    name: "name",
267                    ignoreCase: IgnoreCaseMode.Unknown,
268                    action: AttributeAction.Start,
269                    value: "foo[bar]",
270                },
271            ],
272        ],
273        "quoted attribute",
274    ],
275    [
276        '[name$="[bar]"]',
277        [
278            [
279                {
280                    type: SelectorType.Attribute,
281                    namespace: null,
282                    name: "name",
283                    ignoreCase: IgnoreCaseMode.Unknown,
284                    action: AttributeAction.End,
285                    value: "[bar]",
286                },
287            ],
288        ],
289        "quoted attribute",
290    ],
291    [
292        '[href *= "google"]',
293        [
294            [
295                {
296                    type: SelectorType.Attribute,
297                    namespace: null,
298                    name: "href",
299                    ignoreCase: IgnoreCaseMode.Unknown,
300                    action: AttributeAction.Any,
301                    value: "google",
302                },
303            ],
304        ],
305        "quoted attribute with spaces",
306    ],
307    [
308        '[value="\nsome text\n"]',
309        [
310            [
311                {
312                    type: SelectorType.Attribute,
313                    namespace: null,
314                    name: "value",
315                    ignoreCase: IgnoreCaseMode.Unknown,
316                    action: AttributeAction.Equals,
317                    value: "\nsome text\n",
318                },
319            ],
320        ],
321        "quoted attribute with internal newline",
322    ],
323    [
324        "[name=foo\\.baz]",
325        [
326            [
327                {
328                    type: SelectorType.Attribute,
329                    namespace: null,
330                    name: "name",
331                    ignoreCase: IgnoreCaseMode.Unknown,
332                    action: AttributeAction.Equals,
333                    value: "foo.baz",
334                },
335            ],
336        ],
337        "attribute with escaped dot",
338    ],
339    [
340        "[name=foo\\[bar\\]]",
341        [
342            [
343                {
344                    type: SelectorType.Attribute,
345                    namespace: null,
346                    name: "name",
347                    ignoreCase: IgnoreCaseMode.Unknown,
348                    action: AttributeAction.Equals,
349                    value: "foo[bar]",
350                },
351            ],
352        ],
353        "attribute with escaped square brackets",
354    ],
355    [
356        "[xml\\:test]",
357        [
358            [
359                {
360                    type: SelectorType.Attribute,
361                    namespace: null,
362                    name: "xml:test",
363                    action: AttributeAction.Exists,
364                    value: "",
365                    ignoreCase: IgnoreCaseMode.Unknown,
366                },
367            ],
368        ],
369        "escaped attribute",
370    ],
371    [
372        "[name='foo ~ < > , bar' i]",
373        [
374            [
375                {
376                    type: SelectorType.Attribute,
377                    namespace: null,
378                    name: "name",
379                    action: AttributeAction.Equals,
380                    value: "foo ~ < > , bar",
381                    ignoreCase: IgnoreCaseMode.IgnoreCase,
382                },
383            ],
384        ],
385        "attribute with previously normalized characters",
386    ],
387
388    // ID starting with a dot
389    [
390        "#.identifier",
391        [
392            [
393                {
394                    type: SelectorType.Attribute,
395                    namespace: null,
396                    action: AttributeAction.Equals,
397                    name: "id",
398                    ignoreCase: IgnoreCaseMode.QuirksMode,
399                    value: ".identifier",
400                },
401            ],
402        ],
403        "ID starting with a dot",
404    ],
405
406    // Pseudo elements
407    [
408        "::foo",
409        [
410            [
411                {
412                    type: SelectorType.PseudoElement,
413                    name: "foo",
414                    data: null,
415                },
416            ],
417        ],
418        "pseudo-element",
419    ],
420    [
421        "::foo()",
422        [
423            [
424                {
425                    type: SelectorType.PseudoElement,
426                    name: "foo",
427                    data: "",
428                },
429            ],
430        ],
431        "pseudo-element",
432    ],
433    [
434        "::foo(bar())",
435        [
436            [
437                {
438                    type: SelectorType.PseudoElement,
439                    name: "foo",
440                    data: "bar()",
441                },
442            ],
443        ],
444        "pseudo-element",
445    ],
446
447    // Pseudo selectors
448    [
449        ":foo",
450        [
451            [
452                {
453                    type: SelectorType.Pseudo,
454                    name: "foo",
455                    data: null,
456                },
457            ],
458        ],
459        "pseudo selector without any data",
460    ],
461    [
462        ":bar(baz)",
463        [
464            [
465                {
466                    type: SelectorType.Pseudo,
467                    name: "bar",
468                    data: "baz",
469                },
470            ],
471        ],
472        "pseudo selector with data",
473    ],
474    [
475        ':contains("(foo)")',
476        [
477            [
478                {
479                    type: SelectorType.Pseudo,
480                    name: "contains",
481                    data: "(foo)",
482                },
483            ],
484        ],
485        "pseudo selector with data",
486    ],
487    [
488        ":where(a)",
489        [
490            [
491                {
492                    type: SelectorType.Pseudo,
493                    name: "where",
494                    data: [
495                        [
496                            {
497                                type: SelectorType.Tag,
498                                namespace: null,
499                                name: "a",
500                            },
501                        ],
502                    ],
503                },
504            ],
505        ],
506        "pseudo selector with data",
507    ],
508    [
509        ':contains("(a((foo\\\\\\))))")',
510        [
511            [
512                {
513                    type: SelectorType.Pseudo,
514                    name: "contains",
515                    data: "(a((foo))))",
516                },
517            ],
518        ],
519        "pseudo selector with escaped data",
520    ],
521    [
522        ":icontains('')",
523        [
524            [
525                {
526                    type: SelectorType.Pseudo,
527                    name: "icontains",
528                    data: "",
529                },
530            ],
531        ],
532        "pseudo selector with quote-stripped data",
533    ],
534    [
535        ':contains("(foo)")',
536        [
537            [
538                {
539                    type: SelectorType.Pseudo,
540                    name: "contains",
541                    data: "(foo)",
542                },
543            ],
544        ],
545        "pseudo selector with data",
546    ],
547
548    // Multiple selectors
549    [
550        "a , b",
551        [
552            [
553                {
554                    type: SelectorType.Tag,
555                    namespace: null,
556                    name: "a",
557                },
558            ],
559            [
560                {
561                    type: SelectorType.Tag,
562                    namespace: null,
563                    name: "b",
564                },
565            ],
566        ],
567        "multiple selectors",
568    ],
569
570    [
571        ":host(h1, p)",
572        [
573            [
574                {
575                    type: SelectorType.Pseudo,
576                    name: "host",
577                    data: [
578                        [
579                            {
580                                type: SelectorType.Tag,
581                                namespace: null,
582                                name: "h1",
583                            },
584                        ],
585                        [
586                            {
587                                type: SelectorType.Tag,
588                                namespace: null,
589                                name: "p",
590                            },
591                        ],
592                    ],
593                },
594            ],
595        ],
596        "pseudo selector with data",
597    ],
598
599    /*
600     * Bad attributes (taken from Sizzle)
601     * https://github.com/jquery/sizzle/blob/af163873d7cdfc57f18b16c04b1915209533f0b1/test/unit/selector.js#L602-L651
602     */
603    [
604        "[id=types_all]",
605        [
606            [
607                {
608                    type: SelectorType.Attribute,
609                    namespace: null,
610                    action: AttributeAction.Equals,
611                    name: "id",
612                    ignoreCase: IgnoreCaseMode.Unknown,
613                    value: "types_all",
614                },
615            ],
616        ],
617        "Underscores don't need escaping",
618    ],
619    [
620        "[name=foo\\ bar]",
621        [
622            [
623                {
624                    type: SelectorType.Attribute,
625                    namespace: null,
626                    action: AttributeAction.Equals,
627                    name: "name",
628                    value: "foo bar",
629                    ignoreCase: IgnoreCaseMode.Unknown,
630                },
631            ],
632        ],
633        "Escaped space",
634    ],
635    [
636        "[name=foo\\.baz]",
637        [
638            [
639                {
640                    type: SelectorType.Attribute,
641                    namespace: null,
642                    action: AttributeAction.Equals,
643                    name: "name",
644                    value: "foo.baz",
645                    ignoreCase: IgnoreCaseMode.Unknown,
646                },
647            ],
648        ],
649        "Escaped dot",
650    ],
651    [
652        "[name=foo\\[baz\\]]",
653        [
654            [
655                {
656                    type: SelectorType.Attribute,
657                    namespace: null,
658                    action: AttributeAction.Equals,
659                    name: "name",
660                    value: "foo[baz]",
661                    ignoreCase: IgnoreCaseMode.Unknown,
662                },
663            ],
664        ],
665        "Escaped brackets",
666    ],
667    [
668        "[data-attr='foo_baz\\']']",
669        [
670            [
671                {
672                    type: SelectorType.Attribute,
673                    namespace: null,
674                    action: AttributeAction.Equals,
675                    name: "data-attr",
676                    value: "foo_baz']",
677                    ignoreCase: IgnoreCaseMode.Unknown,
678                },
679            ],
680        ],
681        "Escaped quote + right bracket",
682    ],
683    [
684        "[data-attr='\\'']",
685        [
686            [
687                {
688                    type: SelectorType.Attribute,
689                    namespace: null,
690                    action: AttributeAction.Equals,
691                    name: "data-attr",
692                    value: "'",
693                    ignoreCase: IgnoreCaseMode.Unknown,
694                },
695            ],
696        ],
697        "Quoted quote",
698    ],
699    [
700        "[data-attr='\\\\']",
701        [
702            [
703                {
704                    type: SelectorType.Attribute,
705                    namespace: null,
706                    action: AttributeAction.Equals,
707                    name: "data-attr",
708                    value: "\\",
709                    ignoreCase: IgnoreCaseMode.Unknown,
710                },
711            ],
712        ],
713        "Quoted backslash",
714    ],
715    [
716        "[data-attr='\\\\\\'']",
717        [
718            [
719                {
720                    type: SelectorType.Attribute,
721                    namespace: null,
722                    action: AttributeAction.Equals,
723                    name: "data-attr",
724                    value: "\\'",
725                    ignoreCase: IgnoreCaseMode.Unknown,
726                },
727            ],
728        ],
729        "Quoted backslash quote",
730    ],
731    [
732        "[data-attr='\\\\\\\\']",
733        [
734            [
735                {
736                    type: SelectorType.Attribute,
737                    namespace: null,
738                    action: AttributeAction.Equals,
739                    name: "data-attr",
740                    value: "\\\\",
741                    ignoreCase: IgnoreCaseMode.Unknown,
742                },
743            ],
744        ],
745        "Quoted backslash backslash",
746    ],
747    [
748        "[data-attr='\\5C\\\\']",
749        [
750            [
751                {
752                    type: SelectorType.Attribute,
753                    namespace: null,
754                    action: AttributeAction.Equals,
755                    name: "data-attr",
756                    value: "\\\\",
757                    ignoreCase: IgnoreCaseMode.Unknown,
758                },
759            ],
760        ],
761        "Quoted backslash backslash (numeric escape)",
762    ],
763    [
764        "[data-attr='\\5C \\\\']",
765        [
766            [
767                {
768                    type: SelectorType.Attribute,
769                    namespace: null,
770                    action: AttributeAction.Equals,
771                    name: "data-attr",
772                    value: "\\\\",
773                    ignoreCase: IgnoreCaseMode.Unknown,
774                },
775            ],
776        ],
777        "Quoted backslash backslash (numeric escape with trailing space)",
778    ],
779    [
780        "[data-attr='\\5C\t\\\\']",
781        [
782            [
783                {
784                    type: SelectorType.Attribute,
785                    namespace: null,
786                    action: AttributeAction.Equals,
787                    name: "data-attr",
788                    value: "\\\\",
789                    ignoreCase: IgnoreCaseMode.Unknown,
790                },
791            ],
792        ],
793        "Quoted backslash backslash (numeric escape with trailing tab)",
794    ],
795    [
796        "[data-attr='\\04e00']",
797        [
798            [
799                {
800                    type: SelectorType.Attribute,
801                    namespace: null,
802                    action: AttributeAction.Equals,
803                    name: "data-attr",
804                    value: "\u4e00",
805                    ignoreCase: IgnoreCaseMode.Unknown,
806                },
807            ],
808        ],
809        "Long numeric escape (BMP)",
810    ],
811    [
812        "[data-attr='\\01D306A']",
813        [
814            [
815                {
816                    type: SelectorType.Attribute,
817                    namespace: null,
818                    action: AttributeAction.Equals,
819                    name: "data-attr",
820                    value: "\uD834\uDF06A",
821                    ignoreCase: IgnoreCaseMode.Unknown,
822                },
823            ],
824        ],
825        "Long numeric escape (non-BMP)",
826    ],
827    [
828        "fOo[baR]",
829        [
830            [
831                {
832                    name: "fOo",
833                    type: SelectorType.Tag,
834                    namespace: null,
835                },
836                {
837                    action: AttributeAction.Exists,
838                    name: "baR",
839                    type: SelectorType.Attribute,
840                    namespace: null,
841                    value: "",
842                    ignoreCase: IgnoreCaseMode.Unknown,
843                },
844            ],
845        ],
846        "Mixed case tag and attribute name",
847    ],
848
849    // Namespaces
850    [
851        "foo|bar",
852        [
853            [
854                {
855                    name: "bar",
856                    type: SelectorType.Tag,
857                    namespace: "foo",
858                },
859            ],
860        ],
861        "basic tag namespace",
862    ],
863    [
864        "*|bar",
865        [
866            [
867                {
868                    name: "bar",
869                    type: SelectorType.Tag,
870                    namespace: "*",
871                },
872            ],
873        ],
874        "star tag namespace",
875    ],
876    [
877        "|bar",
878        [
879            [
880                {
881                    name: "bar",
882                    type: SelectorType.Tag,
883                    namespace: "",
884                },
885            ],
886        ],
887        "without namespace",
888    ],
889    [
890        "*|*",
891        [
892            [
893                {
894                    type: SelectorType.Universal,
895                    namespace: "*",
896                },
897            ],
898        ],
899        "universal with namespace",
900    ],
901    [
902        "[foo|bar]",
903        [
904            [
905                {
906                    action: AttributeAction.Exists,
907                    name: "bar",
908                    type: SelectorType.Attribute,
909                    namespace: "foo",
910                    value: "",
911                    ignoreCase: IgnoreCaseMode.Unknown,
912                },
913            ],
914        ],
915        "basic attribute namespace, existential",
916    ],
917    [
918        "[|bar]",
919        [
920            [
921                {
922                    action: AttributeAction.Exists,
923                    name: "bar",
924                    type: SelectorType.Attribute,
925                    namespace: null,
926                    value: "",
927                    ignoreCase: IgnoreCaseMode.Unknown,
928                },
929            ],
930        ],
931        "without namespace, existential",
932    ],
933    [
934        "[foo|bar='baz' i]",
935        [
936            [
937                {
938                    action: AttributeAction.Equals,
939                    ignoreCase: IgnoreCaseMode.IgnoreCase,
940                    name: "bar",
941                    type: SelectorType.Attribute,
942                    namespace: "foo",
943                    value: "baz",
944                },
945            ],
946        ],
947        "basic attribute namespace, equality",
948    ],
949    [
950        "[*|bar='baz' i]",
951        [
952            [
953                {
954                    action: AttributeAction.Equals,
955                    ignoreCase: IgnoreCaseMode.IgnoreCase,
956                    name: "bar",
957                    type: SelectorType.Attribute,
958                    namespace: "*",
959                    value: "baz",
960                },
961            ],
962        ],
963        "star attribute namespace",
964    ],
965    [
966        "[type='a' S]",
967        [
968            [
969                {
970                    action: AttributeAction.Equals,
971                    ignoreCase: IgnoreCaseMode.CaseSensitive,
972                    name: "type",
973                    type: SelectorType.Attribute,
974                    value: "a",
975                    namespace: null,
976                },
977            ],
978        ],
979        "case-sensitive attribute selector",
980    ],
981    [
982        "foo || bar",
983        [
984            [
985                {
986                    name: "foo",
987                    namespace: null,
988                    type: SelectorType.Tag,
989                },
990                {
991                    type: SelectorType.ColumnCombinator,
992                },
993                {
994                    name: "bar",
995                    namespace: null,
996                    type: SelectorType.Tag,
997                },
998            ],
999        ],
1000        "column combinator",
1001    ],
1002    [
1003        "foo||bar",
1004        [
1005            [
1006                {
1007                    name: "foo",
1008                    namespace: null,
1009                    type: SelectorType.Tag,
1010                },
1011                {
1012                    type: SelectorType.ColumnCombinator,
1013                },
1014                {
1015                    name: "bar",
1016                    namespace: null,
1017                    type: SelectorType.Tag,
1018                },
1019            ],
1020        ],
1021        "column combinator without whitespace",
1022    ],
1023];
1024