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.
Files changed (253) hide show
  1. package/README.md +6 -0
  2. package/bin/exiftool.exe +0 -0
  3. package/bin/exiftool_files/Changes +44 -0
  4. package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
  5. package/bin/exiftool_files/README +3 -2
  6. package/bin/exiftool_files/exiftool.pl +36 -14
  7. package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
  8. package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
  9. package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
  10. package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
  11. package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
  12. package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
  13. package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
  14. package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
  15. package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
  16. package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
  17. package/bin/exiftool_files/lib/B.pm +1 -1
  18. package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
  19. package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
  20. package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
  21. package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
  22. package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
  23. package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
  24. package/bin/exiftool_files/lib/Config.pm +9 -9
  25. package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
  26. package/bin/exiftool_files/lib/CryptX.pm +2 -82
  27. package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
  28. package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
  29. package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
  30. package/bin/exiftool_files/lib/Digest/base.pm +26 -20
  31. package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
  32. package/bin/exiftool_files/lib/Encode.pm +3 -3
  33. package/bin/exiftool_files/lib/Errno.pm +13 -13
  34. package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
  35. package/bin/exiftool_files/lib/Exporter.pm +1 -1
  36. package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
  37. package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
  38. package/bin/exiftool_files/lib/File/Find.pm +1 -1
  39. package/bin/exiftool_files/lib/File/Glob.pm +1 -8
  40. package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
  41. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
  42. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
  43. package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
  44. package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
  45. package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
  46. package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
  47. package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
  48. package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
  49. package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
  50. package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
  51. package/bin/exiftool_files/lib/File/Path.pm +3 -3
  52. package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
  53. package/bin/exiftool_files/lib/File/Temp.pm +70 -35
  54. package/bin/exiftool_files/lib/File/Which.pm +1 -240
  55. package/bin/exiftool_files/lib/File/stat.pm +3 -2
  56. package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
  57. package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
  58. package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
  59. package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
  60. package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
  61. package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
  62. package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
  63. package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
  64. package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
  65. package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
  66. package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
  67. package/bin/exiftool_files/lib/IO/File.pm +1 -1
  68. package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
  69. package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
  70. package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
  71. package/bin/exiftool_files/lib/IO/Select.pm +16 -2
  72. package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
  73. package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
  74. package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
  75. package/bin/exiftool_files/lib/IO/String.pm +425 -0
  76. package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
  77. package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
  78. package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
  79. package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
  80. package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
  81. package/bin/exiftool_files/lib/IO.pm +2 -2
  82. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +44 -31
  83. package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +2 -2
  84. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +20 -7
  85. package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +543 -0
  86. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +332 -149
  87. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +9 -4
  88. package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -4
  89. package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +2 -2
  90. package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
  91. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +331 -22
  92. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +55 -1
  93. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -0
  94. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +21 -3
  95. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +3 -3
  96. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +40 -24
  97. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +61 -30
  98. package/bin/exiftool_files/lib/Image/ExifTool/README +2 -0
  99. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +1 -1
  100. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4815 -4775
  101. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +931 -617
  102. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +30 -8
  103. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -4
  104. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
  105. package/bin/exiftool_files/lib/Image/ExifTool.pm +77 -41
  106. package/bin/exiftool_files/lib/Image/ExifTool.pod +24 -11
  107. package/bin/exiftool_files/lib/List/Util.pm +97 -8
  108. package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
  109. package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
  110. package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
  111. package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
  112. package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
  113. package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
  114. package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
  115. package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
  116. package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
  117. package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
  118. package/bin/exiftool_files/lib/POSIX.pm +1 -1
  119. package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
  120. package/bin/exiftool_files/lib/PerlIO.pm +397 -0
  121. package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
  122. package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
  123. package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
  124. package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
  125. package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
  126. package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
  127. package/bin/exiftool_files/lib/Portable.pm +246 -320
  128. package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
  129. package/bin/exiftool_files/lib/Socket.pm +16 -12
  130. package/bin/exiftool_files/lib/Storable.pm +1444 -1441
  131. package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
  132. package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
  133. package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
  134. package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
  135. package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
  136. package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
  137. package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
  138. package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
  139. package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
  140. package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
  141. package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
  142. package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
  143. package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
  144. package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
  145. package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
  146. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
  147. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
  148. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
  149. package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
  150. package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
  151. package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
  152. package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
  153. package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
  154. package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
  155. package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
  156. package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
  157. package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
  158. package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
  159. package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
  160. package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
  161. package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
  162. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
  163. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
  164. package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
  165. package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
  166. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
  167. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
  168. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
  169. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
  170. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
  171. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
  172. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
  173. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
  174. package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
  175. package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
  176. package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
  177. package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
  178. package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
  179. package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
  180. package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
  181. package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
  182. package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
  183. package/bin/exiftool_files/lib/Test/More.pm +1997 -0
  184. package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
  185. package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
  186. package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
  187. package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
  188. package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
  189. package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
  190. package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
  191. package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
  192. package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
  193. package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
  194. package/bin/exiftool_files/lib/Time/Local.pm +82 -35
  195. package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
  196. package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
  197. package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
  198. package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
  199. package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
  200. package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
  201. package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
  202. package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
  203. package/bin/exiftool_files/lib/Win32/API.pm +1 -830
  204. package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
  205. package/bin/exiftool_files/lib/Win32.pm +213 -89
  206. package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
  207. package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
  208. package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
  209. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
  210. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
  211. package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
  212. package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
  213. package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
  214. package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
  215. package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
  216. package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
  217. package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
  218. package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
  219. package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
  220. package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
  221. package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
  222. package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
  223. package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
  224. package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
  225. package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
  226. package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
  227. package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
  228. package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
  229. package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
  230. package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
  231. package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
  232. package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
  233. package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
  234. package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
  235. package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
  236. package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
  237. package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
  238. package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
  239. package/bin/exiftool_files/lib/feature.pm +49 -17
  240. package/bin/exiftool_files/lib/mro.pm +4 -20
  241. package/bin/exiftool_files/lib/overload.pm +15 -15
  242. package/bin/exiftool_files/lib/parent.pm +10 -2
  243. package/bin/exiftool_files/lib/re.pm +91 -33
  244. package/bin/exiftool_files/lib/warnings.pm +17 -6
  245. package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
  246. package/bin/exiftool_files/liblzma-5__.dll +0 -0
  247. package/bin/exiftool_files/libstdc++-6.dll +0 -0
  248. package/bin/exiftool_files/libwinpthread-1.dll +0 -0
  249. package/bin/exiftool_files/perl.exe +0 -0
  250. package/bin/exiftool_files/perl532.dll +0 -0
  251. package/package.json +7 -5
  252. package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
  253. package/bin/exiftool_files/perl530.dll +0 -0
@@ -0,0 +1,220 @@
1
+ package TAP::Formatter::Session;
2
+
3
+ use strict;
4
+ use warnings;
5
+
6
+ use base 'TAP::Base';
7
+
8
+ my @ACCESSOR;
9
+
10
+ BEGIN {
11
+
12
+ @ACCESSOR = qw( name formatter parser show_count );
13
+
14
+ for my $method (@ACCESSOR) {
15
+ no strict 'refs';
16
+ *$method = sub { shift->{$method} };
17
+ }
18
+ }
19
+
20
+ =head1 NAME
21
+
22
+ TAP::Formatter::Session - Abstract base class for harness output delegate
23
+
24
+ =head1 VERSION
25
+
26
+ Version 3.42
27
+
28
+ =cut
29
+
30
+ our $VERSION = '3.42';
31
+
32
+ =head1 METHODS
33
+
34
+ =head2 Class Methods
35
+
36
+ =head3 C<new>
37
+
38
+ my %args = (
39
+ formatter => $self,
40
+ )
41
+ my $harness = TAP::Formatter::Console::Session->new( \%args );
42
+
43
+ The constructor returns a new C<TAP::Formatter::Console::Session> object.
44
+
45
+ =over 4
46
+
47
+ =item * C<formatter>
48
+
49
+ =item * C<parser>
50
+
51
+ =item * C<name>
52
+
53
+ =item * C<show_count>
54
+
55
+ =back
56
+
57
+ =cut
58
+
59
+ sub _initialize {
60
+ my ( $self, $arg_for ) = @_;
61
+ $arg_for ||= {};
62
+
63
+ $self->SUPER::_initialize($arg_for);
64
+ my %arg_for = %$arg_for; # force a shallow copy
65
+
66
+ for my $name (@ACCESSOR) {
67
+ $self->{$name} = delete $arg_for{$name};
68
+ }
69
+
70
+ if ( !defined $self->show_count ) {
71
+ $self->{show_count} = 1; # defaults to true
72
+ }
73
+ if ( $self->show_count ) { # but may be a damned lie!
74
+ $self->{show_count} = $self->_should_show_count;
75
+ }
76
+
77
+ if ( my @props = sort keys %arg_for ) {
78
+ $self->_croak(
79
+ "Unknown arguments to " . __PACKAGE__ . "::new (@props)" );
80
+ }
81
+
82
+ return $self;
83
+ }
84
+
85
+ =head3 C<header>
86
+
87
+ Output test preamble
88
+
89
+ =head3 C<result>
90
+
91
+ Called by the harness for each line of TAP it receives.
92
+
93
+ =head3 C<close_test>
94
+
95
+ Called to close a test session.
96
+
97
+ =head3 C<clear_for_close>
98
+
99
+ Called by C<close_test> to clear the line showing test progress, or the parallel
100
+ test ruler, prior to printing the final test result.
101
+
102
+ =head3 C<time_report>
103
+
104
+ Return a formatted string about the elapsed (wall-clock) time
105
+ and about the consumed CPU time.
106
+
107
+ =cut
108
+
109
+ sub header { }
110
+
111
+ sub result { }
112
+
113
+ sub close_test { }
114
+
115
+ sub clear_for_close { }
116
+
117
+ sub _should_show_count {
118
+ my $self = shift;
119
+ return
120
+ !$self->formatter->verbose
121
+ && -t $self->formatter->stdout
122
+ && !$ENV{HARNESS_NOTTY};
123
+ }
124
+
125
+ sub _format_for_output {
126
+ my ( $self, $result ) = @_;
127
+ return $self->formatter->normalize ? $result->as_string : $result->raw;
128
+ }
129
+
130
+ sub _output_test_failure {
131
+ my ( $self, $parser ) = @_;
132
+ my $formatter = $self->formatter;
133
+ return if $formatter->really_quiet;
134
+
135
+ my $tests_run = $parser->tests_run;
136
+ my $tests_planned = $parser->tests_planned;
137
+
138
+ my $total
139
+ = defined $tests_planned
140
+ ? $tests_planned
141
+ : $tests_run;
142
+
143
+ my $passed = $parser->passed;
144
+
145
+ # The total number of fails includes any tests that were planned but
146
+ # didn't run
147
+ my $failed = $parser->failed + $total - $tests_run;
148
+ my $exit = $parser->exit;
149
+
150
+ if ( my $exit = $parser->exit ) {
151
+ my $wstat = $parser->wait;
152
+ my $status = sprintf( "%d (wstat %d, 0x%x)", $exit, $wstat, $wstat );
153
+ $formatter->_failure_output("Dubious, test returned $status\n");
154
+ }
155
+
156
+ if ( $failed == 0 ) {
157
+ $formatter->_failure_output(
158
+ $total
159
+ ? "All $total subtests passed "
160
+ : 'No subtests run '
161
+ );
162
+ }
163
+ else {
164
+ $formatter->_failure_output("Failed $failed/$total subtests ");
165
+ if ( !$total ) {
166
+ $formatter->_failure_output("\nNo tests run!");
167
+ }
168
+ }
169
+
170
+ if ( my $skipped = $parser->skipped ) {
171
+ $passed -= $skipped;
172
+ my $test = 'subtest' . ( $skipped != 1 ? 's' : '' );
173
+ $formatter->_output(
174
+ "\n\t(less $skipped skipped $test: $passed okay)");
175
+ }
176
+
177
+ if ( my $failed = $parser->todo_passed ) {
178
+ my $test = $failed > 1 ? 'tests' : 'test';
179
+ $formatter->_output(
180
+ "\n\t($failed TODO $test unexpectedly succeeded)");
181
+ }
182
+
183
+ $formatter->_output("\n");
184
+ }
185
+
186
+ sub _make_ok_line {
187
+ my ( $self, $suffix ) = @_;
188
+ return "ok$suffix\n";
189
+ }
190
+
191
+ sub time_report {
192
+ my ( $self, $formatter, $parser ) = @_;
193
+
194
+ my @time_report;
195
+ if ( $formatter->timer ) {
196
+ my $start_time = $parser->start_time;
197
+ my $end_time = $parser->end_time;
198
+ if ( defined $start_time and defined $end_time ) {
199
+ my $elapsed = $end_time - $start_time;
200
+ push @time_report,
201
+ $self->time_is_hires
202
+ ? sprintf( ' %8d ms', $elapsed * 1000 )
203
+ : sprintf( ' %8s s', $elapsed || '<1' );
204
+ }
205
+ my $start_times = $parser->start_times();
206
+ my $end_times = $parser->end_times();
207
+ my $usr = $end_times->[0] - $start_times->[0];
208
+ my $sys = $end_times->[1] - $start_times->[1];
209
+ my $cusr = $end_times->[2] - $start_times->[2];
210
+ my $csys = $end_times->[3] - $start_times->[3];
211
+ push @time_report,
212
+ sprintf('(%5.2f usr %5.2f sys + %5.2f cusr %5.2f csys = %5.2f CPU)',
213
+ $usr, $sys, $cusr, $csys,
214
+ $usr + $sys + $cusr + $csys);
215
+ }
216
+
217
+ return "@time_report";
218
+ }
219
+
220
+ 1;
@@ -0,0 +1,426 @@
1
+ =head1 NAME
2
+
3
+ Test::Harness::Beyond - Beyond make test
4
+
5
+ =head1 Beyond make test
6
+
7
+ Test::Harness is responsible for running test scripts, analysing
8
+ their output and reporting success or failure. When I type
9
+ F<make test> (or F<./Build test>) for a module, Test::Harness is usually
10
+ used to run the tests (not all modules use Test::Harness but the
11
+ majority do).
12
+
13
+ To start exploring some of the features of Test::Harness I need to
14
+ switch from F<make test> to the F<prove> command (which ships with
15
+ Test::Harness). For the following examples I'll also need a recent
16
+ version of Test::Harness installed; 3.14 is current as I write.
17
+
18
+ For the examples I'm going to assume that we're working with a
19
+ 'normal' Perl module distribution. Specifically I'll assume that
20
+ typing F<make> or F<./Build> causes the built, ready-to-install module
21
+ code to be available below ./blib/lib and ./blib/arch and that
22
+ there's a directory called 't' that contains our tests. Test::Harness
23
+ isn't hardwired to that configuration but it saves me from explaining
24
+ which files live where for each example.
25
+
26
+ Back to F<prove>; like F<make test> it runs a test suite - but it
27
+ provides far more control over which tests are executed, in what
28
+ order and how their results are reported. Typically F<make test>
29
+ runs all the test scripts below the 't' directory. To do the same
30
+ thing with prove I type:
31
+
32
+ prove -rb t
33
+
34
+ The switches here are -r to recurse into any directories below 't'
35
+ and -b which adds ./blib/lib and ./blib/arch to Perl's include path
36
+ so that the tests can find the code they will be testing. If I'm
37
+ testing a module of which an earlier version is already installed
38
+ I need to be careful about the include path to make sure I'm not
39
+ running my tests against the installed version rather than the new
40
+ one that I'm working on.
41
+
42
+ Unlike F<make test>, typing F<prove> doesn't automatically rebuild
43
+ my module. If I forget to make before prove I will be testing against
44
+ older versions of those files - which inevitably leads to confusion.
45
+ I either get into the habit of typing
46
+
47
+ make && prove -rb t
48
+
49
+ or - if I have no XS code that needs to be built I use the modules
50
+ below F<lib> instead
51
+
52
+ prove -Ilib -r t
53
+
54
+ So far I've shown you nothing that F<make test> doesn't do. Let's
55
+ fix that.
56
+
57
+ =head2 Saved State
58
+
59
+ If I have failing tests in a test suite that consists of more than
60
+ a handful of scripts and takes more than a few seconds to run it
61
+ rapidly becomes tedious to run the whole test suite repeatedly as
62
+ I track down the problems.
63
+
64
+ I can tell prove just to run the tests that are failing like this:
65
+
66
+ prove -b t/this_fails.t t/so_does_this.t
67
+
68
+ That speeds things up but I have to make a note of which tests are
69
+ failing and make sure that I run those tests. Instead I can use
70
+ prove's --state switch and have it keep track of failing tests for
71
+ me. First I do a complete run of the test suite and tell prove to
72
+ save the results:
73
+
74
+ prove -rb --state=save t
75
+
76
+ That stores a machine readable summary of the test run in a file
77
+ called '.prove' in the current directory. If I have failures I can
78
+ then run just the failing scripts like this:
79
+
80
+ prove -b --state=failed
81
+
82
+ I can also tell prove to save the results again so that it updates
83
+ its idea of which tests failed:
84
+
85
+ prove -b --state=failed,save
86
+
87
+ As soon as one of my failing tests passes it will be removed from
88
+ the list of failed tests. Eventually I fix them all and prove can
89
+ find no failing tests to run:
90
+
91
+ Files=0, Tests=0, 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
92
+ Result: NOTESTS
93
+
94
+ As I work on a particular part of my module it's most likely that
95
+ the tests that cover that code will fail. I'd like to run the whole
96
+ test suite but have it prioritize these 'hot' tests. I can tell
97
+ prove to do this:
98
+
99
+ prove -rb --state=hot,save t
100
+
101
+ All the tests will run but those that failed most recently will be
102
+ run first. If no tests have failed since I started saving state all
103
+ tests will run in their normal order. This combines full test
104
+ coverage with early notification of failures.
105
+
106
+ The --state switch supports a number of options; for example to run
107
+ failed tests first followed by all remaining tests ordered by the
108
+ timestamps of the test scripts - and save the results - I can use
109
+
110
+ prove -rb --state=failed,new,save t
111
+
112
+ See the prove documentation (type prove --man) for the full list
113
+ of state options.
114
+
115
+ When I tell prove to save state it writes a file called '.prove'
116
+ ('_prove' on Windows) in the current directory. It's a YAML document
117
+ so it's quite easy to write tools of your own that work on the saved
118
+ test state - but the format isn't officially documented so it might
119
+ change without (much) warning in the future.
120
+
121
+ =head2 Parallel Testing
122
+
123
+ If my tests take too long to run I may be able to speed them up by
124
+ running multiple test scripts in parallel. This is particularly
125
+ effective if the tests are I/O bound or if I have multiple CPU
126
+ cores. I tell prove to run my tests in parallel like this:
127
+
128
+ prove -rb -j 9 t
129
+
130
+ The -j switch enables parallel testing; the number that follows it
131
+ is the maximum number of tests to run in parallel. Sometimes tests
132
+ that pass when run sequentially will fail when run in parallel. For
133
+ example if two different test scripts use the same temporary file
134
+ or attempt to listen on the same socket I'll have problems running
135
+ them in parallel. If I see unexpected failures I need to check my
136
+ tests to work out which of them are trampling on the same resource
137
+ and rename temporary files or add locks as appropriate.
138
+
139
+ To get the most performance benefit I want to have the test scripts
140
+ that take the longest to run start first - otherwise I'll be waiting
141
+ for the one test that takes nearly a minute to complete after all
142
+ the others are done. I can use the --state switch to run the tests
143
+ in slowest to fastest order:
144
+
145
+ prove -rb -j 9 --state=slow,save t
146
+
147
+ =head2 Non-Perl Tests
148
+
149
+ The Test Anything Protocol (http://testanything.org/) isn't just
150
+ for Perl. Just about any language can be used to write tests that
151
+ output TAP. There are TAP based testing libraries for C, C++, PHP,
152
+ Python and many others. If I can't find a TAP library for my language
153
+ of choice it's easy to generate valid TAP. It looks like this:
154
+
155
+ 1..3
156
+ ok 1 - init OK
157
+ ok 2 - opened file
158
+ not ok 3 - appended to file
159
+
160
+ The first line is the plan - it specifies the number of tests I'm
161
+ going to run so that it's easy to check that the test script didn't
162
+ exit before running all the expected tests. The following lines are
163
+ the test results - 'ok' for pass, 'not ok' for fail. Each test has
164
+ a number and, optionally, a description. And that's it. Any language
165
+ that can produce output like that on STDOUT can be used to write
166
+ tests.
167
+
168
+ Recently I've been rekindling a two-decades-old interest in Forth.
169
+ Evidently I have a masochistic streak that even Perl can't satisfy.
170
+ I want to write tests in Forth and run them using prove (you can
171
+ find my gforth TAP experiments at
172
+ https://svn.hexten.net/andy/Forth/Testing/). I can use the --exec
173
+ switch to tell prove to run the tests using gforth like this:
174
+
175
+ prove -r --exec gforth t
176
+
177
+ Alternately, if the language used to write my tests allows a shebang
178
+ line I can use that to specify the interpreter. Here's a test written
179
+ in PHP:
180
+
181
+ #!/usr/bin/php
182
+ <?php
183
+ print "1..2\n";
184
+ print "ok 1\n";
185
+ print "not ok 2\n";
186
+ ?>
187
+
188
+ If I save that as t/phptest.t the shebang line will ensure that it
189
+ runs correctly along with all my other tests.
190
+
191
+ =head2 Mixing it up
192
+
193
+ Subtle interdependencies between test programs can mask problems -
194
+ for example an earlier test may neglect to remove a temporary file
195
+ that affects the behaviour of a later test. To find this kind of
196
+ problem I use the --shuffle and --reverse options to run my tests
197
+ in random or reversed order.
198
+
199
+ =head2 Rolling My Own
200
+
201
+ If I need a feature that prove doesn't provide I can easily write my own.
202
+
203
+ Typically you'll want to change how TAP gets I<input> into and I<output>
204
+ from the parser. L<App::Prove> supports arbitrary plugins, and L<TAP::Harness>
205
+ supports custom I<formatters> and I<source handlers> that you can load using
206
+ either L<prove> or L<Module::Build>; there are many examples to base mine on.
207
+ For more details see L<App::Prove>, L<TAP::Parser::SourceHandler>, and
208
+ L<TAP::Formatter::Base>.
209
+
210
+ If writing a plugin is not enough, you can write your own test harness; one of
211
+ the motives for the 3.00 rewrite of Test::Harness was to make it easier to
212
+ subclass and extend.
213
+
214
+ The Test::Harness module is a compatibility wrapper around TAP::Harness.
215
+ For new applications I should use TAP::Harness directly. As we'll
216
+ see, prove uses TAP::Harness.
217
+
218
+ When I run prove it processes its arguments, figures out which test
219
+ scripts to run and then passes control to TAP::Harness to run the
220
+ tests, parse, analyse and present the results. By subclassing
221
+ TAP::Harness I can customise many aspects of the test run.
222
+
223
+ I want to log my test results in a database so I can track them
224
+ over time. To do this I override the summary method in TAP::Harness.
225
+ I start with a simple prototype that dumps the results as a YAML
226
+ document:
227
+
228
+ package My::TAP::Harness;
229
+
230
+ use base 'TAP::Harness';
231
+ use YAML;
232
+
233
+ sub summary {
234
+ my ( $self, $aggregate ) = @_;
235
+ print Dump( $aggregate );
236
+ $self->SUPER::summary( $aggregate );
237
+ }
238
+
239
+ 1;
240
+
241
+ I need to tell prove to use my My::TAP::Harness. If My::TAP::Harness
242
+ is on Perl's @INC include path I can
243
+
244
+ prove --harness=My::TAP::Harness -rb t
245
+
246
+ If I don't have My::TAP::Harness installed on @INC I need to provide
247
+ the correct path to perl when I run prove:
248
+
249
+ perl -Ilib `which prove` --harness=My::TAP::Harness -rb t
250
+
251
+ I can incorporate these options into my own version of prove. It's
252
+ pretty simple. Most of the work of prove is handled by App::Prove.
253
+ The important code in prove is just:
254
+
255
+ use App::Prove;
256
+
257
+ my $app = App::Prove->new;
258
+ $app->process_args(@ARGV);
259
+ exit( $app->run ? 0 : 1 );
260
+
261
+ If I write a subclass of App::Prove I can customise any aspect of
262
+ the test runner while inheriting all of prove's behaviour. Here's
263
+ myprove:
264
+
265
+ #!/usr/bin/env perl use lib qw( lib ); # Add ./lib to @INC
266
+ use App::Prove;
267
+
268
+ my $app = App::Prove->new;
269
+
270
+ # Use custom TAP::Harness subclass
271
+ $app->harness( 'My::TAP::Harness' );
272
+
273
+ $app->process_args( @ARGV ); exit( $app->run ? 0 : 1 );
274
+
275
+ Now I can run my tests like this
276
+
277
+ ./myprove -rb t
278
+
279
+ =head2 Deeper Customisation
280
+
281
+ Now that I know how to subclass and replace TAP::Harness I can
282
+ replace any other part of the harness. To do that I need to know
283
+ which classes are responsible for which functionality. Here's a
284
+ brief guided tour; the default class for each component is shown
285
+ in parentheses. Normally any replacements I write will be subclasses
286
+ of these default classes.
287
+
288
+ When I run my tests TAP::Harness creates a scheduler
289
+ (TAP::Parser::Scheduler) to work out the running order for the
290
+ tests, an aggregator (TAP::Parser::Aggregator) to collect and analyse
291
+ the test results and a formatter (TAP::Formatter::Console) to display
292
+ those results.
293
+
294
+ If I'm running my tests in parallel there may also be a multiplexer
295
+ (TAP::Parser::Multiplexer) - the component that allows multiple
296
+ tests to run simultaneously.
297
+
298
+ Once it has created those helpers TAP::Harness starts running the
299
+ tests. For each test it creates a new parser (TAP::Parser) which
300
+ is responsible for running the test script and parsing its output.
301
+
302
+ To replace any of these components I call one of these harness
303
+ methods with the name of the replacement class:
304
+
305
+ aggregator_class
306
+ formatter_class
307
+ multiplexer_class
308
+ parser_class
309
+ scheduler_class
310
+
311
+ For example, to replace the aggregator I would
312
+
313
+ $harness->aggregator_class( 'My::Aggregator' );
314
+
315
+ Alternately I can supply the names of my substitute classes to the
316
+ TAP::Harness constructor:
317
+
318
+ my $harness = TAP::Harness->new(
319
+ { aggregator_class => 'My::Aggregator' }
320
+ );
321
+
322
+ If I need to reach even deeper into the internals of the harness I
323
+ can replace the classes that TAP::Parser uses to execute test scripts
324
+ and tokenise their output. Before running a test script TAP::Parser
325
+ creates a grammar (TAP::Parser::Grammar) to decode the raw TAP into
326
+ tokens, a result factory (TAP::Parser::ResultFactory) to turn the
327
+ decoded TAP results into objects and, depending on whether it's
328
+ running a test script or reading TAP from a file, scalar or array
329
+ a source or an iterator (TAP::Parser::IteratorFactory).
330
+
331
+ Each of these objects may be replaced by calling one of these parser
332
+ methods:
333
+
334
+ source_class
335
+ perl_source_class
336
+ grammar_class
337
+ iterator_factory_class
338
+ result_factory_class
339
+
340
+ =head2 Callbacks
341
+
342
+ As an alternative to subclassing the components I need to change I
343
+ can attach callbacks to the default classes. TAP::Harness exposes
344
+ these callbacks:
345
+
346
+ parser_args Tweak the parameters used to create the parser
347
+ made_parser Just made a new parser
348
+ before_runtests About to run tests
349
+ after_runtests Have run all tests
350
+ after_test Have run an individual test script
351
+
352
+ TAP::Parser also supports callbacks; bailout, comment, plan, test,
353
+ unknown, version and yaml are called for the corresponding TAP
354
+ result types, ALL is called for all results, ELSE is called for all
355
+ results for which a named callback is not installed and EOF is
356
+ called once at the end of each TAP stream.
357
+
358
+ To install a callback I pass the name of the callback and a subroutine
359
+ reference to TAP::Harness or TAP::Parser's callback method:
360
+
361
+ $harness->callback( after_test => sub {
362
+ my ( $script, $desc, $parser ) = @_;
363
+ } );
364
+
365
+ I can also pass callbacks to the constructor:
366
+
367
+ my $harness = TAP::Harness->new({
368
+ callbacks => {
369
+ after_test => sub {
370
+ my ( $script, $desc, $parser ) = @_;
371
+ # Do something interesting here
372
+ }
373
+ }
374
+ });
375
+
376
+ When it comes to altering the behaviour of the test harness there's
377
+ more than one way to do it. Which way is best depends on my
378
+ requirements. In general if I only want to observe test execution
379
+ without changing the harness' behaviour (for example to log test
380
+ results to a database) I choose callbacks. If I want to make the
381
+ harness behave differently subclassing gives me more control.
382
+
383
+ =head2 Parsing TAP
384
+
385
+ Perhaps I don't need a complete test harness. If I already have a
386
+ TAP test log that I need to parse all I need is TAP::Parser and the
387
+ various classes it depends upon. Here's the code I need to run a
388
+ test and parse its TAP output
389
+
390
+ use TAP::Parser;
391
+
392
+ my $parser = TAP::Parser->new( { source => 't/simple.t' } );
393
+ while ( my $result = $parser->next ) {
394
+ print $result->as_string, "\n";
395
+ }
396
+
397
+ Alternately I can pass an open filehandle as source and have the
398
+ parser read from that rather than attempting to run a test script:
399
+
400
+ open my $tap, '<', 'tests.tap'
401
+ or die "Can't read TAP transcript ($!)\n";
402
+ my $parser = TAP::Parser->new( { source => $tap } );
403
+ while ( my $result = $parser->next ) {
404
+ print $result->as_string, "\n";
405
+ }
406
+
407
+ This approach is useful if I need to convert my TAP based test
408
+ results into some other representation. See TAP::Convert::TET
409
+ (http://search.cpan.org/dist/TAP-Convert-TET/) for an example of
410
+ this approach.
411
+
412
+ =head2 Getting Support
413
+
414
+ The Test::Harness developers hang out on the tapx-dev mailing
415
+ list[1]. For discussion of general, language independent TAP issues
416
+ there's the tap-l[2] list. Finally there's a wiki dedicated to the
417
+ Test Anything Protocol[3]. Contributions to the wiki, patches and
418
+ suggestions are all welcome.
419
+
420
+ =for comment
421
+ The URLs in [1] and [2] point to 404 pages. What are currently the
422
+ correct URLs?
423
+
424
+ [1] L<http://www.hexten.net/mailman/listinfo/tapx-dev>
425
+ [2] L<http://testanything.org/mailman/listinfo/tap-l>
426
+ [3] L<http://testanything.org/>