ControlBreak
view release on metacpan or search on metacpan
t/10_end_of_list.t view on Meta::CPAN
# Test suite for ControlBreak
use strict;
use warnings;
use v5.18; # minimum needed for Object::Pad
use Test::More tests => 1;
use FindBin;
use lib $FindBin::Bin . '/../lib';
use Capture::Tiny ':all';
my ($stdout, $stderr, $exit) = capture {
synopsis();
};
my $expected = <<__EX__;
Canada,Alberta,1019942*
Canada,Ontario,3412129*
Canada,Quebec,2397919*
Canada total,,6829990**
USA,Arizona,1640641*
USA,California,4946673*
USA,Illinois,2756546*
USA,New York,9211759*
USA,Pennsylvania,1619355*
USA,Texas,2345606*
USA total,,22520580**
Grand total,,29350570***
__EX__
is $stdout, $expected;
sub synopsis {
use v5.18;
use lib $FindBin::Bin . '/../lib';
use ControlBreak;
# set up two levels, in minor to major order, and an extra level
# for tracking the end of the file
my $cb = ControlBreak->new( qw( District Country EOL ) );
my @totals;
# set up some level number variables for convenient indexing into @totals
my ($L1, $L2, $L3) = $cb->level_numbers;
my @data = <DATA>;
# iterations begin at zero and are incremented during the call
# to test() -- which is called within test_and_do(). So, the
# iteration number of the last value in the list -- for the
# purpose of comparison to the iteration number before a test
# method is called -- is the list length minus one.
my $last_iter = @data - 1;
foreach my $line (@data) {
chomp $line;
my ($country, $district, $city, $population) = split ',', $line;
# # test the values (minor to major order) using perl eof to
# # detect the last record of the file and trigger an EOF break
# $cb->test($district, $country, $cb->iteration == $last_record);
my $sub_totals = sub {
# break on District (or Country) detected
if ($cb->break('District')) {
say join ',', $cb->last('Country'), $cb->last('District'), $totals[$L1] . '*';
$totals[$L1] = 0;
}
# break on Country detected
if ($cb->break('Country')) {
say join ',', $cb->last('Country') . ' total', '', $totals[$L2] . '**';
$totals[$L2] = 0;
}
# break at end of list
if ($cb->break('EOL')) {
say 'Grand total,,', $totals[$L3], '***';
}
# accumulate subtotals
map { $totals[$_] += $population } $cb->level_numbers;
};
$cb->test_and_do($district, $country, $cb->iteration == $last_iter, $sub_totals);
}
}
__DATA__
Canada,Alberta,Calgary,1019942
Canada,Ontario,Ottawa,812129
Canada,Ontario,Toronto,2600000
Canada,Quebec,Montreal,1704694
Canada,Quebec,Quebec City,531902
Canada,Quebec,Sherbrooke,161323
USA,Arizona,Phoenix,1640641
USA,California,Los Angeles,3919973
USA,California,San Jose,1026700
USA,Illinois,Chicago,2756546
USA,New York,New York City,8930002
USA,New York,Buffalo,281757
USA,Pennsylvania,Philadelphia,1619355
USA,Texas,Houston,2345606
( run in 0.495 second using v1.01-cache-2.11-cpan-71847e10f99 )