@@ -303,3 +303,432 @@ LL | abc
303
303
let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( true ) ;
304
304
assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
305
305
}
306
+
307
+ #[ test]
308
+ fn issue_130 ( ) {
309
+ let input = Level :: Error . title ( "dummy" ) . snippet (
310
+ Snippet :: source ( "foo\n bar\n baz" )
311
+ . origin ( "file/path" )
312
+ . line_start ( 3 )
313
+ . fold ( true )
314
+ . annotation ( Level :: Error . span ( 4 ..11 ) ) , // bar\nbaz
315
+ ) ;
316
+
317
+ let expected = str![ [ r#"
318
+ error: dummy
319
+ --> file/path:4:1
320
+ |
321
+ 4 | / bar
322
+ 5 | | baz
323
+ | |___^
324
+ |
325
+ "# ] ] ;
326
+ let renderer = Renderer :: plain ( ) ;
327
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
328
+ }
329
+
330
+ #[ test]
331
+ fn unterminated_string_multiline ( ) {
332
+ let source = "\
333
+ a\"
334
+ // ...
335
+ " ;
336
+ let input = Level :: Error . title ( "" ) . snippet (
337
+ Snippet :: source ( source)
338
+ . origin ( "file/path" )
339
+ . line_start ( 3 )
340
+ . fold ( true )
341
+ . annotation ( Level :: Error . span ( 0 ..10 ) ) , // 1..10 works
342
+ ) ;
343
+ let expected = str![ [ r#"
344
+ error
345
+ --> file/path:3:1
346
+ |
347
+ 3 | / a"
348
+ 4 | | // ...
349
+ | |_______^
350
+ |
351
+ "# ] ] ;
352
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
353
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
354
+ }
355
+
356
+ #[ test]
357
+ fn char_and_nl_annotate_char ( ) {
358
+ let source = "a\r \n b" ;
359
+ let input = Level :: Error . title ( "" ) . snippet (
360
+ Snippet :: source ( source)
361
+ . origin ( "file/path" )
362
+ . line_start ( 3 )
363
+ . annotation ( Level :: Error . span ( 0 ..2 ) ) , // a\r
364
+ ) ;
365
+ let expected = str![ [ r#"
366
+ error
367
+ --> file/path:3:1
368
+ |
369
+ 3 | a
370
+ | ^
371
+ 4 | b
372
+ |"# ] ] ;
373
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
374
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
375
+ }
376
+
377
+ #[ test]
378
+ fn char_eol_annotate_char ( ) {
379
+ let source = "a\r \n b" ;
380
+ let input = Level :: Error . title ( "" ) . snippet (
381
+ Snippet :: source ( source)
382
+ . origin ( "file/path" )
383
+ . line_start ( 3 )
384
+ . annotation ( Level :: Error . span ( 0 ..3 ) ) , // a\r\n
385
+ ) ;
386
+ let expected = str![ [ r#"
387
+ error
388
+ --> file/path:3:1
389
+ |
390
+ 3 | a
391
+ | ^
392
+ 4 | b
393
+ |"# ] ] ;
394
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
395
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
396
+ }
397
+
398
+ #[ test]
399
+ fn char_eol_annotate_char_double_width ( ) {
400
+ let snippets = Level :: Error . title ( "" ) . snippet (
401
+ Snippet :: source ( "こん\r \n にちは\r \n 世界" )
402
+ . origin ( "<current file>" )
403
+ . annotation ( Level :: Error . span ( 3 ..8 ) ) , // ん\r\n
404
+ ) ;
405
+
406
+ let expected = str![ [ r#"
407
+ error
408
+ --> <current file>:1:2
409
+ |
410
+ 1 | こん
411
+ | ^^
412
+ 2 | にちは
413
+ 3 | 世界
414
+ |
415
+ "# ] ] ;
416
+
417
+ let renderer = Renderer :: plain ( ) ;
418
+ assert_data_eq ! ( renderer. render( snippets) . to_string( ) , expected) ;
419
+ }
420
+
421
+ #[ test]
422
+ fn annotate_eol ( ) {
423
+ let source = "a\r \n b" ;
424
+ let input = Level :: Error . title ( "" ) . snippet (
425
+ Snippet :: source ( source)
426
+ . origin ( "file/path" )
427
+ . line_start ( 3 )
428
+ . annotation ( Level :: Error . span ( 1 ..2 ) ) , // \r
429
+ ) ;
430
+ let expected = str![ [ r#"
431
+ error
432
+ --> file/path:3:2
433
+ |
434
+ 3 | a
435
+ | ^
436
+ 4 | b
437
+ |"# ] ] ;
438
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
439
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
440
+ }
441
+
442
+ #[ test]
443
+ fn annotate_eol2 ( ) {
444
+ let source = "a\r \n b" ;
445
+ let input = Level :: Error . title ( "" ) . snippet (
446
+ Snippet :: source ( source)
447
+ . origin ( "file/path" )
448
+ . line_start ( 3 )
449
+ . annotation ( Level :: Error . span ( 1 ..3 ) ) , // \r\n
450
+ ) ;
451
+ let expected = str![ [ r#"
452
+ error
453
+ --> file/path:3:2
454
+ |
455
+ 3 | a
456
+ | ^
457
+ 4 | b
458
+ |"# ] ] ;
459
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
460
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
461
+ }
462
+
463
+ #[ test]
464
+ fn annotate_eol3 ( ) {
465
+ let source = "a\r \n b" ;
466
+ let input = Level :: Error . title ( "" ) . snippet (
467
+ Snippet :: source ( source)
468
+ . origin ( "file/path" )
469
+ . line_start ( 3 )
470
+ . annotation ( Level :: Error . span ( 2 ..3 ) ) , // \n
471
+ ) ;
472
+ let expected = str![ [ r#"
473
+ error
474
+ --> file/path:3:2
475
+ |
476
+ 3 | a
477
+ | ^
478
+ 4 | b
479
+ |"# ] ] ;
480
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
481
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
482
+ }
483
+
484
+ #[ test]
485
+ fn annotate_eol4 ( ) {
486
+ let source = "a\r \n b" ;
487
+ let input = Level :: Error . title ( "" ) . snippet (
488
+ Snippet :: source ( source)
489
+ . origin ( "file/path" )
490
+ . line_start ( 3 )
491
+ . annotation ( Level :: Error . span ( 2 ..2 ) ) , // \n
492
+ ) ;
493
+ let expected = str![ [ r#"
494
+ error
495
+ --> file/path:3:2
496
+ |
497
+ 3 | a
498
+ | ^
499
+ 4 | b
500
+ |"# ] ] ;
501
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
502
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
503
+ }
504
+
505
+ #[ test]
506
+ fn annotate_eol_double_width ( ) {
507
+ let snippets = Level :: Error . title ( "" ) . snippet (
508
+ Snippet :: source ( "こん\r \n にちは\r \n 世界" )
509
+ . origin ( "<current file>" )
510
+ . annotation ( Level :: Error . span ( 7 ..8 ) ) , // \n
511
+ ) ;
512
+
513
+ let expected = str![ [ r#"
514
+ error
515
+ --> <current file>:1:3
516
+ |
517
+ 1 | こん
518
+ | ^
519
+ 2 | にちは
520
+ 3 | 世界
521
+ |
522
+ "# ] ] ;
523
+
524
+ let renderer = Renderer :: plain ( ) ;
525
+ assert_data_eq ! ( renderer. render( snippets) . to_string( ) , expected) ;
526
+ }
527
+
528
+ #[ test]
529
+ fn multiline_eol_start ( ) {
530
+ let source = "a\r \n b" ;
531
+ let input = Level :: Error . title ( "" ) . snippet (
532
+ Snippet :: source ( source)
533
+ . origin ( "file/path" )
534
+ . line_start ( 3 )
535
+ . annotation ( Level :: Error . span ( 1 ..4 ) ) , // \r\nb
536
+ ) ;
537
+ let expected = str![ [ r#"
538
+ error
539
+ --> file/path:3:2
540
+ |
541
+ 3 | a
542
+ | __^
543
+ 4 | | b
544
+ | |_^
545
+ |"# ] ] ;
546
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
547
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
548
+ }
549
+
550
+ #[ test]
551
+ fn multiline_eol_start2 ( ) {
552
+ let source = "a\r \n b" ;
553
+ let input = Level :: Error . title ( "" ) . snippet (
554
+ Snippet :: source ( source)
555
+ . origin ( "file/path" )
556
+ . line_start ( 3 )
557
+ . annotation ( Level :: Error . span ( 2 ..4 ) ) , // \nb
558
+ ) ;
559
+ let expected = str![ [ r#"
560
+ error
561
+ --> file/path:3:2
562
+ |
563
+ 3 | a
564
+ | __^
565
+ 4 | | b
566
+ | |_^
567
+ |"# ] ] ;
568
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
569
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
570
+ }
571
+
572
+ #[ test]
573
+ fn multiline_eol_start3 ( ) {
574
+ let source = "a\n b" ;
575
+ let input = Level :: Error . title ( "" ) . snippet (
576
+ Snippet :: source ( source)
577
+ . origin ( "file/path" )
578
+ . line_start ( 3 )
579
+ . annotation ( Level :: Error . span ( 1 ..3 ) ) , // \nb
580
+ ) ;
581
+ let expected = str![ [ r#"
582
+ error
583
+ --> file/path:3:2
584
+ |
585
+ 3 | a
586
+ | __^
587
+ 4 | | b
588
+ | |_^
589
+ |"# ] ] ;
590
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
591
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
592
+ }
593
+
594
+ #[ test]
595
+ fn multiline_eol_start_double_width ( ) {
596
+ let snippets = Level :: Error . title ( "" ) . snippet (
597
+ Snippet :: source ( "こん\r \n にちは\r \n 世界" )
598
+ . origin ( "<current file>" )
599
+ . annotation ( Level :: Error . span ( 7 ..11 ) ) , // \r\nに
600
+ ) ;
601
+
602
+ let expected = str![ [ r#"
603
+ error
604
+ --> <current file>:1:3
605
+ |
606
+ 1 | こん
607
+ | _____^
608
+ 2 | | にちは
609
+ | |__^
610
+ 3 | 世界
611
+ |
612
+ "# ] ] ;
613
+
614
+ let renderer = Renderer :: plain ( ) ;
615
+ assert_data_eq ! ( renderer. render( snippets) . to_string( ) , expected) ;
616
+ }
617
+
618
+ #[ test]
619
+ fn multiline_eol_start_eol_end ( ) {
620
+ let source = "a\n b\n c" ;
621
+ let input = Level :: Error . title ( "" ) . snippet (
622
+ Snippet :: source ( source)
623
+ . origin ( "file/path" )
624
+ . line_start ( 3 )
625
+ . annotation ( Level :: Error . span ( 1 ..4 ) ) , // \nb\n
626
+ ) ;
627
+ let expected = str![ [ r#"
628
+ error
629
+ --> file/path:3:2
630
+ |
631
+ 3 | a
632
+ | __^
633
+ 4 | | b
634
+ | |__^
635
+ 5 | c
636
+ |
637
+ "# ] ] ;
638
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
639
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
640
+ }
641
+
642
+ #[ test]
643
+ fn multiline_eol_start_eol_end2 ( ) {
644
+ let source = "a\r \n b\r \n c" ;
645
+ let input = Level :: Error . title ( "" ) . snippet (
646
+ Snippet :: source ( source)
647
+ . origin ( "file/path" )
648
+ . line_start ( 3 )
649
+ . annotation ( Level :: Error . span ( 2 ..5 ) ) , // \nb\r
650
+ ) ;
651
+ let expected = str![ [ r#"
652
+ error
653
+ --> file/path:3:2
654
+ |
655
+ 3 | a
656
+ | __^
657
+ 4 | | b
658
+ | |__^
659
+ 5 | c
660
+ |
661
+ "# ] ] ;
662
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
663
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
664
+ }
665
+
666
+ #[ test]
667
+ fn multiline_eol_start_eol_end3 ( ) {
668
+ let source = "a\r \n b\r \n c" ;
669
+ let input = Level :: Error . title ( "" ) . snippet (
670
+ Snippet :: source ( source)
671
+ . origin ( "file/path" )
672
+ . line_start ( 3 )
673
+ . annotation ( Level :: Error . span ( 2 ..6 ) ) , // \nb\r\n
674
+ ) ;
675
+ let expected = str![ [ r#"
676
+ error
677
+ --> file/path:3:2
678
+ |
679
+ 3 | a
680
+ | __^
681
+ 4 | | b
682
+ | |__^
683
+ 5 | c
684
+ |
685
+ "# ] ] ;
686
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
687
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
688
+ }
689
+
690
+ #[ test]
691
+ fn multiline_eol_start_eof_end ( ) {
692
+ let source = "a\r \n b" ;
693
+ let input = Level :: Error . title ( "" ) . snippet (
694
+ Snippet :: source ( source)
695
+ . origin ( "file/path" )
696
+ . line_start ( 3 )
697
+ . annotation ( Level :: Error . span ( 1 ..5 ) ) , // \r\nb(EOF)
698
+ ) ;
699
+ let expected = str![ [ r#"
700
+ error
701
+ --> file/path:3:2
702
+ |
703
+ 3 | a
704
+ | __^
705
+ 4 | | b
706
+ | |__^
707
+ |
708
+ "# ] ] ;
709
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
710
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
711
+ }
712
+
713
+ #[ test]
714
+ fn multiline_eol_start_eof_end_double_width ( ) {
715
+ let source = "ん\r \n に" ;
716
+ let input = Level :: Error . title ( "" ) . snippet (
717
+ Snippet :: source ( source)
718
+ . origin ( "file/path" )
719
+ . line_start ( 3 )
720
+ . annotation ( Level :: Error . span ( 3 ..9 ) ) , // \r\nに(EOF)
721
+ ) ;
722
+ let expected = str![ [ r#"
723
+ error
724
+ --> file/path:3:2
725
+ |
726
+ 3 | ん
727
+ | ___^
728
+ 4 | | に
729
+ | |___^
730
+ |
731
+ "# ] ] ;
732
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( false ) ;
733
+ assert_data_eq ! ( renderer. render( input) . to_string( ) , expected) ;
734
+ }
0 commit comments