Streamline ::ResultSource::* inheritance, similar to d009cb7d
[dbsrgits/DBIx-Class.git] / xt / extra / c3_mro.t
1 BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
2
3 use warnings;
4 use strict;
5
6 use Test::More;
7 use DBICTest;
8 use DBIx::Class::Optional::Dependencies;
9
10 my @global_ISA_tail = qw(
11   DBIx::Class
12   DBIx::Class::Componentised
13   Class::C3::Componentised
14   DBIx::Class::AccessorGroup
15   Class::Accessor::Grouped
16 );
17
18 is(
19   mro::get_mro('DBIx::Class'),
20   'c3',
21   'Correct mro on base class DBIx::Class',
22 );
23
24 {
25   package AAA;
26
27   use base "DBIx::Class::Core";
28 }
29
30 {
31   package BBB;
32
33   use base 'AAA';
34
35   #Injecting a direct parent.
36   __PACKAGE__->inject_base( __PACKAGE__, 'AAA' );
37 }
38
39 {
40   package CCC;
41
42   use base 'AAA';
43
44   #Injecting an indirect parent.
45   __PACKAGE__->inject_base( __PACKAGE__, 'DBIx::Class::Core' );
46 }
47
48 eval { mro::get_linear_isa('BBB'); };
49 ok (! $@, "Correctly skipped injecting a direct parent of class BBB");
50
51 eval { mro::get_linear_isa('CCC'); };
52 ok (! $@, "Correctly skipped injecting an indirect parent of class BBB");
53
54
55 my $art = DBICTest->init_schema->resultset("Artist")->next;
56
57 check_ancestry($_) for (
58   ref( $art ),
59   ref( $art->result_source ),
60   ref( $art->result_source->resultset ),
61   ref( $art->result_source->schema ),
62   ( map
63     { ref $art->result_source->schema->source($_) }
64     $art->result_source->schema->sources
65   ),
66   qw( AAA BBB CCC ),
67   ((! DBIx::Class::Optional::Dependencies->req_ok_for('cdbicompat') ) ? () : do {
68     unshift @INC, 't/cdbi/testlib';
69     map { eval "require $_" or die $@; $_ } qw(
70       Film Lazy Actor ActorAlias ImplicitInflate
71     );
72   }),
73 );
74
75 use DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server;
76
77 is_deeply (
78   mro::get_linear_isa('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server'),
79   [qw/
80     DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server
81     DBIx::Class::Storage::DBI::Sybase
82     DBIx::Class::Storage::DBI::MSSQL
83     DBIx::Class::Storage::DBI::UniqueIdentifier
84     DBIx::Class::Storage::DBI::IdentityInsert
85     DBIx::Class::Storage::DBI
86     DBIx::Class::Storage::DBIHacks
87     DBIx::Class::Storage
88   /, @global_ISA_tail],
89   'Correctly ordered ISA of DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server'
90 );
91
92 my $storage = DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server->new;
93 $storage->connect_info(['dbi:SQLite::memory:']); # determine_driver's init() connects for this subclass
94 $storage->_determine_driver;
95 is (
96   $storage->can('sql_limit_dialect'),
97   'DBIx::Class::Storage::DBI::MSSQL'->can('sql_limit_dialect'),
98   'Correct method picked'
99 );
100
101 if ( "$]" >= 5.010 ) {
102   ok (! $INC{'Class/C3.pm'}, 'No Class::C3 loaded on perl 5.10+');
103
104   # Class::C3::Componentised loads MRO::Compat unconditionally to satisfy
105   # the assumption that once Class::C3::X is loaded, so is Class::C3
106   #ok (! $INC{'MRO/Compat.pm'}, 'No MRO::Compat loaded on perl 5.10+');
107 }
108
109 sub check_ancestry {
110   my $class = shift;
111
112   die "Expecting classname" if length ref $class;
113
114   my @linear_ISA = @{ mro::get_linear_isa($class) };
115
116   # something is *VERY* wrong, the splice below won't make it
117   unless (@linear_ISA > @global_ISA_tail) {
118     fail(
119       "Unexpectedly shallow \@ISA for class '$class': "
120     . join ', ', map { "'$_'" } @linear_ISA
121     );
122     return;
123   }
124
125   is_deeply (
126     [ splice @linear_ISA, ($#linear_ISA - $#global_ISA_tail) ],
127     \@global_ISA_tail,
128     "Correct end of \@ISA for '$class'"
129   );
130
131   # check the remainder
132   for my $c (@linear_ISA) {
133     # nothing to see there
134     next if $c =~ /^DBICTest::/;
135
136     next if mro::get_mro($c) eq 'c3';
137
138     fail( "Incorrect mro '@{[ mro::get_mro($c) ]}' on '$c' (parent of '$class')" );
139   }
140 }
141
142 done_testing;