make all warnings fatal in tests
[gitmo/MooseX-Getopt.git] / t / 008_configfromfile.t
1 use strict;
2 use warnings FATAL => 'all';
3
4 use Test::Requires 'MooseX::ConfigFromFile';    # skip all if not installed
5 use Test::More tests => 56;
6 use Test::Fatal;
7 use Test::Deep '!blessed';
8 use Path::Tiny;
9 use Scalar::Util 'blessed';
10 use Test::NoWarnings 1.04 ':early';
11
12 my %constructor_args;
13 {
14     package App;
15
16     use Moose;
17     with 'MooseX::Getopt';
18     with 'MooseX::ConfigFromFile';
19
20     has 'config_from_override' => (
21         is       => 'ro',
22         isa      => 'Bool',
23         default  => 0,
24     );
25
26     has 'optional_from_config' => (
27         is        => 'ro',
28         isa       => 'Str',
29         required  => 0,
30     );
31
32     has 'required_from_config' => (
33         is        => 'ro',
34         isa       => 'Str',
35         required  => 1,
36     );
37
38     has 'required_from_argv' => (
39         is        => 'ro',
40         isa       => 'Str',
41         required  => 1,
42     );
43
44     sub get_config_from_file
45     {
46         my ( $class, $file ) = @_;
47
48         my %config = (
49             required_from_config => 'from_config_1',
50             optional_from_config => 'from_config_2',
51         );
52
53         if ( $file ne Path::Tiny::path('/notused/default') ) {
54             $config{config_from_override} = 1;
55         }
56
57         return \%config;
58     }
59
60     around BUILDARGS => sub
61     {
62         my ($orig, $class) = (shift, shift);
63         my $args = $class->$orig(@_);
64         $constructor_args{$class} = $args;
65     };
66 }
67
68 {
69     package App::DefaultConfigFile;
70
71     use Moose;
72     extends 'App';
73
74     has '+configfile' => (
75         default => Path::Tiny::path('/notused/default')->stringify,
76     );
77 }
78
79 {
80     package App::DefaultConfigFileCodeRef;
81
82     use Moose;
83     extends 'App';
84
85     has '+configfile' => (
86         default => sub { return Path::Tiny::path('/notused/default')->stringify },
87     );
88 }
89
90 {
91     package App::ConfigFileWrapped;
92
93     use Moose;
94     extends 'App';
95
96     sub _get_default_configfile { '/notused/default' }
97 }
98
99
100 # No config specified
101 {
102     local @ARGV = qw( --required_from_argv 1 );
103
104     like exception { App->new_with_options },
105         ($Getopt::Long::Descriptive::VERSION >= 0.091
106             ? qr/Mandatory parameter 'required_from_config' missing/
107             : qr/Required option missing: required_from_config/);
108
109     {
110         my $app = App::DefaultConfigFile->new_with_options;
111         isa_ok( $app, 'App::DefaultConfigFile' );
112         app_ok( $app );
113
114         ok(  !$app->config_from_override,
115             '... config_from_override false as expected' );
116
117         is( $app->configfile, path('/notused/default'),
118             '... configfile is /notused/default as expected' );
119
120         cmp_deeply(
121             $constructor_args{blessed($app)},
122             superhashof({
123                 configfile => str(path('/notused/default')),
124             }),
125             'correct constructor args passed',
126         );
127     }
128
129     {
130         my $app = App::DefaultConfigFileCodeRef->new_with_options;
131         isa_ok( $app, 'App::DefaultConfigFileCodeRef' );
132         app_ok( $app );
133
134         ok(  !$app->config_from_override,
135             '... config_from_override false as expected' );
136
137         is( $app->configfile, path('/notused/default'),
138             '... configfile is /notused/default as expected' );
139
140         cmp_deeply(
141             $constructor_args{blessed $app},
142             superhashof({
143                 configfile => str(path('/notused/default')),
144             }),
145             'correct constructor args passed',
146         );
147     }
148
149     SKIP: {
150         eval "use MooseX::ConfigFromFile 0.08 (); 1;";
151         diag("MooseX::ConfigFromFile 0.08 needed to test this use of configfile defaults"),
152         skip "MooseX::ConfigFromFile 0.08 needed to test this use of configfile defaults", 7 if $@;
153
154         my $app = App::ConfigFileWrapped->new_with_options;
155         isa_ok( $app, 'App::ConfigFileWrapped' );
156         app_ok( $app );
157
158         ok(  !$app->config_from_override,
159             '... config_from_override false as expected' );
160
161         is( $app->configfile, path('/notused/default'),
162             '... configfile is /notused/default as expected' );
163
164         cmp_deeply(
165             $constructor_args{blessed $app},
166             superhashof({
167                 configfile => str(path('/notused/default')),
168             }),
169             'correct constructor args passed',
170         );
171     }
172 }
173
174 # Config specified
175 {
176     local @ARGV = qw( --configfile /notused/override --required_from_argv 1 );
177
178     {
179         my $app = App->new_with_options;
180         isa_ok( $app, 'App' );
181         app_ok( $app );
182     }
183
184     {
185         my $app = App::DefaultConfigFile->new_with_options;
186         isa_ok( $app, 'App::DefaultConfigFile' );
187         app_ok( $app );
188
189         ok( $app->config_from_override,
190              '... config_from_override true as expected' );
191
192         is( $app->configfile, path('/notused/override'),
193             '... configfile is /notused/override as expected' );
194
195         cmp_deeply(
196             $constructor_args{blessed $app},
197             superhashof({
198                 configfile => str(path('/notused/override')),
199             }),
200             'correct constructor args passed',
201         );
202     }
203     {
204         my $app = App::DefaultConfigFileCodeRef->new_with_options;
205         isa_ok( $app, 'App::DefaultConfigFileCodeRef' );
206         app_ok( $app );
207
208         ok( $app->config_from_override,
209              '... config_from_override true as expected' );
210
211         is( $app->configfile, path('/notused/override'),
212             '... configfile is /notused/override as expected' );
213
214         cmp_deeply(
215             $constructor_args{blessed $app},
216             superhashof({
217                 configfile => str(path('/notused/override')),
218             }),
219             'correct constructor args passed',
220         );
221     }
222     {
223         my $app = App::ConfigFileWrapped->new_with_options;
224         isa_ok( $app, 'App::ConfigFileWrapped' );
225         app_ok( $app );
226
227         ok( $app->config_from_override,
228              '... config_from_override true as expected' );
229
230         is( $app->configfile, path('/notused/override'),
231             '... configfile is /notused as expected' );
232
233         cmp_deeply(
234             $constructor_args{blessed $app},
235             superhashof({
236                 configfile => str(path('/notused/override')),
237             }),
238             'correct constructor args passed',
239         );
240     }
241 }
242
243 # Required arg not supplied from cmdline
244 {
245     local @ARGV = qw( --configfile /notused/override );
246     like exception { App->new_with_options },
247         ($Getopt::Long::Descriptive::VERSION >= 0.091
248             ? qr/Mandatory parameter 'required_from_argv' missing/
249             : qr/Required option missing: required_from_argv/);
250 }
251
252 # Config file value overriden from cmdline
253 {
254     local @ARGV = qw( --configfile /notused/override --required_from_argv 1 --required_from_config override );
255
256     my $app = App->new_with_options;
257     isa_ok( $app, 'App' );
258
259     is( $app->required_from_config, 'override',
260         '... required_from_config is override as expected' );
261
262     is( $app->optional_from_config, 'from_config_2',
263         '... optional_from_config is from_config_2 as expected' );
264 }
265
266 # No config file
267 {
268     local @ARGV = qw( --required_from_argv 1 --required_from_config noconfig );
269
270     my $app = App->new_with_options;
271     isa_ok( $app, 'App' );
272
273     is( $app->required_from_config, 'noconfig',
274         '... required_from_config is noconfig as expected' );
275
276     ok( !defined $app->optional_from_config,
277         '... optional_from_config is undef as expected' );
278 }
279
280 {
281     package BaseApp::WithConfig;
282     use Moose;
283     with 'MooseX::ConfigFromFile';
284
285     sub get_config_from_file { return {}; }
286 }
287
288 {
289     package DerivedApp::Getopt;
290     use Moose;
291     extends 'BaseApp::WithConfig';
292     with 'MooseX::Getopt';
293 }
294
295 # With DerivedApp, the Getopt role was applied at a different level
296 # than the ConfigFromFile role
297 {
298     ok ! exception { DerivedApp::Getopt->new_with_options }, 'Can create DerivedApp';
299 }
300
301 sub app_ok {
302     my $app = shift;
303
304     is( $app->required_from_config, 'from_config_1',
305         '... required_from_config is from_config_1 as expected' );
306
307     is( $app->optional_from_config, 'from_config_2',
308         '... optional_from_config is from_config_2 as expected' );
309
310     is( $app->required_from_argv, '1',
311         '... required_from_argv is 1 as expected' );
312 }