my dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.2 KiB

  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use lib 't/lib';
  5. use Test::More;
  6. use File::Slurp qw/read_file write_file/;
  7. use File::Temp 'tempfile';
  8. use Data::Dumper;
  9. my $ANSI_CODESET = qr/(?:\e\[;*\??(?:\d+(?:;\d+)*)?[A-Za-z])+/;
  10. my $RESET_CODESET = qr/\e\[([;\e\[m]|22|24|25|27|28|39|49|0)+m/;
  11. # Various ANSI reset codes
  12. my %RESETS;
  13. @RESETS{qw/22 24 25 27 28 39 49/} = ();
  14. foreach my $file ($ENV{ANSI_FILES} ? (split ' ', $ENV{ANSI_FILES}||'') : (glob 't/data/files/*.ans*')) {
  15. my $content = read_file $file;
  16. my (undef, $tmp_file) = tempfile;
  17. system qq{t/bin/vimcat -o "$tmp_file" -u NONE -c 'set t_Co=8 | so plugin/cecutil.vim | so autoload/AnsiEsc.vim | call AnsiEsc#AnsiEsc(0)' "$file" };
  18. my $vimcat_out = read_file $tmp_file;
  19. my ($content_pieces, $vimcat_pieces) = normalize($content, $vimcat_out);
  20. if ($content eq $vimcat_out) {
  21. pass($file);
  22. }
  23. else {
  24. fail($file);
  25. # dump a diff by pieces
  26. my (undef, $content_tmp) = tempfile('content_XXXXX', TMPDIR => 1);
  27. my (undef, $vimcat_tmp) = tempfile('vimcat_XXXXX', TMPDIR => 1);
  28. local $Data::Dumper::Useqq = 1;
  29. write_file $content_tmp, Dumper($content_pieces);
  30. write_file $vimcat_tmp, Dumper($vimcat_pieces);
  31. system "t/bin/colordiff -u $content_tmp $vimcat_tmp";
  32. }
  33. }
  34. done_testing;
  35. sub normalize {
  36. my ($content, $vimcat_out) = (\$_[0], \$_[1]);
  37. # strip trailing reset ansi codes (from line ends as well)
  38. s/${RESET_CODESET}$//mg foreach $$content, $$vimcat_out;
  39. # strip CRs
  40. y/\r//d foreach $$content, $$vimcat_out;
  41. if ((not exists $ENV{NORMALIZE_WHITESPACE}) || $ENV{NORMALIZE_WHITESPACE} != 0) {
  42. $$_ =~ s/\s+/ /g, $$_ =~ s/\n//g for $content, $vimcat_out;
  43. }
  44. my @content_pieces = grep { $_ ne '' } split /($ANSI_CODESET)/, $$content;
  45. my @vimcat_pieces = grep { $_ ne '' } split /($ANSI_CODESET)/, $$vimcat_out;
  46. ($$content, $$vimcat_out) = ('', '');
  47. my (@content_pieces_normalized, @vimcat_pieces_normalized);
  48. my ($i, $j) = (0, 0);
  49. while ($i < @content_pieces) {
  50. if (($content_pieces[$i]||'') =~ /^\e\[/ && ($vimcat_pieces[$j]||'') =~ /^\e\[/) {
  51. my $content_piece = $content_pieces[$i];
  52. my $vimcat_piece = $vimcat_pieces[$j];
  53. my @content_codes = $content_piece =~ /\d+/g;
  54. my @vimcat_codes = $vimcat_piece =~ /\d+/g;
  55. my (%content_codes, %vimcat_codes);
  56. @content_codes{@content_codes} = ();
  57. @vimcat_codes{@vimcat_codes} = ();
  58. # remove any reset codes from vimcat codes that are not in
  59. # content
  60. foreach my $reset (keys %RESETS) {
  61. if ((not exists $content_codes{$reset}) && exists $vimcat_codes{$reset}) {
  62. delete $vimcat_codes{$reset};
  63. }
  64. }
  65. # put back sorted codes
  66. $content_piece = "\e[" . (join ';', sort { $a <=> $b } keys %content_codes) . 'm';
  67. $vimcat_piece = "\e[" . (join ';', sort { $a <=> $b } keys %vimcat_codes) . 'm';
  68. push @content_pieces_normalized, $content_piece;
  69. push @vimcat_pieces_normalized, $vimcat_piece;
  70. $$content .= $content_piece;
  71. $$vimcat_out .= $vimcat_piece;
  72. }
  73. else {
  74. # mismatch, skip ahead one piece and keep trying
  75. $$content .= $content_pieces[$i]||'';
  76. $$vimcat_out .= $vimcat_pieces[$j]||'';
  77. push @content_pieces_normalized, $content_pieces[$i]||'';
  78. push @vimcat_pieces_normalized, $vimcat_pieces[$j]||'';
  79. }
  80. $i++; $j++;
  81. # scan ahead to next part that has codes
  82. # assume the codeset positions match
  83. foreach my $set ([\$i, \@content_pieces, $content, \@content_pieces_normalized],
  84. [\$j, \@vimcat_pieces, $vimcat_out, \@vimcat_pieces_normalized]) {
  85. my ($i, $arr, $text, $pieces) = @$set;
  86. while ($$i < @$arr && $arr->[$$i] !~ /^\e\[/) {
  87. $$text .= $arr->[$$i];
  88. push @$pieces, $arr->[$$i];
  89. $$i++;
  90. }
  91. }
  92. }
  93. return (\@content_pieces_normalized, \@vimcat_pieces_normalized);
  94. }