package t::lib::Mocks::Logger; # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # Koha is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Koha; if not, see . use Modern::Perl; use base 'Test::Builder::Module'; use base qw(Class::Accessor); use Test::MockModule; use Test::MockObject; my $CLASS = __PACKAGE__; =head1 NAME t::lib::Mocks::Logger - A library to mock Koha::Logger for testing =head1 API =head2 Methods =head3 new my $logger = t::lib::Mocks::Logger->new(); Mocks the Koha::Logger for testing purposes. The mocked subs (log levels) return the passed string, in case we want to test the debugging string contents. =cut sub new { my ( $class, $params ) = @_; my $mocked_logger_class = Test::MockModule->new("Koha::Logger"); my $mocked_logger = Test::MockObject->new(); $mocked_logger_class->mock( 'get', sub { return $mocked_logger; } ); my $self = $class->SUPER::new( { logger => $mocked_logger_class, debug => [], error => [], info => [], fatal => [], trace => [], warn => [], } ); bless $self, $class; foreach my $level (levels()) { $mocked_logger->mock( $level, sub { my $message = $_[1]; push @{ $self->{$level} }, $message; return $message; } ); } return $self; } =head3 debug_is $logger->debug_is($expected); Method for testing a message was written to the 'debug' log level. =cut sub debug_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'debug', $expect, $name ); return $self; } =head3 error_is $logger->error_is($expected); Method for testing a message was written to the 'error' log level. =cut sub error_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'error', $expect, $name ); return $self; } =head3 fatal_is $logger->fatal_is($expected); Method for testing a message was written to the 'fatal' log level. =cut sub fatal_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'fatal', $expect, $name ); return $self; } =head3 info_is $logger->info_is($expected); Method for testing a message was written to the 'info' log level. =cut sub info_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'info', $expect, $name ); return $self; } =head3 trace_is $logger->trace_is($expected); Method for testing a message was written to the 'trace' log level. =cut sub trace_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'trace', $expect, $name ); return $self; } =head3 warn_is $logger->warn_is($expected); Method for testing a message was written to the 'warn' log level. =cut sub warn_is { my ( $self, $expect, $name ) = @_; $self->generic_is( 'warn', $expect, $name ); return $self; } =head3 debug_like $logger->debug_like($expected); Method for testing a message matching a regex was written to the 'debug' log level. =cut sub debug_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'debug', $expect, $name ); return $self; } =head3 error_like $logger->error_like($expected); Method for testing a message matching a regex was written to the 'error' log level. =cut sub error_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'error', $expect, $name ); return $self; } =head3 fatal_like $logger->fatal_like($expected); Method for testing a message matching a regex was written to the 'fatal' log level. =cut sub fatal_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'fatal', $expect, $name ); return $self; } =head3 info_like $logger->info_like($expected); Method for testing a message matching a regex was written to the 'info' log level. =cut sub info_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'info', $expect, $name ); return $self; } =head3 trace_like $logger->trace_like($expected); Method for testing a message matching a regex was written to the 'trace' log level. =cut sub trace_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'trace', $expect, $name ); return $self; } =head3 warn_like $logger->warn_like($expected); Method for testing a message matching a regex was written to the 'warn' log level. =cut sub warn_like { my ( $self, $expect, $name ) = @_; $self->generic_like( 'warn', $expect, $name ); return $self; } =head3 count is( $logger->count( [ $level ] ), 0 'No logs!' ); Method for counting the generated messages. An optional I<$level> parameter can be passed to restrict the count to the passed level. =cut sub count { my ( $self, $level ) = @_; unless ( $level ) { my $sum = 0; map { $sum += scalar @{$self->{$_}} } levels(); return $sum; } return scalar @{ $self->{$level} }; } =head3 clear $logger->debug_is( "Something", "Something was sent to 'debug'" ) ->warn_like( qr/^Something$/, "Something was sent to 'warn" ) ->clear( [ $level ] ); A method for resetting the mocked I<$logger> object buffer. Useful to avoid inter-tests pollution. =cut sub clear { my ( $self, $level ) = @_; if ( $level ) { $self->{$level} = []; } else { foreach my $l (levels()) { $self->{$l} = []; } } return $self; } =head2 Internal methods =head3 generic_is Internal method to be used to build log level-specific exact string test methods. =cut sub generic_is { my ( $self, $level, $expect, $name ) = @_; local $Test::Builder::Level = $Test::Builder::Level + 1; my $string = shift @{ $self->{$level} }; $string //= ''; my $tb = $CLASS->builder; return $tb->is_eq( $string, $expect, $name); } =head3 generic_like Internal method to be used to build log level-specific regex string test methods. =cut sub generic_like { my ( $self, $level, $expect, $name ) = @_; local $Test::Builder::Level = $Test::Builder::Level + 1; my $string = shift @{ $self->{$level} }; $string //= ''; my $tb = $CLASS->builder; return $tb->like( $string, $expect, $name); } =head3 levels Internal method that returns a list of valid log levels. =cut sub levels { return qw(trace debug info warn error fatal); } 1;