1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
use strict;
use warnings;
use Test::More;
use Test::Exception;
use Try::Tiny;
use lib qw(t/lib);
use make_dbictest_db;
use DBIx::Class::Schema::Loader;
my $schema_counter = 0;
# test skip_relationships
my $regular = schema_with();
is( ref($regular->source('Bar')->relationship_info('fooref')), 'HASH',
'regularly-made schema has fooref rel',
);
my $skip_rel = schema_with( skip_relationships => 1 );
is_deeply( $skip_rel->source('Bar')->relationship_info('fooref'), undef,
'skip_relationships blocks generation of fooref rel',
);
# test hashref as rel_name_map
my $hash_relationship = schema_with(
rel_name_map => {
fooref => "got_fooref",
bars => "ignored",
Foo => {
bars => "got_bars",
fooref => "ignored",
},
}
);
is( ref($hash_relationship->source('Foo')->relationship_info('got_bars')),
'HASH',
'single level hash in rel_name_map picked up correctly'
);
is( ref($hash_relationship->source('Bar')->relationship_info('got_fooref')),
'HASH',
'double level hash in rel_name_map picked up correctly'
);
# test coderef as rel_name_map
my $code_relationship = schema_with(
rel_name_map => sub {
my ($args, $orig) = @_;
if ($args->{local_moniker} eq 'Foo') {
is_deeply(
$args,
{
name => 'bars',
type => 'has_many',
local_class =>
"DBICTest::Schema::${schema_counter}::Result::Foo",
local_moniker => 'Foo',
local_columns => ['fooid'],
remote_class =>
"DBICTest::Schema::${schema_counter}::Result::Bar",
remote_moniker => 'Bar',
remote_columns => ['fooref'],
},
'correct args for Foo passed'
);
}
elsif ($args->{local_moniker} eq 'Bar') {
is_deeply(
$args,
{
name => 'fooref',
type => 'belongs_to',
local_class =>
"DBICTest::Schema::${schema_counter}::Result::Bar",
local_moniker => 'Bar',
local_columns => ['fooref'],
remote_class =>
"DBICTest::Schema::${schema_counter}::Result::Foo",
remote_moniker => 'Foo',
remote_columns => ['fooid'],
},
'correct args for Foo passed'
);
}
else {
fail( 'correct args passed to rel_name_map' );
diag "args were: ", explain $args;
}
return $orig->({
Bar => { fooref => 'fooref_caught' },
Foo => { bars => 'bars_caught' },
});
}
);
is( ref($code_relationship->source('Foo')->relationship_info('bars_caught')),
'HASH',
'rel_name_map overrode local_info correctly'
);
is( ref($code_relationship->source('Bar')->relationship_info('fooref_caught')),
'HASH',
'rel_name_map overrode remote_info correctly'
);
throws_ok {
schema_with( rel_name_map => sub { $_[-1]->(sub{}) } ),
} qr/reentered rel_name_map must be a hashref/, 'throws error for invalid (code) rel_name_map callback map';
# test relationship_attrs
throws_ok {
schema_with( relationship_attrs => 'laughably invalid!!!' );
} qr/relationship_attrs/, 'throws error for invalid (scalar) relationship_attrs';
throws_ok {
schema_with( relationship_attrs => [qw/laughably invalid/] );
} qr/relationship_attrs/, 'throws error for invalid (arrayref) relationship_attrs';
{
my $nodelete = schema_with( relationship_attrs => {
all => { cascade_delete => 0 },
belongs_to => { cascade_delete => 1 },
});
my $bars_info = $nodelete->source('Foo')->relationship_info('bars');
#use Data::Dumper;
#die Dumper([ $nodelete->source('Foo')->relationships() ]);
my $fooref_info = $nodelete->source('Bar')->relationship_info('fooref');
is( ref($fooref_info), 'HASH',
'fooref rel is present',
);
is( $bars_info->{attrs}->{cascade_delete}, 0,
'relationship_attrs settings seem to be getting through to the generated rels',
);
is( $fooref_info->{attrs}->{cascade_delete}, 1,
'belongs_to in relationship_attrs overrides all def',
);
}
# test relationship_attrs coderef
{
my $relationship_attrs_coderef_invoked = 0;
my $schema;
lives_ok {
$schema = schema_with(relationship_attrs => sub {
my %p = @_;
$relationship_attrs_coderef_invoked++;
if ($p{rel_name} eq 'bars') {
is $p{rel_type}, 'has_many', 'correct rel_type';
is $p{local_table}, 'foo', 'correct local_table';
is_deeply $p{local_cols}, [ 'fooid' ], 'correct local_cols';
is $p{remote_table}, 'bar', 'correct remote_table';
is_deeply $p{remote_cols}, [ 'fooref' ], 'correct remote_cols';
is_deeply $p{attrs}, {
cascade_delete => 0,
cascade_copy => 0,
}, "got default rel attrs for $p{rel_name} in $p{local_table}";
like $p{local_source}->result_class,
qr/^DBICTest::Schema::\d+::Result::Foo\z/,
'correct local source';
like $p{remote_source}->result_class,
qr/^DBICTest::Schema::\d+::Result::Bar\z/,
'correct remote source';
$p{attrs}{snoopy} = 1;
return $p{attrs};
}
elsif ($p{rel_name} eq 'fooref') {
is $p{rel_type}, 'belongs_to', 'correct rel_type';
is $p{local_table}, 'bar', 'correct local_table';
is_deeply $p{local_cols}, [ 'fooref' ], 'correct local_cols';
is $p{remote_table}, 'foo', 'correct remote_table';
is_deeply $p{remote_cols}, [ 'fooid' ], 'correct remote_cols';
is_deeply $p{attrs}, {
on_delete => 'NO ACTION',
on_update => 'NO ACTION',
is_deferrable => 0,
}, "got correct rel attrs for $p{rel_name} in $p{local_table}";
like $p{local_source}->result_class,
qr/^DBICTest::Schema::\d+::Result::Bar\z/,
'correct local source';
like $p{remote_source}->result_class,
qr/^DBICTest::Schema::\d+::Result::Foo\z/,
'correct remote source';
$p{attrs}{scooby} = 1;
return $p{attrs};
}
else {
fail "unknown rel $p{rel_name} in $p{local_table}";
}
});
} 'dumping schema with coderef relationship_attrs survived';
is $relationship_attrs_coderef_invoked, 2,
'relationship_attrs coderef was invoked correct number of times';
is ((try { $schema->source('Foo')->relationship_info('bars')->{attrs}{snoopy} }) || undef, 1,
"correct relationship attributes for 'bars' in 'Foo'");
is ((try { $schema->source('Bar')->relationship_info('fooref')->{attrs}{scooby} }) || undef, 1,
"correct relationship attributes for 'fooref' in 'Bar'");
}
done_testing;
#### generates a new schema with the given opts every time it's called
sub schema_with {
$schema_counter++;
DBIx::Class::Schema::Loader::make_schema_at(
'DBICTest::Schema::'.$schema_counter,
{ naming => 'current', @_ },
[ $make_dbictest_db::dsn ],
);
"DBICTest::Schema::$schema_counter"->clone;
}
|