Devel-Cover-Report-Clover-1.01000755000765000024 013031625233 17012 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/Build.PL000555000765000024 250713031625233 20452 0ustar00davidbartlestaff000000000000#!perl use Module::Build; my $build = Module::Build->new( module_name => 'Devel::Cover::Report::Clover', create_makefile_pl => 'traditional', create_readme => 'README', license => 'perl', no_index => { 'directory' => [ 'cover_db_test', 't', ], }, requires => { 'Class::Accessor' => 0, 'Devel::Cover' => 0, 'HTML::Parser' => 0, # For HTML::Entities 'Template' => 0, }, recommends => { 'Test::MockTime' => 0, }, build_requires => { 'Devel::Cover' => '0', 'File::Path' => '2.06', 'File::Which' => '1.08', 'FindBin' => '0', 'List::Util' => '0', 'TAP::Harness' => '0', 'Test::Exception' => '0', 'Test::MockObject' => '0', 'Test::More' => '0', }, meta_add => { resources => { license => 'http://dev.perl.org/licenses/', homepage => 'https://github.com/captin411/devel-cover-report-clover', repository => 'https://github.com/captin411/devel-cover-report-clover.git', bugtracker => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Cover-Report-Clover', }, }, ); $build->add_build_element('tt'); $build->create_build_script; Devel-Cover-Report-Clover-1.01/CHANGES000444000765000024 1047513031625233 20171 0ustar00davidbartlestaff000000000000Devel::Cover::Report::Clover.pm history Release 1.01 - 30th December 2016 - Updated versioning for CPAN indexing Release 1.00 - 30th December 2016 - Added branch, statement, and subroutine details thanks to Oliver Trosien Release 0.35 - 13th March 2012 - Fix RT#75376 thanks to Olivier Mengué - unit tests pass when using local::lib based installs Release 0.34 - 27th February 2012 - dist version mistake Release 0.32 - 27th February 2012 - use the package name 'main' instead of '' - sort the package names Release 0.31 - 25th October 2011 - BUG: if summary was empty the script would die - minor documentation adjustments Release 0.30 - 18th October 2011 - BUG: report was being written twice for no reason - BUG: branch+condition needs to be the default - BUG: make sure to pass project name from the command line - BUG: element (and covered element) totals were wrong and sometimes even zero - More tests for end to end testing to ensure files are written - Refactored metrics call to reduce duplication. Tests to help test this refactor. - a few less undef warnings Release 0.29 - 17th October 2011 - Decided to take out command existance prereq testing out of the Build.PL and Makefile.PL sections. Will try and solve the missing command problems in other ways to prevent cpan tests from exploding Release 0.28 - 17th October 2011 - One more place to find 'perl' binary '$^X' - One more place to find 'cover' binary '$Devel::Cover::Inc::Base' Release 0.27 - 15th October 2011 - Per http://wiki.cpantesters.org/wiki/CPANAuthorNotes, exit(0) if we're running in automated testing mode and the 'cover' command line program was not found (it's a dependency for testing). Release 0.26 - 15th October 2011 - Try and find perl related commands based on the Config module paths rather than the unix 'which' command. Same with the perl command. Release 0.25 - 15th October 2011 - I'm not good at TAP::Harness Release 0.24 - 15th October 2011 - tests in verbose mode failed cause of system command STDOUT spewing. - use TAP::Harness for testing the tests instead of 'prove' Release 0.23 - 15th October 2011 - test setup script no longer blindly tries to delete a (nonexistant) cover_db. Release 0.22 - 15th October 2011 - clover.tt file no longer missing when using Makefile.PL Release 0.21 - 15th October 2011 - Fix for tests for working paths containing spaces - Added explicit license file . License was listed in makefile but some tools like it spelled out in a text file. Release 0.20 - 15th October 2011 - Fairly substantial change to the Clover stats for 'conditionals' / 'coveredconditionals'. Previous to this version, it was only the Devel::Cover 'branch' metric. Now it is the summation of the 'branch' and 'condition' criterion. - Bug fixed where Class/FileFragment objects were not being created with a builder. - Lots more unit tests Release 0.11 - 14th October 2011 - prevent tests from being indexed on CPAN - support older template toolkit versions w/o 'xml' filter - Test::MockTime is now only recommended - die if test system() calls fail - more specific testing of keys in the summarize() methods Release 0.10 - 13th October 2011 - Backend refactor to promote testability A lot of these changes were made to help map the Perl package model into the Java package model. In Perl, a "package" is named, for example, Devel::Cover. In Java, the package would be "Devel" and the class would be "Cover". Many tools and file formats based on Java tech presume this sort of hierarchy. Thus, the backend was rewritten to take this into account for the Clover xml file format. The backend also allows metric summaries to be calculated from the Devel::Cover database on particular ranges in a source file rather than presuming they should be calculated on the entire file all at once. - Also, noted that the extended format of the file with per-line annotations is really no use to implement. After digging into the source code of the Clover ant stuff for the Jenkins plugin, it only parses the metric summaries. Release 0.09 - 11th October 2011 - refactor template variable creation to help make testing easier - fixed a bug with methods_covered being set improperly to methods Release 0.08 - 11th October 2011 - first stable release Devel-Cover-Report-Clover-1.01/INSTALL000444000765000024 76113031625233 20164 0ustar00davidbartlestaff000000000000 Installation instructions for Devel::Cover::Report::Clover To install this module, just do: perl Build.PL ./Build ./Build test ./Build install (this step may need to be done as the superuser) If you really want to, you can use a more traditional Makefile.PL: perl Makefile.PL make test make install (this step may need to be done as the superuser) There's heaps more information in the README and in the documentation of the various packages in this distribution. Devel-Cover-Report-Clover-1.01/LICENSE000444000765000024 2135513031625233 20202 0ustar00davidbartlestaff000000000000 The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Devel-Cover-Report-Clover-1.01/Makefile.PL000444000765000024 145313031625233 21124 0ustar00davidbartlestaff000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.4003 use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'Devel::Cover::Report::Clover', 'INSTALLDIRS' => 'site', 'PL_FILES' => {}, 'VERSION_FROM' => 'lib/Devel/Cover/Report/Clover.pm', 'PREREQ_PM' => { 'Class::Accessor' => 0, 'File::Which' => '1.08', 'Test::MockObject' => 0, 'File::Path' => '2.06', 'TAP::Harness' => 0, 'Template' => 0, 'Test::Exception' => 0, 'FindBin' => 0, 'Test::More' => 0, 'Devel::Cover' => 0, 'List::Util' => 0, 'HTML::Parser' => 0 }, 'EXE_FILES' => [] ) ; Devel-Cover-Report-Clover-1.01/MANIFEST000444000765000024 163613031625233 20306 0ustar00davidbartlestaff000000000000Build.PL CHANGES cover_db_test/Empty/Empty.pm cover_db_test/Empty/Empty.t cover_db_test/multi_file/MultiFile/First.pm cover_db_test/multi_file/MultiFile/Second.pm cover_db_test/multi_file/MultiFile.pm cover_db_test/multi_file/MultiFile.t cover_db_test/multi_package/MultiPackage.pm cover_db_test/multi_package/MultiPackage.t LICENSE Makefile.PL INSTALL lib/Devel/Cover/Report/Clover/Builder.pm lib/Devel/Cover/Report/Clover/Class.pm lib/Devel/Cover/Report/Clover/File.pm lib/Devel/Cover/Report/Clover/FileRegistry.pm lib/Devel/Cover/Report/Clover/Package.pm lib/Devel/Cover/Report/Clover/Project.pm lib/Devel/Cover/Report/Clover/Reportable.pm lib/Devel/Cover/Report/Clover/clover.tt lib/Devel/Cover/Report/Clover.pm MANIFEST This list of files README TODO t/00.load.t t/basic.t t/builder.t t/class.t t/end_to_end.t t/end_to_end_no_stats.t t/file.t t/file_registry.t t/package.t t/project.t t/testcover.pm META.yml META.json Devel-Cover-Report-Clover-1.01/META.json000444000765000024 630313031625233 20572 0ustar00davidbartlestaff000000000000{ "abstract" : "Backend for Clover reporting of coverage statistics", "author" : [ "David Bartle " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4003, CPAN::Meta::Converter version 2.143240", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Devel-Cover-Report-Clover", "no_index" : { "directory" : [ "cover_db_test", "t" ] }, "prereqs" : { "build" : { "requires" : { "Devel::Cover" : "0", "File::Path" : "2.06", "File::Which" : "1.08", "FindBin" : "0", "List::Util" : "0", "TAP::Harness" : "0", "Test::Exception" : "0", "Test::MockObject" : "0", "Test::More" : "0" } }, "configure" : { "requires" : { "Module::Build" : "0.40" } }, "runtime" : { "recommends" : { "Test::MockTime" : "0" }, "requires" : { "Class::Accessor" : "0", "Devel::Cover" : "0", "HTML::Parser" : "0", "Template" : "0" } } }, "provides" : { "Devel::Cover::Report::Clover" : { "file" : "lib/Devel/Cover/Report/Clover.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::Builder" : { "file" : "lib/Devel/Cover/Report/Clover/Builder.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::Class" : { "file" : "lib/Devel/Cover/Report/Clover/Class.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::File" : { "file" : "lib/Devel/Cover/Report/Clover/File.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::FileFragment" : { "file" : "lib/Devel/Cover/Report/Clover/File.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::FileRegistry" : { "file" : "lib/Devel/Cover/Report/Clover/FileRegistry.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::Package" : { "file" : "lib/Devel/Cover/Report/Clover/Package.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::PackageFile" : { "file" : "lib/Devel/Cover/Report/Clover/Package.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::Project" : { "file" : "lib/Devel/Cover/Report/Clover/Project.pm", "version" : "1.01" }, "Devel::Cover::Report::Clover::Reportable" : { "file" : "lib/Devel/Cover/Report/Clover/Reportable.pm", "version" : "1.01" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Cover-Report-Clover" }, "homepage" : "https://github.com/captin411/devel-cover-report-clover", "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "https://github.com/captin411/devel-cover-report-clover.git" } }, "version" : "1.01" } Devel-Cover-Report-Clover-1.01/META.yml000444000765000024 421313031625233 20420 0ustar00davidbartlestaff000000000000--- abstract: 'Backend for Clover reporting of coverage statistics' author: - 'David Bartle ' build_requires: Devel::Cover: '0' File::Path: '2.06' File::Which: '1.08' FindBin: '0' List::Util: '0' TAP::Harness: '0' Test::Exception: '0' Test::MockObject: '0' Test::More: '0' configure_requires: Module::Build: '0.40' dynamic_config: 1 generated_by: 'Module::Build version 0.4003, CPAN::Meta::Converter version 2.143240' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Devel-Cover-Report-Clover no_index: directory: - cover_db_test - t provides: Devel::Cover::Report::Clover: file: lib/Devel/Cover/Report/Clover.pm version: '1.01' Devel::Cover::Report::Clover::Builder: file: lib/Devel/Cover/Report/Clover/Builder.pm version: '1.01' Devel::Cover::Report::Clover::Class: file: lib/Devel/Cover/Report/Clover/Class.pm version: '1.01' Devel::Cover::Report::Clover::File: file: lib/Devel/Cover/Report/Clover/File.pm version: '1.01' Devel::Cover::Report::Clover::FileFragment: file: lib/Devel/Cover/Report/Clover/File.pm version: '1.01' Devel::Cover::Report::Clover::FileRegistry: file: lib/Devel/Cover/Report/Clover/FileRegistry.pm version: '1.01' Devel::Cover::Report::Clover::Package: file: lib/Devel/Cover/Report/Clover/Package.pm version: '1.01' Devel::Cover::Report::Clover::PackageFile: file: lib/Devel/Cover/Report/Clover/Package.pm version: '1.01' Devel::Cover::Report::Clover::Project: file: lib/Devel/Cover/Report/Clover/Project.pm version: '1.01' Devel::Cover::Report::Clover::Reportable: file: lib/Devel/Cover/Report/Clover/Reportable.pm version: '1.01' recommends: Test::MockTime: '0' requires: Class::Accessor: '0' Devel::Cover: '0' HTML::Parser: '0' Template: '0' resources: bugtracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Cover-Report-Clover homepage: https://github.com/captin411/devel-cover-report-clover license: http://dev.perl.org/licenses/ repository: https://github.com/captin411/devel-cover-report-clover.git version: '1.01' Devel-Cover-Report-Clover-1.01/README000444000765000024 325113031625233 20030 0ustar00davidbartlestaff000000000000NAME Devel::Cover::Report::Clover - Backend for Clover reporting of coverage statistics SYNOPSIS cover -report clover DESCRIPTION This module generates a Clover compatible coverage xml file which can be used in a variety of continuous integration software offerings. It is designed to be called from the `cover' program distributed with Devel::Cover. OPTIONS Options are specified by adding the appropriate flags to the `cover' program. This report format supports the following: outputfile This will be the file name that you would like to write this report out to. It defaults to clover.xml. projectname This is simply a cosmetic item. When the xml is generated, it has a project name which will show up in your continuous integration system once it is parsed. This can be any string you want and it defaults to 'Devel::Cover::Report::Clover'. SEE ALSO Devel::Cover http://www.atlassian.com/software/clover/ http://jenkins-ci.org/ https://wiki.jenkins-ci.org/display/JENKINS/Clover+Plugin BUGS https://github.com/captin411/Devel-Cover-Report-Clover/issues CREDITS Jun Kuriyama - nice cosmetic changes to package names Olivier Mengué - fix tests for those using local::lib Oliver Trosien - added branch, statement, and subroutine details AUTHOR David Bartle LICENSE Copyright David Bartle (captindave@gmail.com) This software is free. It is licensed under the same terms as Perl itself. The latest version of this software should be available on github.com https://github.com/captin411/Devel-Cover-Report-Clover Devel-Cover-Report-Clover-1.01/TODO000444000765000024 14713031625233 17621 0ustar00davidbartlestaff000000000000- possibly integrate (optional) Perl::Metrics::Simple for mccabe/cyclomatic complexity calculations Devel-Cover-Report-Clover-1.01/cover_db_test000755000765000024 013031625233 21634 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/cover_db_test/Empty000755000765000024 013031625233 22732 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/cover_db_test/Empty/Empty.pm000444000765000024 7113031625233 24461 0ustar00davidbartlestaff000000000000package Empty; =item go test pod =cut sub go { } 1; Devel-Cover-Report-Clover-1.01/cover_db_test/Empty/Empty.t000444000765000024 6713031625233 24315 0ustar00davidbartlestaff000000000000#!perl use Test::More tests => 1; ok( 1, 'Empty.t' ); Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file000755000765000024 013031625233 23765 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file/MultiFile.pm000444000765000024 77313031625233 26341 0ustar00davidbartlestaff000000000000package MultiFile; use MultiFile::First; use MultiFile::Second; =item go ... go gadget tester =cut sub go { my $x = 1 + MultiFile::First::go() + MultiFile::Second::go(); return $x; } 1; package MultiFile::Sub; use MultiFile::First; use MultiFile::Second; sub go { my $x = 1 + MultiFile::First::go() + MultiFile::Second::go(); my $y = shift || 0; if( $x < $y ) { return $y; } else { return $x; } } 1; __END__ =head1 Test pod more here and here =cut Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file/MultiFile.t000444000765000024 31013031625233 26153 0ustar00davidbartlestaff000000000000#!perl use FindBin qw($Bin); use Test::More tests => 1; use lib "$Bin"; use MultiFile; use MultiFile::First; use MultiFile::Second; my $ret = MultiFile::go(); # 8 is($ret,8,"call three functions"); Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file/MultiFile000755000765000024 013031625233 25657 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file/MultiFile/First.pm000444000765000024 11113031625233 27412 0ustar00davidbartlestaff000000000000package MultiFile::First; sub go { my $a = 2; return $a; } 1; Devel-Cover-Report-Clover-1.01/cover_db_test/multi_file/MultiFile/Second.pm000444000765000024 11113031625233 27536 0ustar00davidbartlestaff000000000000package MultiFile::Second; sub go { my $b = 5; return $b; } 1; Devel-Cover-Report-Clover-1.01/cover_db_test/multi_package000755000765000024 013031625233 24441 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/cover_db_test/multi_package/MultiPackage.pm000444000765000024 21613031625233 27461 0ustar00davidbartlestaff000000000000package MultiPackage; sub go { my $x = 1; return $x; } 1; package MultiPackage::Sub; sub go { my $x = 1; return $x; } 1; Devel-Cover-Report-Clover-1.01/cover_db_test/multi_package/MultiPackage.t000444000765000024 21613031625233 27310 0ustar00davidbartlestaff000000000000#!perl use FindBin qw($Bin); use Test::More tests => 1; use lib $Bin; use MultiPackage; MultiPackage::go(); MultiPackage::Sub::go(); ok(1); Devel-Cover-Report-Clover-1.01/lib000755000765000024 013031625233 17560 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/lib/Devel000755000765000024 013031625233 20617 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/lib/Devel/Cover000755000765000024 013031625233 21675 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report000755000765000024 013031625233 23150 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover.pm000444000765000024 604113031625233 25076 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover; use strict; use warnings; our $VERSION = "1.01"; use Devel::Cover::Report::Clover::Builder; use Getopt::Long; # Entry point which C uses sub report { my ( $pkg, $db, $options ) = @_; my $report = builder( $db, $options ); my $outfile = output_file($options); printf( "Writing clover output file to '%s'...\n", $outfile ) unless $options->{silent}; $report->generate($outfile); } #extend the options for the C command line sub get_options { my ( $self, $opt ) = @_; $opt->{option}{outputfile} = "clover.xml"; $opt->{option}{projectname} = "Devel::Cover::Report::Clover"; die "Invalid command line options" unless GetOptions( $opt->{option}, qw( outputfile=s projectname=s ) ); } sub output_file { my ($options) = @_; my $out_dir = $options->{outputdir}; my $out_file = $options->{option}{outputfile}; my $out_path = sprintf( '%s/%s', $out_dir, $out_file ); return $out_path; } sub builder { my ( $db, $options ) = @_; my $project_name = $options->{option}{projectname}; my $report = Devel::Cover::Report::Clover::Builder->new( { db => $db, name => $project_name, include_condition_criteria => 1 } ); } 1; __END__ =head1 NAME Devel::Cover::Report::Clover - Backend for Clover reporting of coverage statistics =head1 SYNOPSIS cover -report clover =head1 DESCRIPTION This module generates a Clover compatible coverage xml file which can be used in a variety of continuous integration software offerings. It is designed to be called from the C program distributed with L. =head1 OPTIONS Options are specified by adding the appropriate flags to the C program. This report format supports the following: =over 4 =item outputfile This will be the file name that you would like to write this report out to. It defaults to F. =item projectname This is simply a cosmetic item. When the xml is generated, it has a project name which will show up in your continuous integration system once it is parsed. This can be any string you want and it defaults to 'Devel::Cover::Report::Clover'. =back =head1 SEE ALSO L L L L =head1 BUGS L =head1 CREDITS Jun Kuriyama - nice cosmetic changes to package names Olivier Mengué - fix tests for those using local::lib Oliver Trosien - added branch, statement, and subroutine details =head1 AUTHOR David Bartle =head1 LICENSE Copyright David Bartle (captindave@gmail.com) This software is free. It is licensed under the same terms as Perl itself. The latest version of this software should be available on github.com https://github.com/captin411/Devel-Cover-Report-Clover =cut Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover000755000765000024 013031625233 24402 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/Builder.pm000444000765000024 370313031625233 26466 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::Builder; use Template; use File::Basename qw(dirname); use Devel::Cover::Report::Clover; use Devel::Cover::Report::Clover::Project; use Devel::Cover::Report::Clover::FileRegistry; use strict; use warnings; our $VERSION = "1.01"; use base qw(Class::Accessor); __PACKAGE__->mk_ro_accessors(qw(db)); __PACKAGE__->mk_accessors(qw(name file_registry project include_condition_criteria )); sub new { my $class = shift; my $self = $class->SUPER::new(@_); if ( !defined $self->include_condition_criteria ) { $self->include_condition_criteria(1); } my %summary_options = map( ( $_ => 1 ), $self->db->collected ); $summary_options{total} = 1; $self->db->calculate_summary(%summary_options); $self->project( Devel::Cover::Report::Clover::Project->new( { builder => $self, name => $self->name } ) ); $self->file_registry( Devel::Cover::Report::Clover::FileRegistry->new( { builder => $self } ) ); return $self; } sub generate { my ( $self, $outfile ) = @_; my $xml = $self->report_xml(); die("undef is a terrible file name") if !defined $outfile; open( my $fh, '>', $outfile ) or die($!); print {$fh} $xml; close($fh); return $xml; } sub report { my ($self) = @_; my $data = { project => $self->project->report(), generated => time(), generated_by => 'Devel::Cover::Report::Clover', version => $Devel::Cover::Report::Clover::VERSION, }; return $data; } sub report_xml { my ($self) = @_; my $tt = Template->new( { INCLUDE_PATH => $self->template_dir, } ); my $out = ''; my $vars = $self->report(); $tt->process( $self->template_file, $vars, \$out ) || die $tt->error(); return $out; } sub accept_criteria { return qw( statement branch condition subroutine ); } sub template_file { 'clover.tt'; } sub template_dir { sprintf( '%s', dirname(__FILE__) ); } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/Class.pm000444000765000024 167713031625233 26155 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::Class; use strict; use warnings; our $VERSION = "1.01"; use base qw(Devel::Cover::Report::Clover::Reportable); __PACKAGE__->mk_accessors(qw( name package file_fragment )); sub full_name { my ($self) = @_; return join '::', grep {$_} ( $self->package, $self->name ); } sub report { my ($self) = @_; my $name = $self->name() || ''; ( my $name_dotted = $name ) =~ s/\W+/./g; my $data = { name => $name, name_dotted => $name_dotted, metrics => $self->metrics(), lines => $self->file_fragment()->lines() }; return $data; } sub metrics { my ($self) = @_; return $self->SUPER::metrics(); } sub loc { my ($self) = @_; return $self->file_fragment->loc(); } sub ncloc { my ($self) = @_; return $self->file_fragment->ncloc(); } sub summarize { my ($self) = @_; return $self->file_fragment->summarize(); } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/clover.tt000444000765000024 637313031625233 26413 0ustar00davidbartlestaff000000000000 [%- pj = project; m = project.metrics; %] [%- FOREACH package IN pj.packages; SET p = package.metrics; %] [%- FOREACH file IN package.files; SET f = file.metrics; %] [%- FOREACH class IN file.classes; SET c = class.metrics; %] [%- END %] [%- FOREACH class IN file.classes; %][%- FOREACH line IN class.lines %][%- FOREACH statement IN line.criteria.statement %] [% END %][%- FOREACH branch IN line.criteria.branch %] [% END %][%- FOREACH subroutine IN line.criteria.subroutine %] [% END %][% END %][% END %] [%- END %] [%- END %] Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/File.pm000444000765000024 1721413031625233 26001 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::File; use strict; use warnings; our $VERSION = "1.01"; use base qw(Devel::Cover::Report::Clover::Reportable); use overload '""' => \&to_string, fallback => 1; use Devel::Cover::Report::Clover::Class; use Devel::Cover::Report::Clover::Builder; use File::Spec; { my %Lines; sub lines { my ( $self, $optional_range ) = @_; if ( !defined $Lines{$self} ) { my $name = $self->name; my $db = $self->builder->db; my $info = []; open( my $fh, '<', $name ) or warn("Can't read file '$name' [$!]\n"), return $info; my $cover_data = $db->cover->file($name); my ( $full_package, $class, $package, $line_no ); my @lines; SOURCE_LINE: while ( my $sloc = <$fh> ) { chomp($sloc); my $line_no = $.; my $line_info = { number => $line_no, type => 'unknown', content => $sloc, class => $class ? $class : 'main', package => $package ? $package : '', criteria => {}, }; if ( $sloc =~ /^\s*package\s+(.*)\s*;/ ) { $full_package = $1; my @parts = split /::/, $full_package; $class = pop @parts; $package = @parts ? join '::', @parts : ''; $line_info->{package} = $package; $line_info->{class} = $class; } if ( $sloc =~ /^__(END|DATA)__/ ) { last SOURCE_LINE; } # Process embedded POD - yanked and tweaked from # Devel::Cover::Report::Html_minimal if ( $sloc =~ /^=(pod|head|over|item|begin|for)/ ) { $line_info->{type} = 'pod'; push @lines, $line_info; POD_LOOP: while ( my $line = <$fh> ) { $line_no += 1; chomp($line); my %info = %{$line_info}; $info{content} = $line; $info{number} = $line_no; push @lines, \%info; last POD_LOOP if $line =~ /^=cut/; } next SOURCE_LINE; } if ( $sloc =~ /^\s*$/ ) { $line_info->{type} = 'whitespace'; push @lines, $line_info; next SOURCE_LINE; } if ( $sloc =~ /^\s*#/ ) { $line_info->{type} = 'comment'; push @lines, $line_info; next SOURCE_LINE; } my %criteria; for my $c ( $db->criteria ) { next unless grep { $c eq $_ } Devel::Cover::Report::Clover::Builder->accept_criteria(); my $criterion = $cover_data->$c(); if ($criterion) { my $l = $criterion->location($line_no); next unless defined $l; $criteria{$c} = $l ? [@$l] : $l; } } $line_info->{type} = 'code'; $line_info->{criteria} = \%criteria; push @lines, $line_info; } close($fh); $Lines{$self} = \@lines; } if ($optional_range) { my @lines = @{ $Lines{$self} }; return [ @lines[ $optional_range->[0] .. $optional_range->[1] ] ]; } else { return $Lines{$self}; } } } sub absolute_path { my ($self) = @_; return File::Spec->rel2abs( $self->name ); } sub loc { my ( $self, $range ) = @_; my $lines = $self->lines($range); my $code_line_count = scalar grep { $_->{type} eq 'code' } @$lines; return scalar @$lines - $code_line_count; } sub ncloc { my ( $self, $range ) = @_; my $lines = scalar @{ $self->lines($range) }; return $lines - $self->loc; } sub classes { my ( $self, $in_package ) = @_; my @classes; my $pl; my $line_number = 0; my $class_start = 1; my $flush_class = 0; my %classes; foreach my $l ( @{ $self->lines } ) { $line_number++; my $class_changed = defined $pl && ( $l->{package} ne $pl->{package} or $l->{class} ne $pl->{class} ); if ($class_changed) { my $file_frag = Devel::Cover::Report::Clover::FileFragment->new( { name => $self->name, builder => $self->builder, line_start => $class_start - 1, line_end => $line_number - 2, } ); push @classes, Devel::Cover::Report::Clover::Class->new( { file_fragment => $file_frag, builder => $self->builder, name => $pl->{class}, package => $pl->{package} } ); $class_start = $line_number; $flush_class = 0; } else { $flush_class = 1; } $pl = $l; } if ($flush_class) { my $file_frag = Devel::Cover::Report::Clover::FileFragment->new( { name => $self->name, builder => $self->builder, line_start => $class_start - 1, line_end => $line_number - 1, } ); push @classes, Devel::Cover::Report::Clover::Class->new( { file_fragment => $file_frag, builder => $self->builder, name => $pl->{class}, package => $pl->{package} } ); } if ( defined $in_package ) { my @filtered = grep { $_->package eq $in_package } @classes; return \@filtered; } else { return \@classes; } } sub summarize { my ( $self, $range ) = @_; my $lines = $self->lines($range); my $accum = { summary => {} }; my $key = 'accum'; foreach my $line (@$lines) { my $criteria = $line->{criteria}; next unless %$criteria; foreach my $criterion ( keys %$criteria ) { next unless grep { $criterion eq $_ } Devel::Cover::Report::Clover::Builder->accept_criteria(); my $items = $criteria->{$criterion}; foreach my $item (@$items) { $item->calculate_summary( $accum, $key ); } my $c = "Devel::Cover::\u$criterion"; my $s = $accum->{summary}->{$key}; my $t = $accum->{summary}->{Total}; $c->calculate_percentage( $self, $s->{$criterion} ); $c->calculate_percentage( $self, $s->{total} ); $c->calculate_percentage( $self, $t->{$criterion} ); $c->calculate_percentage( $self, $t->{total} ); } } return $accum->{summary}->{Total}; } sub to_string { return $_[0]->name; } 1; package Devel::Cover::Report::Clover::FileFragment; our $VERSION = "1.01"; use base qw(Devel::Cover::Report::Clover::File); __PACKAGE__->mk_accessors(qw(line_start line_end package_limit)); sub classes { my ($self) = @_; return $self->SUPER::classes( $self->package_limit ); } sub lines { my ($self) = @_; return $self->SUPER::lines( [ $self->line_start, $self->line_end ] ); } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/FileRegistry.pm000444000765000024 322513031625233 27507 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::FileRegistry; use strict; use warnings; our $VERSION = "1.01"; use Devel::Cover::Report::Clover::File; use Devel::Cover::Report::Clover::Package; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw(builder files_table)); sub new { my $class = shift; my $self = $class->SUPER::new(@_); my %files_table; foreach ( @{ $self->file_names } ) { $files_table{$_} = Devel::Cover::Report::Clover::File->new( { builder => $self->builder, name => $_ } ); } $self->files_table( \%files_table ); return $self; } sub file_names { my ($self) = @_; my @files = $self->builder->db->cover->items; return \@files; } sub file { my ( $self, $file_name ) = @_; return $self->files_table->{$file_name}; } sub files { my ($self) = @_; my @items = values %{ $self->files_table }; return \@items; } sub classes { my ($self) = @_; my @classes = map { @{ $_->classes } } @{ $self->files }; return \@classes; } sub packages { my ($self) = @_; my $classes = $self->classes(); my %package_classes; foreach my $class (@$classes) { my $name = $class->package(); push @{ $package_classes{$name} }, $class; } my @packages; foreach my $pname ( keys %package_classes ) { my $pcs = $package_classes{$pname}; my $package = Devel::Cover::Report::Clover::Package->new( { name => $pname, builder => $self->builder, classes => $pcs, } ); push @packages, $package; } return \@packages; } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/Package.pm000444000765000024 764113031625233 26440 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::Package; use strict; use warnings; our $VERSION = "1.01"; use Devel::Cover::Criterion; use base qw(Devel::Cover::Report::Clover::Reportable); __PACKAGE__->mk_accessors(qw(classes)); sub report { my ($self) = @_; my $name = $self->name() || 'main'; ( my $name_dotted = $name ) =~ s/\W+/./g; my $data = { name => $name, name_dotted => $name_dotted, metrics => $self->metrics(), files => [ map { $_->report } @{ $self->files } ], }; return $data; } sub files { my ($self) = @_; my %frag_classes; foreach my $c ( @{ $self->classes } ) { my $n = $c->file_fragment->name; push @{ $frag_classes{$n} }, $c; } my @ret; foreach my $name ( sort keys %frag_classes ) { my $classes = $frag_classes{$name}; my $file = Devel::Cover::Report::Clover::PackageFile->new( { name => $name, builder => $self->builder, classes => [@$classes] } ); push @ret, $file; } return \@ret; } sub metrics { my ($self) = @_; my $metrics = $self->SUPER::metrics(); $metrics->{files} = scalar @{ $self->files }; $metrics->{classes} = scalar @{ $self->classes() }; return $metrics; } sub summarize { my ($self) = @_; my $classes = $self->classes(); my $summary = {}; foreach my $class (@$classes) { my $cs = $class->summarize(); foreach my $criteria ( keys %$cs ) { my $cr = $cs->{$criteria}; foreach my $data ( keys %$cr ) { $summary->{$criteria}->{$data} += $cs->{$criteria}->{$data}; } Devel::Cover::Criterion->calculate_percentage( $self, $summary->{$criteria} ); } } Devel::Cover::Criterion->calculate_percentage( $self, $summary->{total} ); return $summary; } sub loc { my ($self) = @_; my $classes = $self->classes(); my $loc = 0; foreach (@$classes) { $loc += $_->loc(); } return $loc; } sub ncloc { my ($self) = @_; my $classes = $self->classes(); my $ncloc = 0; foreach (@$classes) { $ncloc += $_->ncloc(); } return $ncloc; } 1; package Devel::Cover::Report::Clover::PackageFile; use strict; use warnings; our $VERSION = "1.01"; use Devel::Cover::Criterion; use File::Spec; use base qw(Devel::Cover::Report::Clover::Reportable); __PACKAGE__->mk_accessors(qw(classes)); sub report { my ($self) = @_; my $data = { name => $self->name(), filename => $self->filename(), metrics => $self->metrics(), classes => [ map { $_->report } @{ $self->classes } ], }; return $data; } sub metrics { my ($self) = @_; my $metrics = $self->SUPER::metrics(); $metrics->{classes} = scalar @{ $self->classes() }; return $metrics; } sub summarize { my ($self) = @_; my $classes = $self->classes; my $summary = {}; foreach my $class (@$classes) { my $cs = $class->summarize(); foreach my $criteria ( keys %$cs ) { my $cr = $cs->{$criteria}; foreach my $data ( keys %$cr ) { $summary->{$criteria}->{$data} += $cs->{$criteria}->{$data}; } Devel::Cover::Criterion->calculate_percentage( $self, $summary->{$criteria} ); } } Devel::Cover::Criterion->calculate_percentage( $self, $summary->{total} ); return $summary; } sub loc { my ($self) = @_; my $classes = $self->classes(); my $loc = 0; foreach (@$classes) { $loc += $_->loc(); } return $loc; } sub ncloc { my ($self) = @_; my $classes = $self->classes(); my $ncloc = 0; foreach (@$classes) { $ncloc += $_->ncloc(); } return $ncloc; } sub filename { my ($self) = @_; my @splitDir = File::Spec->splitdir($self->name()); return $splitDir[-1]; } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/Project.pm000444000765000024 355413031625233 26512 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::Project; use strict; use warnings; our $VERSION = "1.01"; use base qw(Devel::Cover::Report::Clover::Reportable); sub report { my ($self) = @_; my @p_reports = map { $_->report } sort { $a->name cmp $b->name } @{ $self->packages }; my $data = { name => $self->name(), metrics => $self->metrics(), packages => \@p_reports, }; return $data; } sub metrics { my ($self) = @_; my $metrics = $self->SUPER::metrics(); $metrics->{packages} = scalar @{ $self->packages }; $metrics->{files} = scalar @{ $self->files }; $metrics->{classes} = scalar @{ $self->classes }; return $metrics; } sub classes { my ($self) = @_; return $self->builder->file_registry->classes; } sub packages { my ($self) = @_; return $self->builder->file_registry->packages; } sub package { my ( $self, $name ) = @_; $name = '' if !defined $name; my @found = grep { $_->name eq $name } @{ $self->packages }; return undef unless @found; return $found[0]; } sub files { my ($self) = @_; return $self->builder->file_registry->files; } sub summarize { my ($self) = @_; my $db = $self->builder->db; if ( !$db ) { return {}; } my $summary = $db->summary('Total'); if ( !$summary ) { return {}; } my %s = %{$summary}; my @criteria = $self->builder->accept_criteria(); my %filtered; foreach my $c (@criteria) { next unless exists $s{$c}; $filtered{$c} = $s{$c}; } return \%filtered; } sub loc { my ($self) = @_; my $loc = 0; foreach my $f ( @{ $self->files } ) { $loc += $f->loc(); } return $loc; } sub ncloc { my ($self) = @_; my $ncloc = 0; foreach my $f ( @{ $self->files } ) { $ncloc += $f->ncloc(); } return $ncloc; } 1; Devel-Cover-Report-Clover-1.01/lib/Devel/Cover/Report/Clover/Reportable.pm000444000765000024 317413031625233 27201 0ustar00davidbartlestaff000000000000package Devel::Cover::Report::Clover::Reportable; use strict; use warnings; our $VERSION = "1.01"; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw(builder name)); sub report { die("subclass must implement"); } sub summarize { die("subclass must implement"); } sub metrics { my $self = shift; my $s = $self->summarize(); my $conditionals = $s->{branch}->{total} || 0; my $conditionals_covered = $s->{branch}->{covered} || 0; if ( $self->builder->include_condition_criteria ) { $conditionals += $s->{condition}->{total} || 0; $conditionals_covered += $s->{condition}->{covered} || 0; } my $statements = $s->{statement}->{total} || 0; my $statements_covered = $s->{statement}->{covered} || 0; my $subroutines = $s->{subroutine}->{total} || 0; my $subroutines_covered = $s->{subroutine}->{covered} || 0; my $total = $conditionals + $statements + $subroutines; my $total_covered = $conditionals_covered + $statements_covered + $subroutines_covered; my $metrics = { elements => $total, coveredelements => $total_covered, statements => $statements, coveredstatements => $statements_covered, complexity => 0, loc => $self->loc(), ncloc => $self->ncloc(), conditionals => $conditionals, coveredconditionals => $conditionals_covered, methods => $subroutines, coveredmethods => $subroutines_covered }; return $metrics; } 1; Devel-Cover-Report-Clover-1.01/t000755000765000024 013031625233 17255 5ustar00davidbartlestaff000000000000Devel-Cover-Report-Clover-1.01/t/00.load.t000444000765000024 64613031625233 20722 0ustar00davidbartlestaff000000000000#!perl use Test::More tests => 8; use_ok("Devel::Cover::Report::Clover"); use_ok("Devel::Cover::Report::Clover::Builder"); use_ok("Devel::Cover::Report::Clover::Class"); use_ok("Devel::Cover::Report::Clover::File"); use_ok("Devel::Cover::Report::Clover::FileRegistry"); use_ok("Devel::Cover::Report::Clover::Package"); use_ok("Devel::Cover::Report::Clover::Project"); use_ok("Devel::Cover::Report::Clover::Reportable"); Devel-Cover-Report-Clover-1.01/t/basic.t000444000765000024 373313031625233 20666 0ustar00davidbartlestaff000000000000#!perl use Test::Exception; use Test::More; use FindBin; use lib ($FindBin::Bin); use testcover; use Devel::Cover::Report::Clover; use Devel::Cover::Report::Clover::Reportable; my $reportable = Devel::Cover::Report::Clover::Reportable->new(); my $DB = testcover::run('multi_file'); my @test = ( sub { my $t = "output_file - outputdir + outputfile are defined"; my $dir = "/dir"; my $file = "file.xml"; my $options = { outputdir => $dir, option => { outputfile => $file, } }; my $got = Devel::Cover::Report::Clover::output_file($options); my $expect = "$dir/$file"; is( $got, $expect, $t ); }, sub { my $t = "builder - name comes from correct option"; my $expect = 'test'; my $o = { 'option' => { 'projectname' => $expect } }; my $got = Devel::Cover::Report::Clover::builder( $DB, $o )->name; is( $got, $expect, $t ); }, sub { my $t = "builder - db param comes from first param correctly"; my $expect = $DB; my $o = {}; my $got = Devel::Cover::Report::Clover::builder( $expect, $o )->db; is( $got, $expect, $t ); }, sub { my $t = "builder - include_condition_criteria is on by default"; my $expect = 1; my $o = {}; my $b = Devel::Cover::Report::Clover::builder( $DB, {} ); my $got = $b->include_condition_criteria; is( $got, $expect, $t ); }, sub { my $t = "reportable->report - dies"; throws_ok( sub { $reportable->report() }, '/implement/', $t ); }, sub { my $t = "reportable->summarize - dies"; throws_ok( sub { $reportable->summarize() }, '/implement/', $t ); }, sub { my $t = "reportable->metrics - dies"; throws_ok( sub { $reportable->metrics() }, '/implement/', $t ); }, ); plan tests => scalar @test; $_->() foreach @test; Devel-Cover-Report-Clover-1.01/t/builder.t000444000765000024 744613031625233 21240 0ustar00davidbartlestaff000000000000#!perl BEGIN { $MOCKTIME = 0; eval { require Test::MockTime; $MOCKTIME = 1; }; } use Test::Exception; use Test::MockObject::Extends; use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $EMPTY_DB = testcover::run('Empty'); my @test = ( sub { my $t = "accept_criteria - array exists and has items in it"; my @criteria = Devel::Cover::Report::Clover::Builder->accept_criteria(); ok( scalar @criteria > 0, $t ); }, sub { my $t = "template_dir - returns valid folder"; my $ret = Devel::Cover::Report::Clover::Builder::template_dir(); ok( -d $ret, $t ); }, sub { my $t = "template_file - which template file to use"; my $ret = Devel::Cover::Report::Clover::Builder::template_file(); my $expect = 'clover.tt'; is( $ret, $expect, $t ); }, sub { my $t = "new - file registry object created"; my $b = BUILDER( { name => 'test', db => $EMPTY_DB } ); ok( $b->file_registry, $t ); }, sub { my $t = "new - project created"; my $b = BUILDER( { name => 'test', db => $EMPTY_DB } ); ok( $b->project, $t ); }, sub { my $expect = 'test'; my $t = "new - project created - name is $expect"; my $b = BUILDER( { name => $expect, db => $EMPTY_DB } ); is( $b->project->name, $expect, $t ); }, sub { my $t = 'include_condition_criteria - not specified defaults to true'; my $b = BUILDER( { db => $EMPTY_DB } ); ok( $b->include_condition_criteria, $t ); }, sub { my $t = "include_condition_criteria - set to '0' turns it off"; my $b = BUILDER( { db => $EMPTY_DB, include_condition_criteria => 0 } ); is( $b->include_condition_criteria, 0, $t ); }, sub { my $t = "include_condition_criteria - set to undef defaults to true"; my $b = BUILDER( { db => $EMPTY_DB, include_condition_criteria => undef } ); ok( $b->include_condition_criteria, $t ); }, sub { my $t = "generate - no file specified should die"; my $b = BUILDER( { db => $EMPTY_DB } ); dies_ok( sub { $b->generate() }, $t ); }, sub { my $t = "generate - bad file specified should die"; my $b = BUILDER( { db => $EMPTY_DB } ); dies_ok( sub { $b->generate('.') }, $t ); }, sub { my $t = "report_xml - template toolkit dies on error"; my $b = Test::MockObject::Extends->new( BUILDER( { db => $EMPTY_DB } ) ); $b->mock( 'template_file', sub { return ''; } ); $b->mock( 'report', sub { return {}; } ); throws_ok( sub { $b->report_xml() }, 'Template::Exception', $t ); }, sub { SKIP: { skip "Test::MockTime is not installed", 1 unless $MOCKTIME; my $t = "report - top level structure looks good"; my $b = BUILDER( { name => 'Project Name', db => $EMPTY_DB } ); my $project = $b->project; $project = Test::MockObject::Extends->new($project); $project->mock( 'report', sub { return {} } ); $b->project($project); Test::MockTime::set_fixed_time(123456789); my $report = $b->report(); my $expect = { generated_by => 'Devel::Cover::Report::Clover', version => $Devel::Cover::Report::Clover::VERSION, generated => time(), project => $project->report(), }; Test::MockTime::restore_time(); is_deeply( $report, $expect, $t ); } }, ); plan tests => scalar @test; $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/class.t000444000765000024 167213031625233 20712 0ustar00davidbartlestaff000000000000#!perl use Test::More; use Devel::Cover::Report::Clover::Class; my @test = ( sub { my $t = "name - comes out as passed"; my $c = Devel::Cover::Report::Clover::Class->new( { name => 'a' } ); is( $c->name, 'a', $t ); }, sub { my $t = "full_name - ( '', Class ) -> Class"; my $c = Devel::Cover::Report::Clover::Class->new( { name => 'Class', package => '' } ); is( $c->full_name, 'Class', $t ); }, sub { my $t = "full_name - ( undef, Class ) -> Class"; my $c = Devel::Cover::Report::Clover::Class->new( { name => 'Class', package => undef } ); is( $c->full_name, 'Class', $t ); }, sub { my $t = "full_name - ( My, Class ) -> My::Class"; my $c = Devel::Cover::Report::Clover::Class->new( { name => 'Class', package => 'My' } ); is( $c->full_name, 'My::Class', $t ); }, ); plan tests => scalar @test; $_->() foreach @test; Devel-Cover-Report-Clover-1.01/t/end_to_end.t000444000765000024 3525313031625233 21725 0ustar00davidbartlestaff000000000000#!perl BEGIN { $MOCKTIME = 0; eval { require Test::MockTime; $MOCKTIME = 1; }; } use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $MULTI_FILE_DB = testcover::run('multi_file'); my @test = ( sub { SKIP: { skip "Test::MockTime is not installed", 1 unless $MOCKTIME; my $t = "report - end to end"; my $proj_name = "Multi File"; Test::MockTime::set_fixed_time(123456789); my $b = BUILDER( { name => $proj_name, db => $MULTI_FILE_DB, include_condition_criteria => 1 } ); my $report = $b->report(); Test::MockTime::restore_time(); my $expect = { 'generated' => 123456789, 'generated_by' => 'Devel::Cover::Report::Clover', 'project' => { 'metrics' => { 'classes' => 4, 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 25, 'coveredmethods' => 7, 'coveredstatements' => 18, 'elements' => 35, 'files' => 3, 'loc' => 17, 'methods' => 8, 'ncloc' => 34, 'packages' => 2, 'statements' => 23 }, 'name' => $proj_name, 'packages' => [ { 'files' => [ { 'classes' => [ { 'metrics' => { 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 11, 'coveredmethods' => 3, 'coveredstatements' => 8, 'elements' => 11, 'loc' => 9, 'methods' => 3, 'ncloc' => 8, 'statements' => 8 }, 'name' => 'MultiFile', 'name_dotted' => 'MultiFile', } ], 'metrics' => { 'classes' => 1, 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 11, 'coveredmethods' => 3, 'coveredstatements' => 8, 'elements' => 11, 'loc' => 9, 'methods' => 3, 'ncloc' => 8, 'statements' => 8 }, 'name' => 'cover_db_test/multi_file/MultiFile.pm', 'filename' => 'MultiFile.pm' } ], 'metrics' => { 'classes' => 1, 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 11, 'coveredmethods' => 3, 'coveredstatements' => 8, 'elements' => 11, 'files' => 1, 'loc' => 9, 'methods' => 3, 'ncloc' => 8, 'statements' => 8 }, 'name' => 'main', 'name_dotted' => 'main' }, { 'files' => [ { 'classes' => [ { 'metrics' => { 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 8, 'coveredmethods' => 2, 'coveredstatements' => 6, 'elements' => 18, 'loc' => 3, 'methods' => 3, 'ncloc' => 14, 'statements' => 11 }, 'name' => 'Sub', 'name_dotted' => 'Sub' } ], 'metrics' => { 'classes' => 1, 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 8, 'coveredmethods' => 2, 'coveredstatements' => 6, 'elements' => 18, 'loc' => 3, 'methods' => 3, 'ncloc' => 14, 'statements' => 11 }, 'name' => 'cover_db_test/multi_file/MultiFile.pm', 'filename' => 'MultiFile.pm' }, { 'classes' => [ { 'metrics' => { 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 3, 'coveredmethods' => 1, 'coveredstatements' => 2, 'elements' => 3, 'loc' => 3, 'methods' => 1, 'ncloc' => 6, 'statements' => 2 }, 'name' => 'First', 'name_dotted' => 'First' } ], 'metrics' => { 'classes' => 1, 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 3, 'coveredmethods' => 1, 'coveredstatements' => 2, 'elements' => 3, 'loc' => 3, 'methods' => 1, 'ncloc' => 6, 'statements' => 2 }, 'name' => 'cover_db_test/multi_file/MultiFile/First.pm', 'filename' => 'First.pm' }, { 'classes' => [ { 'metrics' => { 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 3, 'coveredmethods' => 1, 'coveredstatements' => 2, 'elements' => 3, 'loc' => 2, 'methods' => 1, 'ncloc' => 6, 'statements' => 2 }, 'name' => 'Second', 'name_dotted' => 'Second' } ], 'metrics' => { 'classes' => 1, 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 3, 'coveredmethods' => 1, 'coveredstatements' => 2, 'elements' => 3, 'loc' => 2, 'methods' => 1, 'ncloc' => 6, 'statements' => 2 }, 'name' => 'cover_db_test/multi_file/MultiFile/Second.pm', 'filename' => 'Second.pm' } ], 'metrics' => { 'classes' => 3, 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 14, 'coveredmethods' => 4, 'coveredstatements' => 10, 'elements' => 24, 'files' => 3, 'loc' => 8, 'methods' => 5, 'ncloc' => 26, 'statements' => 15 }, 'name' => 'MultiFile', 'name_dotted' => 'MultiFile' } ] }, 'version' => $Devel::Cover::Report::Clover::VERSION }; ok(delete $report->{project}{packages}[0]{files}[0]{classes}[0]{lines}, 'line reporting 1 (existence checked)'); ok(delete $report->{project}{packages}[1]{files}[0]{classes}[0]{lines}, 'line reporting 2 (existence checked)'); ok(delete $report->{project}{packages}[1]{files}[1]{classes}[0]{lines}, 'line reporting 3 (existence checked)'); ok(delete $report->{project}{packages}[1]{files}[2]{classes}[0]{lines}, 'line reporting 4 (existence checked)'); is_deeply( $report, $expect, 'deep inspection of rest' ); } }, sub { my $t = "generate - writes xml file"; my $proj_name = "Multi File"; my $b = BUILDER( { name => $proj_name, db => $MULTI_FILE_DB } ); my $outfile = testcover::test_path('multi_file') . "/clover-1-$$.xml"; $b->generate($outfile); ok( -f $outfile, $t ); }, sub { my $t = "report - core report entry point writes file"; my $proj_name = "Multi File"; my $o = { 'option' => { 'projectname' => "Project Name", 'outputfile' => "clover-2-$$.xml" }, 'silent' => 1, outputdir => testcover::test_path('multi_file'), }; Devel::Cover::Report::Clover->report( $MULTI_FILE_DB, $o ); my $outfile = sprintf( "%s/%s", $o->{outputdir}, $o->{option}{outputfile} ); ok( -f $outfile, $t ); }, ); $_->() foreach @test; done_testing(); sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/end_to_end_no_stats.t000444000765000024 602613031625233 23613 0ustar00davidbartlestaff000000000000#!perl BEGIN { $MOCKTIME = 0; eval { require Test::MockTime; $MOCKTIME = 1; }; } use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $MULTI_FILE_DB = testcover::run('Empty'); my @test = ( sub { SKIP: { skip "Test::MockTime is not installed", 1 unless $MOCKTIME; my $t = "report - end to end"; my $proj_name = "Multi File"; Test::MockTime::set_fixed_time(123456789); my $b = BUILDER( { name => $proj_name, db => $MULTI_FILE_DB, include_condition_criteria => 1 } ); my $report = $b->report(); Test::MockTime::restore_time(); my $expect = { 'generated' => 123456789, 'generated_by' => 'Devel::Cover::Report::Clover', 'project' => { 'metrics' => { 'classes' => 0, 'complexity' => 0, 'conditionals' => 0, 'coveredconditionals' => 0, 'coveredelements' => 0, 'coveredmethods' => 0, 'coveredstatements' => 0, 'elements' => 0, 'files' => 0, 'loc' => 0, 'methods' => 0, 'ncloc' => 0, 'packages' => 0, 'statements' => 0 }, 'name' => $proj_name, 'packages' => [] }, 'version' => $Devel::Cover::Report::Clover::VERSION }; is_deeply( $report, $expect, $t ); } }, sub { my $t = "generate - writes xml file"; my $proj_name = "Multi File"; my $b = BUILDER( { name => $proj_name, db => $MULTI_FILE_DB } ); my $outfile = testcover::test_path('multi_file') . "/clover-1-$$.xml"; $b->generate($outfile); ok( -f $outfile, $t ); }, sub { my $t = "report - core report entry point writes file"; my $proj_name = "Multi File"; my $o = { 'option' => { 'projectname' => "Project Name", 'outputfile' => "clover-2-$$.xml" }, 'silent' => 1, outputdir => testcover::test_path('multi_file'), }; Devel::Cover::Report::Clover->report( $MULTI_FILE_DB, $o ); my $outfile = sprintf( "%s/%s", $o->{outputdir}, $o->{option}{outputfile} ); ok( -f $outfile, $t ); }, ); plan tests => scalar @test; $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/file.t000444000765000024 470313031625233 20522 0ustar00davidbartlestaff000000000000#!perl use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $DB = testcover::run('multi_file'); my $b = BUILDER( { name => 'test', db => $DB } ); my @files = @{ $b->file_registry->files }; my @test = ( sub { my $t = "files - file registry has all files listed"; is( scalar @files, 3, $t ); }, ); my %expected_file_stats = ( 'MultiFile/First.pm' => { loc => 3, ncloc => 6, line_count => 9, class_count => 1, total => { covered => 3, percentage => 100, total => 3, } }, 'MultiFile/Second.pm' => { loc => 2, ncloc => 6, line_count => 8, class_count => 1, total => { covered => 3, percentage => 100, total => 3, } }, 'MultiFile.pm' => { loc => 12, ncloc => 22, line_count => 34, class_count => 2, total => { covered => 19, error => 3, percentage => '86.3636363636364', total => 29, } }, ); foreach my $file (@files) { ( my $rel_path = $file ) =~ s{.*cover_db_test/multi_file/}{}; my $expected = $expected_file_stats{$rel_path}; push @test, sub { my $t = "loc - $file"; my $got = $file->loc; is( $got, $expected->{loc}, $t ); }; push @test, sub { my $t = "ncloc - $file"; my $got = $file->ncloc; is( $got, $expected->{ncloc}, $t ); }; push @test, sub { my $t = "line count - $file"; my $got = scalar @{ $file->lines }; is( $got, $expected->{line_count}, $t ); }; push @test, sub { my $t = "summary calculation - $file"; my $got = $file->summarize(); is( $got->{total}->{total}, $expected->{total}->{total}, "$t - total" ); is( $got->{total}->{covered}, $expected->{total}->{covered}, "$t - covered" ); }; push @test, sub { my $t = "class count -> $file"; my @classes = @{ $file->classes }; my $got = scalar @classes; is( $got, $expected->{class_count}, $t ); } } plan tests => scalar @test + ( 1 * scalar @files ); $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/file_registry.t000444000765000024 371113031625233 22450 0ustar00davidbartlestaff000000000000#!perl use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $DB = testcover::run('multi_file'); my @test = ( sub { my $t = "file_names - 3 items in there"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $got = $file_registry->file_names(); is( scalar @$got, 3, $t ); }, sub { my $t = "file_names - list is expected"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $got = $file_registry->file_names(); my @expect = $b->db->cover->items; is_deeply( $got, \@expect, $t ); }, sub { my $t = "files - 3 items in there"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $got = $file_registry->files(); is( scalar @$got, 3, $t ); }, sub { my $t = "file - get each one individually"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $files = $file_registry->files(); foreach (@$files) { my $got = $file_registry->file($_); is( $_, $got->name, "$t - $_" ); } }, sub { my $t = "classes - count"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $classes = $file_registry->classes(); is( scalar @$classes, 4, $t ); }, sub { my $t = "packages - count"; my $b = BUILDER( { name => 'test', db => $DB } ); my $file_registry = $b->file_registry; my $packages = $file_registry->packages(); is( scalar @$packages, 2, $t ); }, ); plan tests => scalar @test + ( 3 - 1 ); $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/package.t000444000765000024 641713031625233 21202 0ustar00davidbartlestaff000000000000#!perl use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $DB = testcover::run('multi_file'); my $b = BUILDER( { name => 'test', db => $DB, include_condition_criteria => 0 } ); my $proj = $b->project; my @packages = @{ $proj->packages }; my $package = $proj->package(''); my @test = ( sub { my $t = "packages - count"; is( scalar @packages, 2, $t ); }, sub { my $t = "package - single item found"; my $package = $proj->package(''); ok( $package, $t ); }, sub { my $t = "package - single item found with no args"; my $package = $proj->package(); ok( $package, $t ); }, sub { my $t = "package - undef"; my $package = $proj->package('adfasf'); is( $package, undef, $t ); }, sub { my $t = "classes - count"; my $package = $proj->package(''); my @classes = @{ $package->classes }; is( scalar @classes, 1, $t ); }, sub { my $t = "filename"; my $package = $proj->package(''); my $filename = $package->files()->[0]->filename(); is( $filename, 'MultiFile.pm', $t ); }, sub { my $t = "summarize"; my $package = $proj->package('MultiFile'); my $s = $package->summarize()->{total}; is( $s->{covered}, 14, "$t - covered value" ); is( $s->{total}, 24, "$t - total value" ); }, sub { my $t = "metrics - criteria(branch)"; my $package = $proj->package('MultiFile'); my $s = $package->metrics; my $expect = { 'classes' => 3, 'complexity' => 0, 'conditionals' => 2, 'coveredconditionals' => 0, 'coveredelements' => 14, 'coveredmethods' => 4, 'coveredstatements' => 10, 'elements' => 22, 'files' => 3, 'loc' => 8, 'methods' => 5, 'ncloc' => 26, 'statements' => 15 }; is_deeply( $s, $expect, $t ); }, sub { my $t = "metrics - criteria(branch+conditional)"; my $b = BUILDER( { name => 'test', db => $DB, include_condition_criteria => 1 } ); my $proj = $b->project; my $package = $proj->package('MultiFile'); my $s = $package->metrics; my $expect = { 'classes' => 3, 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 14, 'coveredmethods' => 4, 'coveredstatements' => 10, 'elements' => 24, 'files' => 3, 'loc' => 8, 'methods' => 5, 'ncloc' => 26, 'statements' => 15 }; is_deeply( $s, $expect, $t ); }, ); plan tests => scalar @test + 1; $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/project.t000444000765000024 440513031625233 21250 0ustar00davidbartlestaff000000000000#!perl use Test::More; use Devel::Cover::Report::Clover::Builder; use FindBin; use lib ($FindBin::Bin); use testcover; my $DB = testcover::run('multi_file'); my $b = BUILDER( { name => 'test', db => $DB, include_condition_criteria => 0 } ); my $p = $b->project; my @files = @{ $p->files }; my @test = ( sub { my $t = "files - 3 of them"; is( scalar @files, 3, $t ); }, sub { my $t = "loc"; is( $p->loc(), 17, $t ); }, sub { my $t = "ncloc"; is( $p->ncloc(), 34, $t ); }, sub { my $t = "metrics - criteria(branch)"; my $s = $p->metrics; my $expect = { 'classes' => 4, 'complexity' => 0, 'conditionals' => 2, 'coveredconditionals' => 0, 'coveredelements' => 25, 'coveredmethods' => 7, 'coveredstatements' => 18, 'elements' => 33, 'files' => 3, 'loc' => 17, 'methods' => 8, 'ncloc' => 34, 'packages' => 2, 'statements' => 23 }; is_deeply( $s, $expect, $t ); }, sub { my $t = "metrics - criteria(branch+conditional)"; my $b = BUILDER( { name => 'test', db => $DB, include_condition_criteria => 1 } ); my $p = $b->project; my $s = $p->metrics; my $expect = { 'classes' => 4, 'complexity' => 0, 'conditionals' => 4, 'coveredconditionals' => 0, 'coveredelements' => 25, 'coveredmethods' => 7, 'coveredstatements' => 18, 'elements' => 35, 'files' => 3, 'loc' => 17, 'methods' => 8, 'ncloc' => 34, 'packages' => 2, 'statements' => 23 }; is_deeply( $s, $expect, $t ); }, ); plan tests => scalar @test; $_->() foreach @test; sub BUILDER { return Devel::Cover::Report::Clover::Builder->new(shift); } Devel-Cover-Report-Clover-1.01/t/testcover.pm000444000765000024 404413031625233 21770 0ustar00davidbartlestaff000000000000package testcover; use Config; use Devel::Cover::DB; use Devel::Cover::Inc; use File::Glob qw(bsd_glob); use File::Path qw(remove_tree); use FindBin; use List::Util qw(first); use TAP::Harness; use File::Which qw(which); sub run { my $name = shift; my $path = test_path($name); my $cover_db = cover_db_path($name); # Not all @INC paths were set in Devel::Cover::Inc::Inc # when CPAN was used to install Devel::Cover on OSX Lion. # ...try and fake this my @additional_inc_ignores; foreach my $i (@INC) { if( ! grep /^$i$/, @Devel::Cover::Inc::Inc ) { push @additional_inc_ignores, $i; } } my $incs = join ',', map { '+inc,'.$_ } @additional_inc_ignores; if( -d "$cover_db" ) { remove_tree($cover_db); } my $harness = TAP::Harness->new( { verbosity => -3, lib => [$path], switches => "-MDevel::Cover=-db,$cover_db,$incs" } ); my @tests = bsd_glob("$path/*.t"); $harness->runtests(@tests); my $cover_cmd = cover_cmd(); my $perl_cmd = perl_cmd(); run_cmd( $perl_cmd, $cover_cmd, $cover_db ); my $db = Devel::Cover::DB->new( db => $cover_db ); return $db; } sub run_cmd { my @parts = @_; my $str = sprintf( "'%s'", join "','", @parts ); { local *STDOUT = STDOUT; open( STDOUT, '>', '/dev/null' ); system(@parts) == 0 or die "system($str) failed: $? \n"; } return; } sub cover_cmd { my $p_which = which('cover'); my $found = first { defined $_ && $_ && -f $_ } ( $p_which, $Devel::Cover::Inc::Base . "/cover" ); return $found || 'cover'; } sub perl_cmd { my $found = first { defined $_ && $_ && -f $_ } ( $Config{perlpath}, $^W ); return $found || 'perl'; } sub cover_db_path { my $name = shift; my $path = test_path($name) . "/cover_db"; } sub test_path { my $name = shift; return "$FindBin::Bin/../cover_db_test/$name"; } sub test_file { my $name = shift; return test_path($name) . "/{$name}.pm"; } 1;