diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-06-14 16:34:55 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-06-14 16:34:55 +0000 |
commit | 2e0d2bec52bd345ef05ea12ea9052643ef135029 (patch) | |
tree | d128cd9759bc672fa01bac1561911aa8a895981b /t | |
download | Log-Dispatch-tarball-2e0d2bec52bd345ef05ea12ea9052643ef135029.tar.gz |
Log-Dispatch-2.45HEADLog-Dispatch-2.45master
Diffstat (limited to 't')
-rw-r--r-- | t/00-compile.t | 38 | ||||
-rw-r--r-- | t/00-report-prereqs.dd | 60 | ||||
-rw-r--r-- | t/00-report-prereqs.t | 183 | ||||
-rw-r--r-- | t/01-basic.t | 1195 | ||||
-rw-r--r-- | t/02-email-exit.t | 15 | ||||
-rw-r--r-- | t/03-short-syntax.t | 77 | ||||
-rw-r--r-- | t/04-binmode.t | 54 | ||||
-rw-r--r-- | t/05-close-after-write.t | 97 | ||||
-rw-r--r-- | t/06-syslog.t | 66 | ||||
-rw-r--r-- | t/author-eol.t | 60 | ||||
-rw-r--r-- | t/author-no-tabs.t | 60 | ||||
-rw-r--r-- | t/author-pod-spell.t | 97 | ||||
-rwxr-xr-x | t/email-exit-helper.pl | 20 | ||||
-rw-r--r-- | t/lib/Log/Dispatch/TestUtil.pm | 44 | ||||
-rw-r--r-- | t/release-cpan-changes.t | 19 | ||||
-rw-r--r-- | t/release-pod-coverage.t | 63 | ||||
-rw-r--r-- | t/release-pod-no404s.t | 29 | ||||
-rw-r--r-- | t/release-pod-syntax.t | 14 | ||||
-rw-r--r-- | t/release-portability.t | 20 | ||||
-rw-r--r-- | t/release-test-version.t | 46 | ||||
-rw-r--r-- | t/release-tidyall.t | 17 | ||||
-rwxr-xr-x | t/sendmail | 3 |
22 files changed, 2277 insertions, 0 deletions
diff --git a/t/00-compile.t b/t/00-compile.t new file mode 100644 index 0000000..9e006b4 --- /dev/null +++ b/t/00-compile.t @@ -0,0 +1,38 @@ +use strict; +use warnings; + +use Test::More; + +my %deps = ( + ApacheLog => 'Apache::Log', + Code => q{}, + File => q{}, + 'File::Locked' => q{}, + Handle => q{}, + Null => q{}, + Screen => q{}, + Syslog => 'Sys::Syslog 0.28', + 'Email::MailSend' => 'Mail::Send', + 'Email::MIMELite' => 'MIME::Lite', + 'Email::MailSendmail' => 'Mail::Sendmail', + 'Email::MailSender' => 'Mail::Sender', +); + +use_ok('Log::Dispatch'); + +for my $subclass ( sort keys %deps ) { + my $module = "Log::Dispatch::$subclass"; + + if ( !$deps{$subclass} + || ( eval "use $deps{$subclass}; 1" && !$@ ) ) { + use_ok($module); + } + else { + SKIP: + { + skip "Cannot load $module without $deps{$subclass}", 1; + } + } +} + +done_testing(); diff --git a/t/00-report-prereqs.dd b/t/00-report-prereqs.dd new file mode 100644 index 0000000..0f214b2 --- /dev/null +++ b/t/00-report-prereqs.dd @@ -0,0 +1,60 @@ +do { my $x = { + 'configure' => { + 'requires' => { + 'Dist::CheckConflicts' => '0.02', + 'ExtUtils::MakeMaker' => '0' + } + }, + 'develop' => { + 'requires' => { + 'Code::TidyAll' => '0.24', + 'Perl::Critic' => '1.123', + 'Perl::Tidy' => '20140711', + 'Pod::Coverage::TrustPod' => '0', + 'Test::CPAN::Changes' => '0.19', + 'Test::Code::TidyAll' => '0.24', + 'Test::EOL' => '0', + 'Test::More' => '0.88', + 'Test::NoTabs' => '0', + 'Test::Pod' => '1.41', + 'Test::Pod::Coverage' => '1.08', + 'Test::Spelling' => '0.12', + 'Test::Version' => '1' + } + }, + 'runtime' => { + 'requires' => { + 'Carp' => '0', + 'Devel::GlobalDestruction' => '0', + 'Dist::CheckConflicts' => '0.02', + 'Fcntl' => '0', + 'Module::Runtime' => '0', + 'Params::Validate' => '0.15', + 'Scalar::Util' => '0', + 'Sys::Syslog' => '0.28', + 'base' => '0', + 'perl' => '5.006', + 'strict' => '0', + 'warnings' => '0' + } + }, + 'test' => { + 'recommends' => { + 'CPAN::Meta' => '2.120900' + }, + 'requires' => { + 'Data::Dumper' => '0', + 'Exporter' => '0', + 'ExtUtils::MakeMaker' => '0', + 'File::Spec' => '0', + 'File::Temp' => '0', + 'IO::File' => '0', + 'Test::Fatal' => '0', + 'Test::More' => '0.96', + 'Test::Requires' => '0', + 'lib' => '0' + } + } + }; + $x; + }
\ No newline at end of file diff --git a/t/00-report-prereqs.t b/t/00-report-prereqs.t new file mode 100644 index 0000000..d8d15ba --- /dev/null +++ b/t/00-report-prereqs.t @@ -0,0 +1,183 @@ +#!perl + +use strict; +use warnings; + +# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021 + +use Test::More tests => 1; + +use ExtUtils::MakeMaker; +use File::Spec; + +# from $version::LAX +my $lax_version_re = + qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? + | + (?:\.[0-9]+) (?:_[0-9]+)? + ) | (?: + v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? + | + (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? + ) + )/x; + +# hide optional CPAN::Meta modules from prereq scanner +# and check if they are available +my $cpan_meta = "CPAN::Meta"; +my $cpan_meta_pre = "CPAN::Meta::Prereqs"; +my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic + +# Verify requirements? +my $DO_VERIFY_PREREQS = 1; + +sub _max { + my $max = shift; + $max = ( $_ > $max ) ? $_ : $max for @_; + return $max; +} + +sub _merge_prereqs { + my ($collector, $prereqs) = @_; + + # CPAN::Meta::Prereqs object + if (ref $collector eq $cpan_meta_pre) { + return $collector->with_merged_prereqs( + CPAN::Meta::Prereqs->new( $prereqs ) + ); + } + + # Raw hashrefs + for my $phase ( keys %$prereqs ) { + for my $type ( keys %{ $prereqs->{$phase} } ) { + for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { + $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; + } + } + } + + return $collector; +} + +my @include = qw( + +); + +my @exclude = qw( + +); + +# Add static prereqs to the included modules list +my $static_prereqs = do 't/00-report-prereqs.dd'; + +# Merge all prereqs (either with ::Prereqs or a hashref) +my $full_prereqs = _merge_prereqs( + ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), + $static_prereqs +); + +# Add dynamic prereqs to the included modules list (if we can) +my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; +if ( $source && $HAS_CPAN_META ) { + if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { + $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); + } +} +else { + $source = 'static metadata'; +} + +my @full_reports; +my @dep_errors; +my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; + +# Add static includes into a fake section +for my $mod (@include) { + $req_hash->{other}{modules}{$mod} = 0; +} + +for my $phase ( qw(configure build test runtime develop other) ) { + next unless $req_hash->{$phase}; + next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); + + for my $type ( qw(requires recommends suggests conflicts modules) ) { + next unless $req_hash->{$phase}{$type}; + + my $title = ucfirst($phase).' '.ucfirst($type); + my @reports = [qw/Module Want Have/]; + + for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { + next if $mod eq 'perl'; + next if grep { $_ eq $mod } @exclude; + + my $file = $mod; + $file =~ s{::}{/}g; + $file .= ".pm"; + my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; + + my $want = $req_hash->{$phase}{$type}{$mod}; + $want = "undef" unless defined $want; + $want = "any" if !$want && $want == 0; + + my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; + + if ($prefix) { + my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); + $have = "undef" unless defined $have; + push @reports, [$mod, $want, $have]; + + if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { + if ( $have !~ /\A$lax_version_re\z/ ) { + push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; + } + elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { + push @dep_errors, "$mod version '$have' is not in required range '$want'"; + } + } + } + else { + push @reports, [$mod, $want, "missing"]; + + if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { + push @dep_errors, "$mod is not installed ($req_string)"; + } + } + } + + if ( @reports ) { + push @full_reports, "=== $title ===\n\n"; + + my $ml = _max( map { length $_->[0] } @reports ); + my $wl = _max( map { length $_->[1] } @reports ); + my $hl = _max( map { length $_->[2] } @reports ); + + if ($type eq 'modules') { + splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; + push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; + } + else { + splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; + push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; + } + + push @full_reports, "\n"; + } + } +} + +if ( @full_reports ) { + diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; +} + +if ( @dep_errors ) { + diag join("\n", + "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", + "The following REQUIRED prerequisites were not satisfied:\n", + @dep_errors, + "\n" + ); +} + +pass; + +# vim: ts=4 sts=4 sw=4 et: diff --git a/t/01-basic.t b/t/01-basic.t new file mode 100644 index 0000000..293b098 --- /dev/null +++ b/t/01-basic.t @@ -0,0 +1,1195 @@ +use strict; +use warnings; + +use Test::More 0.88; +use Test::Fatal; + +use File::Spec; +use File::Temp qw( tempdir ); +use Module::Runtime qw( use_module ); + +use Log::Dispatch; + +my %tests; + +BEGIN { + local $@; + foreach (qw( MailSend MIMELite MailSendmail MailSender )) { + eval "use Log::Dispatch::Email::$_"; + $tests{$_} = !$@; + $tests{$_} = 0 if $ENV{LD_NO_MAIL}; + } +} + +my %TestConfig; +if ( my $email_address = $ENV{LOG_DISPATCH_TEST_EMAIL} ) { + %TestConfig = ( email_address => $email_address ); +} + +my @syswrite_strs; + +BEGIN { + if ( $] >= 5.016 ) { + my $syswrite = \&CORE::syswrite; + *CORE::GLOBAL::syswrite = sub { + my ( $fh, $str, @other ) = @_; + push @syswrite_strs, $_[1]; + + return $syswrite->( $fh, $str, @other ); + }; + } +} + +use Log::Dispatch::File; +use Log::Dispatch::Handle; +use Log::Dispatch::Null; +use Log::Dispatch::Screen; + +use IO::File; + +my $tempdir = tempdir( CLEANUP => 1 ); + +my $dispatch = Log::Dispatch->new; +ok( $dispatch, "created Log::Dispatch object" ); + +# Test Log::Dispatch::File +{ + my $emerg_log = File::Spec->catdir( $tempdir, 'emerg.log' ); + + $dispatch->add( + Log::Dispatch::File->new( + name => 'file1', + min_level => 'emerg', + filename => $emerg_log + ) + ); + + $dispatch->log( level => 'info', message => "info level 1\n" ); + $dispatch->log( level => 'emerg', message => "emerg level 1\n" ); + + my $debug_log = File::Spec->catdir( $tempdir, 'debug.log' ); + + $dispatch->add( + Log::Dispatch::File->new( + name => 'file2', + min_level => 'debug', + syswrite => 1, + filename => $debug_log + ) + ); + + my %outputs = map { $_->name() => ref $_ } $dispatch->outputs(); + is_deeply( + \%outputs, { + file1 => 'Log::Dispatch::File', + file2 => 'Log::Dispatch::File', + }, + '->outputs() method returns all output objects' + ); + + $dispatch->log( level => 'info', message => "info level 2\n" ); + $dispatch->log( level => 'emerg', message => "emerg level 2\n" ); + + # This'll close them filehandles! + undef $dispatch; + + open my $emerg_fh, '<', $emerg_log + or die "Can't read $emerg_log: $!"; + open my $debug_fh, '<', $debug_log + or die "Can't read $debug_log: $!"; + + my @log = <$emerg_fh>; + is( + $log[0], "emerg level 1\n", + "First line in log file set to level 'emerg' is 'emerg level 1'" + ); + + is( + $log[1], "emerg level 2\n", + "Second line in log file set to level 'emerg' is 'emerg level 2'" + ); + + @log = <$debug_fh>; + is( + $log[0], "info level 2\n", + "First line in log file set to level 'debug' is 'info level 2'" + ); + + is( + $log[1], "emerg level 2\n", + "Second line in log file set to level 'debug' is 'emerg level 2'" + ); + +SKIP: + { + skip 'This test requires Perl 5.16+', 1 + unless $] >= 5.016; + is_deeply( + \@syswrite_strs, + [ + "info level 2\n", + "emerg level 2\n", + ], + 'second LD object used syswrite', + ); + } +} + +# max_level test +{ + my $max_log = File::Spec->catfile( $tempdir, 'max.log' ); + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::File->new( + name => 'file1', + min_level => 'debug', + max_level => 'crit', + filename => $max_log + ) + ); + + $dispatch->log( level => 'emerg', message => "emergency\n" ); + $dispatch->log( level => 'crit', message => "critical\n" ); + + undef $dispatch; # close file handles + + open my $fh, '<', $max_log + or die "Can't read $max_log: $!"; + my @log = <$fh>; + + is( + $log[0], "critical\n", + "First line in log file with a max level of 'crit' is 'critical'" + ); +} + +# Log::Dispatch::Handle test +{ + my $handle_log = File::Spec->catfile( $tempdir, 'handle.log' ); + + my $fh = IO::File->new( $handle_log, 'w' ) + or die "Can't write to $handle_log: $!"; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::Handle->new( + name => 'handle', + min_level => 'debug', + handle => $fh + ) + ); + + $dispatch->log( level => 'notice', message => "handle test\n" ); + + # close file handles + undef $dispatch; + undef $fh; + + open $fh, '<', $handle_log + or die "Can't open $handle_log: $!"; + + my @log = <$fh>; + + close $fh; + + is( + $log[0], "handle test\n", + "Log::Dispatch::Handle created log file should contain 'handle test\\n'" + ); +} + +# Log::Dispatch::Email::MailSend +SKIP: +{ + skip "Cannot do MailSend tests", 1 + unless $tests{MailSend} && $TestConfig{email_address}; + + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Email::MailSend->new( + name => 'Mail::Send', + min_level => 'debug', + to => $TestConfig{email_address}, + subject => 'Log::Dispatch test suite' + ) + ); + + $dispatch->log( + level => 'emerg', + message => + "Mail::Send test - If you can read this then the test succeeded (PID $$)" + ); + + diag( + "Sending email with Mail::Send to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" + ); + undef $dispatch; + + ok( 1, 'sent email via MailSend' ); +} + +# Log::Dispatch::Email::MailSendmail +SKIP: +{ + skip "Cannot do MailSendmail tests", 1 + unless $tests{MailSendmail} && $TestConfig{email_address}; + + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Email::MailSendmail->new( + name => 'Mail::Sendmail', + min_level => 'debug', + to => $TestConfig{email_address}, + subject => 'Log::Dispatch test suite' + ) + ); + + $dispatch->log( + level => 'emerg', + message => + "Mail::Sendmail test - If you can read this then the test succeeded (PID $$)" + ); + + diag( + "Sending email with Mail::Sendmail to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" + ); + undef $dispatch; + + ok( 1, 'sent email via MailSendmail' ); +} + +# Log::Dispatch::Email::MIMELite +SKIP: +{ + + skip "Cannot do MIMELite tests", 1 + unless $tests{MIMELite} && $TestConfig{email_address}; + + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Email::MIMELite->new( + name => 'Mime::Lite', + min_level => 'debug', + to => $TestConfig{email_address}, + subject => 'Log::Dispatch test suite' + ) + ); + + $dispatch->log( + level => 'emerg', + message => + "MIME::Lite - If you can read this then the test succeeded (PID $$)" + ); + + diag( + "Sending email with MIME::Lite to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" + ); + undef $dispatch; + + ok( 1, 'sent mail via MIMELite' ); +} + +# Log::Dispatch::Screen +{ + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Screen->new( + name => 'screen', + min_level => 'debug', + stderr => 0 + ) + ); + + my $text; + tie *STDOUT, 'Test::Tie::STDOUT', \$text; + $dispatch->log( level => 'crit', message => 'testing screen' ); + untie *STDOUT; + + is( + $text, 'testing screen', + "Log::Dispatch::Screen outputs to STDOUT" + ); +} + +# Log::Dispatch::Output->accepted_levels +{ + my $l = Log::Dispatch::Screen->new( + name => 'foo', + min_level => 'warning', + max_level => 'alert', + stderr => 0 + ); + + my @expected = qw(warning error critical alert); + my @levels = $l->accepted_levels; + + my $pass = 1; + for ( my $x = 0; $x < scalar @expected; $x++ ) { + $pass = 0 unless $expected[$x] eq $levels[$x]; + } + + is( + scalar @expected, scalar @levels, + "number of levels matched" + ); + + ok( $pass, "levels matched" ); +} + +# Log::Dispatch single callback +{ + my $reverse = sub { my %p = @_; return reverse $p{message}; }; + my $dispatch = Log::Dispatch->new( callbacks => $reverse ); + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => 'warning', + max_level => 'alert', + ) + ); + + $dispatch->log( level => 'warning', message => 'esrever' ); + + is( + $string, 'reverse', + "callback to reverse text" + ); +} + +# Log::Dispatch multiple callbacks +{ + my $reverse = sub { my %p = @_; return reverse $p{message}; }; + my $uc = sub { my %p = @_; return uc $p{message}; }; + + my $dispatch = Log::Dispatch->new( callbacks => [ $reverse, $uc ] ); + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => 'warning', + max_level => 'alert', + ) + ); + + $dispatch->log( level => 'warning', message => 'esrever' ); + + is( + $string, 'REVERSE', + "callback to reverse and uppercase text" + ); + + is_deeply( + [ $dispatch->callbacks() ], + [ $reverse, $uc ], + '->callbacks() method returns all of the callback subs' + ); + + my $clone = $dispatch->clone(); + is_deeply( + $clone, + $dispatch, + 'clone is a shallow clone of the original object' + ); + + $clone->add( + Log::Dispatch::Screen->new( + name => 'screen', + min_level => 'debug', + ) + ); + my @orig_outputs = map { $_->name() } $dispatch->outputs(); + my @clone_outputs = map { $_->name() } $clone->outputs(); + isnt( + scalar(@orig_outputs), + scalar(@clone_outputs), + 'clone is not the same as original after adding an output' + ); + + $clone->add_callback( sub { return 'foo' } ); + my @orig_cb = $dispatch->callbacks(); + my @clone_cb = $clone->callbacks(); + isnt( + scalar(@orig_cb), + scalar(@clone_cb), + 'clone is not the same as original after adding a callback' + ); +} + +# Log::Dispatch::Output single callback +{ + my $reverse = sub { my %p = @_; return reverse $p{message}; }; + + my $dispatch = Log::Dispatch->new; + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => 'warning', + max_level => 'alert', + callbacks => $reverse + ) + ); + + $dispatch->log( level => 'warning', message => 'esrever' ); + + is( + $string, 'reverse', + "Log::Dispatch::Output callback to reverse text" + ); +} + +# Log::Dispatch::Output multiple callbacks +{ + my $reverse = sub { my %p = @_; return reverse $p{message}; }; + my $uc = sub { my %p = @_; return uc $p{message}; }; + + my $dispatch = Log::Dispatch->new; + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => 'warning', + max_level => 'alert', + callbacks => [ $reverse, $uc ] + ) + ); + + $dispatch->log( level => 'warning', message => 'esrever' ); + + is( + $string, 'REVERSE', + "Log::Dispatch::Output callbacks to reverse and uppercase text" + ); +} + +# test level parameter to callbacks +{ + my $level = sub { my %p = @_; return uc $p{level}; }; + + my $dispatch = Log::Dispatch->new( callbacks => $level ); + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => 'warning', + max_level => 'alert', + stderr => 0 + ) + ); + + $dispatch->log( level => 'warning', message => 'esrever' ); + + is( + $string, 'WARNING', + "Log::Dispatch callback to uppercase the level parameter" + ); +} + +# Comprehensive test of new methods that match level names +{ + my %levels = map { $_ => $_ } + (qw( debug info notice warning error critical alert emergency )); + @levels{qw( warn err crit emerg )} + = (qw( warning error critical emergency )); + + foreach my $allowed_level ( + qw( debug info notice warning error critical alert emergency )) { + my $dispatch = Log::Dispatch->new; + + my $string; + $dispatch->add( + Log::Dispatch::String->new( + name => 'foo', + string => \$string, + min_level => $allowed_level, + max_level => $allowed_level, + ) + ); + + foreach my $test_level ( + qw( debug info notice warn warning err + error crit critical alert emerg emergency ) + ) { + $string = ''; + $dispatch->$test_level( $test_level, 'test' ); + + if ( $levels{$test_level} eq $allowed_level ) { + my $expect = join $", $test_level, 'test'; + is( + $string, $expect, + "Calling $test_level method should send message '$expect'" + ); + } + else { + ok( + !length $string, + "Calling $test_level method should not log anything" + ); + } + } + } +} + +{ + my $string; + my $dispatch = Log::Dispatch->new( + outputs => [ + [ + 'String', + name => 'string', + string => \$string, + min_level => 'debug', + ], + ], + ); + + $dispatch->debug( 'foo', 'bar' ); + is( + $string, + 'foo bar', + 'passing multiple elements to ->debug stringifies them like an array' + ); + + $string = q{}; + $dispatch->debug( sub {'foo'} ); + is( + $string, + 'foo', + 'passing single sub ref to ->debug calls the sub ref' + ); + +} + +# Log::Dispatch->level_is_valid method +{ + foreach my $l ( + qw( debug info notice warning err error + crit critical alert emerg emergency ) + ) { + ok( Log::Dispatch->level_is_valid($l), "$l is valid level" ); + } + + foreach my $l (qw( debu inf foo bar )) { + ok( !Log::Dispatch->level_is_valid($l), "$l is not valid level" ); + } + + # Provide calling line if level missing + my $string; + my $dispatch = Log::Dispatch->new( + outputs => [ + [ + 'String', + name => 'string', + string => \$string, + min_level => 'debug', + ], + ], + ); + + like( + exception { $dispatch->log( msg => "Message" ) }, + qr/Logging level was not provided at .* line \d+./, + "Provide calling line if level not provided" + ); +} + +# make sure passing mode as write works +{ + my $mode_log = File::Spec->catfile( $tempdir, 'mode.log' ); + + my $f1 = Log::Dispatch::File->new( + name => 'file', + min_level => 1, + filename => $mode_log, + mode => 'write', + ); + $f1->log( + level => 'emerg', + message => "test2\n" + ); + + undef $f1; + + open my $fh, '<', $mode_log + or die "Cannot read $mode_log: $!"; + my $data = join '', <$fh>; + close $fh; + + like( $data, qr/^test2/, "test write mode" ); +} + +# Log::Dispatch::Email::MailSender +SKIP: +{ + skip "Cannot do MailSender tests", 1 + unless $tests{MailSender} && $TestConfig{email_address}; + + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Email::MailSender->new( + name => 'Mail::Sender', + min_level => 'debug', + smtp => 'localhost', + to => $TestConfig{email_address}, + subject => 'Log::Dispatch test suite' + ) + ); + + $dispatch->log( + level => 'emerg', + message => + "Mail::Sender - If you can read this then the test succeeded (PID $$)" + ); + + diag( + "Sending email with Mail::Sender to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" + ); + undef $dispatch; + + ok( 1, 'sent email via MailSender' ); +} + +# dispatcher exists +{ + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Screen->new( + name => 'yomama', + min_level => 'alert' + ) + ); + + ok( + $dispatch->output('yomama'), + "yomama output should exist" + ); + + ok( + !$dispatch->output('nomama'), + "nomama output should not exist" + ); +} + +# Test Log::Dispatch::File - close_after_write & permissions +{ + my $dispatch = Log::Dispatch->new; + + my $close_log = File::Spec->catfile( $tempdir, 'close.log' ); + + $dispatch->add( + Log::Dispatch::File->new( + name => 'close', + min_level => 'info', + filename => $close_log, + permissions => 0777, + close_after_write => 1 + ) + ); + + $dispatch->log( level => 'info', message => "info\n" ); + + open my $fh, '<', $close_log + or die "Can't read $close_log: $!"; + + my @log = <$fh>; + close $fh; + + is( + $log[0], "info\n", + "First line in log file should be 'info\\n'" + ); + + my $mode = ( stat $close_log )[2] + or die "Cannot stat $close_log: $!"; + + my $mode_string = sprintf( '%04o', $mode & 07777 ); + + if ( $^O =~ /win32/i ) { + ok( + $mode_string == '0777' || $mode_string == '0666', + "Mode should be 0777 or 0666" + ); + } + elsif ( $^O =~ /cygwin/i ) { + ok( + $mode_string == '0777' || $mode_string == '0644', + "Mode should be 0777 or 0644" + ); + } + else { + is( + $mode_string, '0777', + "Mode should be 0777" + ); + } +} + +{ + my $dispatch = Log::Dispatch->new; + + my $chmod_log = File::Spec->catfile( $tempdir, 'chmod.log' ); + + open my $fh, '>', $chmod_log + or die "Cannot write to $chmod_log: $!"; + close $fh; + + chmod 0777, $chmod_log + or die "Cannot chmod 0777 $chmod_log: $!"; + + my @chmod; + no warnings 'once'; + local *CORE::GLOBAL::chmod = sub { @chmod = @_; warn @chmod }; + + $dispatch->add( + Log::Dispatch::File->new( + name => 'chmod', + min_level => 'info', + filename => $chmod_log, + permissions => 0777, + ) + ); + + $dispatch->warning('test'); + + ok( + !scalar @chmod, + 'chmod() was not called when permissions already matched what was specified' + ); +} + +SKIP: +{ + skip "Cannot test utf8 files with this version of Perl ($])", 1 + unless $] >= 5.008; + + my $dispatch = Log::Dispatch->new; + + my $utf8_log = File::Spec->catfile( $tempdir, 'utf8.log' ); + + $dispatch->add( + Log::Dispatch::File->new( + name => 'utf8', + min_level => 'info', + filename => $utf8_log, + binmode => ':encoding(UTF-8)', + ) + ); + + my @warnings; + + { + local $SIG{__WARN__} = sub { push @warnings, @_ }; + $dispatch->warning("\x{999A}"); + } + + ok( + !scalar @warnings, + 'utf8 binmode was applied to file and no warnings were issued' + ); +} + +# would_log +{ + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Null->new( + name => 'null', + min_level => 'warning', + ) + ); + + ok( + !$dispatch->would_log('foo'), + "will not log 'foo'" + ); + + ok( + !$dispatch->would_log('debug'), + "will not log 'debug'" + ); + + ok( + !$dispatch->is_debug(), + 'is_debug returns false' + ); + + ok( + $dispatch->is_warning(), + 'is_warning returns true' + ); + + ok( + $dispatch->would_log('crit'), + "will log 'crit'" + ); + + ok( + $dispatch->is_crit, + "will log 'crit'" + ); +} + +{ + my $dispatch = Log::Dispatch->new; + + $dispatch->add( + Log::Dispatch::Null->new( + name => 'null', + min_level => 'info', + max_level => 'critical', + ) + ); + + my $called = 0; + my $message = sub { $called = 1 }; + + $dispatch->log( level => 'debug', message => $message ); + ok( !$called, 'subref is not called if the message would not be logged' ); + + $called = 0; + $dispatch->log( level => 'warning', message => $message ); + ok( $called, 'subref is called when message is logged' ); + + $called = 0; + $dispatch->log( level => 'emergency', message => $message ); + ok( !$called, 'subref is not called when message would not be logged' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + $dispatch->log( + level => 'debug', + message => sub {'this is my message'}, + ); + + is( + $string, 'this is my message', + 'message returned by subref is logged' + ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + newline => 1, + ) + ); + $dispatch->debug('hello'); + $dispatch->debug('goodbye'); + + is( $string, "hello\ngoodbye\n", 'added newlines' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + my $e = exception { + $dispatch->log_and_die( + level => 'error', + message => 'this is my message', + ); + }; + + ok( $e, 'died when calling log_and_die()' ); + like( $e, qr{this is my message}, 'error contains expected message' ); + like( $e, qr{01-basic\.t line 9\d\d}, 'error croaked' ); + + is( $string, 'this is my message', 'message is logged' ); + + undef $string; + + $e = do { + local $@; + eval { Croaker::croak($dispatch) }; + $@; + }; + + ok( $e, 'died when calling log_and_croak()' ); + like( $e, qr{croak}, 'error contains expected message' ); + like( + $e, qr{01-basic\.t line 10005}, + 'error croaked from perspective of caller' + ); + + is( $string, 'croak', 'message is logged' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'foo', 'first test w/o callback' ); + + $string = ''; + $dispatch->add_callback( sub { return 'bar' } ); + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'bar', 'second call, callback overrides message' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new( + callbacks => sub { return 'baz' }, + ); + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'baz', 'first test gets orig callback result' ); + + $string = ''; + $dispatch->add_callback( sub { return 'bar' } ); + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'bar', 'second call, callback overrides message' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'foo', 'first test w/o callback' ); + + $string = ''; + $dispatch->add_callback( sub { return 'bar' } ); + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'bar', 'second call, callback overrides message' ); +} + +{ + my $string; + + my $dispatch = Log::Dispatch->new( + callbacks => sub { return 'baz' }, + ); + $dispatch->add( + Log::Dispatch::String->new( + name => 'handle', + string => \$string, + min_level => 'debug', + ) + ); + + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'baz', 'first test gets orig callback result' ); + + $string = ''; + $dispatch->add_callback( sub { return 'bar' } ); + $dispatch->log( level => 'debug', message => 'foo' ); + is( $string, 'bar', 'second call, callback overrides message' ); +} + +{ + + # Test defaults + my $dispatch = Log::Dispatch::Null->new( min_level => 'debug' ); + like( $dispatch->name, qr/anon/, 'generated anon name' ); + is( $dispatch->max_level, 'emergency', 'max_level is emergency' ); +} + +{ + my $level; + my $record_level = sub { + my %p = @_; + $level = $p{level}; + return %p; + }; + + my $dispatch = Log::Dispatch->new( + callbacks => $record_level, + outputs => [ + [ + 'Null', + name => 'null', + min_level => 'debug', + ], + ], + ); + + $dispatch->warn('foo'); + is( + $level, + 'warning', + 'level for call to ->warn is warning' + ); + + $dispatch->err('foo'); + is( + $level, + 'error', + 'level for call to ->err is error' + ); + + $dispatch->crit('foo'); + is( + $level, + 'critical', + 'level for call to ->crit is critical' + ); + + $dispatch->emerg('foo'); + is( + $level, + 'emergency', + 'level for call to ->emerg is emergency' + ); +} + +{ + my @calls; + my $log = Log::Dispatch->new( + outputs => [ + [ + 'Code', + min_level => 'error', + code => sub { push @calls, {@_} }, + ], + ] + ); + + $log->error('foo'); + $log->info('bar'); + $log->critical('baz'); + + is_deeply( + \@calls, + [ + { + level => 'error', + message => 'foo', + }, { + level => 'critical', + message => 'baz', + }, + ], + 'code received the expected messages' + ); +} + +done_testing(); + +package Log::Dispatch::String; + +use strict; + +use Log::Dispatch::Output; + +use base qw( Log::Dispatch::Output ); + +sub new { + my $proto = shift; + my $class = ref $proto || $proto; + my %p = @_; + + my $self = bless { string => $p{string} }, $class; + + $self->_basic_init(%p); + + return $self; +} + +sub log_message { + my $self = shift; + my %p = @_; + + ${ $self->{string} } .= $p{message}; +} + +# Used for testing Log::Dispatch::Screen +package Test::Tie::STDOUT; + +sub TIEHANDLE { + my $class = shift; + my $self = {}; + $self->{string} = shift; + ${ $self->{string} } ||= ''; + + return bless $self, $class; +} + +sub PRINT { + my $self = shift; + ${ $self->{string} } .= join '', @_; +} + +sub PRINTF { + my $self = shift; + my $format = shift; + ${ $self->{string} } .= sprintf( $format, @_ ); +} + +#line 10000 +package Croaker; + +sub croak { + my $log = shift; + + $log->log_and_croak( level => 'error', message => 'croak' ); +} diff --git a/t/02-email-exit.t b/t/02-email-exit.t new file mode 100644 index 0000000..056b52e --- /dev/null +++ b/t/02-email-exit.t @@ -0,0 +1,15 @@ +use strict; +use warnings; + +use Test::More; + +unless ( -d '.git' ) { + plan skip_all => 'This test only runs for the maintainer'; + exit; +} + +system( $^X, 't/email-exit-helper.pl' ); + +is( $? >> 8, 5, 'exit code of helper was 5' ); + +done_testing(); diff --git a/t/03-short-syntax.t b/t/03-short-syntax.t new file mode 100644 index 0000000..2b972bd --- /dev/null +++ b/t/03-short-syntax.t @@ -0,0 +1,77 @@ +use strict; +use warnings; +use lib qw(t/lib); +use Test::More; +use Log::Dispatch; +use Log::Dispatch::TestUtil qw(cmp_deeply); +use File::Temp qw( tempdir ); + +my $tempdir = tempdir( CLEANUP => 1 ); + +{ + my $emerg_log = File::Spec->catdir( $tempdir, 'emerg.log' ); + + # Short syntax + my $dispatch0 = Log::Dispatch->new( + outputs => [ + [ + 'File', name => 'file', min_level => 'emerg', + filename => $emerg_log + ], + [ + '+Log::Dispatch::Screen', name => 'screen', + min_level => 'debug' + ] + ] + ); + + # Short syntax alternate (2.23) + my $dispatch1 = Log::Dispatch->new( + outputs => [ + 'File' => { + name => 'file', min_level => 'emerg', filename => $emerg_log + }, + '+Log::Dispatch::Screen' => + { name => 'screen', min_level => 'debug' } + ] + ); + + # Long syntax + my $dispatch2 = Log::Dispatch->new; + $dispatch2->add( + Log::Dispatch::File->new( + name => 'file', + min_level => 'emerg', + filename => $emerg_log + ) + ); + $dispatch2->add( + Log::Dispatch::Screen->new( name => 'screen', min_level => 'debug' ) + ); + + cmp_deeply( + $dispatch0, $dispatch2, + "created equivalent dispatchers - 0" + ); + cmp_deeply( + $dispatch1, $dispatch2, + "created equivalent dispatchers - 1" + ); +} + +{ + eval { Log::Dispatch->new( outputs => ['File'] ) }; + like( + $@, qr/expected arrayref/, + "got error for expected inner arrayref" + ); +} +{ + eval { Log::Dispatch->new( outputs => 'File' ) }; + like( + $@, qr/not one of the allowed types: arrayref/, + "got error for expected outer arrayref" + ); +} + +done_testing(); diff --git a/t/04-binmode.t b/t/04-binmode.t new file mode 100644 index 0000000..b5ac1fd --- /dev/null +++ b/t/04-binmode.t @@ -0,0 +1,54 @@ +use strict; +use warnings; + +use File::Spec; +use File::Temp qw( tempdir ); +use Test::More 0.88; + +use Log::Dispatch; +use Log::Dispatch::File; + +plan skip_all => "Cannot test utf8 files with this version of Perl ($])" + unless $] >= 5.008; + +my $dir = tempdir( CLEANUP => 1 ); + +my %params = ( + name => 'file', + min_level => 'debug', + filename => File::Spec->catfile( $dir, 'logfile_X.txt' ), +); + +my @tests = ( + { + params => { %params, 'binmode' => ':utf8' }, + message => "foo bar\x{20AC}", + expected_message => "foo bar\xe2\x82\xac", + }, +); + +my $count = 0; +for my $t (@tests) { + my $dispatcher = Log::Dispatch->new(); + ok( $dispatcher, 'got a logger object' ); + + $t->{params}{filename} =~ s/X\.txt$/$count++ . '.txt'/e; + my $file = $t->{params}{filename}; + + my $logger = Log::Dispatch::File->new( %{ $t->{params} } ); + ok( $logger, 'got a file output object' ); + + $dispatcher->add($logger); + $dispatcher->log( level => 'info', message => $t->{message} ); + + ok( -e $file, "$file exists" ); + open my $fh, '<', $file; + + my $line = do { local $/; <$fh> }; + close $fh; + + is( $line, $t->{expected_message}, 'output contains UTF-8 bytes' ); +} + +done_testing(); + diff --git a/t/05-close-after-write.t b/t/05-close-after-write.t new file mode 100644 index 0000000..7875e8a --- /dev/null +++ b/t/05-close-after-write.t @@ -0,0 +1,97 @@ +use strict; +use warnings FATAL => 'all'; + +use Test::More 0.88; + +use File::Spec; +use File::Temp qw( tempdir ); +use Log::Dispatch; + +my $dir = tempdir( CLEANUP => 1 ); + +# test that the same handle is returned if close-on-write is not set... + +{ + my $logger = Log::Dispatch->new( + outputs => [ + [ + 'File', + min_level => 'debug', + newline => 1, + name => 'no_caw', + filename => File::Spec->catfile( $dir, 'no_caw.log' ), + close_after_write => 0, + ], + [ + 'File', + min_level => 'debug', + newline => 1, + name => 'caw', + filename => File::Spec->catfile( $dir, 'caw.log' ), + close_after_write => 1, + ], + ], + ); + + ok( + $logger->output('no_caw')->{fh}, + 'no_caw output has created a fh before first write' + ); + ok( + !$logger->output('caw')->{fh}, + 'caw output has not created a fh before first write' + ); + + $logger->log( level => 'info', message => 'first message' ); + is( + _slurp( $logger->output('no_caw')->{filename} ), + "first message\n", + 'first line from no_caw output' + ); + is( + _slurp( $logger->output('caw')->{filename} ), + "first message\n", + 'first line from caw output' + ); + + my %handle = ( + no_caw => $logger->output('no_caw')->{fh}, + caw => $logger->output('caw')->{fh}, + ); + + $logger->log( level => 'info', message => 'second message' ); + + is( + _slurp( $logger->output('no_caw')->{filename} ), + "first message\nsecond message\n", + 'full content from no_caw output' + ); + is( + _slurp( $logger->output('caw')->{filename} ), + "first message\nsecond message\n", + 'full content from caw output' + ); + + # check the filehandles again... + is( + $logger->output('no_caw')->{fh}, + $handle{no_caw}, + 'handle has not changed when not using CAW' + ); + isnt( + $logger->output('caw')->{fh}, + $handle{caw}, + 'handle has changed when using CAW' + ); +} + +done_testing(); + +sub _slurp { + open my $fh, '<', $_[0] + or die "Cannot read $_[0]: $!"; + return do { + local $/; + <$fh>; + }; +} diff --git a/t/06-syslog.t b/t/06-syslog.t new file mode 100644 index 0000000..7ae6eb2 --- /dev/null +++ b/t/06-syslog.t @@ -0,0 +1,66 @@ +use strict; +use warnings; + +use Test::More 0.88; + +use Test::Requires { + 'Sys::Syslog' => '0.28', +}; + +use Log::Dispatch; +use Log::Dispatch::Syslog; + +no warnings 'redefine', 'once'; + +my @sock; +local *Sys::Syslog::setlogsock = sub { @sock = @_ }; + +local *Sys::Syslog::openlog = sub { return 1 }; +local *Sys::Syslog::closelog = sub { return 1 }; + +my @log; +local *Sys::Syslog::syslog = sub { push @log, [@_] }; + +{ + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::Syslog->new( + name => 'syslog', + min_level => 'debug', + ) + ); + + $dispatch->info('Foo'); + + ok( + !@sock, + 'no call to setlogsock unless socket is set explicitly' + ); + + is_deeply( + \@log, + [ [ 'INFO', 'Foo' ] ], + 'passed message to syslog' + ); +} + +{ + my $dispatch = Log::Dispatch->new; + $dispatch->add( + Log::Dispatch::Syslog->new( + name => 'syslog', + min_level => 'debug', + socket => { type => 'foo' }, + ) + ); + + $dispatch->info('Foo'); + + is_deeply( + \@sock, + [ { type => 'foo' } ], + 'call to setlogsock is made when logging a message if socket was passed to LD::Syslog constructor' + ); +} + +done_testing(); diff --git a/t/author-eol.t b/t/author-eol.t new file mode 100644 index 0000000..8a36b70 --- /dev/null +++ b/t/author-eol.t @@ -0,0 +1,60 @@ + +BEGIN { + unless ($ENV{AUTHOR_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for testing by the author'); + } +} + +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.18 + +use Test::More 0.88; +use Test::EOL; + +my @files = ( + 'lib/Log/Dispatch.pm', + 'lib/Log/Dispatch/ApacheLog.pm', + 'lib/Log/Dispatch/Base.pm', + 'lib/Log/Dispatch/Code.pm', + 'lib/Log/Dispatch/Conflicts.pm', + 'lib/Log/Dispatch/Email.pm', + 'lib/Log/Dispatch/Email/MIMELite.pm', + 'lib/Log/Dispatch/Email/MailSend.pm', + 'lib/Log/Dispatch/Email/MailSender.pm', + 'lib/Log/Dispatch/Email/MailSendmail.pm', + 'lib/Log/Dispatch/File.pm', + 'lib/Log/Dispatch/File/Locked.pm', + 'lib/Log/Dispatch/Handle.pm', + 'lib/Log/Dispatch/Null.pm', + 'lib/Log/Dispatch/Output.pm', + 'lib/Log/Dispatch/Screen.pm', + 'lib/Log/Dispatch/Syslog.pm', + 't/00-compile.t', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/01-basic.t', + 't/02-email-exit.t', + 't/03-short-syntax.t', + 't/04-binmode.t', + 't/05-close-after-write.t', + 't/06-syslog.t', + 't/author-eol.t', + 't/author-no-tabs.t', + 't/author-pod-spell.t', + 't/email-exit-helper.pl', + 't/lib/Log/Dispatch/TestUtil.pm', + 't/release-cpan-changes.t', + 't/release-pod-coverage.t', + 't/release-pod-no404s.t', + 't/release-pod-syntax.t', + 't/release-portability.t', + 't/release-test-version.t', + 't/release-tidyall.t', + 't/sendmail' +); + +eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; +done_testing; diff --git a/t/author-no-tabs.t b/t/author-no-tabs.t new file mode 100644 index 0000000..6c3dc9c --- /dev/null +++ b/t/author-no-tabs.t @@ -0,0 +1,60 @@ + +BEGIN { + unless ($ENV{AUTHOR_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for testing by the author'); + } +} + +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 + +use Test::More 0.88; +use Test::NoTabs; + +my @files = ( + 'lib/Log/Dispatch.pm', + 'lib/Log/Dispatch/ApacheLog.pm', + 'lib/Log/Dispatch/Base.pm', + 'lib/Log/Dispatch/Code.pm', + 'lib/Log/Dispatch/Conflicts.pm', + 'lib/Log/Dispatch/Email.pm', + 'lib/Log/Dispatch/Email/MIMELite.pm', + 'lib/Log/Dispatch/Email/MailSend.pm', + 'lib/Log/Dispatch/Email/MailSender.pm', + 'lib/Log/Dispatch/Email/MailSendmail.pm', + 'lib/Log/Dispatch/File.pm', + 'lib/Log/Dispatch/File/Locked.pm', + 'lib/Log/Dispatch/Handle.pm', + 'lib/Log/Dispatch/Null.pm', + 'lib/Log/Dispatch/Output.pm', + 'lib/Log/Dispatch/Screen.pm', + 'lib/Log/Dispatch/Syslog.pm', + 't/00-compile.t', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/01-basic.t', + 't/02-email-exit.t', + 't/03-short-syntax.t', + 't/04-binmode.t', + 't/05-close-after-write.t', + 't/06-syslog.t', + 't/author-eol.t', + 't/author-no-tabs.t', + 't/author-pod-spell.t', + 't/email-exit-helper.pl', + 't/lib/Log/Dispatch/TestUtil.pm', + 't/release-cpan-changes.t', + 't/release-pod-coverage.t', + 't/release-pod-no404s.t', + 't/release-pod-syntax.t', + 't/release-portability.t', + 't/release-test-version.t', + 't/release-tidyall.t', + 't/sendmail' +); + +notabs_ok($_) foreach @files; +done_testing; diff --git a/t/author-pod-spell.t b/t/author-pod-spell.t new file mode 100644 index 0000000..e17f428 --- /dev/null +++ b/t/author-pod-spell.t @@ -0,0 +1,97 @@ + +BEGIN { + unless ($ENV{AUTHOR_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for testing by the author'); + } +} + +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006009 +use Test::Spelling 0.12; +use Pod::Wordlist; + + +add_stopwords(<DATA>); +all_pod_files_spelling_ok( qw( bin lib ) ); +__DATA__ +DROLSKY +DROLSKY's +Rolsky +Rolsky's +API +CPAN +Cholet +Dumont +Goess +Manfredi +Miyagawa +PayPal +Pfeiffer +STDERR +STDOUT +Schilli +Straup +Subclasses +Swartz +Tatsuhiko +UTF +apache +appenders +auth +authpriv +autoflushed +classname +crit +emerg +filename +ident +kern +logopt +multi +params +smtp +stderr +subclass's +subclasses +uucp +Dave +autarch +Karen +Etheridge +ether +Olaf +Alders +olaf +Olivier +Mengué +dolmen +Ross +Attrill +ross +swartz +Whitney +Jackson +whitney +lib +Log +Dispatch +ApacheLog +Base +Code +Conflicts +Email +MIMELite +MailSend +MailSender +MailSendmail +File +Locked +Handle +Null +Output +Screen +Syslog diff --git a/t/email-exit-helper.pl b/t/email-exit-helper.pl new file mode 100755 index 0000000..1ffe5c5 --- /dev/null +++ b/t/email-exit-helper.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w + +use strict; + +use lib './lib', '../lib'; + +use Log::Dispatch::Email::MailSend; + +Mail::Mailer->import( sendmail => 't/sendmail' ); + +my $email = Log::Dispatch::Email::MailSend->new( + name => 'email', + min_level => 'emerg', + to => 'foo@example.com', + subject => 'Log this', +); + +$email->log( message => 'Something bad is happening', level => 'emerg' ); + +exit 5; diff --git a/t/lib/Log/Dispatch/TestUtil.pm b/t/lib/Log/Dispatch/TestUtil.pm new file mode 100644 index 0000000..5d9f5ab --- /dev/null +++ b/t/lib/Log/Dispatch/TestUtil.pm @@ -0,0 +1,44 @@ +package Log::Dispatch::TestUtil; +use Data::Dumper; +use strict; +use warnings; +use base qw(Exporter); + +our @EXPORT_OK = qw( + cmp_deeply + dump_one_line +); + +sub cmp_deeply { + my ( $ref1, $ref2, $name ) = @_; + + my $tb = Test::Builder->new(); + $tb->is_eq( dump_one_line($ref1), dump_one_line($ref2), $name ); +} + +sub dump_one_line { + my ($value) = @_; + + return Data::Dumper->new( [$value] )->Indent(0)->Sortkeys(1) + ->Quotekeys(0)->Terse(1)->Dump(); +} + +1; + +# ABSTRACT: Utilities used internally by Log::Dispatch for testing + +__END__ + +=head1 METHODS + +=over + +=item cmp_deeply + +A cheap version of Test::Deep::cmp_deeply. + +=item dump_one_line + +Dump a value to a single line using Data::Dumper. + +=cut diff --git a/t/release-cpan-changes.t b/t/release-cpan-changes.t new file mode 100644 index 0000000..214650f --- /dev/null +++ b/t/release-cpan-changes.t @@ -0,0 +1,19 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + + +use strict; +use warnings; + +use Test::More 0.96 tests => 2; +use_ok('Test::CPAN::Changes'); +subtest 'changes_ok' => sub { + changes_file_ok('Changes'); +}; +done_testing(); diff --git a/t/release-pod-coverage.t b/t/release-pod-coverage.t new file mode 100644 index 0000000..55bb523 --- /dev/null +++ b/t/release-pod-coverage.t @@ -0,0 +1,63 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + +# This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable. + +use Test::Pod::Coverage 1.08; +use Test::More 0.88; + +BEGIN { + if ( $] <= 5.008008 ) { + plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; + } +} +use Pod::Coverage::TrustPod; + +my %skip = map { $_ => 1 } qw( Log::Dispatch::ApacheLog Log::Dispatch::Conflicts ); + +my @modules; +for my $module ( all_modules() ) { + next if $skip{$module}; + + push @modules, $module; +} + +plan skip_all => 'All the modules we found were excluded from POD coverage test.' + unless @modules; + +plan tests => scalar @modules; + +my %trustme = ( + 'Log::Dispatch::File' => [ + qr/^(?:O_)?APPEND$/ + ], + 'Log::Dispatch::Output' => [ + qr/^new$/ + ], + 'Log::Dispatch' => [ + qr/^(?:warn|err|crit|emerg)$/, + qr/^is_\w+$/ + ] + ); + +my @also_private; + +for my $module ( sort @modules ) { + pod_coverage_ok( + $module, + { + coverage_class => 'Pod::Coverage::TrustPod', + also_private => \@also_private, + trustme => $trustme{$module} || [], + }, + "pod coverage for $module" + ); +} + +done_testing(); diff --git a/t/release-pod-no404s.t b/t/release-pod-no404s.t new file mode 100644 index 0000000..da185ec --- /dev/null +++ b/t/release-pod-no404s.t @@ -0,0 +1,29 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + + +use strict; +use warnings; +use Test::More; + +foreach my $env_skip ( qw( + SKIP_POD_NO404S + AUTOMATED_TESTING +) ){ + plan skip_all => "\$ENV{$env_skip} is set, skipping" + if $ENV{$env_skip}; +} + +eval "use Test::Pod::No404s"; +if ( $@ ) { + plan skip_all => 'Test::Pod::No404s required for testing POD'; +} +else { + all_pod_files_ok(); +} diff --git a/t/release-pod-syntax.t b/t/release-pod-syntax.t new file mode 100644 index 0000000..cdd6a6c --- /dev/null +++ b/t/release-pod-syntax.t @@ -0,0 +1,14 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + +# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. +use Test::More; +use Test::Pod 1.41; + +all_pod_files_ok(); diff --git a/t/release-portability.t b/t/release-portability.t new file mode 100644 index 0000000..ad285b4 --- /dev/null +++ b/t/release-portability.t @@ -0,0 +1,20 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + + +use strict; +use warnings; + +use Test::More; + +eval 'use Test::Portability::Files'; +plan skip_all => 'Test::Portability::Files required for testing portability' + if $@; + +run_tests(); diff --git a/t/release-test-version.t b/t/release-test-version.t new file mode 100644 index 0000000..aef8636 --- /dev/null +++ b/t/release-test-version.t @@ -0,0 +1,46 @@ + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::Version 1.03 +use Test::Version; + +my @imports = qw( version_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_ok('lib/Log/Dispatch.pm'); +version_ok('lib/Log/Dispatch/ApacheLog.pm'); +version_ok('lib/Log/Dispatch/Base.pm'); +version_ok('lib/Log/Dispatch/Code.pm'); +version_ok('lib/Log/Dispatch/Email.pm'); +version_ok('lib/Log/Dispatch/Email/MIMELite.pm'); +version_ok('lib/Log/Dispatch/Email/MailSend.pm'); +version_ok('lib/Log/Dispatch/Email/MailSender.pm'); +version_ok('lib/Log/Dispatch/Email/MailSendmail.pm'); +version_ok('lib/Log/Dispatch/File.pm'); +version_ok('lib/Log/Dispatch/File/Locked.pm'); +version_ok('lib/Log/Dispatch/Handle.pm'); +version_ok('lib/Log/Dispatch/Null.pm'); +version_ok('lib/Log/Dispatch/Output.pm'); +version_ok('lib/Log/Dispatch/Screen.pm'); +version_ok('lib/Log/Dispatch/Syslog.pm'); +done_testing; diff --git a/t/release-tidyall.t b/t/release-tidyall.t new file mode 100644 index 0000000..9625e53 --- /dev/null +++ b/t/release-tidyall.t @@ -0,0 +1,17 @@ +#!perl + +BEGIN { + unless ($ENV{RELEASE_TESTING}) { + require Test::More; + Test::More::plan(skip_all => 'these tests are for release candidate testing'); + } +} + +# This file was automatically generated by Dist::Zilla::Plugin::Test::TidyAll + +use Test::Code::TidyAll 0.24; +use Test::More 0.88; + +tidyall_ok(); + +done_testing(); diff --git a/t/sendmail b/t/sendmail new file mode 100755 index 0000000..d41087f --- /dev/null +++ b/t/sendmail @@ -0,0 +1,3 @@ +#!/bin/bash + +exit 0; |