TAP-Formatter-JUnit-0.17000755001750001750 014751004727 14745 5ustar00grahamgraham000000000000README100644001750001750 666414751004727 15722 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17NAME
TAP::Formatter::JUnit - Harness output delegate for JUnit output
SYNOPSIS
On the command line, with prove:
$ prove --formatter TAP::Formatter::JUnit ...
Or, in your own scripts:
use TAP::Harness;
# What TAP output did we save from a previous run, with
# PERL_TEST_HARNESS_DUMP_TAP=tap/
my @tests = glob("tap/*.t");
# Convert the TAP to JUnit
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
merge => 1,
} );
$harness->runtests(@tests);
DESCRIPTION
This code is currently in alpha state and is subject to change.
TAP::Formatter::JUnit provides JUnit output formatting for
TAP::Harness.
By default (e.g. when run with prove), the entire test suite is
gathered together into a single JUnit XML document, which is then
displayed on STDOUT. You can, however, have individual JUnit XML files
dumped for each individual test, by setting PERL_TEST_HARNESS_DUMP_TAP
to a directory that you would like the JUnit XML dumped to. Note, that
this will also cause TAP::Harness to dump the original TAP output into
that directory as well (but IMHO that's ok as you've now got the data
in two parseable formats).
Timing information is included in the JUnit XML, if you specified
--timer when you ran prove.
In standard use, a "passing TODO" is treated as failure conditions (and
is reported as such in the generated JUnit). If you wish to treat these
as a "pass" and not a "fail" condition, setting ALLOW_PASSING_TODOS in
your environment will turn these into pass conditions.
The JUnit output generated is partial to being grokked by Hudson
(http://hudson.dev.java.net/). That's the build tool I'm using at the
moment and needed to be able to generate JUnit output for.
ATTRIBUTES
testsuites
List-ref of test suites that have been executed.
xml
An XML::Generator instance, to be used to generate XML output.
METHODS
open_test($test, $parser)
Over-ridden open_test() method.
Creates a TAP::Formatter::JUnit::Session session, instead of a
console formatter session.
summary()
Prints the summary report (in JUnit) after all tests are run.
add_testsuite($suite)
Adds the given XML test $suite to the list of test suites that we've
executed and need to summarize.
AUTHOR
Graham TerMarsch
Many thanks to Andy Armstrong and all those involved for the fabulous
set of tests in Test::Harness; they became the basis for the unit tests
here.
Other thanks go out to those that have provided feedback, comments, or
patches:
Mark Aufflick
Joe McMahon
Michael Nachbaur
Marc Abramowitz
Colin Robertson
Phillip Kimmey
Dave Lambley
COPYRIGHT
Copyright 2008-2010, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
SEE ALSO
TAP::Formatter::Console
TAP::Formatter::JUnit::Session
Hudson home page
JUnitXSchema.xsd
JUnit parsing in Bamboo
.
Changes100644001750001750 1241414751004727 16343 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17Revision history for Perl extension TAP::Formatter::JUnit.
0.17 2025-02-05 17:01:10-08:00 America/Vancouver
- Bump minimum required Perl to 5.010; XML::Generator v1.11 now requires
that as a minimum acceptable Perl.
- Skip BAIL_OUT test when using Test::Harness 3.45_01-3.48, as those
versions contained a bug which output a double summary. Fixes GH#15
0.16 2022-05-14 21:50:19-07:00 America/Vancouver
- Sigh... neglected to consider development versions of Test::Harness in the
recent updates to "t/formatter.t"; although the fixes were released in
v3.44, they were also present in the v3.43_* development versions.
0.15 2022-05-06 11:45:06-07:00 America/Vancouver
- Use "version.pm" to compare version numbers, in "t/formatter.t".
Addresses some CPANTester failures.
0.14 2022-04-30 12:36:14-07:00 America/Vancouver
- Update "t/formatter.t" to accommodate fixes made in Test::Harness v3.44
(most specifically w.r.t. the "bailout" test). david-dot-krupicka++
ppisar++ pghmcfc++
0.13 2021-05-04 10:04:17-07:00 America/Vancouver
- Fix install of "script/tap2junit"
0.12 2021-01-05 21:23:07-08:00 America/Vancouver
- Switch to Dist::Zilla for release management.
- Various POD fixups; syntax, spelling, SYNOPSIS fixes
- Cleaned up and removed unused variables
- Bump minimum required Perl to 5.008, as that's the oldest version I can
still test against.
0.11 Wed Oct 1 13:26 PDT 2014
- Use "IPC::Run" instead of "IPC::Open2" in tests, to fix problems with
tests freezing on Windows.
0.10 Mon Sep 29 12:38 PDT 2014
- Switch from "Test::Differences" to "Test::XML", to eliminate failures due
to differences in ordering of XML attributes. Addresses RT#81552
- Use "File::Spec->null()" to get proper path to NULL. RT#81200, RT#82227.
- Moved POD tests to "xt/" directory.
- Move timing sensitive tests to "xt/" directory, as they can cause
spurious failures for people. While _I_ want to make sure they run
successfully, that's about my checking functionality as opposed to
verifying if things will run successfully on your own system. RT#69777.
0.09 Wed Jan 25 15:13 PST 2012
- Switch from Class::Field to Moose. Thanks to Dave Lambley for the poke,
and the patience.
- Track and report timings for "(init)" and "(teardown)" of the test.
Without this, Hudson does not properly report on the total time needed
for a test suite (it calculates total time by adding up the constituent
tests, not by looking at the "time" attribute).
- Rewrite internals, switching from a streaming style to an iterative style
of processing the TAP. Same results, but easier to work with.
0.08 Thu Jul 15 23:44 PDT 2010
- RT#58838, "Error reporting on die or missing plan". Thanks to Colin
Robertson. Output compatible w/Hudson (so it now sees these as errors).
- RT#59206, "Plan/Tests Mismatch". Thanks for Phillip Kimmey. JUnit
output now reports mismatches with an "" so Hudson detects it.
0.07 Fri Jan 29 23:23 PST 2010
- Fix RT#53927, "Times reported by T:F:JUnit for individual test cases in
a .t file are incorrect". Thanks to Marc Abramowitz.
0.06 Wed Jan 13 21:24 PST 2010
- Fix bug in tap2junit which would cause multiple TAP streams to have the
*same* name in their output JUnit XML. Introduced in 0.04.
0.05 Wed Jan 13 16:32 PST 2010
- Add support for ALLOW_PASSING_TODOS environment variable, which forces
T:F:JUnit to treat passing TODOs as a "pass" and not a "fail" condition.
Thanks to Joe McMahon.
- Removed need for Test::Output; I forgot that you can pass a FH directly
in to TAP::Harness. Doh!
0.04 Wed Jan 13 15:51 PST 2010
- extra escaping/cleanup of characters before inserting them into the XML
stream, to keep JUnit parsers like Hudson's from choking. Thanks go out
to Joe McMahon and Michael Nachbaur for prodding to get this fixed and
for patches.
- new "--name" option for tap2junit, allowing for tests to be explicitly
named. Aliased to "--junit_name" to provide compatibility with patch
from Joe McMahon.
- tap2junit can now filter stdin/stdout; use "-" as the filename. Thanks
to Joe McMahon for the original patch on which this is based
- switch unit tests to use Test::Output for capturing output, instead of
trying to run "prove" directly
- update unit tests to run against "blib/lib" and "blib/script" instead
of just "lib" and "bin"
0.03 Sun Dec 13 22:36 PST 2009
- add timer output for each test case (not just for the suite as a whole);
Hudson needs this in order to show timing output for test runs. Thanks
to Mark Aufflick for the poke.
- internal cleanups
0.02 Fri Jan 9 23:35 PST 2009
- POD updates
- minor cleanup to the test names output in JUnit
- attempt to fix failing CPAN Tester reports, where an older version of
'prove' was being picked up by t/formatter.t; provide our own
't/bin/my-prove' and use that instead.
0.01 Wed Jan 7 22:06 PST 2009
- initial version
- had this sitting around on my HD for several months and am (finally)
getting around to uploading it to CPAN
LICENSE100644001750001750 4644314751004727 16066 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17This software is copyright (c) 2025 by Graham TerMarsch.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
Terms of the Perl programming language system itself
a) the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any
later version, or
b) the "Artistic License"
--- The GNU General Public License, Version 1, February 1989 ---
This software is Copyright (c) 2025 by Graham TerMarsch.
This is free software, licensed under:
The GNU General Public License, Version 1, February 1989
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating that
you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish, that
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
in the simplest and most usual way, to print or display an
announcement including an appropriate copyright notice and a notice
that there is no warranty (or else, saying that you provide a
warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this General
Public License.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
7. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
the license, you may choose any version ever published by the Free Software
Foundation.
8. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
Copyright (C) 19yy
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
That's all there is to it!
--- The Perl Artistic License 1.0 ---
This software is Copyright (c) 2025 by Graham TerMarsch.
This is free software, licensed under:
The Perl Artistic License 1.0
The "Artistic License"
Preamble
The intent of this document is to state the conditions under which a
Package may be copied, such that the Copyright Holder maintains some
semblance of artistic control over the development of the package,
while giving the users of the package the right to use and distribute
the Package in a more-or-less customary fashion, plus the right to make
reasonable modifications.
Definitions:
"Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files
created through textual modification.
"Standard Version" refers to such a Package if it has not been
modified, or has been modified in accordance with the wishes
of the Copyright Holder as specified below.
"Copyright Holder" is whoever is named in the copyright or
copyrights for the package.
"You" is you, if you're thinking about copying or distributing
this Package.
"Reasonable copying fee" is whatever you can justify on the
basis of media cost, duplication charges, time of people involved,
and so on. (You will not be required to justify it to the
Copyright Holder, but only to the computing community at large
as a market that must bear the fee.)
"Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the item.
It also means that recipients of the item may redistribute it
under the same conditions they received it.
1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated disclaimers.
2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A Package
modified in such a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way, provided
that you insert a prominent notice in each changed file stating how and
when you changed that file, and provided that you do at least ONE of the
following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet or
an equivalent medium, or placing the modifications on a major archive
site such as uunet.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict
with standard executables, which must also be provided, and provide
a separate manual page for each non-standard executable that clearly
documents how it differs from the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and library files,
together with instructions (in the manual page or equivalent) on where
to get the Standard Version.
b) accompany the distribution with the machine-readable source of
the Package with your modifications.
c) give non-standard executables non-standard names, and clearly
document the differences in manual pages (or equivalent), together
with instructions on where to get the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
5. You may charge a reasonable copying fee for any distribution of this
Package. You may charge any fee you choose for support of this
Package. You may not charge a fee for this Package itself. However,
you may distribute this Package in aggregate with other (possibly
commercial) programs as part of a larger (possibly commercial) software
distribution provided that you do not advertise this Package as a
product of your own. You may embed this Package's interpreter within
an executable of yours (by linking); this shall be construed as a mere
form of aggregation, provided that the complete Standard Version of the
interpreter is so embedded.
6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall
under the copyright of this Package, but belong to whoever generated
them, and may be sold commercially, and may be aggregated with this
Package. If such scripts or library files are aggregated with this
Package via the so-called "undump" or "unexec" methods of producing a
binary executable image, then distribution of such an image shall
neither be construed as a distribution of this Package nor shall it
fall under the restrictions of Paragraphs 3 and 4, provided that you do
not represent such an executable image as a Standard Version of this
Package.
7. C subroutines (or comparably compiled subroutines in other
languages) supplied by you and linked into this Package in order to
emulate subroutines and variables of the language defined by this
Package shall not be considered part of this Package, but are the
equivalent of input as in Paragraph 6, provided these subroutines do
not change the language in any way that would cause it to fail the
regression tests for the language.
8. Aggregation of this Package with a commercial distribution is always
permitted provided that the use of this Package is embedded; that is,
when no overt attempt is made to make this Package's interfaces visible
to the end user of the commercial distribution. Such use shall not be
construed as a distribution of this Package.
9. The name of the Copyright Holder may not be used to endorse or promote
products derived from this software without specific prior written permission.
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
MANIFEST100644001750001750 564714751004727 16173 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.032.
Changes
LICENSE
MANIFEST
META.json
META.yml
Makefile.PL
README
lib/TAP/Formatter/JUnit.pm
lib/TAP/Formatter/JUnit/Result.pm
lib/TAP/Formatter/JUnit/Session.pm
script/tap2junit
t/00-report-prereqs.dd
t/00-report-prereqs.t
t/01-compile.t
t/data/tap/bad_chars
t/data/tap/bailout
t/data/tap/descriptive
t/data/tap/descriptive_trailing
t/data/tap/die
t/data/tap/die_head_end
t/data/tap/die_last_minute
t/data/tap/die_unfinished
t/data/tap/empty
t/data/tap/junit/bad_chars
t/data/tap/junit/bailout
t/data/tap/junit/descriptive
t/data/tap/junit/descriptive_trailing
t/data/tap/junit/die
t/data/tap/junit/die_head_end
t/data/tap/junit/die_last_minute
t/data/tap/junit/die_unfinished
t/data/tap/junit/empty
t/data/tap/junit/no_nums
t/data/tap/junit/simple
t/data/tap/junit/simple_fail
t/data/tap/junit/simple_yaml
t/data/tap/junit/skip
t/data/tap/junit/skip_nomsg
t/data/tap/junit/skipall
t/data/tap/junit/skipall_nomsg
t/data/tap/junit/stdout_stderr
t/data/tap/junit/todo
t/data/tap/junit/todo_inline
t/data/tap/junit/todo_misparse
t/data/tap/junit/too_many
t/data/tap/no_nums
t/data/tap/simple
t/data/tap/simple_fail
t/data/tap/simple_yaml
t/data/tap/skip
t/data/tap/skip_nomsg
t/data/tap/skipall
t/data/tap/skipall_nomsg
t/data/tap/stdout_stderr
t/data/tap/todo
t/data/tap/todo_inline
t/data/tap/todo_misparse
t/data/tap/too_many
t/data/tests/bad_chars
t/data/tests/bailout
t/data/tests/descriptive
t/data/tests/descriptive_trailing
t/data/tests/die
t/data/tests/die_head_end
t/data/tests/die_last_minute
t/data/tests/die_unfinished
t/data/tests/empty
t/data/tests/junit/bad_chars
t/data/tests/junit/bailout
t/data/tests/junit/descriptive
t/data/tests/junit/descriptive_trailing
t/data/tests/junit/die
t/data/tests/junit/die_head_end
t/data/tests/junit/die_last_minute
t/data/tests/junit/die_unfinished
t/data/tests/junit/empty
t/data/tests/junit/no_nums
t/data/tests/junit/simple
t/data/tests/junit/simple_fail
t/data/tests/junit/simple_yaml
t/data/tests/junit/skip
t/data/tests/junit/skip_nomsg
t/data/tests/junit/skipall
t/data/tests/junit/skipall_nomsg
t/data/tests/junit/stdout_stderr
t/data/tests/junit/todo
t/data/tests/junit/todo_inline
t/data/tests/junit/todo_misparse
t/data/tests/junit/too_many
t/data/tests/no_nums
t/data/tests/simple
t/data/tests/simple_fail
t/data/tests/simple_yaml
t/data/tests/skip
t/data/tests/skip_nomsg
t/data/tests/skipall
t/data/tests/skipall_nomsg
t/data/tests/stdout_stderr
t/data/tests/todo
t/data/tests/todo_inline
t/data/tests/todo_misparse
t/data/tests/too_many
t/formatter.t
t/passing-todos.t
t/tap2junit-filter.t
t/tap2junit-name.t
t/tap2junit.t
t/timer.t
xt/author/clean-namespaces.t
xt/author/distmeta.t
xt/author/eof.t
xt/author/eol.t
xt/author/minimum-version.t
xt/author/no-breakpoints.t
xt/author/no-tabs.t
xt/author/pod-coverage.t
xt/author/pod-spell.t
xt/author/pod-syntax.t
xt/author/synopsis.t
xt/release/kwalitee.t
xt/release/unused-vars.t
xt/timer.t
META.yml100644001750001750 226214751004727 16301 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17---
abstract: 'Harness output delegate for JUnit output'
author:
- 'Graham TerMarsch '
build_requires:
ExtUtils::MakeMaker: '0'
File::Spec: '0'
File::Temp: '0'
IO::Handle: '0'
IO::Scalar: '0'
IPC::Open3: '0'
IPC::Run: '0'
Test::DiagINC: '0.002'
Test::More: '0.96'
Test::XML: '0'
version: '0'
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 0
generated_by: 'Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: TAP-Formatter-JUnit
no_index:
directory:
- local
- t
- xt
requires:
File::Slurp: '0'
Moose: '0'
MooseX::NonMoose: '0'
TAP::Harness: '3.12'
XML::Generator: '0'
namespace::clean: '0'
perl: '5.010'
resources:
bugtracker: https://github.com/bleargh45/TAP-Formatter-JUnit/issues
homepage: https://metacpan.org/release/TAP-Formatter-JUnit/
repository: git://github.com/bleargh45/TAP-Formatter-JUnit.git
version: '0.17'
x_generated_by_perl: v5.40.1
x_serialization_backend: 'YAML::Tiny version 1.76'
x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later'
x_static_install: 1
t000755001750001750 014751004727 15131 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17timer.t100644001750001750 270214751004727 16577 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t#!/usr/bin/perl
use strict;
use warnings;
use if $ENV{AUTOMATED_TESTING}, 'Test::DiagINC'; use Test::More tests => 4;
use TAP::Harness;
use IO::Scalar;
use File::Slurp qw(write_file);
###############################################################################
# When timer is disabled, we should have *NO* timer info in the JUnit output.
timer_disabled: {
my $test = qq|
use Test::More tests => 1;
pass 'no timing in this test';
|;
my $results = run_test($test, {
timer => 0,
} );
ok $results, 'got JUnit';
unlike $results, qr/time/ism, '... without any timing information';
}
###############################################################################
# When timer is enabled, JUnit output *should* have timer info in it.
timer_enabled: {
my $test = qq|
use Test::More tests => 2;
pass 'one';
pass 'two';
|;
my $results = run_test($test, {
timer => 1,
} );
ok $results, 'got JUnit';
like $results, qr/time/ism, '... with timing information';
}
sub run_test {
my $code = shift;
my $opts = shift;
my $file = "test-$$.t";
my $junit = undef;
my $fh = IO::Scalar->new(\$junit);
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
stdout => $fh,
%{$opts},
} );
write_file($file, $code);
$harness->runtests($file);
unlink $file;
return $junit;
}
META.json100644001750001750 551414751004727 16454 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17{
"abstract" : "Harness output delegate for JUnit output",
"author" : [
"Graham TerMarsch "
],
"dynamic_config" : 0,
"generated_by" : "Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"name" : "TAP-Formatter-JUnit",
"no_index" : {
"directory" : [
"local",
"t",
"xt"
]
},
"prereqs" : {
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"develop" : {
"requires" : {
"Dist::Zilla" : "5",
"Dist::Zilla::PluginBundle::Author::GTERMARS" : "0.04",
"Pod::Coverage::TrustPod" : "0",
"Software::License::Perl_5" : "0",
"Test::CPAN::Meta" : "0",
"Test::CleanNamespaces" : "0.15",
"Test::EOF" : "0",
"Test::EOL" : "0",
"Test::Kwalitee" : "1.21",
"Test::MinimumVersion" : "0",
"Test::More" : "0.88",
"Test::NoBreakpoints" : "0.15",
"Test::NoTabs" : "0",
"Test::Pod" : "1.41",
"Test::Pod::Coverage" : "1.08",
"Test::Spelling" : "0.17",
"Test::Synopsis" : "0",
"Test::Vars" : "0"
}
},
"runtime" : {
"requires" : {
"File::Slurp" : "0",
"Moose" : "0",
"MooseX::NonMoose" : "0",
"TAP::Harness" : "3.12",
"XML::Generator" : "0",
"namespace::clean" : "0",
"perl" : "5.010"
}
},
"test" : {
"recommends" : {
"CPAN::Meta" : "2.120900"
},
"requires" : {
"ExtUtils::MakeMaker" : "0",
"File::Spec" : "0",
"File::Temp" : "0",
"IO::Handle" : "0",
"IO::Scalar" : "0",
"IPC::Open3" : "0",
"IPC::Run" : "0",
"Test::DiagINC" : "0.002",
"Test::More" : "0.96",
"Test::XML" : "0",
"version" : "0"
}
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
"web" : "https://github.com/bleargh45/TAP-Formatter-JUnit/issues"
},
"homepage" : "https://metacpan.org/release/TAP-Formatter-JUnit/",
"repository" : {
"type" : "git",
"url" : "git://github.com/bleargh45/TAP-Formatter-JUnit.git",
"web" : "https://github.com/bleargh45/TAP-Formatter-JUnit"
}
},
"version" : "0.17",
"x_generated_by_perl" : "v5.40.1",
"x_serialization_backend" : "Cpanel::JSON::XS version 4.39",
"x_spdx_expression" : "Artistic-1.0-Perl OR GPL-1.0-or-later",
"x_static_install" : 1
}
xt000755001750001750 014751004727 15321 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17timer.t100644001750001750 726214751004727 16775 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 17;
use TAP::Harness;
use IO::Scalar;
use File::Slurp qw(write_file);
###############################################################################
# Ensure timing correctness, when test has a plan
#
# Test once with merged output off, then once with it on; want to make sure that
# merging diagnostic output into the TAP doesn't monkey up the timings.
correct_timing_test_has_plan: {
my $test = qq|
BEGIN { sleep 3 };
END { sleep 2 };
use Test::More tests => 3;
sleep 0; pass "one";
sleep 2; pass "two";
sleep 1; diag "foo";
sleep 1; diag "bar";
sleep 3; diag "foobar";
pass "three";
|;
my $expect = {
'(init)' => 3,
'1 - one' => 0,
'2 - two' => 2,
'3 - three' => 5,
'(teardown)' => 2,
};
unmerged: {
my $results = run_test($test, {
timer => 1,
merge => 0,
} );
ok $results, 'got JUnit - timing correctness w/test plan (unmerged)';
verify_timings($results, $expect);
}
merged: {
my $results = run_test($test, {
timer => 1,
merge => 1,
} );
ok $results, 'got JUnit - timing correctness w/test plan (merged)';
verify_timings($results, $expect);
}
}
###############################################################################
# Ensure timing correctness, when test has no plan
#
# The *first* test isn't going to be predictable/accurate w.r.t. the calculated
# timing, as it'll also involve the startup overhead. As such, its skipped (by
# denoting it as "skip" in its test name).
correct_timing_test_unplanned: {
my $test = qq|
BEGIN { sleep 3 };
END { sleep 2 };
use Test::More qw(no_plan);
sleep 0; pass "one";
sleep 2; pass "two";
sleep 1; diag "foo";
sleep 1; diag "bar";
sleep 3; diag "foobar";
pass "three";
|;
my $expect = {
'1 - one' => 3, # init time is *hidden* in initial test
'2 - two' => 2,
'3 - three' => 5,
'(teardown)' => 2,
};
my $results = run_test($test, {
timer => 1,
merge => 1,
} );
ok $results, 'got JUnit - timing correctness w/o test plan';
verify_timings($results, $expect);
}
sub run_test {
my $code = shift;
my $opts = shift;
my $file = "test-$$.t";
my $junit = undef;
my $fh = IO::Scalar->new(\$junit);
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
stdout => $fh,
%{$opts},
} );
write_file($file, $code);
$harness->runtests($file);
unlink $file;
return $junit;
}
sub verify_timings {
my $junit = shift;
my $expect = shift;
my @lines = split /^/, $junit;
my @tests = grep { /{$name}) {
rounds_to($time, $expect->{$name}, "... test timing: $name");
}
else {
fail "... unexpected test name: $name";
diag $test;
}
}
}
sub rounds_to {
my ($got, $expected, $message) = @_;
my $r_got = sprintf('%1.0f', $got);
my $r_expected = sprintf('%1.0f', $expected);
local $Test::Builder::Level = $Test::Builder::Level + 1;
is $r_got, $r_expected, $message;
}
Makefile.PL100644001750001750 346214751004727 17005 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.032.
use strict;
use warnings;
use 5.010;
use ExtUtils::MakeMaker;
my %WriteMakefileArgs = (
"ABSTRACT" => "Harness output delegate for JUnit output",
"AUTHOR" => "Graham TerMarsch ",
"CONFIGURE_REQUIRES" => {
"ExtUtils::MakeMaker" => 0
},
"DISTNAME" => "TAP-Formatter-JUnit",
"EXE_FILES" => [
"script/tap2junit"
],
"LICENSE" => "perl",
"MIN_PERL_VERSION" => "5.010",
"NAME" => "TAP::Formatter::JUnit",
"PREREQ_PM" => {
"File::Slurp" => 0,
"Moose" => 0,
"MooseX::NonMoose" => 0,
"TAP::Harness" => "3.12",
"XML::Generator" => 0,
"namespace::clean" => 0
},
"TEST_REQUIRES" => {
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"File::Temp" => 0,
"IO::Handle" => 0,
"IO::Scalar" => 0,
"IPC::Open3" => 0,
"IPC::Run" => 0,
"Test::DiagINC" => "0.002",
"Test::More" => "0.96",
"Test::XML" => 0,
"version" => 0
},
"VERSION" => "0.17",
"test" => {
"TESTS" => "t/*.t"
}
);
my %FallbackPrereqs = (
"ExtUtils::MakeMaker" => 0,
"File::Slurp" => 0,
"File::Spec" => 0,
"File::Temp" => 0,
"IO::Handle" => 0,
"IO::Scalar" => 0,
"IPC::Open3" => 0,
"IPC::Run" => 0,
"Moose" => 0,
"MooseX::NonMoose" => 0,
"TAP::Harness" => "3.12",
"Test::DiagINC" => "0.002",
"Test::More" => "0.96",
"Test::XML" => 0,
"XML::Generator" => 0,
"namespace::clean" => 0,
"version" => 0
);
unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
delete $WriteMakefileArgs{TEST_REQUIRES};
delete $WriteMakefileArgs{BUILD_REQUIRES};
$WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
}
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
WriteMakefile(%WriteMakefileArgs);
tap2junit.t100644001750001750 245214751004727 17401 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t#!/usr/bin/perl
use strict;
use warnings;
use if $ENV{AUTOMATED_TESTING}, 'Test::DiagINC'; use Test::More;
use Test::XML;
use File::Slurp qw(slurp);
use File::Spec;
###############################################################################
# Figure out how many TAP files we have to run. Yes, the results *ARE* going
# to be different when parsing the raw TAP output than when running under
# 'prove'; we won't have any context of "did the test die a horrible death?"
my @tests = grep { -f $_ } ;
plan tests => scalar(@tests);
###############################################################################
# Run each of the TAP files in turn through 'tap2junit', and compare the output
# to the expected JUnit output in each case.
my $null = File::Spec->devnull();
foreach my $test (@tests) {
(my $junit = $test) =~ s{/tap/}{/tap/junit/};
my $rc = system(qq{ $^X -Ilib script/tap2junit $test 2>$null });
my $outfile = "$test.xml";
my $received = slurp($outfile);
unlink $outfile;
my $expected = slurp($junit);
# Compare results (bearing in mind that some tests produce zero output, and
# thus cannot be parsed as XML)
if ($received || $expected) {
is_xml $received, $expected, $test;
}
else {
is $received, $expected, $test;
}
}
formatter.t100644001750001750 552414751004727 17467 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t#!/usr/bin/perl
use strict;
use warnings;
use if $ENV{AUTOMATED_TESTING}, 'Test::DiagINC'; use Test::More;
use Test::XML;
use File::Slurp qw(slurp);
use TAP::Harness;
use IO::Scalar;
use version;
###############################################################################
# Figure out how many tests we have to run.
#
# *MANY* thanks Andy Armstrong et al. for the fabulous set of tests in
# Test::Harness. :)
my @tests = grep { -f $_ } ;
plan tests => scalar(@tests);
###############################################################################
# Run each of the tests in turn, and compare the output to the expected JUnit
# output.
foreach my $test (@tests) {
# Where is the JUnit output we should be expecting?
(my $junit = $test) =~ s{/tests/}{/tests/junit/};
# Process TAP, and turn it into JUnit
my $received = '';
my $fh = IO::Scalar->new(\$received);
eval {
my $harness = TAP::Harness->new( {
stdout => $fh,
merge => 1,
formatter_class => 'TAP::Formatter::JUnit',
} );
$harness->runtests($test);
};
my $expected = slurp($junit);
# OVER-RIDE: With Test::Harness prior to v3.43, the "bailout" test would
# result in zero/no output. This was fixed in Test::Harness v3.43_0*
# development releases, but WE need to watch for and provide accommodations
# for newer/older versions.
unless (version->parse($TAP::Harness::VERSION) > version->parse(3.43)) {
if ($test =~ /bailout/) {
$expected = '';
}
}
# Skip this test if it is a bailout test, and we have a broken version of
# Test::Harness
SKIP: {
# Should we be skipping "bailout" tests, because of a broken
# Test::Harness?
#
# A handful of Test::Harness releases contained a bug which resulted in
# a double-summary being output on BAIL_OUT, and which affect our
# expected test output.
my $SKIP_BAILOUT = 0;
{
my $v_harness = version->parse($TAP::Harness::VERSION);
my $v_broken_at = version->parse("3.45_01");
my $v_fixed_at = version->parse("3.50");
$SKIP_BAILOUT = 1 if (
($v_harness >= $v_broken_at)
&&
($v_harness < $v_fixed_at)
);
}
skip "Broken Test::Harness installed; skipping BAIL_OUT test", 1 if ($SKIP_BAILOUT && ($test =~ /bailout/));
# Compare results (bearing in mind that some tests produce zero output, and
# thus cannot be parsed as XML)
if ($received || $expected) {
is_xml $received, $expected, $test
or diag "GOT: ", explain($received);
}
else {
is $received, $expected, $test
or diag "GOT: ", explain($received);
}
}
}
tap000755001750001750 014751004727 16626 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/datadie100644001750001750 014751004727 17360 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap01-compile.t100644001750001750 563214751004727 17332 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/tuse 5.006;
use strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.058
use if $ENV{AUTOMATED_TESTING}, 'Test::DiagINC'; use Test::More 0.94;
plan tests => 4 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
my @module_files = (
'TAP/Formatter/JUnit.pm',
'TAP/Formatter/JUnit/Result.pm',
'TAP/Formatter/JUnit/Session.pm'
);
my @scripts = (
'script/tap2junit'
);
# fake home for cpan-testers
use File::Temp;
local $ENV{HOME} = File::Temp::tempdir( CLEANUP => 1 );
my @switches = (
-d 'blib' ? '-Mblib' : '-Ilib',
);
use File::Spec;
use IPC::Open3;
use IO::Handle;
open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
my @warnings;
for my $lib (@module_files)
{
# see L
my $stderr = IO::Handle->new;
diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} }
$^X, @switches, '-e', "require q[$lib]"))
if $ENV{PERL_COMPILE_TEST_DEBUG};
my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-e', "require q[$lib]");
binmode $stderr, ':crlf' if $^O eq 'MSWin32';
my @_warnings = <$stderr>;
waitpid($pid, 0);
is($?, 0, "$lib loaded ok");
shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/
and not eval { +require blib; blib->VERSION('1.01') };
if (@_warnings)
{
warn @_warnings;
push @warnings, @_warnings;
}
}
foreach my $file (@scripts)
{ SKIP: {
open my $fh, '<', $file or warn("Unable to open $file: $!"), next;
my $line = <$fh>;
close $fh and skip("$file isn't perl", 1) unless $line =~ /^#!\s*(?:\S*perl\S*)((?:\s+-\w*)*)(?:\s*#.*)?$/;
@switches = (@switches, split(' ', $1)) if $1;
close $fh and skip("$file uses -T; not testable with PERL5LIB", 1)
if grep { $_ eq '-T' } @switches and $ENV{PERL5LIB};
my $stderr = IO::Handle->new;
diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} }
$^X, @switches, '-c', $file))
if $ENV{PERL_COMPILE_TEST_DEBUG};
my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-c', $file);
binmode $stderr, ':crlf' if $^O eq 'MSWin32';
my @_warnings = <$stderr>;
waitpid($pid, 0);
is($?, 0, "$file compiled ok");
shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/
and not eval { +require blib; blib->VERSION('1.01') };
# in older perls, -c output is simply the file portion of the path being tested
if (@_warnings = grep { !/\bsyntax OK$/ }
grep { chomp; $_ ne (File::Spec->splitpath($file))[2] } @_warnings)
{
warn @_warnings;
push @warnings, @_warnings;
}
} }
is(scalar(@warnings), 0, 'no warnings found')
or diag 'got warnings: ', explain(\@warnings) if $ENV{AUTHOR_TESTING};
BAIL_OUT("Compilation problems") if !Test::More->builder->is_passing;
skip100644001750001750 6314751004727 17616 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok 1
ok 2 # skip rain delay
ok 3
ok 4
ok 5
todo100644001750001750 5414751004727 17615 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5 todo 3 2;
ok 1
ok 2
not ok 3
ok 4
ok 5
author000755001750001750 014751004727 16623 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xteol.t100644001750001750 661114751004727 17733 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.19
use Test::More 0.88;
use Test::EOL;
my @files = (
'lib/TAP/Formatter/JUnit.pm',
'lib/TAP/Formatter/JUnit/Result.pm',
'lib/TAP/Formatter/JUnit/Session.pm',
'script/tap2junit',
't/00-report-prereqs.dd',
't/00-report-prereqs.t',
't/01-compile.t',
't/data/tap/bad_chars',
't/data/tap/bailout',
't/data/tap/descriptive',
't/data/tap/descriptive_trailing',
't/data/tap/die',
't/data/tap/die_head_end',
't/data/tap/die_last_minute',
't/data/tap/die_unfinished',
't/data/tap/empty',
't/data/tap/junit/bad_chars',
't/data/tap/junit/bailout',
't/data/tap/junit/descriptive',
't/data/tap/junit/descriptive_trailing',
't/data/tap/junit/die',
't/data/tap/junit/die_head_end',
't/data/tap/junit/die_last_minute',
't/data/tap/junit/die_unfinished',
't/data/tap/junit/empty',
't/data/tap/junit/no_nums',
't/data/tap/junit/simple',
't/data/tap/junit/simple_fail',
't/data/tap/junit/simple_yaml',
't/data/tap/junit/skip',
't/data/tap/junit/skip_nomsg',
't/data/tap/junit/skipall',
't/data/tap/junit/skipall_nomsg',
't/data/tap/junit/stdout_stderr',
't/data/tap/junit/todo',
't/data/tap/junit/todo_inline',
't/data/tap/junit/todo_misparse',
't/data/tap/junit/too_many',
't/data/tap/no_nums',
't/data/tap/simple',
't/data/tap/simple_fail',
't/data/tap/simple_yaml',
't/data/tap/skip',
't/data/tap/skip_nomsg',
't/data/tap/skipall',
't/data/tap/skipall_nomsg',
't/data/tap/stdout_stderr',
't/data/tap/todo',
't/data/tap/todo_inline',
't/data/tap/todo_misparse',
't/data/tap/too_many',
't/data/tests/bad_chars',
't/data/tests/bailout',
't/data/tests/descriptive',
't/data/tests/descriptive_trailing',
't/data/tests/die',
't/data/tests/die_head_end',
't/data/tests/die_last_minute',
't/data/tests/die_unfinished',
't/data/tests/empty',
't/data/tests/junit/bad_chars',
't/data/tests/junit/bailout',
't/data/tests/junit/descriptive',
't/data/tests/junit/descriptive_trailing',
't/data/tests/junit/die',
't/data/tests/junit/die_head_end',
't/data/tests/junit/die_last_minute',
't/data/tests/junit/die_unfinished',
't/data/tests/junit/empty',
't/data/tests/junit/no_nums',
't/data/tests/junit/simple',
't/data/tests/junit/simple_fail',
't/data/tests/junit/simple_yaml',
't/data/tests/junit/skip',
't/data/tests/junit/skip_nomsg',
't/data/tests/junit/skipall',
't/data/tests/junit/skipall_nomsg',
't/data/tests/junit/stdout_stderr',
't/data/tests/junit/todo',
't/data/tests/junit/todo_inline',
't/data/tests/junit/todo_misparse',
't/data/tests/junit/too_many',
't/data/tests/no_nums',
't/data/tests/simple',
't/data/tests/simple_fail',
't/data/tests/simple_yaml',
't/data/tests/skip',
't/data/tests/skip_nomsg',
't/data/tests/skipall',
't/data/tests/skipall_nomsg',
't/data/tests/stdout_stderr',
't/data/tests/todo',
't/data/tests/todo_inline',
't/data/tests/todo_misparse',
't/data/tests/too_many',
't/formatter.t',
't/passing-todos.t',
't/tap2junit-filter.t',
't/tap2junit-name.t',
't/tap2junit.t',
't/timer.t'
);
eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files;
done_testing;
eof.t100644001750001750 43714751004727 17705 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
use Test::More;
# Generated by Dist::Zilla::Plugin::Test::EOF 0.0600
eval "use Test::EOF";
plan skip_all => 'Test::EOF required to test for correct end of file flag' if $@;
all_perl_files_ok({ minimum_newlines => 1, maximum_newlines => 4 });
done_testing();
script000755001750001750 014751004727 16172 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17tap2junit100755001750001750 1123714751004727 20224 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/script#!/usr/bin/perl
use strict;
use warnings;
use TAP::Parser;
use TAP::Parser::Aggregator;
use TAP::Formatter::JUnit;
use Getopt::Long;
use Pod::Usage;
use IO::File;
use File::Slurp qw(slurp);
###############################################################################
# Read in our command line options.
my ($help, $man);
my $name;
my $verbose;
my $suffix = '.xml';
GetOptions(
'suffix=s' => \$suffix,
'verbose' => \$verbose,
'name|junit_name=s' => \$name,
'help|?' => \$help,
'man' => \$man,
) || pod2usage(1);
pod2usage(1) if ($help);
pod2usage( -exitstatus=>0, -verbose=>2 ) if ($man);
###############################################################################
# Get the names of all of the TAP files we're supposed to convert.
my @tap_files = @ARGV;
pod2usage(1) unless (@tap_files);
###############################################################################
# Convert all of the TAP files to JUnit.
foreach my $file (@tap_files) {
verbose( "converting TAP to JUnit: $file" );
# Slurp in the TAP.
my $tap = ($file eq '-')
? do { local $/; ; }
: slurp($file);
# Open up a FH for where we're going to dump the JUnit
my $fout;
if ($file eq '-') {
open $fout, '>&STDOUT'
|| die "can't dup STDOUT; $!\n";
}
else {
my $junit_file = "${file}${suffix}";
$fout = IO::File->new( $junit_file, '>' )
|| die "can't open '$junit_file' for writing; $!";
}
# Name the test; if one wasn't provided, name it after the file itself.
my $test_name = $name || $file;
# Convert the TAP to JUnit
eval {
# Create the TAP formatter, aggregator, and parser that we're going to
# use to convert the TAP to JUnit.
my $formatter = TAP::Formatter::JUnit->new( { stdout => $fout } );
my $aggregator = TAP::Parser::Aggregator->new();
my $parser = TAP::Parser->new( { tap => $tap } );
# Parse all of the TAP in this file.
$aggregator->start();
my $session = $formatter->open_test($test_name, $parser);
while (my $result = $parser->next()) {
$session->result($result);
}
$session->close_test();
$aggregator->add($file, $parser);
$aggregator->stop();
# Summarize the results (in JUnit)
$formatter->summary;
};
if ($@) {
warn $@;
}
$fout->close();
}
###############################################################################
# All done; exit peacefully.
exit;
sub verbose {
print "$_[0]\n" if ($verbose);
}
=head1 NAME
tap2junit - Converts TAP output to JUnit
=head1 SYNOPSIS
tap2junit [options] ...
Options:
--suffix Suffix for JUnit output files (default ".xml")
--verbose Display verbose status during conversion
--name Provide explicit name for the JUnit test
--help/-? Display brief help message
--man Display full documentation
=head1 DESCRIPTION
C converts TAP output to JUnit.
Give it a list of files containing TAP results and it will create a series of
F output files containing the JUnit representations of that TAP
contained in the files.
If you specify F<-> as the filename, C will read from STDIN and write
to STDOUT. You may also want to use the C<--name> option to name the test
explicitly (as the default name of "-" isn't going to make much sense).
=head1 OPTIONS
=over
=item B<--suffix EsuffixE>
Specifies the suffix which is appended to all of the input files, in order to
generate the filename for the JUnit XML file that is being output.
If you want to live dangerously and over-write your original TAP files, you can
set this to "" and your original TAP files will be over-written.
Defaults to F<.xml>
=item B<--verbose>
Display verbose status information during the conversion (telling you which TAP
file its working on).
=item B<--name EnameE>
Specifies an explicit name for the JUnit test. If no name is provided, a
default name will be constructed based on the full path of the TAP file being
processed.
This option has also been aliased as C<--junit_name> to provide compatibility
with a patch from Joe McMahon.
=item B<--help/-?>
Display brief help message.
=item B<--man>
Displays the full documentation.
=back
=head1 AUTHOR
Graham TerMarsch
=head1 COPYRIGHT
Copyright 2008-2010, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under the same
terms as Perl itself.
=head1 SEE ALSO
L.
=cut
empty100644001750001750 014751004727 17755 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/taptests000755001750001750 014751004727 17204 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/datadie100644001750001750 13114751004727 20003 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testseval "use vmsish 'hushed'" if ($^O eq 'VMS');
exit 1; # exit because die() can be noisy
passing-todos.t100644001750001750 260614751004727 20254 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t#!/usr/bin/perl
use strict;
use warnings;
use if $ENV{AUTOMATED_TESTING}, 'Test::DiagINC'; use Test::More tests => 6;
use TAP::Harness;
use IO::Scalar;
###############################################################################
# TEST: passing TODOs are normally treated as failure condition.
passing_todo_default_fail: {
my $results = undef;
my $fh = IO::Scalar->new(\$results);
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
stdout => $fh,
} );
$harness->runtests('t/data/tests/todo');
ok $results, 'Ran test with passing TODO';
like $results, qr/]+errors="1"/, '... with one error';
like $results, qr/TodoTestSucceeded/, '... passing TODO';
}
###############################################################################
# TEST: over-ride allows for passing TODOs to be treated as a pass.
passing_todo_ok: {
local $ENV{ALLOW_PASSING_TODOS} = 1;
my $results = undef;
my $fh = IO::Scalar->new(\$results);
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
stdout => $fh,
} );
$harness->runtests('t/data/tests/todo');
ok $results, 'Re-ran test with passing TODO';
like $results, qr/]+errors="0"/, '... with NO errors';
unlike $results, qr/TodoTestSucceeded/, '... passing TODO was OK';
}
simple100644001750001750 3614751004727 20141 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok 1
ok 2
ok 3
ok 4
ok 5
skip100644001750001750 12214751004727 20210 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint < 2;
use File::Slurp qw(slurp);
use File::Spec;
###############################################################################
# TEST: Run "tap2junit" and let it name the test in the JUnit automatically.
tap2junit_default_name: {
my $test_file = 't/data/tap/simple';
my $xml_file = "$test_file.xml";
_tap2junit($test_file);
my $xml = slurp($xml_file);
unlink $xml_file;
like $xml, qr/]+name="data_tap_simple"/m,
'default name based on TAP filename';
}
###############################################################################
# TEST: Run "tap2junit" with "--name" and rename a test
tap2junit_name: {
my $test_file = 't/data/tap/simple';
my $xml_file = "$test_file.xml";
_tap2junit($test_file, '--name', 'foo');
my $xml = slurp($xml_file);
unlink $xml_file;
like $xml, qr/]+name="foo"/m, 'name explicitly provided';
}
sub _tap2junit {
my @args = @_;
my $null = File::Spec->devnull();
system(qq{ $^X -Ilib script/tap2junit @args 2>$null });
}
bailout100644001750001750 7414751004727 20311 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok 1
ok 2
ok 3
Bail out! GERONIMMMOOOOOO!!!
ok 4
ok 5
no_nums100644001750001750 3014751004727 20320 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok
ok
not ok
ok
ok
skipall100644001750001750 2614751004727 20306 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..0 # skipping: rope
empty100644001750001750 6014751004727 20361 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests__END__
Used to exercise the "empty test" case.
too_many100644001750001750 5014751004727 20471 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..3
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
simple100644001750001750 7514751004727 20522 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint < 1;
use Test::XML;
use IPC::Run qw(run);
use File::Slurp qw(slurp);
###############################################################################
# TEST: Run "tap2junit" in filter mode (in STDIN, out STDOUT)
tap2junit_filter: {
my $tap = slurp('t/data/tap/simple');
my $xml = slurp('t/data/tap/junit/simple');
my @cmd = ($^X, '-Ilib', 'script/tap2junit', '--name' => 'data_tap_simple', '-');
my ($out, $err);
run \@cmd, \$tap, \$out, \$err or die $?;
is_xml $out, $xml, 'results generated on STDOUT';
}
bad_chars100644001750001750 12514751004727 20575 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..3
ok 1 - Control chars
ok 2 - Weird control chars
ok 3 - Unicode Þϴ쌇
junit000755001750001750 014751004727 17757 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tapdie100644001750001750 014751004727 20511 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junitbailout100644001750001750 23414751004727 20705 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests# Sleep makes Mac OS open3 race problem more repeatable
sleep 1;
print <
todo100644001750001750 101714751004727 21006 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
too_many100644001750001750 15514751004727 21075 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint < 1;
use ExtUtils::MakeMaker;
use File::Spec;
# from $version::LAX
my $lax_version_re =
qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
|
(?:\.[0-9]+) (?:_[0-9]+)?
) | (?:
v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
|
(?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
)
)/x;
# hide optional CPAN::Meta modules from prereq scanner
# and check if they are available
my $cpan_meta = "CPAN::Meta";
my $cpan_meta_pre = "CPAN::Meta::Prereqs";
my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
# Verify requirements?
my $DO_VERIFY_PREREQS = 1;
sub _max {
my $max = shift;
$max = ( $_ > $max ) ? $_ : $max for @_;
return $max;
}
sub _merge_prereqs {
my ($collector, $prereqs) = @_;
# CPAN::Meta::Prereqs object
if (ref $collector eq $cpan_meta_pre) {
return $collector->with_merged_prereqs(
CPAN::Meta::Prereqs->new( $prereqs )
);
}
# Raw hashrefs
for my $phase ( keys %$prereqs ) {
for my $type ( keys %{ $prereqs->{$phase} } ) {
for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
$collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
}
}
}
return $collector;
}
my @include = qw(
);
my @exclude = qw(
);
# Add static prereqs to the included modules list
my $static_prereqs = do './t/00-report-prereqs.dd';
# Merge all prereqs (either with ::Prereqs or a hashref)
my $full_prereqs = _merge_prereqs(
( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
$static_prereqs
);
# Add dynamic prereqs to the included modules list (if we can)
my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
my $cpan_meta_error;
if ( $source && $HAS_CPAN_META
&& (my $meta = eval { CPAN::Meta->load_file($source) } )
) {
$full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
}
else {
$cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source)
$source = 'static metadata';
}
my @full_reports;
my @dep_errors;
my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
# Add static includes into a fake section
for my $mod (@include) {
$req_hash->{other}{modules}{$mod} = 0;
}
for my $phase ( qw(configure build test runtime develop other) ) {
next unless $req_hash->{$phase};
next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
for my $type ( qw(requires recommends suggests conflicts modules) ) {
next unless $req_hash->{$phase}{$type};
my $title = ucfirst($phase).' '.ucfirst($type);
my @reports = [qw/Module Want Have/];
for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
next if grep { $_ eq $mod } @exclude;
my $want = $req_hash->{$phase}{$type}{$mod};
$want = "undef" unless defined $want;
$want = "any" if !$want && $want == 0;
if ($mod eq 'perl') {
push @reports, ['perl', $want, $]];
next;
}
my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
my $file = $mod;
$file =~ s{::}{/}g;
$file .= ".pm";
my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
if ($prefix) {
my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
$have = "undef" unless defined $have;
push @reports, [$mod, $want, $have];
if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
if ( $have !~ /\A$lax_version_re\z/ ) {
push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
}
elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
push @dep_errors, "$mod version '$have' is not in required range '$want'";
}
}
}
else {
push @reports, [$mod, $want, "missing"];
if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
push @dep_errors, "$mod is not installed ($req_string)";
}
}
}
if ( @reports ) {
push @full_reports, "=== $title ===\n\n";
my $ml = _max( map { length $_->[0] } @reports );
my $wl = _max( map { length $_->[1] } @reports );
my $hl = _max( map { length $_->[2] } @reports );
if ($type eq 'modules') {
splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
}
else {
splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
}
push @full_reports, "\n";
}
}
}
if ( @full_reports ) {
diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
}
if ( $cpan_meta_error || @dep_errors ) {
diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n";
}
if ( $cpan_meta_error ) {
my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n";
}
if ( @dep_errors ) {
diag join("\n",
"\nThe following REQUIRED prerequisites were not satisfied:\n",
@dep_errors,
"\n"
);
}
pass('Reported prereqs');
# vim: ts=4 sts=4 sw=4 et:
pod-spell.t100644001750001750 46214751004727 21031 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
use Test::More;
# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007006
use Test::Spelling 0.17;
use Pod::Wordlist;
add_stopwords();
all_pod_files_spelling_ok( qw( bin lib ) );
__DATA__
Formatter
Graham
JUnit
Result
Session
TAP
TerMarsch
cpan
lib
script
tap2junit
release000755001750001750 014751004727 16741 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xtkwalitee.t100644001750001750 27514751004727 21057 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/release# this test was generated with Dist::Zilla::Plugin::Test::Kwalitee 2.12
use strict;
use warnings;
use Test::More 0.88;
use Test::Kwalitee 1.21 'kwalitee_ok';
kwalitee_ok();
done_testing;
descriptive100644001750001750 21114751004727 21204 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok 1 Interlock activated
ok 2 Megathrusters are go
ok 3 Head formed
ok 4 Blazing sword formed
ok 5 Robeast destroyed
simple_fail100644001750001750 4614751004727 21135 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..5
ok 1
not ok 2
ok 3
ok 4
not ok 5
simple_yaml100644001750001750 32014751004727 21177 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tapTAP version 13
1..5
ok 1
ok 2
---
-
fnurk: skib
ponk: gleeb
-
bar: krup
foo: plink
...
ok 3
ok 4
---
expected:
- 1
- 2
- 4
got:
- 1
- pong
- 4
...
ok 5
todo_inline100644001750001750 22614751004727 21174 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..3
not ok 1 - Foo # TODO Just testing the todo interface.
ok 2 - Unexpected success # TODO Just testing the todo interface.
ok 3 - This is not todo
empty100644001750001750 014751004727 21106 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junitbad_chars100644001750001750 16414751004727 21156 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
00-report-prereqs.dd100644001750001750 564014751004727 21016 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/tdo { my $x = {
'configure' => {
'requires' => {
'ExtUtils::MakeMaker' => '0'
}
},
'develop' => {
'requires' => {
'Dist::Zilla' => '5',
'Dist::Zilla::PluginBundle::Author::GTERMARS' => '0.04',
'Pod::Coverage::TrustPod' => '0',
'Software::License::Perl_5' => '0',
'Test::CPAN::Meta' => '0',
'Test::CleanNamespaces' => '0.15',
'Test::EOF' => '0',
'Test::EOL' => '0',
'Test::Kwalitee' => '1.21',
'Test::MinimumVersion' => '0',
'Test::More' => '0.88',
'Test::NoBreakpoints' => '0.15',
'Test::NoTabs' => '0',
'Test::Pod' => '1.41',
'Test::Pod::Coverage' => '1.08',
'Test::Spelling' => '0.17',
'Test::Synopsis' => '0',
'Test::Vars' => '0'
}
},
'runtime' => {
'requires' => {
'File::Slurp' => '0',
'Moose' => '0',
'MooseX::NonMoose' => '0',
'TAP::Harness' => '3.12',
'XML::Generator' => '0',
'namespace::clean' => '0',
'perl' => '5.010'
}
},
'test' => {
'recommends' => {
'CPAN::Meta' => '2.120900'
},
'requires' => {
'ExtUtils::MakeMaker' => '0',
'File::Spec' => '0',
'File::Temp' => '0',
'IO::Handle' => '0',
'IO::Scalar' => '0',
'IPC::Open3' => '0',
'IPC::Run' => '0',
'Test::DiagINC' => '0.002',
'Test::More' => '0.96',
'Test::XML' => '0',
'version' => '0'
}
}
};
$x;
}pod-syntax.t100644001750001750 25214751004727 21235 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/author#!perl
# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
use strict; use warnings;
use Test::More;
use Test::Pod 1.41;
all_pod_files_ok();
die_head_end100644001750001750 2414751004727 21215 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tapok 1
ok 2
ok 3
ok 4
simple100644001750001750 65414751004727 21320 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
skip_nomsg100644001750001750 4614751004727 21400 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
todo100644001750001750 102114751004727 21357 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
skipall_nomsg100644001750001750 514751004727 21466 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..0
stdout_stderr100644001750001750 12214751004727 21571 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap# comments
ok 1
ok 2
ok 3
# comment
ok 4
# more ignored stuff
# and yet more
1..4
todo_misparse100644001750001750 4714751004727 21522 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..1
not ok 1 Hamlette # TODOORNOTTODO
bailout100644001750001750 71314751004727 21462 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
no_nums100644001750001750 101614751004727 21516 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
skipall100644001750001750 36614751004727 21466 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
descriptive100644001750001750 25014751004727 21565 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
pod-coverage.t100644001750001750 36514751004727 21507 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/author#!perl
# This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests.
use strict;
use warnings;
use Test::Pod::Coverage 1.08;
use Pod::Coverage::TrustPod;
all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' });
unused-vars.t100644001750001750 14214751004727 21517 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/releaseuse Test::More 0.96 tests => 1;
use Test::Vars;
subtest 'unused vars' => sub {
all_vars_ok();
};
die_unfinished100644001750001750 2414751004727 21622 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap1..4
ok 1
ok 2
ok 3
too_many100644001750001750 157414751004727 21676 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
die_head_end100644001750001750 15214751004727 21615 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
Formatter000755001750001750 014751004727 20023 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/lib/TAPJUnit.pm100644001750001750 1231614751004727 21575 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/lib/TAP/Formatterpackage TAP::Formatter::JUnit;
use Moose;
use MooseX::NonMoose;
extends qw(
TAP::Formatter::Console
);
use XML::Generator;
use TAP::Formatter::JUnit::Session;
use namespace::clean;
our $VERSION = '0.17';
has 'testsuites' => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] },
traits => [qw( Array )],
handles => {
add_testsuite => 'push',
},
);
has 'xml' => (
is => 'rw',
isa => 'XML::Generator',
lazy_build => 1,
);
sub _build_xml {
return XML::Generator->new(
':pretty',
':std',
'escape' => 'always,high-bit,even-entities',
'encoding' => 'UTF-8',
);
}
###############################################################################
# Subroutine: open_test($test, $parser)
###############################################################################
# Over-ridden 'open_test()' method.
#
# Creates a 'TAP::Formatter::JUnit::Session' session, instead of a console
# formatter session.
sub open_test {
my ($self, $test, $parser) = @_;
my $session = TAP::Formatter::JUnit::Session->new( {
name => $test,
formatter => $self,
parser => $parser,
passing_todo_ok => $ENV{ALLOW_PASSING_TODOS} ? 1 : 0,
} );
return $session;
}
###############################################################################
# Subroutine: summary()
###############################################################################
# Prints the summary report (in JUnit) after all tests are run.
sub summary {
my $self = shift;
return if $self->silent();
my @suites = @{$self->testsuites};
print { $self->stdout } $self->xml->testsuites( @suites );
}
1;
=for stopwords xml testsuites TODO parseable JUnitXSchema.xsd
=head1 NAME
TAP::Formatter::JUnit - Harness output delegate for JUnit output
=head1 SYNOPSIS
On the command line, with F:
=for test_synopsis BEGIN { die "SKIP: This isn't Perl, but shell" }
$ prove --formatter TAP::Formatter::JUnit ...
Or, in your own scripts:
use TAP::Harness;
# What TAP output did we save from a previous run, with
# PERL_TEST_HARNESS_DUMP_TAP=tap/
my @tests = glob("tap/*.t");
# Convert the TAP to JUnit
my $harness = TAP::Harness->new( {
formatter_class => 'TAP::Formatter::JUnit',
merge => 1,
} );
$harness->runtests(@tests);
=head1 DESCRIPTION
B
C provides JUnit output formatting for C.
By default (e.g. when run with F), the I test suite is gathered
together into a single JUnit XML document, which is then displayed on C.
You can, however, have individual JUnit XML files dumped for each individual
test, by setting C to a directory that you would
like the JUnit XML dumped to. Note, that this will B cause
C to dump the original TAP output into that directory as well (but
IMHO that's ok as you've now got the data in two parseable formats).
Timing information is included in the JUnit XML, I you specified C<--timer>
when you ran F.
In standard use, a "passing TODO" is treated as failure conditions (and is
reported as such in the generated JUnit). If you wish to treat these as a
"pass" and not a "fail" condition, setting C in your
environment will turn these into pass conditions.
The JUnit output generated is partial to being grokked by Hudson
(L). That's the build tool I'm using at the
moment and needed to be able to generate JUnit output for.
=head1 ATTRIBUTES
=over
=item testsuites
List-ref of test suites that have been executed.
=item xml
An C instance, to be used to generate XML output.
=back
=head1 METHODS
=over
=item open_test($test, $parser)
Over-ridden C method.
Creates a C session, instead of a console
formatter session.
=item summary()
Prints the summary report (in JUnit) after all tests are run.
=item add_testsuite($suite)
Adds the given XML test C<$suite> to the list of test suites that we've
executed and need to summarize.
=back
=head1 AUTHOR
Graham TerMarsch
Many thanks to Andy Armstrong and all those involved for the B set of
tests in C; they became the basis for the unit tests here.
Other thanks go out to those that have provided feedback, comments, or patches:
Mark Aufflick
Joe McMahon
Michael Nachbaur
Marc Abramowitz
Colin Robertson
Phillip Kimmey
Dave Lambley
=head1 COPYRIGHT
Copyright 2008-2010, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under the same
terms as Perl itself.
=head1 SEE ALSO
=over
=item L
=item L
=item L
=item L
=item L.
=back
=cut
die_last_minute100644001750001750 3114751004727 22010 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tapok 1
ok 2
ok 3
ok 4
1..4
bad_chars100644001750001750 107514751004727 21753 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
skipall_nomsg100644001750001750 3014751004727 22062 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint "1..0\n";
exit 0;
stdout_stderr100644001750001750 20314751004727 22147 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsuse Test::More 'no_plan';
diag 'comments';
ok 1;
ok 1;
ok 1;
diag 'comment';
ok 1;
diag 'more ignored stuff';
diag 'and yet more';
todo_misparse100644001750001750 7314751004727 22077 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <<'END';
1..1
not ok 1 Hamlette # TODOORNOTTODO
END
no_nums100644001750001750 102014751004727 22067 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
skipall100644001750001750 37014751004727 22037 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
bailout100644001750001750 57614751004727 22047 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
no-breakpoints.t100644001750001750 31414751004727 22061 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::NoBreakpoints 0.0.2
use Test::More 0.88;
use Test::NoBreakpoints 0.15;
all_files_no_breakpoints_ok();
done_testing;
skip_nomsg100644001750001750 42714751004727 22176 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
die_unfinished100644001750001750 15214751004727 22222 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
minimum-version.t100644001750001750 15414751004727 22266 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
use Test::More;
use Test::MinimumVersion;
all_minimum_version_from_metayml_ok();
descriptive100644001750001750 117014751004727 22362 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
simple_fail100644001750001750 120714751004727 22326 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
simple_yaml100644001750001750 114314751004727 22354 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
todo_inline100644001750001750 131214751004727 22342 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
die_last_minute100644001750001750 15714751004727 22417 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
clean-namespaces.t100644001750001750 36114751004727 22327 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/xt/authoruse strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::CleanNamespaces 0.006
use Test::More 0.94;
use Test::CleanNamespaces 0.15;
subtest all_namespaces_clean => sub { all_namespaces_clean() };
done_testing;
die_head_end100644001750001750 66314751004727 22377 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
skip_nomsg100644001750001750 43114751004727 22547 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
skipall_nomsg100644001750001750 35314751004727 22665 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
stdout_stderr100644001750001750 70414751004727 22730 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
todo_misparse100644001750001750 74214751004727 22675 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
descriptive100644001750001750 117214751004727 22742 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
simple_fail100644001750001750 121114751004727 22677 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
simple_yaml100644001750001750 114514751004727 22734 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
todo_inline100644001750001750 131414751004727 22722 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
descriptive_trailing100644001750001750 21114751004727 23075 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tapok 1 Interlock activated
ok 2 Megathrusters are go
ok 3 Head formed
ok 4 Blazing sword formed
ok 5 Robeast destroyed
1..5
die_unfinished100644001750001750 64614751004727 23005 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
die_head_end100644001750001750 100314751004727 22762 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
die_last_minute100644001750001750 61514751004727 23171 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
skipall_nomsg100644001750001750 35514751004727 23245 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
stdout_stderr100644001750001750 70614751004727 23310 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
todo_misparse100644001750001750 74414751004727 23255 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
JUnit000755001750001750 014751004727 21054 5ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/lib/TAP/FormatterResult.pm100644001750001750 175514751004727 23040 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/lib/TAP/Formatter/JUnitpackage TAP::Formatter::JUnit::Result;
use Moose;
use namespace::clean;
has 'time' => (
is => 'ro',
isa => 'Num',
required => 1,
);
has 'result' => (
is => 'ro',
isa => 'TAP::Parser::Result',
required => 1,
handles => [qw(
name
number
description
as_string
raw
is_test
is_plan
is_unplanned
is_ok
todo_passed
explanation
)],
);
1;
=head1 NAME
TAP::Formatter::JUnit::Result - Wrapper for a TAP result
=head1 DESCRIPTION
C is an internal class, used to wrap/augment
C objects with timing information.
B
=head1 AUTHOR
Graham TerMarsch
=head1 COPYRIGHT
Copyright 2011, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under the same
terms as Perl itself.
=cut
descriptive_trailing100644001750001750 25014751004727 23456 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/testsprint <
Session.pm100644001750001750 3301714751004727 23221 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/lib/TAP/Formatter/JUnitpackage TAP::Formatter::JUnit::Session;
use Moose;
use MooseX::NonMoose;
extends qw(
TAP::Formatter::Console::Session
);
use Storable qw(dclone);
use File::Path qw(mkpath);
use IO::File;
use TAP::Formatter::JUnit::Result;
use namespace::clean;
has 'testcases' => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] },
traits => [qw( Array )],
handles => {
add_testcase => 'push',
num_testcases => 'count',
},
);
has 'passing_todo_ok' => (
is => 'rw',
isa => 'Bool',
default => 0,
);
has '_queue' => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] },
traits => [qw( Array )],
handles => {
_queue_add => 'push',
},
);
###############################################################################
# Subroutine: _initialize($arg_for)
###############################################################################
# Custom initializer, so we can accept a new "passing_todo_ok" argument at
# instantiation time.
sub _initialize {
my ($self, $arg_for) = @_;
$arg_for ||= {};
my $passing_todo_ok = delete $arg_for->{passing_todo_ok};
$self->passing_todo_ok($passing_todo_ok);
return $self->SUPER::_initialize($arg_for);
}
###############################################################################
# Subroutine: result($result)
###############################################################################
# Called by the harness for each line of TAP it receives.
#
# Queues up all of the TAP output for later conversion to JUnit.
sub result {
my ($self, $result) = @_;
# except for a few things we don't want to process as a "test case", add
# the test result to the queue.
unless ( ($result->raw() =~ /^# Looks like you failed \d+ tests? of \d+/)
|| ($result->raw() =~ /^# Looks like you planned \d+ tests? but ran \d+/)
|| ($result->raw() =~ /^# Looks like your test died before it could output anything/)
) {
my $wrapped = TAP::Formatter::JUnit::Result->new(
'time' => $self->get_time,
'result' => $result,
);
$self->_queue_add($wrapped);
}
}
###############################################################################
# Subroutine: close_test()
###############################################################################
# Called to close the test session.
#
# Flushes the queue if we've got anything left in it, dumps the JUnit to disk
# (if necessary), and adds the XML for this test suite to our formatter.
sub close_test {
my $self = shift;
my $xml = $self->xml;
my $parser = $self->parser;
# Process the queued up TAP stream
my $is_first = 1;
my $t_start = $self->parser->start_time;
my $t_last_test = $t_start;
my $timer_enabled = $self->formatter->timer;
my $queue = $self->_queue;
my $index = 0;
while ($index < @{$queue}) {
my $result = $queue->[$index++];
# First line of output generates the "init" timing.
if ($is_first) {
if ($timer_enabled) {
unless ($result->is_test) {
my $duration = $result->time - $t_start;
my $case = $xml->testcase( {
'name' => _squeaky_clean('(init)'),
'time' => $duration,
} );
$self->add_testcase($case);
$t_last_test = $result->time;
}
}
$is_first = 0;
}
# Test output
if ($result->is_test) {
# how long did it take for this test?
my $duration = $result->time - $t_last_test;
# slurp in all of the content up until the next test
my $content = $result->as_string;
while ($index < @{$queue}) {
last if ($queue->[$index]->is_test);
last if ($queue->[$index]->is_plan);
my $stuff = $queue->[$index++];
$content .= "\n" . $stuff->as_string;
}
# create a failure/error element if the test was bogus
my $failure;
my $bogosity = $self->_check_for_test_bogosity($result);
if ($bogosity) {
my $cdata = $self->_cdata($content);
my $level = $bogosity->{level};
$failure = $xml->$level( {
type => $bogosity->{type},
message => $bogosity->{message},
}, $cdata );
}
# add this test to the XML stream
my $case = $xml->testcase(
{
'name' => _get_testcase_name($result),
(
$timer_enabled ? ('time' => $duration) : ()
),
},
$failure,
);
$self->add_testcase($case);
# update time of last test seen
$t_last_test = $result->time;
}
}
# track time for teardown, if needed
if ($timer_enabled) {
my $duration = $self->parser->end_time - $queue->[-1]->time;
my $case = $xml->testcase( {
'name' => _squeaky_clean('(teardown)'),
'time' => $duration,
} );
$self->add_testcase($case);
}
# collect up all of the captured test output
my $captured = join '', map { $_->raw . "\n" } @{$queue};
# if the test died unexpectedly, make note of that
my $die_msg;
my $exit = $parser->exit();
if ($exit) {
my $wstat = $parser->wait();
my $status = sprintf("%d (wstat %d, 0x%x)", $exit, $wstat, $wstat);
$die_msg = "Dubious, test returned $status";
}
# add system-out/system-err data, as raw CDATA
my $sys_out = 'system-out';
$sys_out = $xml->$sys_out($captured ? $self->_cdata($captured) : undef);
my $sys_err = 'system-err';
$sys_err = $xml->$sys_err($die_msg ? $self->_cdata("$die_msg\n") : undef);
# update the testsuite with aggregate info on this test suite
#
# tests - total number of tests run
# time - wallclock time taken for test run (floating point)
# failures - number of tests that we detected as failing
# errors - number of errors:
# - passing TODOs
# - if a plan was provided, mismatch between that and the
# number of actual tests that were run
# - either "no plan was issued" or "test died" (a dying test
# may not have a plan issued, but should still be considered
# a single error condition)
my $testsrun = $parser->tests_run() || 0;
my $time = $parser->end_time() - $parser->start_time();
my $failures = $parser->failed();
my $noplan = $parser->plan() ? 0 : 1;
my $planned = $parser->tests_planned() || 0;
my $num_errors = 0;
$num_errors += $parser->todo_passed() unless $self->passing_todo_ok();
$num_errors += abs($testsrun - $planned) if ($planned);
my $suite_err;
if ($die_msg) {
$suite_err = $xml->error( { message => $die_msg } );
$num_errors ++;
}
elsif ($noplan) {
$suite_err = $xml->error( { message => 'No plan in TAP output' } );
$num_errors ++;
}
elsif ($planned && ($testsrun != $planned)) {
$suite_err = $xml->error( { message => "Looks like you planned $planned tests but ran $testsrun." } );
}
my @tests = @{$self->testcases()};
my %attrs = (
'name' => _get_testsuite_name($self),
'tests' => $testsrun,
'failures' => $failures,
'errors' => $num_errors,
(
$timer_enabled ? ('time' => $time) : ()
),
);
my $testsuite = $xml->testsuite(\%attrs, @tests, $sys_out, $sys_err, $suite_err);
$self->formatter->add_testsuite($testsuite);
$self->dump_junit_xml($testsuite);
}
###############################################################################
# Subroutine: dump_junit_xml($testsuite)
###############################################################################
# Dumps the JUnit for the given XML '$testsuite', to the directory specified by
# 'PERL_TEST_HARNESS_DUMP_TAP'.
sub dump_junit_xml {
my ($self, $testsuite) = @_;
if (my $spool_dir = $ENV{PERL_TEST_HARNESS_DUMP_TAP}) {
my $spool = File::Spec->catfile($spool_dir, $self->name() . '.junit.xml');
# clone the testsuite; XML::Generator only lets us auto-vivify the
# CDATA sections *ONCE*.
$testsuite = dclone($testsuite);
# create target dir
my ($vol, $dir, undef) = File::Spec->splitpath($spool);
my $path = File::Spec->catpath($vol, $dir, '');
mkpath($path);
# create JUnit XML, and dump to disk
my $junit = $self->xml->xml($self->xml->testsuites($testsuite) );
my $fout = IO::File->new( $spool, '>:utf8' )
|| die "Can't write $spool ( $! )\n";
$fout->print($junit);
$fout->close();
}
}
###############################################################################
# Subroutine: xml()
###############################################################################
# Returns a new 'XML::Generator' to generate XML output. This is simply a
# shortcut to '$self->formatter->xml()'.
sub xml {
my $self = shift;
return $self->formatter->xml();
}
###############################################################################
# Checks for bogosity in the test result.
sub _check_for_test_bogosity {
my $self = shift;
my $result = shift;
if ($result->todo_passed() && !$self->passing_todo_ok()) {
return {
level => 'error',
type => 'TodoTestSucceeded',
message => $result->explanation(),
};
}
if ($result->is_unplanned()) {
return {
level => 'error',
type => 'UnplannedTest',
message => $result->as_string(),
};
}
if (not $result->is_ok()) {
return {
level => 'failure',
type => 'TestFailed',
message => $result->as_string(),
};
}
return;
}
###############################################################################
# Generates the name for a test case.
sub _get_testcase_name {
my $test = shift;
my $name = join(' ', $test->number(), _clean_test_description($test));
$name =~ s/\s+$//;
return $name;
}
###############################################################################
# Generates the name for the entire test suite.
sub _get_testsuite_name {
my $self = shift;
my $name = $self->name;
$name =~ s{^\./}{};
$name =~ s{^t/}{};
return _clean_to_java_class_name($name);
}
###############################################################################
# Cleans up the given string, removing any characters that aren't suitable for
# use in a Java class name.
sub _clean_to_java_class_name {
my $str = shift;
$str =~ s/[^-:_A-Za-z0-9]+/_/gs;
return $str;
}
###############################################################################
# Cleans up the description of the given test.
sub _clean_test_description {
my $test = shift;
my $desc = $test->description();
return _squeaky_clean($desc);
}
###############################################################################
# Creates a CDATA block for the given data (which is made squeaky clean first,
# so that JUnit parsers like Hudson's don't choke).
sub _cdata {
my ($self, $data) = @_;
$data = _squeaky_clean($data);
return $self->xml->xmlcdata($data);
}
###############################################################################
# Clean a string to the point that JUnit can't possibly have a problem with it.
sub _squeaky_clean {
my $string = shift;
# control characters (except CR and LF)
$string =~ s/([\x00-\x09\x0b\x0c\x0e-\x1f])/"^".chr(ord($1)+64)/ge;
# high-byte characters
$string =~ s/([\x7f-\xff])/'[\\x'.sprintf('%02x',ord($1)).']'/ge;
return $string;
}
1;
=for stopwords instantiation testcases
=head1 NAME
TAP::Formatter::JUnit::Session - Harness output delegate for JUnit output
=head1 DESCRIPTION
C provides JUnit output formatting for
C.
=head1 METHODS
=over
=item _initialize($arg_for)
Over-ridden private initializer, so we can accept a new "passing_todo_ok"
argument at instantiation time.
=item result($result)
Called by the harness for each line of TAP it receives.
Internally, all of the TAP is added to a queue until we hit the start of
the "next" test (at which point we flush the queue. This allows us to
capture any error output or diagnostic info that comes after a test
failure.
=item close_test()
Called to close the test session.
Flushes the queue if we've got anything left in it, dumps the JUnit to disk
(if necessary), and adds the XML for this test suite to our formatter.
=item dump_junit_xml($testsuite)
Dumps the JUnit for the given XML C<$testsuite>, to the directory specified
by C.
=item add_testcase($case)
Adds an XML test C<$case> to the list of testcases we've run in this
session.
=item xml()
Returns a new C to generate XML output. This is simply a
shortcut to C<$self-Eformatter-Exml()>.
=back
=head1 AUTHOR
Graham TerMarsch
=head1 COPYRIGHT
Copyright 2008-2010, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under the same
terms as Perl itself.
=head1 SEE ALSO
L.
=cut
die_last_minute100644001750001750 101314751004727 23560 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit
descriptive_trailing100644001750001750 120114751004727 24246 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tap/junit
descriptive_trailing100644001750001750 120314751004727 24626 0ustar00grahamgraham000000000000TAP-Formatter-JUnit-0.17/t/data/tests/junit