exiftool-vendored.exe 12.80.0 → 12.82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/bin/exiftool.exe +0 -0
- package/bin/exiftool_files/Changes +44 -0
- package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
- package/bin/exiftool_files/README +3 -2
- package/bin/exiftool_files/exiftool.pl +36 -14
- package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
- package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
- package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
- package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
- package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
- package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
- package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
- package/bin/exiftool_files/lib/B.pm +1 -1
- package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
- package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
- package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
- package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
- package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
- package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
- package/bin/exiftool_files/lib/Config.pm +9 -9
- package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
- package/bin/exiftool_files/lib/CryptX.pm +2 -82
- package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
- package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
- package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
- package/bin/exiftool_files/lib/Digest/base.pm +26 -20
- package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
- package/bin/exiftool_files/lib/Encode.pm +3 -3
- package/bin/exiftool_files/lib/Errno.pm +13 -13
- package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
- package/bin/exiftool_files/lib/Exporter.pm +1 -1
- package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
- package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
- package/bin/exiftool_files/lib/File/Find.pm +1 -1
- package/bin/exiftool_files/lib/File/Glob.pm +1 -8
- package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
- package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
- package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
- package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
- package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
- package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
- package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
- package/bin/exiftool_files/lib/File/Path.pm +3 -3
- package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
- package/bin/exiftool_files/lib/File/Temp.pm +70 -35
- package/bin/exiftool_files/lib/File/Which.pm +1 -240
- package/bin/exiftool_files/lib/File/stat.pm +3 -2
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
- package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
- package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
- package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
- package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
- package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
- package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
- package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
- package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
- package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
- package/bin/exiftool_files/lib/IO/File.pm +1 -1
- package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
- package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
- package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
- package/bin/exiftool_files/lib/IO/Select.pm +16 -2
- package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
- package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
- package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
- package/bin/exiftool_files/lib/IO/String.pm +425 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
- package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
- package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
- package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
- package/bin/exiftool_files/lib/IO.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +44 -31
- package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +20 -7
- package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +543 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +332 -149
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +9 -4
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -4
- package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +331 -22
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +55 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +21 -3
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +40 -24
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +61 -30
- package/bin/exiftool_files/lib/Image/ExifTool/README +2 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4815 -4775
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +931 -617
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +30 -8
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
- package/bin/exiftool_files/lib/Image/ExifTool.pm +77 -41
- package/bin/exiftool_files/lib/Image/ExifTool.pod +24 -11
- package/bin/exiftool_files/lib/List/Util.pm +97 -8
- package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
- package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
- package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
- package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
- package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
- package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
- package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
- package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
- package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
- package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
- package/bin/exiftool_files/lib/POSIX.pm +1 -1
- package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
- package/bin/exiftool_files/lib/PerlIO.pm +397 -0
- package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
- package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
- package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
- package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
- package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
- package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
- package/bin/exiftool_files/lib/Portable.pm +246 -320
- package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
- package/bin/exiftool_files/lib/Socket.pm +16 -12
- package/bin/exiftool_files/lib/Storable.pm +1444 -1441
- package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
- package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
- package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
- package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
- package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
- package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
- package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
- package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
- package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
- package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
- package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
- package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
- package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
- package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
- package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
- package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
- package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
- package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
- package/bin/exiftool_files/lib/Test/More.pm +1997 -0
- package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
- package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
- package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
- package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
- package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
- package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
- package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
- package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
- package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
- package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
- package/bin/exiftool_files/lib/Time/Local.pm +82 -35
- package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
- package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
- package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
- package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
- package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
- package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
- package/bin/exiftool_files/lib/Win32/API.pm +1 -830
- package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
- package/bin/exiftool_files/lib/Win32.pm +213 -89
- package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
- package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
- package/bin/exiftool_files/lib/feature.pm +49 -17
- package/bin/exiftool_files/lib/mro.pm +4 -20
- package/bin/exiftool_files/lib/overload.pm +15 -15
- package/bin/exiftool_files/lib/parent.pm +10 -2
- package/bin/exiftool_files/lib/re.pm +91 -33
- package/bin/exiftool_files/lib/warnings.pm +17 -6
- package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
- package/bin/exiftool_files/liblzma-5__.dll +0 -0
- package/bin/exiftool_files/libstdc++-6.dll +0 -0
- package/bin/exiftool_files/libwinpthread-1.dll +0 -0
- package/bin/exiftool_files/perl.exe +0 -0
- package/bin/exiftool_files/perl532.dll +0 -0
- package/package.json +7 -5
- package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
- package/bin/exiftool_files/perl530.dll +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
package TAP::Base;
|
|
2
|
+
|
|
3
|
+
use strict;
|
|
4
|
+
use warnings;
|
|
5
|
+
|
|
6
|
+
use base 'TAP::Object';
|
|
7
|
+
|
|
8
|
+
=head1 NAME
|
|
9
|
+
|
|
10
|
+
TAP::Base - Base class that provides common functionality to L<TAP::Parser>
|
|
11
|
+
and L<TAP::Harness>
|
|
12
|
+
|
|
13
|
+
=head1 VERSION
|
|
14
|
+
|
|
15
|
+
Version 3.42
|
|
16
|
+
|
|
17
|
+
=cut
|
|
18
|
+
|
|
19
|
+
our $VERSION = '3.42';
|
|
20
|
+
|
|
21
|
+
use constant GOT_TIME_HIRES => do {
|
|
22
|
+
eval 'use Time::HiRes qw(time);';
|
|
23
|
+
$@ ? 0 : 1;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
=head1 SYNOPSIS
|
|
27
|
+
|
|
28
|
+
package TAP::Whatever;
|
|
29
|
+
|
|
30
|
+
use base 'TAP::Base';
|
|
31
|
+
|
|
32
|
+
# ... later ...
|
|
33
|
+
|
|
34
|
+
my $thing = TAP::Whatever->new();
|
|
35
|
+
|
|
36
|
+
$thing->callback( event => sub {
|
|
37
|
+
# do something interesting
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
=head1 DESCRIPTION
|
|
41
|
+
|
|
42
|
+
C<TAP::Base> provides callback management.
|
|
43
|
+
|
|
44
|
+
=head1 METHODS
|
|
45
|
+
|
|
46
|
+
=head2 Class Methods
|
|
47
|
+
|
|
48
|
+
=cut
|
|
49
|
+
|
|
50
|
+
sub _initialize {
|
|
51
|
+
my ( $self, $arg_for, $ok_callback ) = @_;
|
|
52
|
+
|
|
53
|
+
my %ok_map = map { $_ => 1 } @$ok_callback;
|
|
54
|
+
|
|
55
|
+
$self->{ok_callbacks} = \%ok_map;
|
|
56
|
+
|
|
57
|
+
if ( my $cb = delete $arg_for->{callbacks} ) {
|
|
58
|
+
while ( my ( $event, $callback ) = each %$cb ) {
|
|
59
|
+
$self->callback( $event, $callback );
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return $self;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
=head3 C<callback>
|
|
67
|
+
|
|
68
|
+
Install a callback for a named event.
|
|
69
|
+
|
|
70
|
+
=cut
|
|
71
|
+
|
|
72
|
+
sub callback {
|
|
73
|
+
my ( $self, $event, $callback ) = @_;
|
|
74
|
+
|
|
75
|
+
my %ok_map = %{ $self->{ok_callbacks} };
|
|
76
|
+
|
|
77
|
+
$self->_croak('No callbacks may be installed')
|
|
78
|
+
unless %ok_map;
|
|
79
|
+
|
|
80
|
+
$self->_croak( "Callback $event is not supported. Valid callbacks are "
|
|
81
|
+
. join( ', ', sort keys %ok_map ) )
|
|
82
|
+
unless exists $ok_map{$event};
|
|
83
|
+
|
|
84
|
+
push @{ $self->{code_for}{$event} }, $callback;
|
|
85
|
+
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
sub _has_callbacks {
|
|
90
|
+
my $self = shift;
|
|
91
|
+
return keys %{ $self->{code_for} } != 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
sub _callback_for {
|
|
95
|
+
my ( $self, $event ) = @_;
|
|
96
|
+
return $self->{code_for}{$event};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
sub _make_callback {
|
|
100
|
+
my $self = shift;
|
|
101
|
+
my $event = shift;
|
|
102
|
+
|
|
103
|
+
my $cb = $self->_callback_for($event);
|
|
104
|
+
return unless defined $cb;
|
|
105
|
+
return map { $_->(@_) } @$cb;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
=head3 C<get_time>
|
|
109
|
+
|
|
110
|
+
Return the current time using Time::HiRes if available.
|
|
111
|
+
|
|
112
|
+
=cut
|
|
113
|
+
|
|
114
|
+
sub get_time { return time() }
|
|
115
|
+
|
|
116
|
+
=head3 C<time_is_hires>
|
|
117
|
+
|
|
118
|
+
Return true if the time returned by get_time is high resolution (i.e. if Time::HiRes is available).
|
|
119
|
+
|
|
120
|
+
=cut
|
|
121
|
+
|
|
122
|
+
sub time_is_hires { return GOT_TIME_HIRES }
|
|
123
|
+
|
|
124
|
+
=head3 C<get_times>
|
|
125
|
+
|
|
126
|
+
Return array reference of the four-element list of CPU seconds,
|
|
127
|
+
as with L<perlfunc/times>.
|
|
128
|
+
|
|
129
|
+
=cut
|
|
130
|
+
|
|
131
|
+
sub get_times { return [ times() ] }
|
|
132
|
+
|
|
133
|
+
1;
|
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
package TAP::Formatter::Base;
|
|
2
|
+
|
|
3
|
+
use strict;
|
|
4
|
+
use warnings;
|
|
5
|
+
use base 'TAP::Base';
|
|
6
|
+
use POSIX qw(strftime);
|
|
7
|
+
|
|
8
|
+
my $MAX_ERRORS = 5;
|
|
9
|
+
my %VALIDATION_FOR;
|
|
10
|
+
|
|
11
|
+
BEGIN {
|
|
12
|
+
%VALIDATION_FOR = (
|
|
13
|
+
directives => sub { shift; shift },
|
|
14
|
+
verbosity => sub { shift; shift },
|
|
15
|
+
normalize => sub { shift; shift },
|
|
16
|
+
timer => sub { shift; shift },
|
|
17
|
+
failures => sub { shift; shift },
|
|
18
|
+
comments => sub { shift; shift },
|
|
19
|
+
errors => sub { shift; shift },
|
|
20
|
+
color => sub { shift; shift },
|
|
21
|
+
jobs => sub { shift; shift },
|
|
22
|
+
show_count => sub { shift; shift },
|
|
23
|
+
stdout => sub {
|
|
24
|
+
my ( $self, $ref ) = @_;
|
|
25
|
+
|
|
26
|
+
$self->_croak("option 'stdout' needs a filehandle")
|
|
27
|
+
unless $self->_is_filehandle($ref);
|
|
28
|
+
|
|
29
|
+
return $ref;
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
sub _is_filehandle {
|
|
34
|
+
my ( $self, $ref ) = @_;
|
|
35
|
+
|
|
36
|
+
return 0 if !defined $ref;
|
|
37
|
+
|
|
38
|
+
return 1 if ref $ref eq 'GLOB'; # lexical filehandle
|
|
39
|
+
return 1 if !ref $ref && ref \$ref eq 'GLOB'; # bare glob like *STDOUT
|
|
40
|
+
|
|
41
|
+
return 1 if eval { $ref->can('print') };
|
|
42
|
+
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
my @getter_setters = qw(
|
|
47
|
+
_longest
|
|
48
|
+
_printed_summary_header
|
|
49
|
+
_colorizer
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
__PACKAGE__->mk_methods( @getter_setters, keys %VALIDATION_FOR );
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
=head1 NAME
|
|
56
|
+
|
|
57
|
+
TAP::Formatter::Base - Base class for harness output delegates
|
|
58
|
+
|
|
59
|
+
=head1 VERSION
|
|
60
|
+
|
|
61
|
+
Version 3.42
|
|
62
|
+
|
|
63
|
+
=cut
|
|
64
|
+
|
|
65
|
+
our $VERSION = '3.42';
|
|
66
|
+
|
|
67
|
+
=head1 DESCRIPTION
|
|
68
|
+
|
|
69
|
+
This provides console orientated output formatting for TAP::Harness.
|
|
70
|
+
|
|
71
|
+
=head1 SYNOPSIS
|
|
72
|
+
|
|
73
|
+
use TAP::Formatter::Console;
|
|
74
|
+
my $harness = TAP::Formatter::Console->new( \%args );
|
|
75
|
+
|
|
76
|
+
=cut
|
|
77
|
+
|
|
78
|
+
sub _initialize {
|
|
79
|
+
my ( $self, $arg_for ) = @_;
|
|
80
|
+
$arg_for ||= {};
|
|
81
|
+
|
|
82
|
+
$self->SUPER::_initialize($arg_for);
|
|
83
|
+
my %arg_for = %$arg_for; # force a shallow copy
|
|
84
|
+
|
|
85
|
+
$self->verbosity(0);
|
|
86
|
+
|
|
87
|
+
for my $name ( keys %VALIDATION_FOR ) {
|
|
88
|
+
my $property = delete $arg_for{$name};
|
|
89
|
+
if ( defined $property ) {
|
|
90
|
+
my $validate = $VALIDATION_FOR{$name};
|
|
91
|
+
$self->$name( $self->$validate($property) );
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if ( my @props = keys %arg_for ) {
|
|
96
|
+
$self->_croak(
|
|
97
|
+
"Unknown arguments to " . __PACKAGE__ . "::new (@props)" );
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
$self->stdout( \*STDOUT ) unless $self->stdout;
|
|
101
|
+
|
|
102
|
+
if ( $self->color ) {
|
|
103
|
+
require TAP::Formatter::Color;
|
|
104
|
+
$self->_colorizer( TAP::Formatter::Color->new );
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return $self;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
sub verbose { shift->verbosity >= 1 }
|
|
111
|
+
sub quiet { shift->verbosity <= -1 }
|
|
112
|
+
sub really_quiet { shift->verbosity <= -2 }
|
|
113
|
+
sub silent { shift->verbosity <= -3 }
|
|
114
|
+
|
|
115
|
+
=head1 METHODS
|
|
116
|
+
|
|
117
|
+
=head2 Class Methods
|
|
118
|
+
|
|
119
|
+
=head3 C<new>
|
|
120
|
+
|
|
121
|
+
my %args = (
|
|
122
|
+
verbose => 1,
|
|
123
|
+
)
|
|
124
|
+
my $harness = TAP::Formatter::Console->new( \%args );
|
|
125
|
+
|
|
126
|
+
The constructor returns a new C<TAP::Formatter::Console> object. If
|
|
127
|
+
a L<TAP::Harness> is created with no C<formatter> a
|
|
128
|
+
C<TAP::Formatter::Console> is automatically created. If any of the
|
|
129
|
+
following options were given to TAP::Harness->new they well be passed to
|
|
130
|
+
this constructor which accepts an optional hashref whose allowed keys are:
|
|
131
|
+
|
|
132
|
+
=over 4
|
|
133
|
+
|
|
134
|
+
=item * C<verbosity>
|
|
135
|
+
|
|
136
|
+
Set the verbosity level.
|
|
137
|
+
|
|
138
|
+
=item * C<verbose>
|
|
139
|
+
|
|
140
|
+
Printing individual test results to STDOUT.
|
|
141
|
+
|
|
142
|
+
=item * C<timer>
|
|
143
|
+
|
|
144
|
+
Append run time for each test to output. Uses L<Time::HiRes> if available.
|
|
145
|
+
|
|
146
|
+
=item * C<failures>
|
|
147
|
+
|
|
148
|
+
Show test failures (this is a no-op if C<verbose> is selected).
|
|
149
|
+
|
|
150
|
+
=item * C<comments>
|
|
151
|
+
|
|
152
|
+
Show test comments (this is a no-op if C<verbose> is selected).
|
|
153
|
+
|
|
154
|
+
=item * C<quiet>
|
|
155
|
+
|
|
156
|
+
Suppressing some test output (mostly failures while tests are running).
|
|
157
|
+
|
|
158
|
+
=item * C<really_quiet>
|
|
159
|
+
|
|
160
|
+
Suppressing everything but the tests summary.
|
|
161
|
+
|
|
162
|
+
=item * C<silent>
|
|
163
|
+
|
|
164
|
+
Suppressing all output.
|
|
165
|
+
|
|
166
|
+
=item * C<errors>
|
|
167
|
+
|
|
168
|
+
If parse errors are found in the TAP output, a note of this will be made
|
|
169
|
+
in the summary report. To see all of the parse errors, set this argument to
|
|
170
|
+
true:
|
|
171
|
+
|
|
172
|
+
errors => 1
|
|
173
|
+
|
|
174
|
+
=item * C<directives>
|
|
175
|
+
|
|
176
|
+
If set to a true value, only test results with directives will be displayed.
|
|
177
|
+
This overrides other settings such as C<verbose>, C<failures>, or C<comments>.
|
|
178
|
+
|
|
179
|
+
=item * C<stdout>
|
|
180
|
+
|
|
181
|
+
A filehandle for catching standard output.
|
|
182
|
+
|
|
183
|
+
=item * C<color>
|
|
184
|
+
|
|
185
|
+
If defined specifies whether color output is desired. If C<color> is not
|
|
186
|
+
defined it will default to color output if color support is available on
|
|
187
|
+
the current platform and output is not being redirected.
|
|
188
|
+
|
|
189
|
+
=item * C<jobs>
|
|
190
|
+
|
|
191
|
+
The number of concurrent jobs this formatter will handle.
|
|
192
|
+
|
|
193
|
+
=item * C<show_count>
|
|
194
|
+
|
|
195
|
+
Boolean value. If false, disables the C<X/Y> test count which shows up while
|
|
196
|
+
tests are running.
|
|
197
|
+
|
|
198
|
+
=back
|
|
199
|
+
|
|
200
|
+
Any keys for which the value is C<undef> will be ignored.
|
|
201
|
+
|
|
202
|
+
=cut
|
|
203
|
+
|
|
204
|
+
# new supplied by TAP::Base
|
|
205
|
+
|
|
206
|
+
=head3 C<prepare>
|
|
207
|
+
|
|
208
|
+
Called by Test::Harness before any test output is generated.
|
|
209
|
+
|
|
210
|
+
This is an advisory and may not be called in the case where tests are
|
|
211
|
+
being supplied to Test::Harness by an iterator.
|
|
212
|
+
|
|
213
|
+
=cut
|
|
214
|
+
|
|
215
|
+
sub prepare {
|
|
216
|
+
my ( $self, @tests ) = @_;
|
|
217
|
+
|
|
218
|
+
my $longest = 0;
|
|
219
|
+
|
|
220
|
+
for my $test (@tests) {
|
|
221
|
+
$longest = length $test if length $test > $longest;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
$self->_longest($longest);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
sub _format_now { strftime "[%H:%M:%S]", localtime }
|
|
228
|
+
|
|
229
|
+
sub _format_name {
|
|
230
|
+
my ( $self, $test ) = @_;
|
|
231
|
+
my $name = $test;
|
|
232
|
+
my $periods = '.' x ( $self->_longest + 2 - length $test );
|
|
233
|
+
$periods = " $periods ";
|
|
234
|
+
|
|
235
|
+
if ( $self->timer ) {
|
|
236
|
+
my $stamp = $self->_format_now();
|
|
237
|
+
return "$stamp $name$periods";
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
return "$name$periods";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
=head3 C<open_test>
|
|
246
|
+
|
|
247
|
+
Called to create a new test session. A test session looks like this:
|
|
248
|
+
|
|
249
|
+
my $session = $formatter->open_test( $test, $parser );
|
|
250
|
+
while ( defined( my $result = $parser->next ) ) {
|
|
251
|
+
$session->result($result);
|
|
252
|
+
exit 1 if $result->is_bailout;
|
|
253
|
+
}
|
|
254
|
+
$session->close_test;
|
|
255
|
+
|
|
256
|
+
=cut
|
|
257
|
+
|
|
258
|
+
sub open_test {
|
|
259
|
+
die "Unimplemented.";
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
sub _output_success {
|
|
263
|
+
my ( $self, $msg ) = @_;
|
|
264
|
+
$self->_output($msg);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
=head3 C<summary>
|
|
268
|
+
|
|
269
|
+
$harness->summary( $aggregate );
|
|
270
|
+
|
|
271
|
+
C<summary> prints the summary report after all tests are run. The first
|
|
272
|
+
argument is an aggregate to summarise. An optional second argument may
|
|
273
|
+
be set to a true value to indicate that the summary is being output as a
|
|
274
|
+
result of an interrupted test run.
|
|
275
|
+
|
|
276
|
+
=cut
|
|
277
|
+
|
|
278
|
+
sub summary {
|
|
279
|
+
my ( $self, $aggregate, $interrupted ) = @_;
|
|
280
|
+
|
|
281
|
+
return if $self->silent;
|
|
282
|
+
|
|
283
|
+
my @t = $aggregate->descriptions;
|
|
284
|
+
my $tests = \@t;
|
|
285
|
+
|
|
286
|
+
my $runtime = $aggregate->elapsed_timestr;
|
|
287
|
+
|
|
288
|
+
my $total = $aggregate->total;
|
|
289
|
+
my $passed = $aggregate->passed;
|
|
290
|
+
|
|
291
|
+
if ( $self->timer ) {
|
|
292
|
+
$self->_output( $self->_format_now(), "\n" );
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
$self->_failure_output("Test run interrupted!\n")
|
|
296
|
+
if $interrupted;
|
|
297
|
+
|
|
298
|
+
# TODO: Check this condition still works when all subtests pass but
|
|
299
|
+
# the exit status is nonzero
|
|
300
|
+
|
|
301
|
+
if ( $aggregate->all_passed ) {
|
|
302
|
+
$self->_output_success("All tests successful.\n");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
# ~TODO option where $aggregate->skipped generates reports
|
|
306
|
+
if ( $total != $passed or $aggregate->has_problems ) {
|
|
307
|
+
$self->_output("\nTest Summary Report");
|
|
308
|
+
$self->_output("\n-------------------\n");
|
|
309
|
+
for my $test (@$tests) {
|
|
310
|
+
$self->_printed_summary_header(0);
|
|
311
|
+
my ($parser) = $aggregate->parsers($test);
|
|
312
|
+
$self->_output_summary_failure(
|
|
313
|
+
'failed',
|
|
314
|
+
[ ' Failed test: ', ' Failed tests: ' ],
|
|
315
|
+
$test, $parser
|
|
316
|
+
);
|
|
317
|
+
$self->_output_summary_failure(
|
|
318
|
+
'todo_passed',
|
|
319
|
+
" TODO passed: ", $test, $parser
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
# ~TODO this cannot be the default
|
|
323
|
+
#$self->_output_summary_failure( 'skipped', " Tests skipped: " );
|
|
324
|
+
|
|
325
|
+
if ( my $exit = $parser->exit ) {
|
|
326
|
+
$self->_summary_test_header( $test, $parser );
|
|
327
|
+
$self->_failure_output(" Non-zero exit status: $exit\n");
|
|
328
|
+
}
|
|
329
|
+
elsif ( my $wait = $parser->wait ) {
|
|
330
|
+
$self->_summary_test_header( $test, $parser );
|
|
331
|
+
$self->_failure_output(" Non-zero wait status: $wait\n");
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if ( my @errors = $parser->parse_errors ) {
|
|
335
|
+
my $explain;
|
|
336
|
+
if ( @errors > $MAX_ERRORS && !$self->errors ) {
|
|
337
|
+
$explain
|
|
338
|
+
= "Displayed the first $MAX_ERRORS of "
|
|
339
|
+
. scalar(@errors)
|
|
340
|
+
. " TAP syntax errors.\n"
|
|
341
|
+
. "Re-run prove with the -p option to see them all.\n";
|
|
342
|
+
splice @errors, $MAX_ERRORS;
|
|
343
|
+
}
|
|
344
|
+
$self->_summary_test_header( $test, $parser );
|
|
345
|
+
$self->_failure_output(
|
|
346
|
+
sprintf " Parse errors: %s\n",
|
|
347
|
+
shift @errors
|
|
348
|
+
);
|
|
349
|
+
for my $error (@errors) {
|
|
350
|
+
my $spaces = ' ' x 16;
|
|
351
|
+
$self->_failure_output("$spaces$error\n");
|
|
352
|
+
}
|
|
353
|
+
$self->_failure_output($explain) if $explain;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
my $files = @$tests;
|
|
358
|
+
$self->_output("Files=$files, Tests=$total, $runtime\n");
|
|
359
|
+
my $status = $aggregate->get_status;
|
|
360
|
+
$self->_output("Result: $status\n");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
sub _output_summary_failure {
|
|
364
|
+
my ( $self, $method, $name, $test, $parser ) = @_;
|
|
365
|
+
|
|
366
|
+
# ugly hack. Must rethink this :(
|
|
367
|
+
my $output = $method eq 'failed' ? '_failure_output' : '_output';
|
|
368
|
+
|
|
369
|
+
if ( my @r = $parser->$method() ) {
|
|
370
|
+
$self->_summary_test_header( $test, $parser );
|
|
371
|
+
my ( $singular, $plural )
|
|
372
|
+
= 'ARRAY' eq ref $name ? @$name : ( $name, $name );
|
|
373
|
+
$self->$output( @r == 1 ? $singular : $plural );
|
|
374
|
+
my @results = $self->_balanced_range( 40, @r );
|
|
375
|
+
$self->$output( sprintf "%s\n" => shift @results );
|
|
376
|
+
my $spaces = ' ' x 16;
|
|
377
|
+
while (@results) {
|
|
378
|
+
$self->$output( sprintf "$spaces%s\n" => shift @results );
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
sub _summary_test_header {
|
|
384
|
+
my ( $self, $test, $parser ) = @_;
|
|
385
|
+
return if $self->_printed_summary_header;
|
|
386
|
+
my $spaces = ' ' x ( $self->_longest - length $test );
|
|
387
|
+
$spaces = ' ' unless $spaces;
|
|
388
|
+
my $output = $self->_get_output_method($parser);
|
|
389
|
+
my $wait = $parser->wait;
|
|
390
|
+
defined $wait or $wait = '(none)';
|
|
391
|
+
$self->$output(
|
|
392
|
+
sprintf "$test$spaces(Wstat: %s Tests: %d Failed: %d)\n",
|
|
393
|
+
$wait, $parser->tests_run, scalar $parser->failed
|
|
394
|
+
);
|
|
395
|
+
$self->_printed_summary_header(1);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
sub _output {
|
|
399
|
+
my $self = shift;
|
|
400
|
+
|
|
401
|
+
print { $self->stdout } @_;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
sub _failure_output {
|
|
405
|
+
my $self = shift;
|
|
406
|
+
|
|
407
|
+
$self->_output(@_);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
sub _balanced_range {
|
|
411
|
+
my ( $self, $limit, @range ) = @_;
|
|
412
|
+
@range = $self->_range(@range);
|
|
413
|
+
my $line = "";
|
|
414
|
+
my @lines;
|
|
415
|
+
my $curr = 0;
|
|
416
|
+
while (@range) {
|
|
417
|
+
if ( $curr < $limit ) {
|
|
418
|
+
my $range = ( shift @range ) . ", ";
|
|
419
|
+
$line .= $range;
|
|
420
|
+
$curr += length $range;
|
|
421
|
+
}
|
|
422
|
+
elsif (@range) {
|
|
423
|
+
$line =~ s/, $//;
|
|
424
|
+
push @lines => $line;
|
|
425
|
+
$line = '';
|
|
426
|
+
$curr = 0;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if ($line) {
|
|
430
|
+
$line =~ s/, $//;
|
|
431
|
+
push @lines => $line;
|
|
432
|
+
}
|
|
433
|
+
return @lines;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
sub _range {
|
|
437
|
+
my ( $self, @numbers ) = @_;
|
|
438
|
+
|
|
439
|
+
# shouldn't be needed, but subclasses might call this
|
|
440
|
+
@numbers = sort { $a <=> $b } @numbers;
|
|
441
|
+
my ( $min, @range );
|
|
442
|
+
|
|
443
|
+
for my $i ( 0 .. $#numbers ) {
|
|
444
|
+
my $num = $numbers[$i];
|
|
445
|
+
my $next = $numbers[ $i + 1 ];
|
|
446
|
+
if ( defined $next && $next == $num + 1 ) {
|
|
447
|
+
if ( !defined $min ) {
|
|
448
|
+
$min = $num;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
elsif ( defined $min ) {
|
|
452
|
+
push @range => "$min-$num";
|
|
453
|
+
undef $min;
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
push @range => $num;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return @range;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
sub _get_output_method {
|
|
463
|
+
my ( $self, $parser ) = @_;
|
|
464
|
+
return $parser->has_problems ? '_failure_output' : '_output';
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
1;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
package TAP::Formatter::Color;
|
|
2
|
+
|
|
3
|
+
use strict;
|
|
4
|
+
use warnings;
|
|
5
|
+
|
|
6
|
+
use constant IS_WIN32 => ( $^O =~ /^(MS)?Win32$/ );
|
|
7
|
+
|
|
8
|
+
use base 'TAP::Object';
|
|
9
|
+
|
|
10
|
+
my $NO_COLOR;
|
|
11
|
+
|
|
12
|
+
BEGIN {
|
|
13
|
+
$NO_COLOR = 0;
|
|
14
|
+
|
|
15
|
+
eval 'require Term::ANSIColor';
|
|
16
|
+
if ($@) {
|
|
17
|
+
$NO_COLOR = $@;
|
|
18
|
+
};
|
|
19
|
+
if (IS_WIN32) {
|
|
20
|
+
eval 'use Win32::Console::ANSI';
|
|
21
|
+
if ($@) {
|
|
22
|
+
$NO_COLOR = $@;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if ($NO_COLOR) {
|
|
27
|
+
*set_color = sub { };
|
|
28
|
+
} else {
|
|
29
|
+
*set_color = sub {
|
|
30
|
+
my ( $self, $output, $color ) = @_;
|
|
31
|
+
$output->( Term::ANSIColor::color($color) );
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
=head1 NAME
|
|
37
|
+
|
|
38
|
+
TAP::Formatter::Color - Run Perl test scripts with color
|
|
39
|
+
|
|
40
|
+
=head1 VERSION
|
|
41
|
+
|
|
42
|
+
Version 3.42
|
|
43
|
+
|
|
44
|
+
=cut
|
|
45
|
+
|
|
46
|
+
our $VERSION = '3.42';
|
|
47
|
+
|
|
48
|
+
=head1 DESCRIPTION
|
|
49
|
+
|
|
50
|
+
Note that this harness is I<experimental>. You may not like the colors I've
|
|
51
|
+
chosen and I haven't yet provided an easy way to override them.
|
|
52
|
+
|
|
53
|
+
This test harness is the same as L<TAP::Harness>, but test results are output
|
|
54
|
+
in color. Passing tests are printed in green. Failing tests are in red.
|
|
55
|
+
Skipped tests are blue on a white background and TODO tests are printed in
|
|
56
|
+
white.
|
|
57
|
+
|
|
58
|
+
If L<Term::ANSIColor> cannot be found (and L<Win32::Console::ANSI> if running
|
|
59
|
+
under Windows) tests will be run without color.
|
|
60
|
+
|
|
61
|
+
=head1 SYNOPSIS
|
|
62
|
+
|
|
63
|
+
use TAP::Formatter::Color;
|
|
64
|
+
my $harness = TAP::Formatter::Color->new( \%args );
|
|
65
|
+
$harness->runtests(@tests);
|
|
66
|
+
|
|
67
|
+
=head1 METHODS
|
|
68
|
+
|
|
69
|
+
=head2 Class Methods
|
|
70
|
+
|
|
71
|
+
=head3 C<new>
|
|
72
|
+
|
|
73
|
+
The constructor returns a new C<TAP::Formatter::Color> object. If
|
|
74
|
+
L<Term::ANSIColor> is not installed, returns undef.
|
|
75
|
+
|
|
76
|
+
=cut
|
|
77
|
+
|
|
78
|
+
# new() implementation supplied by TAP::Object
|
|
79
|
+
|
|
80
|
+
sub _initialize {
|
|
81
|
+
my $self = shift;
|
|
82
|
+
|
|
83
|
+
if ($NO_COLOR) {
|
|
84
|
+
|
|
85
|
+
# shorten that message a bit
|
|
86
|
+
( my $error = $NO_COLOR ) =~ s/ in \@INC .*//s;
|
|
87
|
+
warn "Note: Cannot run tests in color: $error\n";
|
|
88
|
+
return; # abort object construction
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return $self;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
##############################################################################
|
|
95
|
+
|
|
96
|
+
=head3 C<can_color>
|
|
97
|
+
|
|
98
|
+
Test::Formatter::Color->can_color()
|
|
99
|
+
|
|
100
|
+
Returns a boolean indicating whether or not this module can actually
|
|
101
|
+
generate colored output. This will be false if it could not load the
|
|
102
|
+
modules needed for the current platform.
|
|
103
|
+
|
|
104
|
+
=cut
|
|
105
|
+
|
|
106
|
+
sub can_color {
|
|
107
|
+
return !$NO_COLOR;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
=head3 C<set_color>
|
|
111
|
+
|
|
112
|
+
Set the output color.
|
|
113
|
+
|
|
114
|
+
=cut
|
|
115
|
+
|
|
116
|
+
1;
|