picomatch-rs 0.1.0

Rust glob matching core for the picomatch-rs workspace.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
mod support;

use picomatch_rs::CompileOptions;

use support::{assert_is_match, default_compile_options};

#[test]
fn should_handle_regular_globbing() {
    let opts = default_compile_options();
    assert_is_match("*", "a*", opts.clone(), false);
    assert_is_match("**", "a*", opts.clone(), false);
    assert_is_match("\\*", "a*", opts.clone(), false);
    assert_is_match("a/*", "a*", opts.clone(), false);
    assert_is_match("b", "a*", opts.clone(), false);
    assert_is_match("bc", "a*", opts.clone(), false);
    assert_is_match("bcd", "a*", opts.clone(), false);
    assert_is_match("bdir/", "a*", opts.clone(), false);
    assert_is_match("Beware", "a*", opts.clone(), false);
    assert_is_match("a", "a*", opts.clone(), true);
    assert_is_match("ab", "a*", opts.clone(), true);
    assert_is_match("abc", "a*", opts.clone(), true);

    assert_is_match("*", "\\a*", opts.clone(), false);
    assert_is_match("**", "\\a*", opts.clone(), false);
    assert_is_match("\\*", "\\a*", opts.clone(), false);

    assert_is_match("a", "\\a*", opts.clone(), true);
    assert_is_match("a/*", "\\a*", opts.clone(), false);
    assert_is_match("abc", "\\a*", opts.clone(), true);
    assert_is_match("abd", "\\a*", opts.clone(), true);
    assert_is_match("abe", "\\a*", opts.clone(), true);
    assert_is_match("b", "\\a*", opts.clone(), false);
    assert_is_match("bb", "\\a*", opts.clone(), false);
    assert_is_match("bcd", "\\a*", opts.clone(), false);
    assert_is_match("bdir/", "\\a*", opts.clone(), false);
    assert_is_match("Beware", "\\a*", opts.clone(), false);
    assert_is_match("c", "\\a*", opts.clone(), false);
    assert_is_match("ca", "\\a*", opts.clone(), false);
    assert_is_match("cb", "\\a*", opts.clone(), false);
    assert_is_match("d", "\\a*", opts.clone(), false);
    assert_is_match("dd", "\\a*", opts.clone(), false);
    assert_is_match("de", "\\a*", opts.clone(), false);
}

#[test]
fn should_match_directories() {
    let opts = default_compile_options();
    assert_is_match("*", "b*/", opts.clone(), false);
    assert_is_match("**", "b*/", opts.clone(), false);
    assert_is_match("\\*", "b*/", opts.clone(), false);
    assert_is_match("a", "b*/", opts.clone(), false);
    assert_is_match("a/*", "b*/", opts.clone(), false);
    assert_is_match("abc", "b*/", opts.clone(), false);
    assert_is_match("abd", "b*/", opts.clone(), false);
    assert_is_match("abe", "b*/", opts.clone(), false);
    assert_is_match("b", "b*/", opts.clone(), false);
    assert_is_match("bb", "b*/", opts.clone(), false);
    assert_is_match("bcd", "b*/", opts.clone(), false);
    assert_is_match("bdir/", "b*/", opts.clone(), true);
    assert_is_match("Beware", "b*/", opts.clone(), false);
    assert_is_match("c", "b*/", opts.clone(), false);
    assert_is_match("ca", "b*/", opts.clone(), false);
    assert_is_match("cb", "b*/", opts.clone(), false);
    assert_is_match("d", "b*/", opts.clone(), false);
    assert_is_match("dd", "b*/", opts.clone(), false);
    assert_is_match("de", "b*/", opts.clone(), false);
}

#[test]
fn should_use_escaped_characters_as_literals() {
    let opts = default_compile_options();
    assert_is_match("*", "\\^", opts.clone(), false);
    assert_is_match("**", "\\^", opts.clone(), false);
    assert_is_match("\\*", "\\^", opts.clone(), false);
    assert_is_match("a", "\\^", opts.clone(), false);
    assert_is_match("a/*", "\\^", opts.clone(), false);
    assert_is_match("abc", "\\^", opts.clone(), false);
    assert_is_match("abd", "\\^", opts.clone(), false);
    assert_is_match("abe", "\\^", opts.clone(), false);
    assert_is_match("b", "\\^", opts.clone(), false);
    assert_is_match("bb", "\\^", opts.clone(), false);
    assert_is_match("bcd", "\\^", opts.clone(), false);
    assert_is_match("bdir/", "\\^", opts.clone(), false);
    assert_is_match("Beware", "\\^", opts.clone(), false);
    assert_is_match("c", "\\^", opts.clone(), false);
    assert_is_match("ca", "\\^", opts.clone(), false);
    assert_is_match("cb", "\\^", opts.clone(), false);
    assert_is_match("d", "\\^", opts.clone(), false);
    assert_is_match("dd", "\\^", opts.clone(), false);
    assert_is_match("de", "\\^", opts.clone(), false);

    assert_is_match("*", "\\*", opts.clone(), true);
    assert_is_match("\\*", "\\*", opts.clone(), true);
    assert_is_match("**", "\\*", opts.clone(), false);
    assert_is_match("a", "\\*", opts.clone(), false);
    assert_is_match("a/*", "\\*", opts.clone(), false);
    assert_is_match("abc", "\\*", opts.clone(), false);
    assert_is_match("abd", "\\*", opts.clone(), false);
    assert_is_match("abe", "\\*", opts.clone(), false);
    assert_is_match("b", "\\*", opts.clone(), false);
    assert_is_match("bb", "\\*", opts.clone(), false);
    assert_is_match("bcd", "\\*", opts.clone(), false);
    assert_is_match("bdir/", "\\*", opts.clone(), false);
    assert_is_match("Beware", "\\*", opts.clone(), false);
    assert_is_match("c", "\\*", opts.clone(), false);
    assert_is_match("ca", "\\*", opts.clone(), false);
    assert_is_match("cb", "\\*", opts.clone(), false);
    assert_is_match("d", "\\*", opts.clone(), false);
    assert_is_match("dd", "\\*", opts.clone(), false);
    assert_is_match("de", "\\*", opts.clone(), false);

    assert_is_match("*", "a\\*", opts.clone(), false);
    assert_is_match("**", "a\\*", opts.clone(), false);
    assert_is_match("\\*", "a\\*", opts.clone(), false);
    assert_is_match("a", "a\\*", opts.clone(), false);
    assert_is_match("a/*", "a\\*", opts.clone(), false);
    assert_is_match("abc", "a\\*", opts.clone(), false);
    assert_is_match("abd", "a\\*", opts.clone(), false);
    assert_is_match("abe", "a\\*", opts.clone(), false);
    assert_is_match("b", "a\\*", opts.clone(), false);
    assert_is_match("bb", "a\\*", opts.clone(), false);
    assert_is_match("bcd", "a\\*", opts.clone(), false);
    assert_is_match("bdir/", "a\\*", opts.clone(), false);
    assert_is_match("Beware", "a\\*", opts.clone(), false);
    assert_is_match("c", "a\\*", opts.clone(), false);
    assert_is_match("ca", "a\\*", opts.clone(), false);
    assert_is_match("cb", "a\\*", opts.clone(), false);
    assert_is_match("d", "a\\*", opts.clone(), false);
    assert_is_match("dd", "a\\*", opts.clone(), false);
    assert_is_match("de", "a\\*", opts.clone(), false);

    assert_is_match("aqa", "*q*", opts.clone(), true);
    assert_is_match("aaqaa", "*q*", opts.clone(), true);
    assert_is_match("*", "*q*", opts.clone(), false);
    assert_is_match("**", "*q*", opts.clone(), false);
    assert_is_match("\\*", "*q*", opts.clone(), false);
    assert_is_match("a", "*q*", opts.clone(), false);
    assert_is_match("a/*", "*q*", opts.clone(), false);
    assert_is_match("abc", "*q*", opts.clone(), false);
    assert_is_match("abd", "*q*", opts.clone(), false);
    assert_is_match("abe", "*q*", opts.clone(), false);
    assert_is_match("b", "*q*", opts.clone(), false);
    assert_is_match("bb", "*q*", opts.clone(), false);
    assert_is_match("bcd", "*q*", opts.clone(), false);
    assert_is_match("bdir/", "*q*", opts.clone(), false);
    assert_is_match("Beware", "*q*", opts.clone(), false);
    assert_is_match("c", "*q*", opts.clone(), false);
    assert_is_match("ca", "*q*", opts.clone(), false);
    assert_is_match("cb", "*q*", opts.clone(), false);
    assert_is_match("d", "*q*", opts.clone(), false);
    assert_is_match("dd", "*q*", opts.clone(), false);
    assert_is_match("de", "*q*", opts.clone(), false);

    assert_is_match("*", "\\**", opts.clone(), true);
    assert_is_match("**", "\\**", opts.clone(), true);
    assert_is_match("\\*", "\\**", opts.clone(), false);
    assert_is_match("a", "\\**", opts.clone(), false);
    assert_is_match("a/*", "\\**", opts.clone(), false);
    assert_is_match("abc", "\\**", opts.clone(), false);
    assert_is_match("abd", "\\**", opts.clone(), false);
    assert_is_match("abe", "\\**", opts.clone(), false);
    assert_is_match("b", "\\**", opts.clone(), false);
    assert_is_match("bb", "\\**", opts.clone(), false);
    assert_is_match("bcd", "\\**", opts.clone(), false);
    assert_is_match("bdir/", "\\**", opts.clone(), false);
    assert_is_match("Beware", "\\**", opts.clone(), false);
    assert_is_match("c", "\\**", opts.clone(), false);
    assert_is_match("ca", "\\**", opts.clone(), false);
    assert_is_match("cb", "\\**", opts.clone(), false);
    assert_is_match("d", "\\**", opts.clone(), false);
    assert_is_match("dd", "\\**", opts.clone(), false);
    assert_is_match("de", "\\**", opts.clone(), false);
}

#[test]
fn should_work_for_quoted_characters() {
    let opts = default_compile_options();
    assert_is_match("*", "\"***\"", opts.clone(), false);
    assert_is_match("**", "\"***\"", opts.clone(), false);
    assert_is_match("\\*", "\"***\"", opts.clone(), false);
    assert_is_match("a", "\"***\"", opts.clone(), false);
    assert_is_match("a/*", "\"***\"", opts.clone(), false);
    assert_is_match("abc", "\"***\"", opts.clone(), false);
    assert_is_match("abd", "\"***\"", opts.clone(), false);
    assert_is_match("abe", "\"***\"", opts.clone(), false);
    assert_is_match("b", "\"***\"", opts.clone(), false);
    assert_is_match("bb", "\"***\"", opts.clone(), false);
    assert_is_match("bcd", "\"***\"", opts.clone(), false);
    assert_is_match("bdir/", "\"***\"", opts.clone(), false);
    assert_is_match("Beware", "\"***\"", opts.clone(), false);
    assert_is_match("c", "\"***\"", opts.clone(), false);
    assert_is_match("ca", "\"***\"", opts.clone(), false);
    assert_is_match("cb", "\"***\"", opts.clone(), false);
    assert_is_match("d", "\"***\"", opts.clone(), false);
    assert_is_match("dd", "\"***\"", opts.clone(), false);
    assert_is_match("de", "\"***\"", opts.clone(), false);
    assert_is_match("***", "\"***\"", opts.clone(), true);

    assert_is_match("*", "'***'", opts.clone(), false);
    assert_is_match("**", "'***'", opts.clone(), false);
    assert_is_match("\\*", "'***'", opts.clone(), false);
    assert_is_match("a", "'***'", opts.clone(), false);
    assert_is_match("a/*", "'***'", opts.clone(), false);
    assert_is_match("abc", "'***'", opts.clone(), false);
    assert_is_match("abd", "'***'", opts.clone(), false);
    assert_is_match("abe", "'***'", opts.clone(), false);
    assert_is_match("b", "'***'", opts.clone(), false);
    assert_is_match("bb", "'***'", opts.clone(), false);
    assert_is_match("bcd", "'***'", opts.clone(), false);
    assert_is_match("bdir/", "'***'", opts.clone(), false);
    assert_is_match("Beware", "'***'", opts.clone(), false);
    assert_is_match("c", "'***'", opts.clone(), false);
    assert_is_match("ca", "'***'", opts.clone(), false);
    assert_is_match("cb", "'***'", opts.clone(), false);
    assert_is_match("d", "'***'", opts.clone(), false);
    assert_is_match("dd", "'***'", opts.clone(), false);
    assert_is_match("de", "'***'", opts.clone(), false);
    assert_is_match("'***'", "'***'", opts.clone(), true);

    assert_is_match("*", "\"*\"*", opts.clone(), true);
    assert_is_match("**", "\"*\"*", opts.clone(), true);
    assert_is_match("\\*", "\"*\"*", opts.clone(), false);
    assert_is_match("a", "\"*\"*", opts.clone(), false);
    assert_is_match("a/*", "\"*\"*", opts.clone(), false);
    assert_is_match("abc", "\"*\"*", opts.clone(), false);
    assert_is_match("abd", "\"*\"*", opts.clone(), false);
    assert_is_match("abe", "\"*\"*", opts.clone(), false);
    assert_is_match("b", "\"*\"*", opts.clone(), false);
    assert_is_match("bb", "\"*\"*", opts.clone(), false);
    assert_is_match("bcd", "\"*\"*", opts.clone(), false);
    assert_is_match("bdir/", "\"*\"*", opts.clone(), false);
    assert_is_match("Beware", "\"*\"*", opts.clone(), false);
    assert_is_match("c", "\"*\"*", opts.clone(), false);
    assert_is_match("ca", "\"*\"*", opts.clone(), false);
    assert_is_match("cb", "\"*\"*", opts.clone(), false);
    assert_is_match("d", "\"*\"*", opts.clone(), false);
    assert_is_match("dd", "\"*\"*", opts.clone(), false);
    assert_is_match("de", "\"*\"*", opts.clone(), false);
}

#[test]
fn should_match_escaped_quotes() {
    let opts = default_compile_options();
    assert_is_match("*", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("**", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("\\*", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("a", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("a/*", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("abc", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("abd", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("abe", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("b", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("bb", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("bcd", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("bdir/", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("Beware", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("c", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("ca", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("cb", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("d", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("dd", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("de", "\\\"**\\\"", opts.clone(), false);
    assert_is_match("\"**\"", "\\\"**\\\"", opts.clone(), true);

    assert_is_match("foo/\"**\"/bar", "foo/\\\"**\\\"/bar", opts.clone(), true);

    assert_is_match("foo/\"*\"/bar", "foo/\\\"*\\\"/bar", opts.clone(), true);
    assert_is_match("foo/\"a\"/bar", "foo/\\\"*\\\"/bar", opts.clone(), true);
    assert_is_match("foo/\"b\"/bar", "foo/\\\"*\\\"/bar", opts.clone(), true);
    assert_is_match("foo/\"c\"/bar", "foo/\\\"*\\\"/bar", opts.clone(), true);
    assert_is_match("foo/'*'/bar", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("foo/'a'/bar", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("foo/'b'/bar", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("foo/'c'/bar", "foo/\\\"*\\\"/bar", opts.clone(), false);

    assert_is_match("foo/*/bar", "foo/\"*\"/bar", opts.clone(), true);
    assert_is_match("foo/\"*\"/bar", "foo/\"*\"/bar", opts.clone(), true);
    assert_is_match("foo/\"a\"/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/\"b\"/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/\"c\"/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/'*'/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/'a'/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/'b'/bar", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("foo/'c'/bar", "foo/\"*\"/bar", opts.clone(), false);

    assert_is_match("*", "\\'**\\'", opts.clone(), false);
    assert_is_match("**", "\\'**\\'", opts.clone(), false);
    assert_is_match("\\*", "\\'**\\'", opts.clone(), false);
    assert_is_match("a", "\\'**\\'", opts.clone(), false);
    assert_is_match("a/*", "\\'**\\'", opts.clone(), false);
    assert_is_match("abc", "\\'**\\'", opts.clone(), false);
    assert_is_match("abd", "\\'**\\'", opts.clone(), false);
    assert_is_match("abe", "\\'**\\'", opts.clone(), false);
    assert_is_match("b", "\\'**\\'", opts.clone(), false);
    assert_is_match("bb", "\\'**\\'", opts.clone(), false);
    assert_is_match("bcd", "\\'**\\'", opts.clone(), false);
    assert_is_match("bdir/", "\\'**\\'", opts.clone(), false);
    assert_is_match("Beware", "\\'**\\'", opts.clone(), false);
    assert_is_match("c", "\\'**\\'", opts.clone(), false);
    assert_is_match("ca", "\\'**\\'", opts.clone(), false);
    assert_is_match("cb", "\\'**\\'", opts.clone(), false);
    assert_is_match("d", "\\'**\\'", opts.clone(), false);
    assert_is_match("dd", "\\'**\\'", opts.clone(), false);
    assert_is_match("de", "\\'**\\'", opts.clone(), false);
    assert_is_match("'**'", "\\'**\\'", opts.clone(), true);
    // Additional assertions migrated from test/bash.js.
    assert_is_match("*", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("**", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("\\*", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("a", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("a/*", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("abc", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("abd", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("abe", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("b", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("bb", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("bcd", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("bdir/", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("Beware", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("c", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("ca", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("cb", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("d", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("dd", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("de", "foo/\\\"**\\\"/bar", opts.clone(), false);
    assert_is_match("*", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("**", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("\\*", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("a", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("a/*", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("abc", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("abd", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("abe", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("b", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("bb", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("bcd", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("bdir/", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("Beware", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("c", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("ca", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("cb", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("d", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("dd", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("de", "foo/\\\"*\\\"/bar", opts.clone(), false);
    assert_is_match("*", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("**", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("\\*", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("a", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("a/*", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("abc", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("abd", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("abe", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("b", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("bb", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("bcd", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("bdir/", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("Beware", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("c", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("ca", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("cb", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("d", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("dd", "foo/\"*\"/bar", opts.clone(), false);
    assert_is_match("de", "foo/\"*\"/bar", opts.clone(), false);
}

#[test]
fn pattern_from_larry_walls_configure_that_caused_bash_to_blow_up() {
    let opts = default_compile_options();
    assert_is_match("*", "[a-c]b*", opts.clone(), false);
    assert_is_match("**", "[a-c]b*", opts.clone(), false);
    assert_is_match("\\*", "[a-c]b*", opts.clone(), false);
    assert_is_match("a", "[a-c]b*", opts.clone(), false);
    assert_is_match("a/*", "[a-c]b*", opts.clone(), false);
    assert_is_match("abc", "[a-c]b*", opts.clone(), true);
    assert_is_match("abd", "[a-c]b*", opts.clone(), true);
    assert_is_match("abe", "[a-c]b*", opts.clone(), true);
    assert_is_match("b", "[a-c]b*", opts.clone(), false);
    assert_is_match("bb", "[a-c]b*", opts.clone(), true);
    assert_is_match("bcd", "[a-c]b*", opts.clone(), false);
    assert_is_match("bdir/", "[a-c]b*", opts.clone(), false);
    assert_is_match("Beware", "[a-c]b*", opts.clone(), false);
    assert_is_match("c", "[a-c]b*", opts.clone(), false);
    assert_is_match("ca", "[a-c]b*", opts.clone(), false);
    assert_is_match("cb", "[a-c]b*", opts.clone(), true);
    assert_is_match("d", "[a-c]b*", opts.clone(), false);
    assert_is_match("dd", "[a-c]b*", opts.clone(), false);
    assert_is_match("de", "[a-c]b*", opts.clone(), false);
}

#[test]
fn should_support_character_classes() {
    let opts = default_compile_options();
    assert_is_match("*", "a*[^c]", opts.clone(), false);
    assert_is_match("**", "a*[^c]", opts.clone(), false);
    assert_is_match("\\*", "a*[^c]", opts.clone(), false);
    assert_is_match("a", "a*[^c]", opts.clone(), false);
    assert_is_match("a/*", "a*[^c]", opts.clone(), false);
    assert_is_match("abc", "a*[^c]", opts.clone(), false);
    assert_is_match("abd", "a*[^c]", opts.clone(), true);
    assert_is_match("abe", "a*[^c]", opts.clone(), true);
    assert_is_match("b", "a*[^c]", opts.clone(), false);
    assert_is_match("bb", "a*[^c]", opts.clone(), false);
    assert_is_match("bcd", "a*[^c]", opts.clone(), false);
    assert_is_match("bdir/", "a*[^c]", opts.clone(), false);
    assert_is_match("Beware", "a*[^c]", opts.clone(), false);
    assert_is_match("c", "a*[^c]", opts.clone(), false);
    assert_is_match("ca", "a*[^c]", opts.clone(), false);
    assert_is_match("cb", "a*[^c]", opts.clone(), false);
    assert_is_match("d", "a*[^c]", opts.clone(), false);
    assert_is_match("dd", "a*[^c]", opts.clone(), false);
    assert_is_match("de", "a*[^c]", opts.clone(), false);
    assert_is_match("baz", "a*[^c]", opts.clone(), false);
    assert_is_match("bzz", "a*[^c]", opts.clone(), false);
    assert_is_match("BZZ", "a*[^c]", opts.clone(), false);
    assert_is_match("beware", "a*[^c]", opts.clone(), false);
    assert_is_match("BewAre", "a*[^c]", opts.clone(), false);

    assert_is_match("a-b", "a[X-]b", opts.clone(), true);
    assert_is_match("aXb", "a[X-]b", opts.clone(), true);

    let bash_opts = CompileOptions {
        bash: true,
        ..CompileOptions::default()
    };

    let regex_opts = CompileOptions {
        regex: true,
        ..CompileOptions::default()
    };

    assert_is_match("a*", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("a*", "[a-y]*[^c]", bash_opts.clone(), true);
    assert_is_match("a123b", "[a-y]*[^c]", bash_opts.clone(), true);
    assert_is_match("a123c", "[a-y]*[^c]", bash_opts.clone(), false);
    assert_is_match("ab", "[a-y]*[^c]", bash_opts.clone(), true);
    assert_is_match("bd", "[a-y]*[^c]", bash_opts.clone(), true);

    assert_is_match("a*b/ooo", "a\\*b/*", opts.clone(), true);
    assert_is_match("a*b/ooo", "a\\*?/*", opts.clone(), true);

    assert_is_match("*", "a[b]c", opts.clone(), false);
    assert_is_match("**", "a[b]c", opts.clone(), false);
    assert_is_match("\\*", "a[b]c", opts.clone(), false);
    assert_is_match("a", "a[b]c", opts.clone(), false);
    assert_is_match("a/*", "a[b]c", opts.clone(), false);
    assert_is_match("abc", "a[b]c", opts.clone(), true);
    assert_is_match("abd", "a[b]c", opts.clone(), false);
    assert_is_match("abe", "a[b]c", opts.clone(), false);

    assert_is_match("*", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("abc", "a[\"b\"]c", opts.clone(), true);

    assert_is_match("*", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("abc", "a[\\\\b]c", opts.clone(), true);

    assert_is_match("abc", "a[\\b]c", opts.clone(), false);

    assert_is_match("*", "a[b-d]c", opts.clone(), false);
    assert_is_match("abc", "a[b-d]c", opts.clone(), true);

    assert_is_match("*", "a?c", opts.clone(), false);
    assert_is_match("abc", "a?c", opts.clone(), true);

    assert_is_match("man/man1/bash.1", "*/man*/bash.*", opts.clone(), true);

    assert_is_match("*", "[^a-c]*", opts.clone(), true);
    assert_is_match("**", "[^a-c]*", opts.clone(), true);
    assert_is_match("a", "[^a-c]*", opts.clone(), false);
    assert_is_match("abc", "[^a-c]*", opts.clone(), false);
    assert_is_match("abd", "[^a-c]*", opts.clone(), false);
    assert_is_match("abe", "[^a-c]*", opts.clone(), false);
    assert_is_match("b", "[^a-c]*", opts.clone(), false);
    assert_is_match("bb", "[^a-c]*", opts.clone(), false);
    assert_is_match("bcd", "[^a-c]*", opts.clone(), false);
    assert_is_match("bdir/", "[^a-c]*", opts.clone(), false);
    assert_is_match("Beware", "[^a-c]*", opts.clone(), true);
    assert_is_match("Beware", "[^a-c]*", bash_opts.clone(), true);
    assert_is_match("c", "[^a-c]*", opts.clone(), false);
    assert_is_match("ca", "[^a-c]*", opts.clone(), false);
    assert_is_match("cb", "[^a-c]*", opts.clone(), false);
    assert_is_match("d", "[^a-c]*", opts.clone(), true);
    assert_is_match("dd", "[^a-c]*", opts.clone(), true);
    assert_is_match("de", "[^a-c]*", opts.clone(), true);
    assert_is_match("baz", "[^a-c]*", opts.clone(), false);
    assert_is_match("bzz", "[^a-c]*", opts.clone(), false);
    assert_is_match("BZZ", "[^a-c]*", opts.clone(), true);
    assert_is_match("beware", "[^a-c]*", opts.clone(), false);
    assert_is_match("BewAre", "[^a-c]*", opts.clone(), true);
    // Additional assertions migrated from test/bash.js.
    assert_is_match("*", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("**", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("\\*", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("a", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("a/*", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("abc", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("abd", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("abe", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("b", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("bb", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("bcd", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("bdir/", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("Beware", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("c", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("ca", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("cb", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("d", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("dd", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("dd", "[a-y]*[^c]", regex_opts.clone(), true);
    assert_is_match("dd", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("de", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("baz", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("bzz", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("bzz", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("bzz", "[a-y]*[^c]", regex_opts.clone(), false);
    assert_is_match("BZZ", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("beware", "[a-y]*[^c]", opts.clone(), true);
    assert_is_match("BewAre", "[a-y]*[^c]", opts.clone(), false);
    assert_is_match("b", "a[b]c", opts.clone(), false);
    assert_is_match("bb", "a[b]c", opts.clone(), false);
    assert_is_match("bcd", "a[b]c", opts.clone(), false);
    assert_is_match("bdir/", "a[b]c", opts.clone(), false);
    assert_is_match("Beware", "a[b]c", opts.clone(), false);
    assert_is_match("c", "a[b]c", opts.clone(), false);
    assert_is_match("ca", "a[b]c", opts.clone(), false);
    assert_is_match("cb", "a[b]c", opts.clone(), false);
    assert_is_match("d", "a[b]c", opts.clone(), false);
    assert_is_match("dd", "a[b]c", opts.clone(), false);
    assert_is_match("de", "a[b]c", opts.clone(), false);
    assert_is_match("baz", "a[b]c", opts.clone(), false);
    assert_is_match("bzz", "a[b]c", opts.clone(), false);
    assert_is_match("BZZ", "a[b]c", opts.clone(), false);
    assert_is_match("beware", "a[b]c", opts.clone(), false);
    assert_is_match("BewAre", "a[b]c", opts.clone(), false);
    assert_is_match("**", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("\\*", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("a", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("a/*", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("abd", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("abe", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("b", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("bb", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("bcd", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("bdir/", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("Beware", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("c", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("ca", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("cb", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("d", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("dd", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("de", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("baz", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("bzz", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("BZZ", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("beware", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("BewAre", "a[\"b\"]c", opts.clone(), false);
    assert_is_match("**", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("\\*", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("a", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("a/*", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("abd", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("abe", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("b", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("bb", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("bcd", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("bdir/", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("Beware", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("c", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("ca", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("cb", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("d", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("dd", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("de", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("baz", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("bzz", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("BZZ", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("beware", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("BewAre", "a[\\\\b]c", opts.clone(), false);
    assert_is_match("*", "a[\\b]c", opts.clone(), false);
    assert_is_match("**", "a[\\b]c", opts.clone(), false);
    assert_is_match("\\*", "a[\\b]c", opts.clone(), false);
    assert_is_match("a", "a[\\b]c", opts.clone(), false);
    assert_is_match("a/*", "a[\\b]c", opts.clone(), false);
    assert_is_match("abd", "a[\\b]c", opts.clone(), false);
    assert_is_match("abe", "a[\\b]c", opts.clone(), false);
    assert_is_match("b", "a[\\b]c", opts.clone(), false);
    assert_is_match("bb", "a[\\b]c", opts.clone(), false);
    assert_is_match("bcd", "a[\\b]c", opts.clone(), false);
    assert_is_match("bdir/", "a[\\b]c", opts.clone(), false);
    assert_is_match("Beware", "a[\\b]c", opts.clone(), false);
    assert_is_match("c", "a[\\b]c", opts.clone(), false);
    assert_is_match("ca", "a[\\b]c", opts.clone(), false);
    assert_is_match("cb", "a[\\b]c", opts.clone(), false);
    assert_is_match("d", "a[\\b]c", opts.clone(), false);
    assert_is_match("dd", "a[\\b]c", opts.clone(), false);
    assert_is_match("de", "a[\\b]c", opts.clone(), false);
    assert_is_match("baz", "a[\\b]c", opts.clone(), false);
    assert_is_match("bzz", "a[\\b]c", opts.clone(), false);
    assert_is_match("BZZ", "a[\\b]c", opts.clone(), false);
    assert_is_match("beware", "a[\\b]c", opts.clone(), false);
    assert_is_match("BewAre", "a[\\b]c", opts.clone(), false);
    assert_is_match("**", "a[b-d]c", opts.clone(), false);
    assert_is_match("\\*", "a[b-d]c", opts.clone(), false);
    assert_is_match("a", "a[b-d]c", opts.clone(), false);
    assert_is_match("a/*", "a[b-d]c", opts.clone(), false);
    assert_is_match("abd", "a[b-d]c", opts.clone(), false);
    assert_is_match("abe", "a[b-d]c", opts.clone(), false);
    assert_is_match("b", "a[b-d]c", opts.clone(), false);
    assert_is_match("bb", "a[b-d]c", opts.clone(), false);
    assert_is_match("bcd", "a[b-d]c", opts.clone(), false);
    assert_is_match("bdir/", "a[b-d]c", opts.clone(), false);
    assert_is_match("Beware", "a[b-d]c", opts.clone(), false);
    assert_is_match("c", "a[b-d]c", opts.clone(), false);
    assert_is_match("ca", "a[b-d]c", opts.clone(), false);
    assert_is_match("cb", "a[b-d]c", opts.clone(), false);
    assert_is_match("d", "a[b-d]c", opts.clone(), false);
    assert_is_match("dd", "a[b-d]c", opts.clone(), false);
    assert_is_match("de", "a[b-d]c", opts.clone(), false);
    assert_is_match("baz", "a[b-d]c", opts.clone(), false);
    assert_is_match("bzz", "a[b-d]c", opts.clone(), false);
    assert_is_match("BZZ", "a[b-d]c", opts.clone(), false);
    assert_is_match("beware", "a[b-d]c", opts.clone(), false);
    assert_is_match("BewAre", "a[b-d]c", opts.clone(), false);
    assert_is_match("**", "a?c", opts.clone(), false);
    assert_is_match("\\*", "a?c", opts.clone(), false);
    assert_is_match("a", "a?c", opts.clone(), false);
    assert_is_match("a/*", "a?c", opts.clone(), false);
    assert_is_match("abd", "a?c", opts.clone(), false);
    assert_is_match("abe", "a?c", opts.clone(), false);
    assert_is_match("b", "a?c", opts.clone(), false);
    assert_is_match("bb", "a?c", opts.clone(), false);
    assert_is_match("bcd", "a?c", opts.clone(), false);
    assert_is_match("bdir/", "a?c", opts.clone(), false);
    assert_is_match("Beware", "a?c", opts.clone(), false);
    assert_is_match("c", "a?c", opts.clone(), false);
    assert_is_match("ca", "a?c", opts.clone(), false);
    assert_is_match("cb", "a?c", opts.clone(), false);
    assert_is_match("d", "a?c", opts.clone(), false);
    assert_is_match("dd", "a?c", opts.clone(), false);
    assert_is_match("de", "a?c", opts.clone(), false);
    assert_is_match("baz", "a?c", opts.clone(), false);
    assert_is_match("bzz", "a?c", opts.clone(), false);
    assert_is_match("BZZ", "a?c", opts.clone(), false);
    assert_is_match("beware", "a?c", opts.clone(), false);
    assert_is_match("BewAre", "a?c", opts.clone(), false);
    assert_is_match("a/*", "[^a-c]*", opts.clone(), false);
}

#[test]
fn should_support_basic_wildmatch_brackets_features() {
    let opts = default_compile_options();
    assert_is_match("aab", "a[]-]b", opts.clone(), false);
    assert_is_match("ten", "[ten]", opts.clone(), false);
    assert_is_match("]", "]", opts.clone(), true);
    assert_is_match("a-b", "a[]-]b", opts.clone(), true);
    assert_is_match("a]b", "a[]-]b", opts.clone(), true);
    assert_is_match("a]b", "a[]]b", opts.clone(), true);
    assert_is_match("aab", "a[\\]a\\-]b", opts.clone(), true);
    assert_is_match("ten", "t[a-g]n", opts.clone(), true);
    assert_is_match("ton", "t[^a-g]n", opts.clone(), true);
}

#[test]
fn should_support_extended_slash_matching_features() {
    let opts = default_compile_options();
    assert_is_match(
        "foo/bar",
        "f[^eiu][^eiu][^eiu][^eiu][^eiu]r",
        opts.clone(),
        false,
    );
    assert_is_match("foo/bar", "foo[/]bar", opts.clone(), true);
    assert_is_match(
        "foo-bar",
        "f[^eiu][^eiu][^eiu][^eiu][^eiu]r",
        opts.clone(),
        true,
    );
}

#[test]
fn should_match_escaped_characters() {
    let opts = default_compile_options();
    if !cfg!(windows) {
        assert_is_match("\\*", "\\*", opts.clone(), true);
        assert_is_match("XXX/\\", "[A-Z]+/\\\\", opts.clone(), true);
    }

    assert_is_match("[ab]", "\\[ab]", opts.clone(), true);
    assert_is_match("[ab]", "[\\[:]ab]", opts.clone(), true);
}

#[test]
fn should_consolidate_extra_stars() {
    let opts = default_compile_options();
    assert_is_match("bbc", "a**c", opts.clone(), false);
    assert_is_match("abc", "a**c", opts.clone(), true);
    assert_is_match("bbd", "a**c", opts.clone(), false);

    assert_is_match("bbc", "a***c", opts.clone(), false);
    assert_is_match("abc", "a***c", opts.clone(), true);
    assert_is_match("bbd", "a***c", opts.clone(), false);

    assert_is_match("bbc", "a*****?c", opts.clone(), false);
    assert_is_match("abc", "a*****?c", opts.clone(), true);
    assert_is_match("bbc", "a*****?c", opts.clone(), false);

    assert_is_match("bbc", "?*****??", opts.clone(), true);
    assert_is_match("abc", "?*****??", opts.clone(), true);

    assert_is_match("bbc", "*****??", opts.clone(), true);
    assert_is_match("abc", "*****??", opts.clone(), true);

    assert_is_match("bbc", "?*****?c", opts.clone(), true);
    assert_is_match("abc", "?*****?c", opts.clone(), true);

    assert_is_match("bbc", "?***?****c", opts.clone(), true);
    assert_is_match("abc", "?***?****c", opts.clone(), true);
    assert_is_match("bbd", "?***?****c", opts.clone(), false);

    assert_is_match("bbc", "?***?****?", opts.clone(), true);
    assert_is_match("abc", "?***?****?", opts.clone(), true);

    assert_is_match("bbc", "?***?****", opts.clone(), true);
    assert_is_match("abc", "?***?****", opts.clone(), true);

    assert_is_match("bbc", "*******c", opts.clone(), true);
    assert_is_match("abc", "*******c", opts.clone(), true);

    assert_is_match("bbc", "*******?", opts.clone(), true);
    assert_is_match("abc", "*******?", opts.clone(), true);

    assert_is_match("abcdecdhjk", "a*cd**?**??k", opts.clone(), true);
    assert_is_match("abcdecdhjk", "a**?**cd**?**??k", opts.clone(), true);
    assert_is_match("abcdecdhjk", "a**?**cd**?**??k***", opts.clone(), true);
    assert_is_match("abcdecdhjk", "a**?**cd**?**??***k", opts.clone(), true);
    assert_is_match("abcdecdhjk", "a**?**cd**?**??***k**", opts.clone(), true);
    assert_is_match("abcdecdhjk", "a****c**?**??*****", opts.clone(), true);
}

#[test]
fn none_of_these_should_output_anything() {
    let opts = default_compile_options();
    assert_is_match("abc", "??**********?****?", opts.clone(), false);
    assert_is_match("abc", "??**********?****c", opts.clone(), false);
    assert_is_match("abc", "?************c****?****", opts.clone(), false);
    assert_is_match("abc", "*c*?**", opts.clone(), false);
    assert_is_match("abc", "a*****c*?**", opts.clone(), false);
    assert_is_match("abc", "a********???*******", opts.clone(), false);
    assert_is_match("a", "[]", opts.clone(), false);
    assert_is_match("[", "[abc", opts.clone(), false);
}