(travis) Make sure everything works even when we are SAD
[dbsrgits/DBIx-Class.git] / xt / extra / internals / optional_deps.t
CommitLineData
c052f3dd 1my ($inc_before, $inc_after);
be68095d 2BEGIN {
c052f3dd 3 $inc_before = [ keys %INC ];
4 require DBIx::Class::Optional::Dependencies;
5 $inc_after = [ keys %INC ];
be68095d 6}
7
cb551b07 8use strict;
9use warnings;
10no warnings qw/once/;
11
c052f3dd 12use Test::More;
13use Test::Exception;
e3a7746c 14
32871272 15BEGIN {
16 plan skip_all => 'This test breaking module loading interferes with PERL_UNICODE on perls prior to 5.12'
17 if exists $ENV{PERL_UNICODE} and "$]" < 5.012;
18}
19
e3a7746c 20# load before we break require()
21use Scalar::Util();
22use MRO::Compat();
cb551b07 23use Carp 'confess';
d1f653cf 24use List::Util 'shuffle';
64d48e19 25use Config;
05c0614b 26
bd510251 27SKIP: {
399b9455 28 skip 'Lean load pattern testing makes no sense with TempExtlib', 1
29 if grep { $_ =~ /TempExtlib/ } @INC;
30
26710bc9 31 skip 'Lean load pattern testing unsafe with $ENV{PERL5OPT}', 1
32 if $ENV{PERL5OPT};
33
34 skip 'Lean load pattern testing unsafe with sitecustomize.pl', 1
35 if grep { $_ =~ m| \/ sitecustomize\.pl $ |x } keys %INC;
36
37 skip 'Lean load pattern testing useless with $ENV{RELEASE_TESTING}', 1
38 if $ENV{RELEASE_TESTING};
39
64d48e19 40 skip 'Lean load pattern testing useless under cperl', 1
41 if $Config{usecperl};
42
bd510251 43 is_deeply
44 $inc_before,
45 [],
46 'Nothing was loaded before inc-test'
47 ;
48 is_deeply
49 $inc_after,
50 [ 'DBIx/Class/Optional/Dependencies.pm' ],
51 'Nothing was loaded other than DBIx::Class::OptDeps'
52 ;
53}
3c3e76bd 54
31c31b8d 55# check the project-local groups for sanity
56lives_ok {
57 DBIx::Class::Optional::Dependencies->req_group_list
58} "The entire optdep list is well formed";
59
05c0614b 60is_deeply (
31c31b8d 61 [ keys %{ DBIx::Class::Optional::Dependencies->req_list_for ('deploy') } ],
05c0614b 62 [ 'SQL::Translator' ],
63 'Correct deploy() dependency list',
64);
65
31c31b8d 66# scope to break require()
d8799bab 67{
31c31b8d 68
69# make module loading impossible, regardless of actual libpath contents
250d9e55 70 local @INC;
d8799bab 71
31c31b8d 72# basic test using the deploy target
73 for ('deploy', ['deploy']) {
74
75 # explicitly blow up cache
76 %DBIx::Class::Optional::Dependencies::req_unavailability_cache = ();
77
78 ok (
79 ! DBIx::Class::Optional::Dependencies->req_ok_for ($_),
80 'deploy() deps missing',
81 );
82
83 like (
e3a7746c 84 DBIx::Class::Optional::Dependencies->modreq_missing_for ($_),
85 qr/
86 \A
34f354c3 87 SQL::Translator \~ [\d\.]+
e3a7746c 88 \z
89 /x,
90 'expected modreq missing string contents',
91 );
92
93 like (
31c31b8d 94 DBIx::Class::Optional::Dependencies->req_missing_for ($_),
95 qr/
e3a7746c 96 \A
34f354c3 97 SQL::Translator \~ [\d\.]+
e3a7746c 98 \Q (see DBIx::Class::Optional::Dependencies documentation for details)\E
31c31b8d 99 \z
100 /x,
101 'expected missing string contents',
102 );
103
104 like (
5ffa39c7 105 DBIx::Class::Optional::Dependencies->modreq_errorlist_for ($_)->{'SQL::Translator'},
250d9e55 106 qr|\QCan't locate SQL/Translator.pm|,
107 'correct "unable to locate" exception found in errorlist',
31c31b8d 108 );
109
110 #make it so module appears loaded
111 local $INC{'SQL/Translator.pm'} = 1;
112 local $SQL::Translator::VERSION = 999;
113
114 ok (
115 ! DBIx::Class::Optional::Dependencies->req_ok_for ($_),
116 'deploy() deps missing cached properly from previous run',
117 );
118
119 # blow cache again
120 %DBIx::Class::Optional::Dependencies::req_unavailability_cache = ();
121
122 ok (
123 DBIx::Class::Optional::Dependencies->req_ok_for ($_),
124 'deploy() deps present',
125 );
126
127 is (
128 DBIx::Class::Optional::Dependencies->req_missing_for ($_),
129 '',
130 'expected null missing string',
131 );
132
133 is_deeply (
5ffa39c7 134 # use the deprecated method name
31c31b8d 135 DBIx::Class::Optional::Dependencies->req_errorlist_for ($_),
136 undef,
137 'expected empty errorlist',
138 );
139 }
140
e3a7746c 141# test single-db text
142 local $ENV{DBICTEST_MYSQL_DSN};
143 is_deeply(
144 DBIx::Class::Optional::Dependencies->req_list_for('test_rdbms_mysql'),
145 undef,
146 'unknown optional dependencies list for testing MySQL without ENV var',
147 );
31c31b8d 148 is_deeply(
e3a7746c 149 DBIx::Class::Optional::Dependencies->modreq_list_for('test_rdbms_mysql'),
150 { 'DBD::mysql' => 0 },
151 'correct optional module dependencies list for testing MySQL without ENV var',
152 );
153
154 local $ENV{DBICTEST_MYSQL_DSN};
155 local $ENV{DBICTEST_PG_DSN};
156
2baba3d9 157# regular
e3a7746c 158 is_deeply(
74919a00 159 DBIx::Class::Optional::Dependencies->modreq_list_for([shuffle qw( test_rdbms_pg binary_data )]),
e3a7746c 160 { 'DBD::Pg' => '2.009002' },
161 'optional dependencies list for testing Postgres without envvar',
162 );
163
164 is_deeply(
74919a00 165 DBIx::Class::Optional::Dependencies->req_list_for([shuffle qw( test_rdbms_pg binary_data )]),
e3a7746c 166 undef,
167 'optional dependencies list for testing Postgres without envvar',
d8799bab 168 );
169
31c31b8d 170 is_deeply(
171 DBIx::Class::Optional::Dependencies->req_list_for('rdbms_pg'),
172 { 'DBD::Pg' => '0', },
173 'optional dependencies list for using Postgres matches',
d8799bab 174 );
175
d1f653cf 176 is_deeply(
177 DBIx::Class::Optional::Dependencies->req_missing_for('rdbms_pg'),
178 'DBD::Pg (see DBIx::Class::Optional::Dependencies documentation for details)',
179 'optional dependencies missing list for using Postgres matches',
180 );
181
e3a7746c 182# test combination of different requirements on same module (pg's are relatively stable)
31c31b8d 183 is_deeply (
d1f653cf 184 DBIx::Class::Optional::Dependencies->req_list_for([shuffle qw( rdbms_pg test_rdbms_pg )]),
e3a7746c 185 { 'DBD::Pg' => '0' },
186 'optional module dependencies list for testing Postgres matches without envvar',
187 );
188
189 is(
74919a00 190 DBIx::Class::Optional::Dependencies->req_missing_for([shuffle qw( rdbms_pg test_rdbms_pg binary_data )]),
34f354c3 191 'DBD::Pg~2.009002 as well as the following group(s) of environment variables: DBICTEST_PG_DSN/..._USER/..._PASS',
e3a7746c 192 'optional dependencies for testing Postgres without envvar'
193 );
194
195 is(
74919a00 196 DBIx::Class::Optional::Dependencies->req_missing_for([shuffle qw( test_rdbms_mysql test_rdbms_pg binary_data)]),
34f354c3 197 'DBD::mysql DBD::Pg~2.009002 as well as the following group(s) of environment variables: DBICTEST_MYSQL_DSN/..._USER/..._PASS and DBICTEST_PG_DSN/..._USER/..._PASS',
e3a7746c 198 'optional dependencies for testing Postgres+MySQL without envvars'
199 );
200
201 $ENV{DBICTEST_PG_DSN} = 'boo';
202 is_deeply (
74919a00 203 DBIx::Class::Optional::Dependencies->modreq_list_for([shuffle qw( rdbms_pg test_rdbms_pg binary_data)]),
31c31b8d 204 { 'DBD::Pg' => '2.009002' },
e3a7746c 205 'optional module dependencies list for testing Postgres matches with envvar',
d8799bab 206 );
05c0614b 207
31c31b8d 208 is(
74919a00 209 DBIx::Class::Optional::Dependencies->req_missing_for([shuffle qw( rdbms_pg test_rdbms_pg binary_data )]),
34f354c3 210 'DBD::Pg~2.009002',
e3a7746c 211 'optional dependencies error text for testing Postgres matches with evvar',
31c31b8d 212 );
05c0614b 213
2baba3d9 214# ICDT augmentation
0d1e5280 215 my %expected_icdt_base = ( DateTime => '0.55', 'DateTime::TimeZone::OlsonDB' => 0 );
216
54a9a088 217 my $mysql_icdt = [shuffle qw( test_rdbms_mysql ic_dt )];
2baba3d9 218
219 is_deeply(
220 DBIx::Class::Optional::Dependencies->modreq_list_for($mysql_icdt),
221 {
0d1e5280 222 %expected_icdt_base,
2baba3d9 223 'DBD::mysql' => 0,
224 'DateTime::Format::MySQL' => 0,
225 },
226 'optional module dependencies list for testing ICDT MySQL without envvar',
227 );
228
229 is_deeply(
230 DBIx::Class::Optional::Dependencies->req_list_for($mysql_icdt),
0d1e5280 231 \%expected_icdt_base,
2baba3d9 232 'optional dependencies list for testing ICDT MySQL without envvar',
233 );
234
235 is(
236 DBIx::Class::Optional::Dependencies->req_missing_for($mysql_icdt),
0d1e5280 237 "DateTime~0.55 DateTime::Format::MySQL DateTime::TimeZone::OlsonDB DBD::mysql as well as the following group(s) of environment variables: DBICTEST_MYSQL_DSN/..._USER/..._PASS",
2baba3d9 238 'missing optional dependencies for testing ICDT MySQL without envvars'
239 );
240
d1f653cf 241# test multi-level include with a variable and mandatory part converging on same included dep
242 local $ENV{DBICTEST_MSACCESS_ODBC_DSN};
243 local $ENV{DBICTEST_MSSQL_ODBC_DSN} = 'foo';
54a9a088 244 my $msaccess_mssql_icdt = [ shuffle qw( test_rdbms_msaccess_odbc test_rdbms_mssql_odbc ic_dt ) ];
d1f653cf 245 is_deeply(
2baba3d9 246 DBIx::Class::Optional::Dependencies->req_missing_for($msaccess_mssql_icdt),
0d1e5280 247 'Data::GUID DateTime~0.55 DateTime::Format::Strptime~1.2 DateTime::TimeZone::OlsonDB DBD::ODBC as well as the following group(s) of environment variables: DBICTEST_MSACCESS_ODBC_DSN/..._USER/..._PASS',
d1f653cf 248 'Correct req_missing_for on multi-level converging include',
249 );
250
251 is_deeply(
2baba3d9 252 DBIx::Class::Optional::Dependencies->modreq_missing_for($msaccess_mssql_icdt),
0d1e5280 253 'Data::GUID DateTime~0.55 DateTime::Format::Strptime~1.2 DateTime::TimeZone::OlsonDB DBD::ODBC',
d1f653cf 254 'Correct modreq_missing_for on multi-level converging include',
255 );
256
257 is_deeply(
2baba3d9 258 DBIx::Class::Optional::Dependencies->req_list_for($msaccess_mssql_icdt),
d1f653cf 259 {
260 'DBD::ODBC' => 0,
2baba3d9 261 'DateTime::Format::Strptime' => '1.2',
0d1e5280 262 %expected_icdt_base,
d1f653cf 263 },
264 'Correct req_list_for on multi-level converging include',
265 );
266
267 is_deeply(
2baba3d9 268 DBIx::Class::Optional::Dependencies->modreq_list_for($msaccess_mssql_icdt),
d1f653cf 269 {
270 'DBD::ODBC' => 0,
271 'Data::GUID' => 0,
2baba3d9 272 'DateTime::Format::Strptime' => '1.2',
0d1e5280 273 %expected_icdt_base,
d1f653cf 274 },
275 'Correct modreq_list_for on multi-level converging include',
276 );
277
31c31b8d 278}
05c0614b 279
be68095d 280# test multiple times to find autovivification bugs
e3a7746c 281for my $meth (qw(req_list_for modreq_list_for)) {
be68095d 282 throws_ok {
e3a7746c 283 DBIx::Class::Optional::Dependencies->$meth();
be68095d 284 } qr/\Qreq_list_for() expects a requirement group name/,
e3a7746c 285 "$meth without groupname throws exception";
be68095d 286
287 throws_ok {
e3a7746c 288 DBIx::Class::Optional::Dependencies->$meth('');
289 } qr/\Q$meth() expects a requirement group name/,
290 "$meth with empty groupname throws exception";
be68095d 291
292 throws_ok {
e3a7746c 293 DBIx::Class::Optional::Dependencies->$meth('invalid_groupname');
31c31b8d 294 } qr/Requirement group 'invalid_groupname' is not defined/,
e3a7746c 295 "$meth with invalid groupname throws exception";
be68095d 296}
297
05c0614b 298done_testing;