From e6feea80a688445f9f009fba6cbedfa33afdcc91 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 16 2020 16:18:48 +0000 Subject: perl-Test-FailWarnings-0.008 base --- diff --git a/CONTRIBUTING b/CONTRIBUTING new file mode 100644 index 0000000..0d13aaa --- /dev/null +++ b/CONTRIBUTING @@ -0,0 +1,70 @@ +## HOW TO CONTRIBUTE + +Thank you for considering contributing to this distribution. This file +contains instructions that will help you work with the source code. + +The distribution is managed with Dist::Zilla. This means than many of the +usual files you might expect are not in the repository, but are generated +at release time (e.g. Makefile.PL). + +### Getting dependencies + +See the included `cpanfile` file for a list of dependencies. If you have +App::cpanminus 1.6 or later installed, you can use `cpanm` to satisfy +dependencies like this: + + $ cpanm --installdeps . + +Otherwise, you can install Module::CPANfile 1.0002 or later and then satisfy +dependencies with the regular `cpan` client and `cpanfile-dump`: + + $ cpan `cpanfile-dump` + +### Running tests + +You can run tests directly using the `prove` tool: + + $ prove -l + $ prove -lv t/some_test_file.t + +For most distributions, `prove` is entirely sufficent for you to test any +patches you have. + +### Code style and tidying + +Please try to match any existing coding style. If there is a `.perltidyrc` +file, please install Perl::Tidy and use perltidy before submitting patches. + +If there is a `tidyall.ini` file, you can also install Code::TidyAll and run +`tidyall` on a file or `tidyall -a` to tidy all files. + +### Patching documentation + +Much of the documentation Pod is generated at release time. +Depending on the distribution, some documentation may be written in a Pod +dialect called WikiDoc. (See Pod::WikiDoc on CPAN.) + +If you would like to submit a documentation edit, please limit yourself to the +documentation you see. + +If you see typos or documentation issues in the generated docs, please +email or open a bug ticket instead of patching. + +### Learning Dist::Zilla + +Dist::Zilla is a very powerful authoring tool, but requires a number of +author-specific plugins. If you would like to use it for contributing, +install it from CPAN, then run one of the following commands, depending on +your CPAN client: + + $ cpan `dzil authordeps` + $ dzil authordeps | cpanm + +Once installed, here are some dzil commands you might try: + + $ dzil build + $ dzil test + $ dzil xtest + +You can learn more about Dist::Zilla at http://dzil.org/ + diff --git a/Changes b/Changes new file mode 100644 index 0000000..cc908a4 --- /dev/null +++ b/Changes @@ -0,0 +1,66 @@ +Revision history for Test-FailWarnings + +0.008 2013-09-25 14:08:48 America/New_York + + [FIXES] + + - Compile test could hang on Windows + + [PREREQS] + + - Dropped configure_requires for ExtUtils::MakeMaker to 6.17 + +0.007 2013-08-30 09:53:47 America/New_York + + [FIXED] + + - In some situations, the source of a local warning can have an + absolute filename and would not be reported if ALLOW_DEPS were true. + Now absolute filenames are made relative to the original cwd before + checking if they are local or not. + + [DOCUMENTED] + + - Fixed synopsis to match new failing test label + +0.006 2013-08-22 10:41:11 America/New_York + + [CHANGED] + + - The label of the failing test has been revised for clarity + +0.005 2013-05-03 14:03:28 America/New_York + + [DOCUMENTED] + + - Added Test::Warnings to See Also + +0.004 2013-05-02 10:50:37 America/New_York + + [FIXED] + + - Bumped Capture::Tiny test prerequisite version + +0.003 2013-03-13 13:30:24 America/New_York + + [FIXED] + + - Fixed @ALLOW_FROM initialization to suppress our own warning + +0.002 2013-03-10 17:28:53 America/New_York + + [ADDED] + + - Now can optionally allow warnings from dependencies + + - Now can optionally allow warnings from specific modules + + [CHANGED] + + - warnings handler only installed by import(); handler function + is now available for custom, localized use + +0.001 2013-02-25 17:44:33 America/New_York + + - First release + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1306a66 --- /dev/null +++ b/LICENSE @@ -0,0 +1,207 @@ +This software is Copyright (c) 2013 by David Golden. + +This is free software, licensed under: + + The Apache License, Version 2.0, January 2004 + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..b7147bb --- /dev/null +++ b/MANIFEST @@ -0,0 +1,31 @@ +CONTRIBUTING +Changes +LICENSE +MANIFEST +META.json +META.yml +Makefile.PL +README +cpanfile +dist.ini +lib/Test/FailWarnings.pm +perlcritic.rc +t/00-compile.t +t/00-report-prereqs.t +t/bin/allow-constant.pl +t/bin/allow-deps.pl +t/bin/force-deps.pl +t/bin/main-warn.pl +t/bin/module-warn.pl +t/bin/warn-newline.pl +t/failwarn.t +t/lib/Noisy.pm +tidyall.ini +xt/author/critic.t +xt/author/pod-spell.t +xt/release/distmeta.t +xt/release/minimum-version.t +xt/release/pod-coverage.t +xt/release/pod-syntax.t +xt/release/portability.t +xt/release/test-version.t diff --git a/META.json b/META.json new file mode 100644 index 0000000..d05c3f0 --- /dev/null +++ b/META.json @@ -0,0 +1,89 @@ +{ + "abstract" : "Add test failures if warnings are caught", + "author" : [ + "David Golden " + ], + "dynamic_config" : 0, + "generated_by" : "Dist::Zilla version 4.300039, CPAN::Meta::Converter version 2.132620", + "license" : [ + "apache_2_0" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Test-FailWarnings", + "no_index" : { + "directory" : [ + "t", + "xt", + "examples", + "corpus" + ], + "package" : [ + "DB" + ] + }, + "prereqs" : { + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "6.17" + } + }, + "develop" : { + "requires" : { + "Pod::Coverage::TrustPod" : "0", + "Test::CPAN::Meta" : "0", + "Test::Pod" : "1.41", + "Test::Pod::Coverage" : "1.08" + } + }, + "runtime" : { + "requires" : { + "Carp" : "0", + "Cwd" : "0", + "File::Spec" : "0", + "Test::More" : "0.86", + "perl" : "5.008001", + "strict" : "0", + "warnings" : "0" + } + }, + "test" : { + "requires" : { + "Capture::Tiny" : "0.12", + "ExtUtils::MakeMaker" : "0", + "File::Spec" : "0", + "File::Spec::Functions" : "0", + "File::Temp" : "0", + "IO::Handle" : "0", + "IPC::Open3" : "0", + "List::Util" : "0", + "Test::More" : "0.96", + "constant" : "0", + "lib" : "0" + } + } + }, + "provides" : { + "Test::FailWarnings" : { + "file" : "lib/Test/FailWarnings.pm", + "version" : "0.008" + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "web" : "https://github.com/dagolden/Test-FailWarnings/issues" + }, + "homepage" : "https://github.com/dagolden/Test-FailWarnings", + "repository" : { + "type" : "git", + "url" : "https://github.com/dagolden/Test-FailWarnings.git", + "web" : "https://github.com/dagolden/Test-FailWarnings" + } + }, + "version" : "0.008", + "x_authority" : "cpan:DAGOLDEN" +} + diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..f35a9a2 --- /dev/null +++ b/META.yml @@ -0,0 +1,51 @@ +--- +abstract: 'Add test failures if warnings are caught' +author: + - 'David Golden ' +build_requires: + Capture::Tiny: 0.12 + ExtUtils::MakeMaker: 0 + File::Spec: 0 + File::Spec::Functions: 0 + File::Temp: 0 + IO::Handle: 0 + IPC::Open3: 0 + List::Util: 0 + Test::More: 0.96 + constant: 0 + lib: 0 +configure_requires: + ExtUtils::MakeMaker: 6.17 +dynamic_config: 0 +generated_by: 'Dist::Zilla version 4.300039, CPAN::Meta::Converter version 2.132620' +license: apache +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: Test-FailWarnings +no_index: + directory: + - t + - xt + - examples + - corpus + package: + - DB +provides: + Test::FailWarnings: + file: lib/Test/FailWarnings.pm + version: 0.008 +requires: + Carp: 0 + Cwd: 0 + File::Spec: 0 + Test::More: 0.86 + perl: 5.008001 + strict: 0 + warnings: 0 +resources: + bugtracker: https://github.com/dagolden/Test-FailWarnings/issues + homepage: https://github.com/dagolden/Test-FailWarnings + repository: https://github.com/dagolden/Test-FailWarnings.git +version: 0.008 +x_authority: cpan:DAGOLDEN diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..2fa17b2 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,82 @@ + +use strict; +use warnings; + +use 5.008001; + +use ExtUtils::MakeMaker 6.17; + + + +my %WriteMakefileArgs = ( + "ABSTRACT" => "Add test failures if warnings are caught", + "AUTHOR" => "David Golden ", + "BUILD_REQUIRES" => {}, + "CONFIGURE_REQUIRES" => { + "ExtUtils::MakeMaker" => "6.17" + }, + "DISTNAME" => "Test-FailWarnings", + "EXE_FILES" => [], + "LICENSE" => "apache", + "NAME" => "Test::FailWarnings", + "PREREQ_PM" => { + "Carp" => 0, + "Cwd" => 0, + "File::Spec" => 0, + "Test::More" => "0.86", + "strict" => 0, + "warnings" => 0 + }, + "TEST_REQUIRES" => { + "Capture::Tiny" => "0.12", + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "File::Spec::Functions" => 0, + "File::Temp" => 0, + "IO::Handle" => 0, + "IPC::Open3" => 0, + "List::Util" => 0, + "Test::More" => "0.96", + "constant" => 0, + "lib" => 0 + }, + "VERSION" => "0.008", + "test" => { + "TESTS" => "t/*.t" + } +); + + +unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { + my $tr = delete $WriteMakefileArgs{TEST_REQUIRES}; + my $br = $WriteMakefileArgs{BUILD_REQUIRES}; + for my $mod ( keys %$tr ) { + if ( exists $br->{$mod} ) { + $br->{$mod} = $tr->{$mod} if $tr->{$mod} > $br->{$mod}; + } + else { + $br->{$mod} = $tr->{$mod}; + } + } +} + +unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { + my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; + my $pp = $WriteMakefileArgs{PREREQ_PM}; + for my $mod ( keys %$br ) { + if ( exists $pp->{$mod} ) { + $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; + } + else { + $pp->{$mod} = $br->{$mod}; + } + } +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; + +WriteMakefile(%WriteMakefileArgs); + + + diff --git a/README b/README new file mode 100644 index 0000000..fbf66d1 --- /dev/null +++ b/README @@ -0,0 +1,111 @@ +NAME + Test::FailWarnings - Add test failures if warnings are caught + +VERSION + version 0.008 + +SYNOPSIS + Test file: + + use strict; + use warnings; + use Test::More; + use Test::FailWarnings; + + ok( 1, "first test" ); + ok( 1 + "lkadjaks", "add non-numeric" ); + + done_testing; + + Output: + + ok 1 - first test + not ok 2 - Test::FailWarnings should catch no warnings + # Failed test 'Test::FailWarnings should catch no warnings' + # at t/bin/main-warn.pl line 7. + # Warning was 'Argument "lkadjaks" isn't numeric in addition (+) at t/bin/main-warn.pl line 7.' + ok 3 - add non-numeric + 1..3 + # Looks like you failed 1 test of 3. + +DESCRIPTION + This module hooks $SIG{__WARN__} and converts warnings to Test::More + "fail()" calls. It is designed to be used with "done_testing", when you + don't need to know the test count in advance. + + Just as with Test::NoWarnings, this does not catch warnings if other + things localize $SIG{__WARN__}, as this is designed to catch *unhandled* + warnings. + +USAGE + Overriding $SIG{__WARN__} + On "import", $SIG{__WARN__} is replaced with + "Test::FailWarnings::handler". + + use Test::FailWarnings; # global + + If you don't want global replacement, require the module instead and + localize in whatever scope you want. + + require Test::FailWarnings; + + { + local $SIG{__WARN__} = \&Test::FailWarnings::handler; + # ... warnings will issue fail() here + } + + When the handler reports on the source of the warning, it will look past + any calling packages starting with "Carp" or "warnings" to try to detect + the real origin of the warning. + + Allowing warnings from dependencies + If you want to ignore failures from outside your own code, you can set + $Test::FailWarnings::ALLOW_DEPS to a true value. You can do that on the + "use" line with "-allow_deps". + + use Test::FailWarnings -allow_deps => 1; + + When true, warnings will only be thrown if they appear to originate from + a filename matching "qr/^(?:t|xt|lib|blib)/" + + Allowing warnings from specific modules + If you want to white-list specific modules only, you can add their + package names to @Test::NoWarnings::ALLOW_FROM. You can do that on the + "use" line with "-allow_from". + + use Test::FailWarnings -allow_from => [ qw/Annoying::Module/ ]; + +SEE ALSO + * Test::NoWarnings -- catches warnings and reports in an "END" block. + Not (yet) friendly with "done_testing". + + * Test::Warnings -- a replacement for Test::NoWarnings that works with + done_testing + + * Test::Warn -- test for warnings without triggering failures from + this modules + +SUPPORT + Bugs / Feature Requests + Please report any bugs or feature requests through the issue tracker at + . You will be + notified automatically of any progress on your issue. + + Source Code + This is open source software. The code repository is available for + public review and contribution under the terms of the license. + + + + git clone https://github.com/dagolden/Test-FailWarnings.git + +AUTHOR + David Golden + +COPYRIGHT AND LICENSE + This software is Copyright (c) 2013 by David Golden. + + This is free software, licensed under: + + The Apache License, Version 2.0, January 2004 + diff --git a/cpanfile b/cpanfile new file mode 100644 index 0000000..21adb55 --- /dev/null +++ b/cpanfile @@ -0,0 +1,32 @@ +requires "Carp" => "0"; +requires "Cwd" => "0"; +requires "File::Spec" => "0"; +requires "Test::More" => "0.86"; +requires "perl" => "5.008001"; +requires "strict" => "0"; +requires "warnings" => "0"; + +on 'test' => sub { + requires "Capture::Tiny" => "0.12"; + requires "ExtUtils::MakeMaker" => "0"; + requires "File::Spec" => "0"; + requires "File::Spec::Functions" => "0"; + requires "File::Temp" => "0"; + requires "IO::Handle" => "0"; + requires "IPC::Open3" => "0"; + requires "List::Util" => "0"; + requires "Test::More" => "0.96"; + requires "constant" => "0"; + requires "lib" => "0"; +}; + +on 'configure' => sub { + requires "ExtUtils::MakeMaker" => "6.17"; +}; + +on 'develop' => sub { + requires "Pod::Coverage::TrustPod" => "0"; + requires "Test::CPAN::Meta" => "0"; + requires "Test::Pod" => "1.41"; + requires "Test::Pod::Coverage" => "1.08"; +}; diff --git a/dist.ini b/dist.ini new file mode 100644 index 0000000..e404a63 --- /dev/null +++ b/dist.ini @@ -0,0 +1,8 @@ +name = Test-FailWarnings +author = David Golden +license = Apache_2_0 +copyright_holder = David Golden +copyright_year = 2013 + +[@DAGOLDEN] +:version = 0.053 diff --git a/lib/Test/FailWarnings.pm b/lib/Test/FailWarnings.pm new file mode 100644 index 0000000..3f52773 --- /dev/null +++ b/lib/Test/FailWarnings.pm @@ -0,0 +1,216 @@ +use 5.008001; +use strict; +use warnings; + +package Test::FailWarnings; +# ABSTRACT: Add test failures if warnings are caught +our $VERSION = '0.008'; # VERSION + +use Test::More 0.86; +use Cwd qw/getcwd/; +use File::Spec; +use Carp; + +our $ALLOW_DEPS = 0; +our @ALLOW_FROM = (); + +my $ORIG_DIR = getcwd(); # cache in case handler runs after a chdir + +sub import { + my ( $class, @args ) = @_; + croak("import arguments must be key/value pairs") + unless @args % 2 == 0; + my %opts = @args; + $ALLOW_DEPS = $opts{'-allow_deps'}; + if ( $opts{'-allow_from'} ) { + @ALLOW_FROM = + ref $opts{'-allow_from'} ? @{ $opts{'-allow_from'} } : $opts{'-allow_from'}; + } + $SIG{__WARN__} = \&handler; +} + +sub handler { + my $msg = shift; + $msg = '' unless defined $msg; + chomp $msg; + my ( $package, $filename, $line ) = _find_source(); + + # shortcut if ignoring dependencies and warning did not + # come from something local + if ($ALLOW_DEPS) { + $filename = File::Spec->abs2rel( $filename, $ORIG_DIR ) + if File::Spec->file_name_is_absolute($filename); + return if $filename !~ /^(?:t|xt|lib|blib)/; + } + + return if grep { $package eq $_ } @ALLOW_FROM; + + if ( $msg !~ m/at .*? line \d/ ) { + chomp $msg; + $msg = "'$msg' at $filename line $line."; + } + else { + $msg = "'$msg'"; + } + my $builder = Test::More->builder; + $builder->ok( 0, "Test::FailWarnings should catch no warnings" ) + or $builder->diag("Warning was $msg"); +} + +sub _find_source { + my $i = 1; + while (1) { + my ( $pkg, $filename, $line ) = caller( $i++ ); + return caller( $i - 2 ) unless defined $pkg; + next if $pkg =~ /^(?:Carp|warnings)/; + return ( $pkg, $filename, $line ); + } +} + +1; + + +# vim: ts=4 sts=4 sw=4 et: + +__END__ + +=pod + +=encoding utf-8 + +=head1 NAME + +Test::FailWarnings - Add test failures if warnings are caught + +=head1 VERSION + +version 0.008 + +=head1 SYNOPSIS + +Test file: + + use strict; + use warnings; + use Test::More; + use Test::FailWarnings; + + ok( 1, "first test" ); + ok( 1 + "lkadjaks", "add non-numeric" ); + + done_testing; + +Output: + + ok 1 - first test + not ok 2 - Test::FailWarnings should catch no warnings + # Failed test 'Test::FailWarnings should catch no warnings' + # at t/bin/main-warn.pl line 7. + # Warning was 'Argument "lkadjaks" isn't numeric in addition (+) at t/bin/main-warn.pl line 7.' + ok 3 - add non-numeric + 1..3 + # Looks like you failed 1 test of 3. + +=head1 DESCRIPTION + +This module hooks C<$SIG{__WARN__}> and converts warnings to L +C calls. It is designed to be used with C, when you +don't need to know the test count in advance. + +Just as with L, this does not catch warnings if other things +localize C<$SIG{__WARN__}>, as this is designed to catch I warnings. + +=for Pod::Coverage handler + +=head1 USAGE + +=head2 Overriding C<$SIG{__WARN__}> + +On C, C<$SIG{__WARN__}> is replaced with +C. + + use Test::FailWarnings; # global + +If you don't want global replacement, require the module instead and localize +in whatever scope you want. + + require Test::FailWarnings; + + { + local $SIG{__WARN__} = \&Test::FailWarnings::handler; + # ... warnings will issue fail() here + } + +When the handler reports on the source of the warning, it will look past +any calling packages starting with C or C to try to detect +the real origin of the warning. + +=head2 Allowing warnings from dependencies + +If you want to ignore failures from outside your own code, you can set +C<$Test::FailWarnings::ALLOW_DEPS> to a true value. You can +do that on the C line with C<< -allow_deps >>. + + use Test::FailWarnings -allow_deps => 1; + +When true, warnings will only be thrown if they appear to originate from a filename +matching C<< qr/^(?:t|xt|lib|blib)/ >> + +=head2 Allowing warnings from specific modules + +If you want to white-list specific modules only, you can add their package +names to C<@Test::NoWarnings::ALLOW_FROM>. You can do that on the C line +with C<< -allow_from >>. + + use Test::FailWarnings -allow_from => [ qw/Annoying::Module/ ]; + +=head1 SEE ALSO + +=over 4 + +=item * + +L -- catches warnings and reports in an C block. Not (yet) friendly with C. + +=item * + +L -- a replacement for Test::NoWarnings that works with done_testing + +=item * + +L -- test for warnings without triggering failures from this modules + +=back + +=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan + +=head1 SUPPORT + +=head2 Bugs / Feature Requests + +Please report any bugs or feature requests through the issue tracker +at L. +You will be notified automatically of any progress on your issue. + +=head2 Source Code + +This is open source software. The code repository is available for +public review and contribution under the terms of the license. + +L + + git clone https://github.com/dagolden/Test-FailWarnings.git + +=head1 AUTHOR + +David Golden + +=head1 COPYRIGHT AND LICENSE + +This software is Copyright (c) 2013 by David Golden. + +This is free software, licensed under: + + The Apache License, Version 2.0, January 2004 + +=cut diff --git a/perlcritic.rc b/perlcritic.rc new file mode 100644 index 0000000..cef05a8 --- /dev/null +++ b/perlcritic.rc @@ -0,0 +1,23 @@ +severity = 5 +verbose = 8 + +[Variables::ProhibitPunctuationVars] +allow = $@ $! + +[TestingAndDebugging::ProhibitNoStrict] +allow = refs + +# Turn these off +[-BuiltinFunctions::ProhibitStringyEval] +[-ControlStructures::ProhibitPostfixControls] +[-ControlStructures::ProhibitUnlessBlocks] +[-Documentation::RequirePodSections] +[-InputOutput::ProhibitInteractiveTest] +[-References::ProhibitDoubleSigils] +[-RegularExpressions::RequireExtendedFormatting] +[-InputOutput::ProhibitTwoArgOpen] +[-Modules::ProhibitEvilModules] + +# Turn this on +[Lax::ProhibitStringyEval::ExceptForRequire] + diff --git a/t/00-compile.t b/t/00-compile.t new file mode 100644 index 0000000..2747f2b --- /dev/null +++ b/t/00-compile.t @@ -0,0 +1,49 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.033 + +use Test::More tests => 1 + ($ENV{AUTHOR_TESTING} ? 1 : 0); + + + +my @module_files = ( + 'Test/FailWarnings.pm' +); + + + +# fake home for cpan-testers +use File::Temp; +local $ENV{HOME} = File::Temp::tempdir( CLEANUP => 1 ); + + +use File::Spec; +use IPC::Open3; +use IO::Handle; + +my @warnings; +for my $lib (@module_files) +{ + # see L + open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; + my $stderr = IO::Handle->new; + + my $pid = open3($stdin, '>&STDERR', $stderr, $^X, '-Mblib', '-e', "require q[$lib]"); + binmode $stderr, ':crlf' if $^O eq 'MSWin32'; + my @_warnings = <$stderr>; + waitpid($pid, 0); + is($? >> 8, 0, "$lib loaded ok"); + + if (@_warnings) + { + warn @_warnings; + push @warnings, @_warnings; + } +} + + + +is(scalar(@warnings), 0, 'no warnings found') if $ENV{AUTHOR_TESTING}; + + diff --git a/t/00-report-prereqs.t b/t/00-report-prereqs.t new file mode 100644 index 0000000..8bda3ee --- /dev/null +++ b/t/00-report-prereqs.t @@ -0,0 +1,71 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 1; + +use ExtUtils::MakeMaker; +use File::Spec::Functions; +use List::Util qw/max/; + +my @modules = qw( + Capture::Tiny + Carp + Cwd + ExtUtils::MakeMaker + File::Spec + File::Spec::Functions + File::Temp + IO::Handle + IPC::Open3 + List::Util + Test::More + constant + lib + perl + strict + warnings +); + +# replace modules with dynamic results from MYMETA.json if we can +# (hide CPAN::Meta from prereq scanner) +my $cpan_meta = "CPAN::Meta"; +if ( -f "MYMETA.json" && eval "require $cpan_meta" ) { ## no critic + if ( my $meta = eval { CPAN::Meta->load_file("MYMETA.json") } ) { + my $prereqs = $meta->prereqs; + delete $prereqs->{develop}; + my %uniq = map {$_ => 1} map { keys %$_ } map { values %$_ } values %$prereqs; + $uniq{$_} = 1 for @modules; # don't lose any static ones + @modules = sort keys %uniq; + } +} + +my @reports = [qw/Version Module/]; + +for my $mod ( @modules ) { + next if $mod eq 'perl'; + my $file = $mod; + $file =~ s{::}{/}g; + $file .= ".pm"; + my ($prefix) = grep { -e catfile($_, $file) } @INC; + if ( $prefix ) { + my $ver = MM->parse_version( catfile($prefix, $file) ); + $ver = "undef" unless defined $ver; # Newer MM should do this anyway + push @reports, [$ver, $mod]; + } + else { + push @reports, ["missing", $mod]; + } +} + +if ( @reports ) { + my $vl = max map { length $_->[0] } @reports; + my $ml = max map { length $_->[1] } @reports; + splice @reports, 1, 0, ["-" x $vl, "-" x $ml]; + diag "Prerequisite Report:\n", map {sprintf(" %*s %*s\n",$vl,$_->[0],-$ml,$_->[1])} @reports; +} + +pass; + +# vim: ts=2 sts=2 sw=2 et: diff --git a/t/bin/allow-constant.pl b/t/bin/allow-constant.pl new file mode 100644 index 0000000..a35b7d0 --- /dev/null +++ b/t/bin/allow-constant.pl @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings -allow_from => [qw/constant/]; + +use constant AUTOLOAD => 1; + +is( AUTOLOAD(), 1, "AUTOLOAD turned into a constant" ); + +done_testing; diff --git a/t/bin/allow-deps.pl b/t/bin/allow-deps.pl new file mode 100644 index 0000000..b4feb22 --- /dev/null +++ b/t/bin/allow-deps.pl @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings -allow_deps => 1; + +use constant AUTOLOAD => 1; + +is( AUTOLOAD(), 1, "AUTOLOAD turned into a constant" ); + +done_testing; diff --git a/t/bin/force-deps.pl b/t/bin/force-deps.pl new file mode 100644 index 0000000..c8ad7a5 --- /dev/null +++ b/t/bin/force-deps.pl @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings -allow_deps => 0; + +use constant AUTOLOAD => 1; + +is( AUTOLOAD(), 1, "AUTOLOAD turned into a constant" ); + +done_testing; diff --git a/t/bin/main-warn.pl b/t/bin/main-warn.pl new file mode 100644 index 0000000..cc62fd0 --- /dev/null +++ b/t/bin/main-warn.pl @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings; + +ok( 1, "first test" ); +ok( 1 + "lkadjaks", "add non-numeric" ); + +done_testing; diff --git a/t/bin/module-warn.pl b/t/bin/module-warn.pl new file mode 100644 index 0000000..a0bbd5f --- /dev/null +++ b/t/bin/module-warn.pl @@ -0,0 +1,11 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings; +use lib 't/lib'; +use Noisy; + +ok( 1, "first test" ); +ok( Noisy::do_it(), "call do_it" ); + +done_testing; diff --git a/t/bin/warn-newline.pl b/t/bin/warn-newline.pl new file mode 100644 index 0000000..5668ea5 --- /dev/null +++ b/t/bin/warn-newline.pl @@ -0,0 +1,11 @@ +use strict; +use warnings; +use Test::More; +use Test::FailWarnings; +use lib 't/lib'; +use Noisy; + +ok( 1, "first test" ); +ok( Noisy::with_newline(), "call with_newline" ); + +done_testing; diff --git a/t/failwarn.t b/t/failwarn.t new file mode 100644 index 0000000..48f9217 --- /dev/null +++ b/t/failwarn.t @@ -0,0 +1,65 @@ +use 5.008001; +use Test::More 0.96; +use Capture::Tiny 0.12 qw/capture/; + +use lib 't/lib'; + +my @cases = ( + { + label => "warning in .t", + file => "t/bin/main-warn.pl", + expect => qr/isn't numeric/, + }, + { + label => "warning from module", + file => "t/bin/module-warn.pl", + expect => qr/I am noisy/, + }, + { + label => "warning without line", + file => "t/bin/warn-newline.pl", + expect => qr/No line number/, + }, + { + label => "allow_deps true", + file => "t/bin/allow-deps.pl", + exit_ok => 1, + }, + { + label => "allow_deps false", + file => "t/bin/force-deps.pl", + expect => qr/is a Perl keyword/, + }, + { + label => "allow_from", + file => "t/bin/allow-constant.pl", + exit_ok => 1, + }, +); + +for my $c (@cases) { + my ( $output, $error, $rc ) = capture { system( $^X, $c->{file} ) }; + subtest $c->{label} => sub { + if ( $c->{exit_ok} ) { + ok( !$rc, "exit ok" ) + or diag "ERROR: $error"; + } + else { + ok( $rc, "nonzero exit" ); + like( $c->{stdout} ? $output : $error, $c->{expect}, "exception text" ); + } + }; +} + +done_testing; +# +# This file is part of Test-FailWarnings +# +# This software is Copyright (c) 2013 by David Golden. +# +# This is free software, licensed under: +# +# The Apache License, Version 2.0, January 2004 +# +# vim: ts=4 sts=4 sw=4 et: + diff --git a/t/lib/Noisy.pm b/t/lib/Noisy.pm new file mode 100644 index 0000000..356e450 --- /dev/null +++ b/t/lib/Noisy.pm @@ -0,0 +1,16 @@ +use 5.008001; +use strict; +use warnings; + +package Noisy; + +sub do_it { + warn "I am noisy"; +} + +sub with_newline { + warn "No line number\n"; +} + +1; + diff --git a/tidyall.ini b/tidyall.ini new file mode 100644 index 0000000..91aa246 --- /dev/null +++ b/tidyall.ini @@ -0,0 +1,5 @@ +; Install Code::TidyAll +; run "tidyall -a" to tidy all files +; run "tidyall -g" to tidy only files modified from git +[PerlTidy] +select = {lib,t}/**/*.{pl,pm,t} diff --git a/xt/author/critic.t b/xt/author/critic.t new file mode 100644 index 0000000..d5b4c96 --- /dev/null +++ b/xt/author/critic.t @@ -0,0 +1,12 @@ +#!perl + +use strict; +use warnings; + +use Test::More; +use English qw(-no_match_vars); + +eval "use Test::Perl::Critic"; +plan skip_all => 'Test::Perl::Critic required to criticise code' if $@; +Test::Perl::Critic->import( -profile => "perlcritic.rc" ) if -e "perlcritic.rc"; +all_critic_ok(); diff --git a/xt/author/pod-spell.t b/xt/author/pod-spell.t new file mode 100644 index 0000000..5dbdf2d --- /dev/null +++ b/xt/author/pod-spell.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006001 +use Test::Spelling 0.12; +use Pod::Wordlist; + + +add_stopwords(); +all_pod_files_spelling_ok( qw( bin lib ) ); +__DATA__ +David +Golden +dagolden +lib +Test +FailWarnings diff --git a/xt/release/distmeta.t b/xt/release/distmeta.t new file mode 100644 index 0000000..b46c7fc --- /dev/null +++ b/xt/release/distmeta.t @@ -0,0 +1,7 @@ +#!perl + +use Test::More; + +eval "use Test::CPAN::Meta"; +plan skip_all => "Test::CPAN::Meta required for testing META.yml" if $@; +meta_yaml_ok(); diff --git a/xt/release/minimum-version.t b/xt/release/minimum-version.t new file mode 100644 index 0000000..708ba15 --- /dev/null +++ b/xt/release/minimum-version.t @@ -0,0 +1,8 @@ +#!perl + +use Test::More; + +eval "use Test::MinimumVersion"; +plan skip_all => "Test::MinimumVersion required for testing minimum versions" + if $@; +all_minimum_version_ok( qq{5.010} ); diff --git a/xt/release/pod-coverage.t b/xt/release/pod-coverage.t new file mode 100644 index 0000000..b52218b --- /dev/null +++ b/xt/release/pod-coverage.t @@ -0,0 +1,13 @@ +#!perl + +use Test::More; + +eval "use Test::Pod::Coverage 1.08"; +plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage" + if $@; + +eval "use Pod::Coverage::TrustPod"; +plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage" + if $@; + +all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); diff --git a/xt/release/pod-syntax.t b/xt/release/pod-syntax.t new file mode 100644 index 0000000..8a22900 --- /dev/null +++ b/xt/release/pod-syntax.t @@ -0,0 +1,7 @@ +#!perl +use Test::More; + +eval "use Test::Pod 1.41"; +plan skip_all => "Test::Pod 1.41 required for testing POD" if $@; + +all_pod_files_ok(); diff --git a/xt/release/portability.t b/xt/release/portability.t new file mode 100644 index 0000000..58dbc20 --- /dev/null +++ b/xt/release/portability.t @@ -0,0 +1,12 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +eval 'use Test::Portability::Files'; +plan skip_all => 'Test::Portability::Files required for testing portability' + if $@; +options(test_one_dot => 0); +run_tests(); diff --git a/xt/release/test-version.t b/xt/release/test-version.t new file mode 100644 index 0000000..b7a0f17 --- /dev/null +++ b/xt/release/test-version.t @@ -0,0 +1,22 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::Version 0.002004 +BEGIN { eval "use Test::Version; 1;" or die $@; } + +my @imports = ( 'version_all_ok' ); + +my $params = { + is_strict => 0, + has_version => 1, +}; + +push @imports, $params + if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); + + +Test::Version->import(@imports); + +version_all_ok; +done_testing;