App-Greple-ical
view release on metacpan or search on metacpan
t/01_ical.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use Test::More;
use File::Temp qw(tempdir);
use File::Path qw(make_path);
use File::Spec;
use Time::Local qw(timegm);
##
## End-to-end test with a fake Calendar.sqlitedb under a temporary
## HOME directory.
##
chomp(my $sqlite3 = `sh -c 'command -v sqlite3' 2>/dev/null` // '');
plan skip_all => 'sqlite3 not available' unless $sqlite3;
chomp(my $greple = `sh -c 'command -v greple' 2>/dev/null` // '');
plan skip_all => 'greple not available' unless $greple;
my $home = tempdir(CLEANUP => 1);
my $dir = File::Spec->catdir($home, 'Library', 'Group Containers',
'group.com.apple.calendar');
make_path($dir) or die "make_path: $!";
my $db = File::Spec->catfile($dir, 'Calendar.sqlitedb');
# Core Data epoch (2001-01-01) offset from Unix epoch
use constant CD_EPOCH => 978307200;
sub cd { timegm(0, 0, $_[3] // 12, $_[2], $_[1] - 1, $_[0]) - CD_EPOCH }
my $sql = <<END;
CREATE TABLE CalendarItem (
summary TEXT, description TEXT,
start_date REAL, end_date REAL, all_day INTEGER, location_id INTEGER
);
CREATE TABLE Location (title TEXT);
INSERT INTO Location (title) VALUES ('Theater X');
INSERT INTO CalendarItem VALUES
('MOVIE: foo bar', NULL, @{[cd(2026,1,2)]}, @{[cd(2026,1,2,14)]}, 0, 1),
('MOVIE: baz', 'good movie', @{[cd(2026,2,3)]}, @{[cd(2026,2,3,14)]}, 0, NULL),
('other event', NULL, @{[cd(2026,3,4)]}, @{[cd(2026,3,5)]}, 1, NULL);
END
do {
open my $fh, '|-', $sqlite3, $db or die "sqlite3: $!";
print $fh $sql;
close $fh or die "sqlite3 failed";
};
local $ENV{HOME} = $home;
local $ENV{PERL5LIB} = join ':', File::Spec->rel2abs('lib'), $ENV{PERL5LIB} // ();
delete local $ENV{GREPLEOPTS};
sub run_greple {
my @cmd = ($^X, '-S', 'greple', @_);
my $pid = open my $fh, '-|';
defined $pid or die "fork: $!";
if ($pid == 0) {
open STDERR, '>&', \*STDOUT;
exec @cmd or die "exec: $!";
}
local $/;
my $out = <$fh>;
close $fh;
$out;
}
my $out = run_greple(qw(-Mical MOVIE --simple));
like($out, qr{^2026/01/02 .*MOVIE: foo bar.*\@\[Theater X\]$}m, 'simple: summary with location');
like($out, qr{^2026/02/03 .*MOVIE: baz\*$}m, 'simple: description mark');
unlike($out, qr{other event}, 'simple: unmatched event not printed');
$out = run_greple(qw(-Mical MOVIE --color=never));
like($out, qr{SUMMARY:MOVIE: foo bar}, 'default: VEVENT format');
like($out, qr{LOCATION:Theater X}, 'default: location line');
$out = run_greple(qw(-Mical MOVIE --detail --color=never));
like($out, qr{^2026/02/03 .*MOVIE: baz\*\nDESCRIPTION:good movie$}m, 'detail: description body');
done_testing;
( run in 0.484 second using v1.01-cache-2.11-cpan-f52f0507bed )