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