Revision control

Copy as Markdown

#!/usr/bin/env perl
# Copyright (C) 2017 The Qt Company Ltd and/or its subsidiary(-ies).
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
use 5.010;
use strict;
use warnings;
use utf8;
=head1 NAME
30-parse_build_log.t - various tests for parse_build_log.pl
=head1 SYNOPSIS
perl ./30-parse_build_log.t [pattern1 [pattern2 ...]]
Runs parse_build_log over all the testdata under the `data' directory.
If any patterns are given, only logs with filenames matching those patterns
(regular expressions) will be tested.
perl ./30-parse_build_log.t --update
Runs the test as usual, and updates the testdata such that the test
passes. Use this with care for mass updating of multiple testdata.
=cut
use Getopt::Long qw( GetOptionsFromArray );
use Capture::Tiny qw( capture );
use English qw( -no_match_vars );
use File::Basename;
use File::Slurp;
use File::Spec::Functions;
use FindBin;
use List::MoreUtils qw( none );
use Readonly;
use Test::More;
use Text::Diff;
use autodie;
Readonly my $DATADIR
=> catfile( $FindBin::Bin, 'data' );
Readonly my $PARSE_BUILD_LOG
=> catfile( $FindBin::Bin, '..', 'parse_build_log.pl' );
sub test_from_file
{
my ($file, $update) = @_;
my $testname = basename( $file );
my @expected_lines = read_file( $file );
# first line is special, it's the arguments to pass to parse_build_log;
# the rest is the expected output of parse_build_log
my $args_perl = shift @expected_lines;
my $args_ref = eval $args_perl; ## no critic
if ($EVAL_ERROR) {
die "internal error: while eval'ing first line of $file, `$args_perl': $EVAL_ERROR";
}
if (ref($args_ref) ne 'ARRAY') {
die "internal error: first line of $file, `$args_perl', did not eval to an arrayref";
}
my @command = ( $EXECUTABLE_NAME, $PARSE_BUILD_LOG, @{$args_ref} );
my $status = -1;
my ($stdout, $stderr) = capture {
$status = system( @command );
};
# Basic checks that the command succeeded and didn't print any warnings
is( $status, 0, "$testname - exit code 0" )
|| diag("stdout:\n$stdout\nstderr:\n$stderr");
is( $stderr, q{}, "$testname - no standard error" );
# Now check if the output was really what we expected.
# To get the nicest looking failure messages, we use `diff', so the failure message
# contains exactly the difference between what we wanted and what we got.
my $diff = diff(
\@expected_lines,
\$stdout,
{
STYLE => 'Unified',
FILENAME_A => 'expected',
FILENAME_B => 'actual',
},
);
# Normal mode: just test.
if (!$update) {
ok( !$diff, "$testname - actual matches expected" )
|| diag( $diff );
return;
}
# Update mode: update the testdata if necessary.
my $message = "$testname - actual matches expected";
if ($diff) {
open( my $fh, '>', $file );
print $fh $args_perl.$stdout;
close( $fh );
$message .= " - UPDATED!";
}
pass( $message );
return;
}
sub run
{
my (@args) = @_;
my $update;
GetOptionsFromArray( \@args,
update => \$update,
) || die $!;
foreach my $file (glob "$DATADIR/parsed-logs/*") {
# README.txt is not testdata; treat all other files as testdata
next if ( basename( $file ) eq 'README.txt' );
next if ( ! -f $file );
next if (@args && none { $file =~ qr{$_} } @args);
test_from_file( $file, $update );
}
done_testing;
return;
}
run( @ARGV ) if (!caller);
1;