Add import-time-skip support to OptDeps, switch most tests over to that
[dbsrgits/DBIx-Class.git] / xt / optional_deps.t
1 my ($inc_before, $inc_after);
2 BEGIN {
3   $inc_before = [ keys %INC ];
4   require DBIx::Class::Optional::Dependencies;
5   $inc_after = [ keys %INC ];
6 }
7
8 use strict;
9 use warnings;
10 no warnings qw/once/;
11
12 use Test::More;
13 use Test::Exception;
14
15 # load before we break require()
16 use Scalar::Util();
17 use MRO::Compat();
18 use Carp 'confess';
19
20 ok ( (! grep { $_ =~ m|DBIx/Class| } @$inc_before ), 'Nothing DBIC related was loaded before inc-test')
21   unless $ENV{PERL5OPT}; # a defined PERL5OPT may inject extra deps crashing this test
22
23 is_deeply (
24   [ sort @$inc_after],
25   [ sort (@$inc_before, qw( DBIx/Class/Optional/Dependencies.pm if.pm )) ],
26   'Nothing loaded other than DBIx::Class::OptDeps',
27 ) unless $ENV{RELEASE_TESTING};
28
29
30 # check the project-local groups for sanity
31 lives_ok {
32   DBIx::Class::Optional::Dependencies->req_group_list
33 } "The entire optdep list is well formed";
34
35 is_deeply (
36   [ keys %{ DBIx::Class::Optional::Dependencies->req_list_for ('deploy') } ],
37   [ 'SQL::Translator' ],
38   'Correct deploy() dependency list',
39 );
40
41 # scope to break require()
42 {
43
44 # make module loading impossible, regardless of actual libpath contents
45   local @INC = (sub { confess('Optional Dep Test') } );
46
47 # basic test using the deploy target
48   for ('deploy', ['deploy']) {
49
50     # explicitly blow up cache
51     %DBIx::Class::Optional::Dependencies::req_unavailability_cache = ();
52
53     ok (
54       ! DBIx::Class::Optional::Dependencies->req_ok_for ($_),
55       'deploy() deps missing',
56     );
57
58     like (
59       DBIx::Class::Optional::Dependencies->modreq_missing_for ($_),
60       qr/
61         \A
62         " SQL::Translator \~ \>\= [\d\.]+ "
63         \z
64       /x,
65       'expected modreq missing string contents',
66     );
67
68     like (
69       DBIx::Class::Optional::Dependencies->req_missing_for ($_),
70       qr/
71         \A
72         " SQL::Translator \~ \>\= [\d\.]+ "
73         \Q (see DBIx::Class::Optional::Dependencies documentation for details)\E
74         \z
75       /x,
76       'expected missing string contents',
77     );
78
79     like (
80       DBIx::Class::Optional::Dependencies->modreq_errorlist_for ($_)->{'SQL::Translator'},
81       qr/Optional Dep Test/,
82       'custom exception found in errorlist',
83     );
84
85     #make it so module appears loaded
86     local $INC{'SQL/Translator.pm'} = 1;
87     local $SQL::Translator::VERSION = 999;
88
89     ok (
90       ! DBIx::Class::Optional::Dependencies->req_ok_for ($_),
91       'deploy() deps missing cached properly from previous run',
92     );
93
94     # blow cache again
95     %DBIx::Class::Optional::Dependencies::req_unavailability_cache = ();
96
97     ok (
98       DBIx::Class::Optional::Dependencies->req_ok_for ($_),
99       'deploy() deps present',
100     );
101
102     is (
103       DBIx::Class::Optional::Dependencies->req_missing_for ($_),
104       '',
105       'expected null missing string',
106     );
107
108     is_deeply (
109       # use the deprecated method name
110       DBIx::Class::Optional::Dependencies->req_errorlist_for ($_),
111       undef,
112       'expected empty errorlist',
113     );
114   }
115
116 # test single-db text
117   local $ENV{DBICTEST_MYSQL_DSN};
118   is_deeply(
119     DBIx::Class::Optional::Dependencies->req_list_for('test_rdbms_mysql'),
120     undef,
121     'unknown optional dependencies list for testing MySQL without ENV var',
122   );
123   is_deeply(
124     DBIx::Class::Optional::Dependencies->modreq_list_for('test_rdbms_mysql'),
125     { 'DBD::mysql' => 0 },
126     'correct optional module dependencies list for testing MySQL without ENV var',
127   );
128
129   local $ENV{DBICTEST_MYSQL_DSN};
130   local $ENV{DBICTEST_PG_DSN};
131
132   is_deeply(
133     DBIx::Class::Optional::Dependencies->modreq_list_for('test_rdbms_pg'),
134     { 'DBD::Pg' => '2.009002' },
135     'optional dependencies list for testing Postgres without envvar',
136   );
137
138   is_deeply(
139     DBIx::Class::Optional::Dependencies->req_list_for('test_rdbms_pg'),
140     undef,
141     'optional dependencies list for testing Postgres without envvar',
142   );
143
144   is_deeply(
145     DBIx::Class::Optional::Dependencies->req_list_for('rdbms_pg'),
146     { 'DBD::Pg' => '0', },
147     'optional dependencies list for using Postgres matches',
148   );
149
150 # test combination of different requirements on same module (pg's are relatively stable)
151   is_deeply (
152     DBIx::Class::Optional::Dependencies->req_list_for([qw( rdbms_pg test_rdbms_pg )]),
153     { 'DBD::Pg' => '0' },
154     'optional module dependencies list for testing Postgres matches without envvar',
155   );
156
157   is(
158     DBIx::Class::Optional::Dependencies->req_missing_for([qw( rdbms_pg test_rdbms_pg )]),
159     '"DBD::Pg~>=2.009002" as well as the following group(s) of environment variables: DBICTEST_PG_DSN/..._USER/..._PASS',
160     'optional dependencies for testing Postgres without envvar'
161   );
162
163   is(
164     DBIx::Class::Optional::Dependencies->req_missing_for([qw( test_rdbms_mysql test_rdbms_pg )]),
165     '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',
166     'optional dependencies for testing Postgres+MySQL without envvars'
167   );
168
169   $ENV{DBICTEST_PG_DSN} = 'boo';
170   is_deeply (
171     DBIx::Class::Optional::Dependencies->modreq_list_for([qw( rdbms_pg test_rdbms_pg )]),
172     { 'DBD::Pg' => '2.009002' },
173     'optional module dependencies list for testing Postgres matches with envvar',
174   );
175
176   is(
177     DBIx::Class::Optional::Dependencies->req_missing_for([qw( rdbms_pg test_rdbms_pg )]),
178     '"DBD::Pg~>=2.009002"',
179     'optional dependencies error text for testing Postgres matches with evvar',
180   );
181
182 }
183
184 # test multiple times to find autovivification bugs
185 for my $meth (qw(req_list_for modreq_list_for)) {
186   throws_ok {
187     DBIx::Class::Optional::Dependencies->$meth();
188   } qr/\Qreq_list_for() expects a requirement group name/,
189   "$meth without groupname throws exception";
190
191   throws_ok {
192     DBIx::Class::Optional::Dependencies->$meth('');
193   } qr/\Q$meth() expects a requirement group name/,
194   "$meth with empty groupname throws exception";
195
196   throws_ok {
197     DBIx::Class::Optional::Dependencies->$meth('invalid_groupname');
198   } qr/Requirement group 'invalid_groupname' is not defined/,
199   "$meth with invalid groupname throws exception";
200 }
201
202 done_testing;