DBIx-QuickORM
view release on metacpan or search on metacpan
t/AI/handle_builder.t view on Meta::CPAN
use Test2::V0;
use DBI;
use File::Temp qw/tempdir/;
use Scalar::Util qw/refaddr/;
# Exercises the handle BUILDER (not the terminal fetches covered by
# t/handle/*): immutability of refiners, void-context croaks, the
# argument-shape parsing of $con->handle(...), and the where/and/or,
# order_by, limit, fields, omit, all_fields, and data_only refiners. The
# connection shortcut proxies (all/one/count/by_id/insert/update/delete)
# are also exercised to confirm they build a handle and run it.
BEGIN {
skip_all "DBD::SQLite is required for these tests"
unless eval { require DBD::SQLite; 1 };
}
require DBIx::QuickORM;
my $dir = tempdir(CLEANUP => 1);
my $dsn = "dbi:SQLite:dbname=$dir/handle_builder.sqlite";
{
my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
$dbh->do('CREATE TABLE people (id INTEGER PRIMARY KEY, surname TEXT, first_name TEXT, bio TEXT)');
$dbh->do(
"INSERT INTO people (surname, first_name, bio) VALUES "
. "('smith', 'al', 'x'), ('jones', 'bob', 'y'), ('smith', 'cy', 'z')"
);
$dbh->disconnect;
}
my $con = DBIx::QuickORM->quick(credentials => {dsn => $dsn});
my $base = $con->handle('people');
isa_ok($base, ['DBIx::QuickORM::Handle'], "got a handle for the people table");
subtest immutability => sub {
my $smiths = $base->where({surname => 'smith'});
my $jones = $base->where({surname => 'jones'});
isnt(refaddr($smiths), refaddr($base), "where() returns a new handle, not the original");
isnt(refaddr($jones), refaddr($base), "a second where() returns yet another new handle");
isnt(refaddr($smiths), refaddr($jones), "the two derived handles are distinct objects");
is($base->where, undef, "base handle WHERE is untouched");
is($smiths->where, {surname => 'smith'}, "first derived handle has its own WHERE");
is($jones->where, {surname => 'jones'}, "second derived handle has its own WHERE");
# Refiners that need a WHERE/row to be present first operate on a
# handle that already has one.
my $w = $base->where({});
isnt(refaddr($w->order_by(['surname'])), refaddr($w), "order_by() returns a new handle");
isnt(refaddr($w->limit(5)), refaddr($w), "limit() returns a new handle");
isnt(refaddr($base->fields(['id'])), refaddr($base), "fields() returns a new handle");
isnt(refaddr($base->omit(['bio'])), refaddr($base), "omit() returns a new handle");
isnt(refaddr($base->all_fields), refaddr($base), "all_fields() returns a new handle");
isnt(refaddr($base->data_only), refaddr($base), "data_only() returns a new handle");
isnt(
refaddr($base->where({surname => 'smith'})->and({first_name => 'al'})),
refaddr($base), "and() returns a new handle",
);
isnt(
refaddr($base->where({surname => 'smith'})->or({surname => 'jones'})),
refaddr($base), "or() returns a new handle",
);
is($w->order_by, undef, "order_by on the source handle is still unset");
is($w->limit, undef, "limit on the source handle is still unset");
};
subtest void_context_croak => sub {
# Refiners whose entire point is the returned value croak in void context.
like(dies { $base->where({surname => 'smith'}); 1 },
qr/Must not be called in void context/, "where() croaks in void context");
my $w = $base->where({});
like(dies { $w->order_by(['surname']); 1 },
qr/Must not be called in void context/, "order_by() croaks in void context");
like(dies { $w->limit(5); 1 },
qr/Must not be called in void context/, "limit() croaks in void context");
like(dies { $base->fields(['id']); 1 },
qr/Must not be called in void context/, "fields() croaks in void context");
like(dies { $base->omit(['bio']); 1 },
qr/Must not be called in void context/, "omit() croaks in void context");
like(dies { $base->data_only; 1 },
qr/Must not be called in void context/, "data_only() croaks in void context");
like(dies { $base->all_fields; 1 },
qr/Must not be called in void context/, "all_fields() croaks in void context");
like(dies { $base->sync; 1 },
qr/Must not be called in void context/, "sync() croaks in void context");
};
( run in 0.512 second using v1.01-cache-2.11-cpan-5b529ec07f3 )