From cf9aaf3541a45089f7736ada443a37f4a78ae47f Mon Sep 17 00:00:00 2001 From: sergiotarxz Date: Thu, 27 Jun 2024 12:12:50 +0200 Subject: [PATCH] Add test for previously discovered bug. --- Build.PL | 5 +++++ lib/JapaChar.pm | 6 ++---- lib/JapaChar/Characters.pm | 13 ++++++++----- lib/JapaChar/Random.pm | 18 ++++++++++++++++++ t/01-characters.t | 28 ++++++++++++++++++++++++++++ t/all-learned-basic-characters.db | Bin 0 -> 40960 bytes 6 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 lib/JapaChar/Random.pm create mode 100644 t/01-characters.t create mode 100644 t/all-learned-basic-characters.db diff --git a/Build.PL b/Build.PL index cab7dec..bc192d5 100755 --- a/Build.PL +++ b/Build.PL @@ -22,5 +22,10 @@ my $build = Module::Build->new( 'Pango' => 0, 'Crypt::URandom' => 0, }, + test_requires => { + 'Test::MockModule' => 0, + 'Test::Most' => 0, + 'Test::MockObject' => 0, + } ); $build->create_build_script; diff --git a/lib/JapaChar.pm b/lib/JapaChar.pm index 5024833..04660c0 100644 --- a/lib/JapaChar.pm +++ b/lib/JapaChar.pm @@ -14,7 +14,7 @@ use YAML::PP; use JapaChar::DB; use JapaChar::Characters; use Pango; -use Crypt::URandom qw( urandom ); +use JapaChar::Random; use Glib::IO; @@ -58,9 +58,7 @@ sub _new_challenge($self, $window, $type = undef) { $self->_create_main_menu($window); return; } - my $rng = urandom(4); - $rng = unpack 'L', $rng; - $rng = ($rng % 100) + 1; + my $rng = JapaChar::Random->new->get(1, 100); if ($rng > 50) { $self->_new_challenge_romanji($window, $type); return; diff --git a/lib/JapaChar/Characters.pm b/lib/JapaChar/Characters.pm index 9f71a45..7db1f61 100644 --- a/lib/JapaChar/Characters.pm +++ b/lib/JapaChar/Characters.pm @@ -10,6 +10,8 @@ use Path::Tiny; use JSON; use Data::Dumper; +use JapaChar::Random; + my $option_populated = 'populated_basic_characters'; require JapaChar::DB; require JapaChar::Schema; @@ -68,7 +70,7 @@ sub get_4_incorrect_answers( $self, $char ) { return \@bad_answers; } -sub next_review_char( $self, $type = undef ) { +sub _next_review_char( $self, $type = undef ) { my $basic_character_resultset = JapaChar::Schema->Schema->resultset('BasicCharacter'); my @chars = $basic_character_resultset->search( @@ -90,22 +92,23 @@ sub next_review_char( $self, $type = undef ) { } sub next_char( $self, $type = undef ) { - my $next_review = $self->next_review_char($type); - my $next_learning = $self->next_learning_char($type); + my $next_review = $self->_next_review_char($type); + my $next_learning = $self->_next_learning_char($type); if ( !defined $next_review ) { return $next_learning; } if ( !defined $next_learning) { return $next_review; } - my $rng = int( rand(100) ) + 1; + my $rng = JapaChar::Random->new->get(1, 100); if ( $rng > 20 ) { return $next_learning; } return $next_review; } -sub next_learning_char( $self, $type = undef ) { + +sub _next_learning_char( $self, $type = undef ) { $self->populate_basic_characters; my $basic_character_resultset = JapaChar::Schema->Schema->resultset('BasicCharacter'); diff --git a/lib/JapaChar/Random.pm b/lib/JapaChar/Random.pm new file mode 100644 index 0000000..e6456e6 --- /dev/null +++ b/lib/JapaChar/Random.pm @@ -0,0 +1,18 @@ +package JapaChar::Random; + +use v5.38.2; + +use strict; +use warnings; + +use Moo; + +use Crypt::URandom qw( urandom ); + +sub get($min = 1, $max = 100) { + my $rng = urandom(4); + $rng = unpack 'L', $rng; + $rng = ($rng % $max) + $min; + return $rng; +} +1; diff --git a/t/01-characters.t b/t/01-characters.t new file mode 100644 index 0000000..0744a52 --- /dev/null +++ b/t/01-characters.t @@ -0,0 +1,28 @@ +#!/usr/bin/env perl + +use v5.38.2; + +use strict; +use warnings; + +use Test::Most tests => 2; +use Test::MockModule; +use Path::Tiny; + +use File::Basename; + +use lib dirname(dirname(__FILE__)).'/lib'; + +use JapaChar::DB; + +BEGIN { + use_ok 'JapaChar::Characters'; +}; + +{ + my $mock_db = Test::MockModule->new('JapaChar::DB'); + $mock_db->mock(_db_path => sub { + return path(__FILE__)->parent->child('all-learned-basic-characters.db'); + }); + ok defined(JapaChar::Characters->new->next_char), 'The next char is defined.'; +} diff --git a/t/all-learned-basic-characters.db b/t/all-learned-basic-characters.db new file mode 100644 index 0000000000000000000000000000000000000000..2bd93f20046ec712af89345968078e4656522f0d GIT binary patch literal 40960 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 literal 0 HcmV?d00001