better case-sensitivity detection for MSSQL
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 25backcompat.t
CommitLineData
66afce69 1use strict;
2use warnings;
3use Test::More;
b24cb177 4use Test::Exception;
a0e0a56a 5use File::Path qw/rmtree make_path/;
66afce69 6use Class::Unload;
ffc705f3 7use File::Temp qw/tempfile tempdir/;
8use IO::File;
281d0f3e 9use File::Slurp 'slurp';
68d49e50 10use DBIx::Class::Schema::Loader ();
08e80fda 11use Lingua::EN::Inflect::Number ();
66afce69 12use lib qw(t/lib);
c496748b 13use make_dbictest_db_with_unique;
66afce69 14
15my $DUMP_DIR = './t/_common_dump';
16rmtree $DUMP_DIR;
a0e0a56a 17my $SCHEMA_CLASS = 'DBIXCSL_Test::Schema';
66afce69 18
08e80fda 19sub class_content_like;
20
66afce69 21# test dynamic schema in 0.04006 mode
22{
23 my $res = run_loader();
a0e0a56a 24 my $warning = $res->{warnings}[0];
66afce69 25
a0e0a56a 26 like $warning, qr/dynamic schema/i,
66afce69 27 'dynamic schema in backcompat mode detected';
a0e0a56a 28 like $warning, qr/run in 0\.04006 mode/i,
66afce69 29 'dynamic schema in 0.04006 mode warning';
a0e0a56a 30 like $warning, qr/DBIx::Class::Schema::Loader::Manual::UpgradingFromV4/,
31 'warning refers to upgrading doc';
32
33 run_v4_tests($res);
34}
66afce69 35
a0e0a56a 36# setting naming accessor on dynamic schema should disable warning (even when
37# we're setting it to 'v4' .)
38{
39 my $res = run_loader(naming => 'v4');
a0e0a56a 40 is_deeply $res->{warnings}, [], 'no warnings with naming attribute set';
f53dcdf0 41 run_v4_tests($res);
a0e0a56a 42}
43
44# test upgraded dynamic schema
45{
46 my $res = run_loader(naming => 'current');
a0e0a56a 47 is_deeply $res->{warnings}, [], 'no warnings with naming attribute set';
ecf930e6 48 run_v6_tests($res);
a0e0a56a 49}
50
ffc705f3 51# test upgraded dynamic schema with external content loaded
52{
08e80fda 53 my $temp_dir = setup_load_external({
54 Quuxs => 'Bazs',
55 Bar => 'Foos',
56 });
ffc705f3 57
58 my $res = run_loader(naming => 'current');
59 my $schema = $res->{schema};
60
61 is scalar @{ $res->{warnings} }, 1,
62'correct nummber of warnings for upgraded dynamic schema with external ' .
63'content for unsingularized Result.';
64
65 my $warning = $res->{warnings}[0];
66 like $warning, qr/Detected external content/i,
67 'detected external content warning';
68
b24cb177 69 lives_and { is $schema->resultset('Quux')->find(1)->a_method, 'hlagh' }
ffc705f3 70'external custom content for unsingularized Result was loaded by upgraded ' .
71'dynamic Schema';
72
b24cb177 73 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
74 $res->{classes}{bazs} }
75 'unsingularized class names in external content are translated';
76
08e80fda 77 lives_and { is $schema->resultset('Bar')->find(1)->a_method, 'hlagh' }
78'external content from unchanged Result class';
79
b24cb177 80 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
81 $res->{classes}{foos} }
82'unsingularized class names in external content from unchanged Result class ' .
83'names are translated';
84
ecf930e6 85 run_v6_tests($res);
ffc705f3 86}
87
805dbe0a 88# test upgraded dynamic schema with use_namespaces with external content loaded
89{
08e80fda 90 my $temp_dir = setup_load_external({
91 Quuxs => 'Bazs',
92 Bar => 'Foos',
93 });
805dbe0a 94
95 my $res = run_loader(naming => 'current', use_namespaces => 1);
96 my $schema = $res->{schema};
97
98 is scalar @{ $res->{warnings} }, 2,
99'correct nummber of warnings for upgraded dynamic schema with external ' .
100'content for unsingularized Result with use_namespaces.';
101
102 my $warning = $res->{warnings}[0];
103 like $warning, qr/Detected external content/i,
104 'detected external content warning';
105
106 lives_and { is $schema->resultset('Quux')->find(1)->a_method, 'hlagh' }
107'external custom content for unsingularized Result was loaded by upgraded ' .
108'dynamic Schema';
109
08e80fda 110 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
805dbe0a 111 $res->{classes}{bazs} }
112 'unsingularized class names in external content are translated';
113
08e80fda 114 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
805dbe0a 115 $res->{classes}{foos} }
116'unsingularized class names in external content from unchanged Result class ' .
117'names are translated';
118
ecf930e6 119 run_v6_tests($res);
805dbe0a 120}
121
30a4c064 122# test upgraded static schema with external content loaded
123{
08e80fda 124 clean_dumpdir();
b24cb177 125
08e80fda 126 my $temp_dir = setup_load_external({
127 Quuxs => 'Bazs',
128 Bar => 'Foos',
129 });
30a4c064 130
131 write_v4_schema_pm();
132
08e80fda 133 my $res = run_loader(static => 1, naming => 'current');
30a4c064 134 my $schema = $res->{schema};
135
ecf930e6 136 run_v6_tests($res);
30a4c064 137
08e80fda 138 lives_and { is $schema->resultset('Quux')->find(1)->a_method, 'hlagh' }
30a4c064 139'external custom content for unsingularized Result was loaded by upgraded ' .
140'static Schema';
141
08e80fda 142 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
b24cb177 143 $res->{classes}{bazs} }
144 'unsingularized class names in external content are translated';
145
08e80fda 146 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
b24cb177 147 $res->{classes}{foos} }
148'unsingularized class names in external content from unchanged Result class ' .
149'names are translated in static schema';
150
08e80fda 151 class_content_like $schema, $res->{classes}{quuxs}, qr/package ${SCHEMA_CLASS}::Quux;/,
30a4c064 152'package line translated correctly from external custom content in static dump';
153
08e80fda 154 class_content_like $schema, $res->{classes}{quuxs}, qr/sub a_method { 'hlagh' }/,
30a4c064 155'external custom content loaded into static dump correctly';
30a4c064 156}
157
ecf930e6 158# test creating static schema in v5 mode then upgrade to current with external
159# content loaded
160# XXX needs real load_external tests
161{
162 clean_dumpdir();
163
164 my $temp_dir = setup_load_external({
165 Quux => 'Baz',
166 Bar => 'Foo',
167 }, { result_namespace => 'Result' });
168
169 write_v5_schema_pm();
170
171 my $res = run_loader(static => 1);
172
173 run_v5_tests($res);
174
175 $res = run_loader(static => 1, naming => 'current');
176 my $schema = $res->{schema};
177
178 run_v6_tests($res);
179}
180
b24cb177 181# test running against v4 schema without upgrade, twice, then upgrade
a0e0a56a 182{
08e80fda 183 clean_dumpdir();
30a4c064 184 write_v4_schema_pm();
08e80fda 185 my $res = run_loader(static => 1);
a1a91c42 186 my $warning = $res->{warnings}[1];
a0e0a56a 187
188 like $warning, qr/static schema/i,
189 'static schema in backcompat mode detected';
190 like $warning, qr/0.04006/,
191 'correct version detected';
192 like $warning, qr/DBIx::Class::Schema::Loader::Manual::UpgradingFromV4/,
193 'refers to upgrading doc';
194
a1a91c42 195 is scalar @{ $res->{warnings} }, 4,
ffc705f3 196 'correct number of warnings for static schema in backcompat mode';
197
a0e0a56a 198 run_v4_tests($res);
199
08e80fda 200 add_custom_content($res->{schema}, {
201 Quuxs => 'Bazs'
202 });
a0e0a56a 203
b24cb177 204 # Rerun the loader in backcompat mode to make sure it's still in backcompat
205 # mode.
08e80fda 206 $res = run_loader(static => 1);
b24cb177 207 run_v4_tests($res);
208
a0e0a56a 209 # now upgrade the schema
a1a91c42 210 $res = run_loader(
08e80fda 211 static => 1,
a1a91c42 212 naming => 'current',
213 use_namespaces => 1
214 );
08e80fda 215 my $schema = $res->{schema};
a0e0a56a 216
217 like $res->{warnings}[0], qr/Dumping manual schema/i,
218 'correct warnings on upgrading static schema (with "naming" set)';
219
220 like $res->{warnings}[1], qr/dump completed/i,
221 'correct warnings on upgrading static schema (with "naming" set)';
222
223 is scalar @{ $res->{warnings} }, 2,
f53dcdf0 224'correct number of warnings on upgrading static schema (with "naming" set)'
225 or diag @{ $res->{warnings} };
a0e0a56a 226
ecf930e6 227 run_v6_tests($res);
a0e0a56a 228
ecf930e6 229 is result_count('Result'), 6,
a1a91c42 230 'un-singularized results were replaced during upgrade';
231
232 # check that custom content was preserved
08e80fda 233 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
a1a91c42 234 'custom content was carried over from un-singularized Result';
235
08e80fda 236 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
a1a91c42 237 $res->{classes}{bazs} }
238 'unsingularized class names in custom content are translated';
239
08e80fda 240 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
a1a91c42 241'custom content from unsingularized Result loaded into static dump correctly';
242}
243
244# test running against v4 schema without upgrade, then upgrade with
245# use_namespaces not explicitly set
246{
08e80fda 247 clean_dumpdir();
a1a91c42 248 write_v4_schema_pm();
08e80fda 249 my $res = run_loader(static => 1);
a1a91c42 250 my $warning = $res->{warnings}[1];
251
252 like $warning, qr/static schema/i,
253 'static schema in backcompat mode detected';
254 like $warning, qr/0.04006/,
255 'correct version detected';
256 like $warning, qr/DBIx::Class::Schema::Loader::Manual::UpgradingFromV4/,
257 'refers to upgrading doc';
258
259 is scalar @{ $res->{warnings} }, 4,
260 'correct number of warnings for static schema in backcompat mode';
261
262 run_v4_tests($res);
263
08e80fda 264 add_custom_content($res->{schema}, {
265 Quuxs => 'Bazs'
266 });
a1a91c42 267
268 # now upgrade the schema
269 $res = run_loader(
08e80fda 270 static => 1,
a1a91c42 271 naming => 'current'
272 );
08e80fda 273 my $schema = $res->{schema};
a1a91c42 274
275 like $res->{warnings}[0], qr/load_classes/i,
276'correct warnings on upgrading static schema (with "naming" set and ' .
277'use_namespaces not set)';
278
279 like $res->{warnings}[1], qr/Dumping manual schema/i,
280'correct warnings on upgrading static schema (with "naming" set and ' .
281'use_namespaces not set)';
282
283 like $res->{warnings}[2], qr/dump completed/i,
284'correct warnings on upgrading static schema (with "naming" set and ' .
285'use_namespaces not set)';
286
287 is scalar @{ $res->{warnings} }, 3,
288'correct number of warnings on upgrading static schema (with "naming" set)'
289 or diag @{ $res->{warnings} };
290
ecf930e6 291 run_v6_tests($res);
a1a91c42 292
ecf930e6 293 is result_count(), 6,
a0e0a56a 294 'un-singularized results were replaced during upgrade';
295
296 # check that custom content was preserved
08e80fda 297 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
a0e0a56a 298 'custom content was carried over from un-singularized Result';
b24cb177 299
08e80fda 300 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
a4b94090 301 $res->{classes}{bazs} }
302 'unsingularized class names in custom content are translated';
303
08e80fda 304 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
a4b94090 305'custom content from unsingularized Result loaded into static dump correctly';
306}
307
ecf930e6 308# test running against v4 schema with load_namespaces, upgrade to current but
77bf4429 309# downgrade to load_classes, with external content
a4b94090 310{
08e80fda 311 clean_dumpdir();
77bf4429 312
08e80fda 313 my $temp_dir = setup_load_external({
314 Quuxs => 'Bazs',
315 Bar => 'Foos',
316 }, { result_namespace => 'Result' });
77bf4429 317
a4b94090 318 write_v4_schema_pm(use_namespaces => 1);
77bf4429 319
08e80fda 320 my $res = run_loader(static => 1);
a4b94090 321 my $warning = $res->{warnings}[0];
322
323 like $warning, qr/static schema/i,
324 'static schema in backcompat mode detected';
325 like $warning, qr/0.04006/,
326 'correct version detected';
327 like $warning, qr/DBIx::Class::Schema::Loader::Manual::UpgradingFromV4/,
328 'refers to upgrading doc';
329
330 is scalar @{ $res->{warnings} }, 3,
331 'correct number of warnings for static schema in backcompat mode';
332
333 run_v4_tests($res);
334
77bf4429 335 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Result::Quuxs',
336 'use_namespaces in backcompat mode';
337
08e80fda 338 add_custom_content($res->{schema}, {
339 Quuxs => 'Bazs',
340 }, {
341 result_namespace => 'Result',
342 rel_name_map => { QuuxBaz => 'bazrel2' },
343 });
a4b94090 344
ecf930e6 345 # now upgrade the schema to current but downgrade to load_classes
a4b94090 346 $res = run_loader(
08e80fda 347 static => 1,
a4b94090 348 naming => 'current',
349 use_namespaces => 0,
350 );
08e80fda 351 my $schema = $res->{schema};
a4b94090 352
353 like $res->{warnings}[0], qr/Dumping manual schema/i,
354'correct warnings on upgrading static schema (with "naming" set and ' .
355'use_namespaces => 0)';
356
357 like $res->{warnings}[1], qr/dump completed/i,
358'correct warnings on upgrading static schema (with "naming" set and ' .
359'use_namespaces => 0)';
360
361 is scalar @{ $res->{warnings} }, 2,
362'correct number of warnings on upgrading static schema (with "naming" set)'
363 or diag @{ $res->{warnings} };
364
ecf930e6 365 run_v6_tests($res);
a4b94090 366
ecf930e6 367 is result_count(), 6,
a4b94090 368'un-singularized results were replaced during upgrade and Result dir removed';
369
08e80fda 370 ok ((not -d result_dir('Result')),
a4b94090 371 'Result dir was removed for load_classes downgrade');
372
540a8149 373 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Quux',
374 'load_classes in upgraded mode';
375
77bf4429 376 # check that custom and external content was preserved
08e80fda 377 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
a4b94090 378 'custom content was carried over from un-singularized Result';
379
08e80fda 380 lives_and { is $schema->resultset('Quux')->find(1)->a_method, 'hlagh' }
77bf4429 381 'external content was carried over from un-singularized Result';
382
08e80fda 383 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel2,
b24cb177 384 $res->{classes}{bazs} }
385 'unsingularized class names in custom content are translated';
386
08e80fda 387 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
77bf4429 388 $res->{classes}{bazs} }
389 'unsingularized class names in external content are translated';
390
08e80fda 391 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
77bf4429 392 $res->{classes}{foos} }
393'unsingularized class names in external content from unchanged Result class ' .
394'names are translated in static schema';
395
08e80fda 396 class_content_like $schema, $res->{classes}{quuxs}, qr/sub a_method { 'hlagh' }/,
77bf4429 397'external content from unsingularized Result loaded into static dump correctly';
398
08e80fda 399 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
400'custom content from unsingularized Result loaded into static dump correctly';
b24cb177 401}
402
540a8149 403# test a regular schema with use_namespaces => 0 upgraded to
404# use_namespaces => 1
405{
540a8149 406 my $res = run_loader(
08e80fda 407 clean_dumpdir => 1,
408 static => 1,
540a8149 409 use_namespaces => 0,
410 );
411
412 like $res->{warnings}[0], qr/Dumping manual schema/i,
413'correct warnings on dumping static schema with use_namespaces => 0';
414
415 like $res->{warnings}[1], qr/dump completed/i,
416'correct warnings on dumping static schema with use_namespaces => 0';
417
418 is scalar @{ $res->{warnings} }, 2,
419'correct number of warnings on dumping static schema with use_namespaces => 0'
420 or diag @{ $res->{warnings} };
421
ecf930e6 422 run_v6_tests($res);
540a8149 423
540a8149 424 my $schema = $res->{schema};
08e80fda 425 add_custom_content($res->{schema}, {
426 Quux => 'Baz'
427 });
540a8149 428
429 # test that with no use_namespaces option, there is a warning and
430 # load_classes is preserved
08e80fda 431 $res = run_loader(static => 1);
540a8149 432
433 like $res->{warnings}[0], qr/load_classes/i,
434'correct warnings on re-dumping static schema with load_classes';
435
436 like $res->{warnings}[1], qr/Dumping manual schema/i,
437'correct warnings on re-dumping static schema with load_classes';
438
439 like $res->{warnings}[2], qr/dump completed/i,
440'correct warnings on re-dumping static schema with load_classes';
441
442 is scalar @{ $res->{warnings} }, 3,
443'correct number of warnings on re-dumping static schema with load_classes'
444 or diag @{ $res->{warnings} };
445
446 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Quux',
447 'load_classes preserved on re-dump';
448
ecf930e6 449 run_v6_tests($res);
540a8149 450
451 # now upgrade the schema to use_namespaces
452 $res = run_loader(
08e80fda 453 static => 1,
540a8149 454 use_namespaces => 1,
455 );
456 $schema = $res->{schema};
457
458 like $res->{warnings}[0], qr/Dumping manual schema/i,
459'correct warnings on upgrading to use_namespaces';
460
461 like $res->{warnings}[1], qr/dump completed/i,
462'correct warnings on upgrading to use_namespaces';
463
464 is scalar @{ $res->{warnings} }, 2,
465'correct number of warnings on upgrading to use_namespaces'
466 or diag @{ $res->{warnings} };
467
ecf930e6 468 run_v6_tests($res);
540a8149 469
08e80fda 470 my @schema_files = schema_files();
540a8149 471
472 is 1, (scalar @schema_files),
08e80fda 473 "schema dir contains only 1 entry";
540a8149 474
475 like $schema_files[0], qr{/Result\z},
476 "schema dir contains only a Result/ directory";
477
478 # check that custom content was preserved
08e80fda 479 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
540a8149 480 'custom content was carried over during use_namespaces upgrade';
481
08e80fda 482 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
540a8149 483 $res->{classes}{bazs} }
484 'un-namespaced class names in custom content are translated';
485
08e80fda 486 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
540a8149 487'custom content from un-namespaced Result loaded into static dump correctly';
488}
489
490# test a regular schema with default use_namespaces => 1, redump, and downgrade
491# to load_classes
492{
08e80fda 493 my $res = run_loader(clean_dumpdir => 1, static => 1);
540a8149 494
495 like $res->{warnings}[0], qr/Dumping manual schema/i,
496'correct warnings on dumping static schema';
497
498 like $res->{warnings}[1], qr/dump completed/i,
499'correct warnings on dumping static schema';
500
501 is scalar @{ $res->{warnings} }, 2,
502'correct number of warnings on dumping static schema'
503 or diag @{ $res->{warnings} };
504
ecf930e6 505 run_v6_tests($res);
540a8149 506
507 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Result::Quux',
508 'defaults to use_namespaces on regular dump';
509
08e80fda 510 add_custom_content($res->{schema}, { Quux => 'Baz' }, { result_namespace => 'Result' });
540a8149 511
512 # test that with no use_namespaces option, use_namespaces is preserved
08e80fda 513 $res = run_loader(static => 1);
540a8149 514
515 like $res->{warnings}[0], qr/Dumping manual schema/i,
516'correct warnings on re-dumping static schema';
517
518 like $res->{warnings}[1], qr/dump completed/i,
519'correct warnings on re-dumping static schema';
520
521 is scalar @{ $res->{warnings} }, 2,
522'correct number of warnings on re-dumping static schema'
523 or diag @{ $res->{warnings} };
524
525 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Result::Quux',
526 'use_namespaces preserved on re-dump';
527
ecf930e6 528 run_v6_tests($res);
540a8149 529
530 # now downgrade the schema to load_classes
531 $res = run_loader(
08e80fda 532 static => 1,
540a8149 533 use_namespaces => 0,
534 );
08e80fda 535 my $schema = $res->{schema};
540a8149 536
537 like $res->{warnings}[0], qr/Dumping manual schema/i,
538'correct warnings on downgrading to load_classes';
539
540 like $res->{warnings}[1], qr/dump completed/i,
541'correct warnings on downgrading to load_classes';
542
543 is scalar @{ $res->{warnings} }, 2,
544'correct number of warnings on downgrading to load_classes'
545 or diag @{ $res->{warnings} };
546
ecf930e6 547 run_v6_tests($res);
540a8149 548
549 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Quux',
550 'load_classes downgrade correct';
551
ecf930e6 552 is result_count(), 6,
540a8149 553'correct number of Results after upgrade and Result dir removed';
554
08e80fda 555 ok ((not -d result_dir('Result')),
540a8149 556 'Result dir was removed for load_classes downgrade');
557
558 # check that custom content was preserved
08e80fda 559 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
540a8149 560 'custom content was carried over during load_classes downgrade';
561
08e80fda 562 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
540a8149 563 $res->{classes}{bazs} }
564'namespaced class names in custom content are translated during load_classes '.
565'downgrade';
566
08e80fda 567 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
540a8149 568'custom content from namespaced Result loaded into static dump correctly '.
569'during load_classes downgrade';
570}
571
572# test a regular schema with use_namespaces => 1 and a custom result_namespace
573# downgraded to load_classes
574{
540a8149 575 my $res = run_loader(
08e80fda 576 clean_dumpdir => 1,
577 static => 1,
540a8149 578 result_namespace => 'MyResult',
579 );
580
581 like $res->{warnings}[0], qr/Dumping manual schema/i,
582'correct warnings on dumping static schema';
583
584 like $res->{warnings}[1], qr/dump completed/i,
585'correct warnings on dumping static schema';
586
587 is scalar @{ $res->{warnings} }, 2,
588'correct number of warnings on dumping static schema'
589 or diag @{ $res->{warnings} };
590
ecf930e6 591 run_v6_tests($res);
540a8149 592
593 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::MyResult::Quux',
594 'defaults to use_namespaces and uses custom result_namespace';
595
08e80fda 596 add_custom_content($res->{schema}, { Quux => 'Baz' }, { result_namespace => 'MyResult' });
540a8149 597
598 # test that with no use_namespaces option, use_namespaces is preserved, and
599 # the custom result_namespace is preserved
08e80fda 600 $res = run_loader(static => 1);
540a8149 601
602 like $res->{warnings}[0], qr/Dumping manual schema/i,
603'correct warnings on re-dumping static schema';
604
605 like $res->{warnings}[1], qr/dump completed/i,
606'correct warnings on re-dumping static schema';
607
608 is scalar @{ $res->{warnings} }, 2,
609'correct number of warnings on re-dumping static schema'
610 or diag @{ $res->{warnings} };
611
612 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::MyResult::Quux',
613 'use_namespaces and custom result_namespace preserved on re-dump';
614
ecf930e6 615 run_v6_tests($res);
540a8149 616
617 # now downgrade the schema to load_classes
618 $res = run_loader(
08e80fda 619 static => 1,
540a8149 620 use_namespaces => 0,
621 );
08e80fda 622 my $schema = $res->{schema};
540a8149 623
624 like $res->{warnings}[0], qr/Dumping manual schema/i,
625'correct warnings on downgrading to load_classes';
626
627 like $res->{warnings}[1], qr/dump completed/i,
628'correct warnings on downgrading to load_classes';
629
630 is scalar @{ $res->{warnings} }, 2,
631'correct number of warnings on downgrading to load_classes'
632 or diag @{ $res->{warnings} };
633
ecf930e6 634 run_v6_tests($res);
540a8149 635
636 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Quux',
637 'load_classes downgrade correct';
638
ecf930e6 639 is result_count(), 6,
540a8149 640'correct number of Results after upgrade and Result dir removed';
641
08e80fda 642 ok ((not -d result_dir('MyResult')),
540a8149 643 'Result dir was removed for load_classes downgrade');
644
645 # check that custom content was preserved
08e80fda 646 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
540a8149 647 'custom content was carried over during load_classes downgrade';
648
08e80fda 649 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
540a8149 650 $res->{classes}{bazs} }
651'namespaced class names in custom content are translated during load_classes '.
652'downgrade';
653
08e80fda 654 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
540a8149 655'custom content from namespaced Result loaded into static dump correctly '.
656'during load_classes downgrade';
657}
658
77bf4429 659# rewrite from one result_namespace to another, with external content
540a8149 660{
08e80fda 661 clean_dumpdir();
662 my $temp_dir = setup_load_external({ Quux => 'Baz', Bar => 'Foo' }, { result_namespace => 'Result' });
77bf4429 663
08e80fda 664 my $res = run_loader(static => 1);
540a8149 665
666 # add some custom content to a Result that will be replaced
08e80fda 667 add_custom_content($res->{schema}, { Quux => 'Baz' }, { result_namespace => 'Result', rel_name_map => { QuuxBaz => 'bazrel2' } });
540a8149 668
669 # Rewrite implicit 'Result' to 'MyResult'
670 $res = run_loader(
08e80fda 671 static => 1,
540a8149 672 result_namespace => 'MyResult',
673 );
08e80fda 674 my $schema = $res->{schema};
540a8149 675
676 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::MyResult::Quux',
677 'using new result_namespace';
678
ecf930e6 679 is result_count('MyResult'), 6,
540a8149 680'correct number of Results after rewritten result_namespace';
681
08e80fda 682 ok ((not -d schema_dir('Result')),
540a8149 683 'original Result dir was removed when rewriting result_namespace');
684
685 # check that custom content was preserved
08e80fda 686 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
540a8149 687 'custom content was carried over when rewriting result_namespace';
688
08e80fda 689 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel2,
540a8149 690 $res->{classes}{bazs} }
691'class names in custom content are translated when rewriting result_namespace';
692
08e80fda 693 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
540a8149 694'custom content from namespaced Result loaded into static dump correctly '.
695'when rewriting result_namespace';
696
697 # Now rewrite 'MyResult' to 'Mtfnpy'
698 $res = run_loader(
08e80fda 699 static => 1,
540a8149 700 result_namespace => 'Mtfnpy',
701 );
702 $schema = $res->{schema};
703
704 is $res->{classes}{quuxs}, 'DBIXCSL_Test::Schema::Mtfnpy::Quux',
705 'using new result_namespace';
706
ecf930e6 707 is result_count('Mtfnpy'), 6,
540a8149 708'correct number of Results after rewritten result_namespace';
709
08e80fda 710 ok ((not -d result_dir('MyResult')),
540a8149 711 'original Result dir was removed when rewriting result_namespace');
712
77bf4429 713 # check that custom and external content was preserved
08e80fda 714 lives_and { is $schema->resultset('Quux')->find(1)->a_method, 'hlagh' }
715 'external content was carried over when rewriting result_namespace';
540a8149 716
08e80fda 717 lives_and { is $schema->resultset('Quux')->find(1)->b_method, 'dongs' }
77bf4429 718 'custom content was carried over when rewriting result_namespace';
719
08e80fda 720 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel2,
540a8149 721 $res->{classes}{bazs} }
722'class names in custom content are translated when rewriting result_namespace';
723
08e80fda 724 lives_and { isa_ok $schema->resultset('Quux')->find(1)->bazrel,
77bf4429 725 $res->{classes}{bazs} }
726'class names in external content are translated when rewriting '.
727'result_namespace';
728
08e80fda 729 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
77bf4429 730 $res->{classes}{foos} }
731'class names in external content are translated when rewriting '.
732'result_namespace';
733
08e80fda 734 class_content_like $schema, $res->{classes}{quuxs}, qr/sub b_method { 'dongs' }/,
540a8149 735'custom content from namespaced Result loaded into static dump correctly '.
736'when rewriting result_namespace';
77bf4429 737
08e80fda 738 class_content_like $schema, $res->{classes}{quuxs}, qr/sub a_method { 'hlagh' }/,
77bf4429 739'external content from unsingularized Result loaded into static dump correctly';
540a8149 740}
741
08e80fda 742# test upgrading a v4 schema, then check that the version string is correct
68d49e50 743{
08e80fda 744 clean_dumpdir();
68d49e50 745 write_v4_schema_pm();
08e80fda 746 run_loader(static => 1);
747 my $res = run_loader(static => 1, naming => 'current');
68d49e50 748 my $schema = $res->{schema};
749
750 my $file = $schema->_loader->_get_dump_filename($SCHEMA_CLASS);
281d0f3e 751 my $code = slurp $file;
68d49e50 752
753 my ($dumped_ver) =
754 $code =~ /^# Created by DBIx::Class::Schema::Loader v(\S+)/m;
755
756 is $dumped_ver, $DBIx::Class::Schema::Loader::VERSION,
757 'correct version dumped after upgrade of v4 static schema';
758}
759
b24cb177 760# Test upgrading an already singular result with custom content that refers to
761# old class names.
762{
08e80fda 763 clean_dumpdir();
b24cb177 764 write_v4_schema_pm();
08e80fda 765 my $res = run_loader(static => 1);
766 my $schema = $res->{schema};
b24cb177 767 run_v4_tests($res);
768
769 # add some custom content to a Result that will be replaced
08e80fda 770 add_custom_content($schema, { Bar => 'Foos' });
b24cb177 771
772 # now upgrade the schema
08e80fda 773 $res = run_loader(static => 1, naming => 'current');
b24cb177 774 $schema = $res->{schema};
ecf930e6 775 run_v6_tests($res);
b24cb177 776
777 # check that custom content was preserved
08e80fda 778 lives_and { is $schema->resultset('Bar')->find(1)->b_method, 'dongs' }
b24cb177 779 'custom content was preserved from Result pre-upgrade';
780
08e80fda 781 lives_and { isa_ok $schema->resultset('Bar')->find(1)->foorel,
b24cb177 782 $res->{classes}{foos} }
783'unsingularized class names in custom content from Result with unchanged ' .
784'name are translated';
785
08e80fda 786 class_content_like $schema, $res->{classes}{bar}, qr/sub b_method { 'dongs' }/,
b24cb177 787'custom content from Result with unchanged name loaded into static dump ' .
788'correctly';
66afce69 789}
790
791done_testing;
792
ffc705f3 793END {
794 rmtree $DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
795}
a0e0a56a 796
08e80fda 797sub clean_dumpdir {
798 rmtree $DUMP_DIR;
799 make_path $DUMP_DIR;
800}
801
dbe9e0f7 802sub run_loader {
803 my %loader_opts = @_;
804
08e80fda 805 $loader_opts{dump_directory} = $DUMP_DIR if delete $loader_opts{static};
806
807 clean_dumpdir() if delete $loader_opts{clean_dumpdir};
808
dbe9e0f7 809 eval {
810 foreach my $source_name ($SCHEMA_CLASS->clone->sources) {
811 Class::Unload->unload("${SCHEMA_CLASS}::${source_name}");
812 }
813
814 Class::Unload->unload($SCHEMA_CLASS);
815 };
816 undef $@;
817
c496748b 818 my @connect_info = $make_dbictest_db_with_unique::dsn;
dbe9e0f7 819 my @loader_warnings;
820 local $SIG{__WARN__} = sub { push(@loader_warnings, $_[0]); };
821 eval qq{
822 package $SCHEMA_CLASS;
823 use base qw/DBIx::Class::Schema::Loader/;
824
825 __PACKAGE__->loader_options(\%loader_opts);
826 __PACKAGE__->connection(\@connect_info);
827 };
828
829 ok(!$@, "Loader initialization") or diag $@;
830
831 my $schema = $SCHEMA_CLASS->clone;
832 my (%monikers, %classes);
833 foreach my $source_name ($schema->sources) {
834 my $table_name = $schema->source($source_name)->from;
835 $monikers{$table_name} = $source_name;
d073740e 836 $classes{$table_name} = $schema->source($source_name)->result_class;
dbe9e0f7 837 }
838
839 return {
840 schema => $schema,
841 warnings => \@loader_warnings,
842 monikers => \%monikers,
843 classes => \%classes,
844 };
845}
846
30a4c064 847sub write_v4_schema_pm {
a4b94090 848 my %opts = @_;
849
30a4c064 850 (my $schema_dir = "$DUMP_DIR/$SCHEMA_CLASS") =~ s/::[^:]+\z//;
851 rmtree $schema_dir;
852 make_path $schema_dir;
853 my $schema_pm = "$schema_dir/Schema.pm";
854 open my $fh, '>', $schema_pm or die $!;
a4b94090 855 if (not $opts{use_namespaces}) {
856 print $fh <<'EOF';
30a4c064 857package DBIXCSL_Test::Schema;
858
859use strict;
860use warnings;
861
862use base 'DBIx::Class::Schema';
863
864__PACKAGE__->load_classes;
865
866
867# Created by DBIx::Class::Schema::Loader v0.04006 @ 2009-12-25 01:49:25
868# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ibIJTbfM1ji4pyD/lgSEog
869
870
871# You can replace this text with custom content, and it will be preserved on regeneration
8721;
873EOF
a4b94090 874 }
875 else {
876 print $fh <<'EOF';
877package DBIXCSL_Test::Schema;
878
879use strict;
880use warnings;
881
882use base 'DBIx::Class::Schema';
883
884__PACKAGE__->load_namespaces;
885
886
887# Created by DBIx::Class::Schema::Loader v0.04006 @ 2010-01-12 16:04:12
888# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:d3wRVsHBNisyhxeaWJZcZQ
889
890
891# You can replace this text with custom content, and it will be preserved on
892# regeneration
8931;
894EOF
895 }
30a4c064 896}
897
ecf930e6 898sub write_v5_schema_pm {
899 my %opts = @_;
900
901 (my $schema_dir = "$DUMP_DIR/$SCHEMA_CLASS") =~ s/::[^:]+\z//;
902 rmtree $schema_dir;
903 make_path $schema_dir;
904 my $schema_pm = "$schema_dir/Schema.pm";
905 open my $fh, '>', $schema_pm or die $!;
906 if (exists $opts{use_namespaces} && $opts{use_namespaces} == 0) {
907 print $fh <<'EOF';
908package DBIXCSL_Test::Schema;
909
910# Created by DBIx::Class::Schema::Loader
911# DO NOT MODIFY THE FIRST PART OF THIS FILE
912
913use strict;
914use warnings;
915
916use base 'DBIx::Class::Schema';
917
918__PACKAGE__->load_classes;
919
920
921# Created by DBIx::Class::Schema::Loader v0.05003 @ 2010-03-27 17:07:37
922# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LIzC/LT5IYvWpgusfbqMrg
923
924
925# You can replace this text with custom content, and it will be preserved on regeneration
9261;
927EOF
928 }
929 else {
930 print $fh <<'EOF';
931package DBIXCSL_Test::Schema;
932
933# Created by DBIx::Class::Schema::Loader
934# DO NOT MODIFY THE FIRST PART OF THIS FILE
935
936use strict;
937use warnings;
938
939use base 'DBIx::Class::Schema';
940
941__PACKAGE__->load_classes;
942
943
944# Created by DBIx::Class::Schema::Loader v0.05003 @ 2010-03-27 17:07:37
945# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LIzC/LT5IYvWpgusfbqMrg
946
947
948# You can replace this text with custom content, and it will be preserved on regeneration
9491;
950EOF
951 }
952}
953
dbe9e0f7 954sub run_v4_tests {
955 my $res = shift;
956 my $schema = $res->{schema};
957
ecf930e6 958 is_deeply [ @{ $res->{monikers} }{qw/foos bar bazs quuxs stations_visited email/} ],
959 [qw/Foos Bar Bazs Quuxs StationsVisited Email/],
dbe9e0f7 960 'correct monikers in 0.04006 mode';
961
962 isa_ok ((my $bar = eval { $schema->resultset('Bar')->find(1) }),
963 $res->{classes}{bar},
964 'found a bar');
965
966 isa_ok eval { $bar->foo_id }, $res->{classes}{foos},
967 'correct rel name in 0.04006 mode';
968
969 ok my $baz = eval { $schema->resultset('Bazs')->find(1) };
970
971 isa_ok eval { $baz->quux }, 'DBIx::Class::ResultSet',
972 'correct rel type and name for UNIQUE FK in 0.04006 mode';
ecf930e6 973
974 ok my $foo = eval { $schema->resultset('Foos')->find(1) };
975
976 isa_ok eval { $foo->email_to_ids }, 'DBIx::Class::ResultSet',
977 'correct rel name inflection in 0.04006 mode';
dbe9e0f7 978}
979
980sub run_v5_tests {
981 my $res = shift;
982 my $schema = $res->{schema};
983
ecf930e6 984 is_deeply [ @{ $res->{monikers} }{qw/foos bar bazs quuxs stations_visited email/} ],
985 [qw/Foo Bar Baz Quux StationsVisited Email/],
986 'correct monikers in current mode';
987
988 ok my $bar = eval { $schema->resultset('Bar')->find(1) };
989
990 isa_ok eval { $bar->foo }, $res->{classes}{foos},
991 'correct rel name in v5 mode';
992
993 ok my $baz = eval { $schema->resultset('Baz')->find(1) };
994
995 isa_ok eval { $baz->quux }, $res->{classes}{quuxs},
996 'correct rel type and name for UNIQUE FK in v5 mode';
997
998 ok my $foo = eval { $schema->resultset('Foo')->find(1) };
999
1000 isa_ok eval { $foo->email_to_ids }, 'DBIx::Class::ResultSet',
1001 'correct rel name inflection in v5 mode';
1002}
1003
1004sub run_v6_tests {
1005 my $res = shift;
1006 my $schema = $res->{schema};
1007
1008 is_deeply [ @{ $res->{monikers} }{qw/foos bar bazs quuxs stations_visited email/} ],
1009 [qw/Foo Bar Baz Quux StationVisited Email/],
dbe9e0f7 1010 'correct monikers in current mode';
1011
1012 ok my $bar = eval { $schema->resultset('Bar')->find(1) };
1013
1014 isa_ok eval { $bar->foo }, $res->{classes}{foos},
1015 'correct rel name in current mode';
1016
1017 ok my $baz = eval { $schema->resultset('Baz')->find(1) };
1018
1019 isa_ok eval { $baz->quux }, $res->{classes}{quuxs},
1020 'correct rel type and name for UNIQUE FK in current mode';
ecf930e6 1021
1022 ok my $foo = eval { $schema->resultset('Foo')->find(1) };
1023
1024 isa_ok eval { $foo->emails_to }, 'DBIx::Class::ResultSet',
1025 'correct rel name inflection in current mode';
dbe9e0f7 1026}
08e80fda 1027
1028{
1029 package DBICSL::Test::TempExtDir;
1030
1031 use overload '""' => sub { ${$_[0]} };
1032
1033 sub DESTROY {
1034 pop @INC;
ca12f6c9 1035 File::Path::rmtree ${$_[0]};
08e80fda 1036 }
1037}
1038
1039sub setup_load_external {
1040 my ($rels, $opts) = @_;
1041
1042 my $temp_dir = tempdir(CLEANUP => 1);
1043 push @INC, $temp_dir;
1044
1045 my $external_result_dir = join '/', $temp_dir, (split /::/, $SCHEMA_CLASS),
1046 ($opts->{result_namespace} || ());
1047
1048 make_path $external_result_dir;
1049
1050 while (my ($from, $to) = each %$rels) {
1051 write_ext_result($external_result_dir, $from, $to, $opts);
1052 }
1053
1054 my $guard = bless \$temp_dir, 'DBICSL::Test::TempExtDir';
1055
1056 return $guard;
1057}
1058
1059sub write_ext_result {
1060 my ($result_dir, $from, $to, $opts) = @_;
1061
1062 my $relname = $opts->{rel_name_map}{_rel_key($from, $to)} || _relname($to);
1063 my $from_class = _qualify_class($from, $opts->{result_namespace});
1064 my $to_class = _qualify_class($to, $opts->{result_namespace});
1065 my $condition = _rel_condition($from, $to);
1066
1067 IO::File->new(">$result_dir/${from}.pm")->print(<<"EOF");
1068package ${from_class};
1069sub a_method { 'hlagh' }
1070
1071__PACKAGE__->has_one('$relname', '$to_class',
1072{ $condition });
1073
10741;
1075EOF
1076
1077 return $relname;
1078}
1079
1080sub _relname {
1081 my $to = shift;
1082
1083 return Lingua::EN::Inflect::Number::to_S(lc $to) . 'rel';
1084}
1085
1086sub _qualify_class {
1087 my ($class, $result_namespace) = @_;
1088
1089 return $SCHEMA_CLASS . '::'
1090 . ($result_namespace ? $result_namespace . '::' : '')
1091 . $class;
1092}
1093
1094sub _rel_key {
1095 my ($from, $to) = @_;
1096
1097 return join '', map ucfirst(Lingua::EN::Inflect::Number::to_S(lc($_))), $from, $to;
1098}
1099
1100sub _rel_condition {
1101 my ($from, $to) = @_;
1102
1103 return +{
1104 QuuxBaz => q{'foreign.baz_num' => 'self.baz_id'},
1105 BarFoo => q{'foreign.fooid' => 'self.foo_id'},
1106 }->{_rel_key($from, $to)};
1107}
1108
1109sub class_content_like {
1110 my ($schema, $class, $re, $test_name) = @_;
1111
1112 my $file = $schema->_loader->_get_dump_filename($class);
1113 my $code = slurp $file;
1114
1115 like $code, $re, $test_name;
1116}
1117
1118sub add_custom_content {
1119 my ($schema, $rels, $opts) = @_;
1120
1121 while (my ($from, $to) = each %$rels) {
1122 my $relname = $opts->{rel_name_map}{_rel_key($from, $to)} || _relname($to);
1123 my $from_class = _qualify_class($from, $opts->{result_namespace});
1124 my $to_class = _qualify_class($to, $opts->{result_namespace});
1125 my $condition = _rel_condition($from, $to);
1126
1127 my $content = <<"EOF";
1128package ${from_class};
1129sub b_method { 'dongs' }
1130
1131__PACKAGE__->has_one('$relname', '$to_class',
1132{ $condition });
1133
11341;
1135EOF
1136
1137 _write_custom_content($schema, $from_class, $content);
1138 }
1139}
1140
1141sub _write_custom_content {
1142 my ($schema, $class, $content) = @_;
1143
1144 my $pm = $schema->_loader->_get_dump_filename($class);
1145 {
1146 local ($^I, @ARGV) = ('.bak', $pm);
1147 while (<>) {
1148 if (/DO NOT MODIFY THIS OR ANYTHING ABOVE/) {
1149 print;
1150 print $content;
1151 }
1152 else {
1153 print;
1154 }
1155 }
1156 close ARGV;
1157 unlink "${pm}.bak" or die $^E;
1158 }
1159}
1160
1161sub result_count {
1162 my $path = shift || '';
1163
1164 my $dir = result_dir($path);
1165
1166 my $file_count =()= glob "$dir/*";
1167
1168 return $file_count;
1169}
1170
1171sub result_files {
1172 my $path = shift || '';
1173
1174 my $dir = result_dir($path);
1175
1176 return glob "$dir/*";
1177}
1178
1179sub schema_files { result_files(@_) }
1180
1181sub result_dir {
1182 my $path = shift || '';
1183
1184 (my $dir = "$DUMP_DIR/$SCHEMA_CLASS/$path") =~ s{::}{/}g;
1185 $dir =~ s{/+\z}{};
1186
1187 return $dir;
1188}
1189
1190sub schema_dir { result_dir(@_) }
ecf930e6 1191
1192# vim:et sts=4 sw=4 tw=0: