开发者

How can I test strings containing ANSI color codes for equivalence in Perl?

开发者 https://www.devze.com 2023-02-05 16:38 出处:网络
I\'m writing tests for a Perl module that does things with ANSI color codes. I would like to be able to test two strings with embedded ANSI col开发者_如何学Pythonor codes to see if they would produce

I'm writing tests for a Perl module that does things with ANSI color codes. I would like to be able to test two strings with embedded ANSI col开发者_如何学Pythonor codes to see if they would produce the same output if printed. This is not a simple string equality test, because putting multiple codes in a different order can still yield the same result. For example, the codes for "bold" and "blue" can be put together with either one first to yield bold blue.

So, is there any easy way to test two strings with ANSI color codes for equivalence of output?


The easiest way is to convert each string into a representation of the output it would produce by simulating the device. I.e. produce a list of (character, colour, boldness) tuples (add any other attributes you want to track), one for each character that would be output. You can then compare these outputs directly for equality.

Here's an example to start you off:

sub simulate($) {
    my ($s) = @_;
    my $colour = 'black';
    my $bold = 0;
    my @output;

    while (length $s) {
        if ($s =~ s/\A\x1B\[1m//) { $bold = 1; }
        elsif ($s =~ s/\A\x1B\[22m//) { $bold = 0; }
        elsif ($s =~ s/\A\x1B\[30m//) { $colour = 'black'; }
        elsif ($s =~ s/\A\x1B\[31m//) { $colour = 'red'; }
        # ...
        else {   # Plain character to be output
            s/\A(.)//s;
            push @output, [ $1, $colour, $bold ];
        }
    }

    return @output;
}

# Example usage
use Test::More;
is_deeply(
    simulate("Hi \x1B[31\x1B[1mthere!"), 
    simulate("Hi \x1B[1\x1B[31mthere!"),
    "FTW!");
0

精彩评论

暂无评论...
验证码 换一张
取 消