use strict;
use warnings;
use lib 't/lib';
use Fey::Test;
use Test::More;
use Fey::Table;
{
eval { my $t = Fey::Table->new() };
like(
$@, qr/\QAttribute (name) is required/,
'name is a required param'
);
}
{
my $t = Fey::Table->new( name => 'Test' );
is( $t->name(), 'Test', 'table name is Test' );
ok( !$t->is_view(), 'table is not view' );
is( $t->id(), 'Test', 'table id is Test' );
ok( !$t->is_alias(), 'Test has no alias' );
}
{
my $t = Fey::Table->new( name => 'Test', is_view => 1 );
ok( $t->is_view(), 'table is view' );
}
{
my $t = Fey::Table->new( name => 'Test' );
my $c1 = Fey::Column->new(
name => 'test_id',
type => 'text',
);
ok( !$c1->table(), 'column has no table' );
$t->add_column($c1);
ok( $t->column('test_id'), 'test_id column is in table' );
is(
$c1->table(), $t,
'column has a table after calling add_column()'
);
my @cols = $t->columns;
is( scalar @cols, 1, 'table has one column' );
is( $cols[0], $c1, 'columns() returned one column - test_id' );
eval { $t->add_column($c1) };
like(
$@, qr/already has a column named test_id/,
'cannot add a column twice'
);
$t->remove_column($c1);
ok( !$t->column('test_id'), 'test_id column is not in table' );
ok(
!$c1->table(),
'column has no table after calling remove_column()'
);
$t->add_column($c1);
$t->remove_column( $c1->name() );
ok( !$t->column('test_id'), 'test_id column is not in table' );
}
{
my $t = Fey::Table->new( name => 'Test' );
my $c1 = Fey::Column->new(
name => 'test_id',
type => 'text',
);
my $c2 = Fey::Column->new(
name => 'size',
type => 'integer',
);
$t->add_column($_) for $c1, $c2;
is( scalar $t->columns, 2, 'table has two columns' );
eval { $t->add_candidate_key('no_such_thing') };
like(
$@, qr/The column no_such_thing is not part of the Test table./,
'add_candidate_key() called with invalid column name'
);
eval { $t->add_candidate_key() };
like(
$@, qr/\Q0 parameters/,
'add_candidate_key() called with no parameters'
);
$t->add_candidate_key('test_id');
is_deeply(
_keys_to_names( $t->candidate_keys() ),
[ ['test_id'] ],
'one key set and it contains only test_id'
);
$t->add_candidate_key('test_id');
is_deeply(
_keys_to_names( $t->candidate_keys() ),
[ ['test_id'] ],
'one key set and it contains only test_id (after adding same key twice)'
);
my $pk = $t->primary_key();
is( scalar @{$pk}, 1, 'table has a one column pk' );
is( $pk->[0]->name(), 'test_id', 'pk column is test_id' );
$t->remove_column('test_id');
$pk = $t->primary_key();
is( scalar @{$pk}, 0, 'table has no pk' );
$t->add_column($c1);
$t->add_candidate_key('test_id');
$t->remove_column($c2);
$pk = $t->primary_key();
is(
scalar @{$pk}, 1,
'table has a one column pk (removing a non-key column does not affect keys)'
);
is( $pk->[0]->name(), 'test_id', 'pk column is test_id' );
}
{
my $s = Fey::Test->mock_test_schema();
my $t = $s->table('User');
my @cols = sort map { $_->name() } $t->columns( 'user_id', 'username' );
is( scalar @cols, 2, 'columns() returns named columns' );
is_deeply(
\@cols, [ 'user_id', 'username' ],
'columns are user_id & username'
);
@cols = sort map { $_->name() } $t->columns('no_such_column');
is( scalar @cols, 0, 'columns() ignores columns which do not exist' );
}
{
my $s = Fey::Test->mock_test_schema();
my $t = $s->table('User');
$t->remove_candidate_key( @{$_} ) for @{ $t->candidate_keys() };
$t->add_candidate_key('user_id');
$t->add_candidate_key( 'username', 'email' );
is_deeply(
_keys_to_names( $t->candidate_keys() ),
[ ['user_id'], [ 'email', 'username' ] ],
'two keys, one for user_id and one for email + username'
);
my $pk = $t->primary_key();
is( scalar @{$pk}, 1, 'table has one pk column' );
is( $pk->[0]->name(), 'user_id', 'pk is user_id' );
ok(
$t->has_candidate_key('user_id'),
'table has key for (user_Id)'
);
ok(
$t->has_candidate_key( 'username', 'email' ),
'table has key for (username, email)'
);
ok(
!$t->has_candidate_key('username'),
'table does not have key for (username)'
);
eval { $t->has_candidate_key() };
like(
$@, qr/\Q0 parameters/,
'has_candidate_key() called with no parameters'
);
eval { $t->has_candidate_key('no_such_thing') };
like(
$@, qr/The column no_such_thing is not part of the User table./,
'has_candidate_key() called with invalid column name'
);
$t->remove_candidate_key('user_id');
is_deeply(
_keys_to_names( $t->candidate_keys() ),
[ [ 'email', 'username' ] ],
'one key, email + username'
);
$t->remove_candidate_key('user_id');
is_deeply(
_keys_to_names( $t->candidate_keys() ),
[ [ 'email', 'username' ] ],
'one key, email + username after removing key which is not in table'
);
eval { $t->remove_candidate_key('no_such_thing') };
like(
$@, qr/The column no_such_thing is not part of the User table./,
'remove_candidate_key() called with invalid column name'
);
eval { $t->remove_candidate_key() };
like(
$@, qr/\Q0 parameters/,
'remove_candidate_key() called with no parameters'
);
}
{
my $s = Fey::Test->mock_test_schema();
my $t = $s->table('User');
my $a1 = $t->aliased_column( 'foo_', 'user_id' );
is(
$a1->alias_name(), 'foo_user_id',
'aliased_column return column alias with expected alias_name'
);
my ( $a2, $a3 ) = $t->aliased_columns( 'foo_', 'user_id', 'username' );
is(
$a2->alias_name(), 'foo_user_id',
'aliased_columns return column aliases with expected alias_names'
);
is(
$a3->alias_name(), 'foo_username',
'aliased_columns return column aliases with expected alias_names'
);
}
{
my $s = Fey::Test->mock_test_schema();
my $t = $s->table('User');
my @a = $t->aliased_columns('foo_');
is(
scalar @a, 3,
'aliased_columns with no explicit columns returns all columns'
);
}
sub _keys_to_names {
my @n;
for my $k ( @{ $_[0] } ) {
push @n, [ sort map { $_->name() } @{$k} ];
}
return \@n;
}
done_testing();