Add extra tests and changes for config_from file.
[gitmo/MooseX-Getopt.git] / t / 008_configfromfile.t
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 use Test::Exception;
7 use Test::More;
8 use File::Spec;
9
10 if ( !eval { require MooseX::ConfigFromFile } )
11 {
12     plan skip_all => 'Test requires MooseX::ConfigFromFile';
13 }
14
15 {
16     package App;
17
18     use Moose;
19     with 'MooseX::Getopt';
20     with 'MooseX::ConfigFromFile';
21
22     has 'config_from_override' => (
23         is       => 'ro',
24         isa      => 'Bool',
25         default  => 0,
26     );
27
28     has 'optional_from_config' => (
29         is        => 'ro',
30         isa       => 'Str',
31         required  => 0,
32     );
33
34     has 'required_from_config' => (
35         is        => 'ro',
36         isa       => 'Str',
37         required  => 1,
38     );
39
40     has 'required_from_argv' => (
41         is        => 'ro',
42         isa       => 'Str',
43         required  => 1,
44     );
45
46     sub get_config_from_file
47     {
48         my ( $class, $file ) = @_;
49
50         my %config = (
51             required_from_config => 'from_config_1',
52             optional_from_config => 'from_config_2',
53         );
54
55         my $cpath = File::Spec->canonpath('/notused/default');
56         if ( $file ne $cpath ) {
57             $config{config_from_override} = 1;
58         }
59
60         return \%config;
61     }
62 }
63
64 {
65     package App::DefaultConfigFile;
66
67     use Moose;
68     extends 'App';
69
70     has '+configfile' => (
71         default => File::Spec->canonpath('/notused/default'),
72     );
73 }
74
75 {
76     package App::DefaultConfigFileCodeRef;
77
78     use Moose;
79     extends 'App';
80
81     has '+configfile' => (
82         default => sub { return File::Spec->canonpath('/notused/default') },
83     );
84 }
85
86 {
87     package App::ConfigFileFromProjectOption;
88
89     use Moose;
90     extends 'App';
91
92     has 'project' => (
93         is        => 'rw',
94         isa       => 'Str',
95         required  => 1,
96     );
97     has '+configfile' => ();
98
99     around _get_configfile_from_cli => sub {
100         my ($orig, $self) = @_;
101         my $project;
102         my $opt_parser = Getopt::Long::Parser->new( config => [ qw( pass_through ) ] );
103         $opt_parser->getoptions( "project=s" => \$project );
104         return "/notused/specific/$project/config";
105     };
106 }
107
108 # No config specified
109 {
110     local @ARGV = qw( --required_from_argv 1 );
111
112     throws_ok { App->new_with_options } qr/(Required option missing: required_from_config|Attribute \(required_from_config\) is required)/;
113
114     {
115         my $app = App::DefaultConfigFile->new_with_options;
116         isa_ok( $app, 'App::DefaultConfigFile' );
117         app_ok( $app );
118
119         ok(  !$app->config_from_override,
120             '... config_from_override false as expected' );
121
122         is( $app->configfile, File::Spec->canonpath('/notused/default'),
123             '... configfile is /notused/default as expected' );
124     }
125 }
126
127 # No config specified
128 {
129     local @ARGV = qw( --required_from_argv 1 );
130
131     {
132         my $app = App::DefaultConfigFileCodeRef->new_with_options;
133         isa_ok( $app, 'App::DefaultConfigFileCodeRef' );
134         app_ok( $app );
135
136         ok(  !$app->config_from_override,
137             '... config_from_override false as expected' );
138
139         is( $app->configfile, File::Spec->canonpath('/notused/default'),
140             '... configfile is /notused/default as expected' );
141     }
142 }
143
144 # Config specified
145 {
146     local @ARGV = qw( --configfile /notused --required_from_argv 1 );
147
148     {
149         my $app = App->new_with_options;
150         isa_ok( $app, 'App' );
151         app_ok( $app );
152     }
153
154     {
155         my $app = App::DefaultConfigFile->new_with_options;
156         isa_ok( $app, 'App::DefaultConfigFile' );
157         app_ok( $app );
158
159         ok( $app->config_from_override,
160              '... config_from_override true as expected' );
161
162         is( $app->configfile, File::Spec->canonpath('/notused'),
163             '... configfile is /notused as expected' );
164     }
165     {
166         my $app = App::DefaultConfigFileCodeRef->new_with_options;
167         isa_ok( $app, 'App::DefaultConfigFileCodeRef' );
168         app_ok( $app );
169
170         ok( $app->config_from_override,
171              '... config_from_override true as expected' );
172
173         is( $app->configfile, File::Spec->canonpath('/notused'),
174             '... configfile is /notused as expected' );
175     }
176 }
177
178 # No config specified
179 {
180     local @ARGV = qw( --required_from_argv 1 --project quux );
181
182     {
183         my $app = App::ConfigFileFromProjectOption->new_with_options;
184         isa_ok( $app, 'App::ConfigFileFromProjectOption' );
185         app_ok( $app );
186
187         ok( $app->config_from_override,
188             '... config_from_override true as expected' );
189
190         is( $app->project, 'quux',
191             '... project is quux as expected' );
192
193         is( $app->configfile, File::Spec->canonpath('/notused/specific/quux/config'),
194             '... configfile is /notused/specific/quux/config as expected' );
195     }
196 }
197
198 # Config specified
199 {
200     local @ARGV = qw( --configfile /notused --required_from_argv 1 --project quux );
201
202     {
203         my $app = App::ConfigFileFromProjectOption->new_with_options;
204         isa_ok( $app, 'App::ConfigFileFromProjectOption' );
205         app_ok( $app );
206
207         ok( $app->config_from_override,
208              '... config_from_override true as expected' );
209
210         is( $app->project, 'quux',
211             '... project is quux as expected' );
212
213         is( $app->configfile, File::Spec->canonpath('/notused'),
214             '... configfile is /notused as expected' );
215     }
216 }
217
218 # Required arg not supplied from cmdline
219 {
220     local @ARGV = qw( --configfile /notused );
221     throws_ok { App->new_with_options } qr/(Required option missing: required_from_argv|Attribute \(required_from_argv\) is required)/;
222 }
223
224 # Config file value overriden from cmdline
225 {
226     local @ARGV = qw( --configfile /notused --required_from_argv 1 --required_from_config override );
227
228     my $app = App->new_with_options;
229     isa_ok( $app, 'App' );
230
231     is( $app->required_from_config, 'override',
232         '... required_from_config is override as expected' );
233
234     is( $app->optional_from_config, 'from_config_2',
235         '... optional_from_config is from_config_2 as expected' );
236 }
237
238 # No config file
239 {
240     local @ARGV = qw( --required_from_argv 1 --required_from_config noconfig );
241
242     my $app = App->new_with_options;
243     isa_ok( $app, 'App' );
244
245     is( $app->required_from_config, 'noconfig',
246         '... required_from_config is noconfig as expected' );
247
248     ok( !defined $app->optional_from_config,
249         '... optional_from_config is undef as expected' );
250 }
251
252 {
253     package BaseApp::WithConfig;
254     use Moose;
255     with 'MooseX::ConfigFromFile';
256
257     sub get_config_from_file { return {}; }
258 }
259
260 {
261     package DerivedApp::Getopt;
262     use Moose;
263     extends 'BaseApp::WithConfig';
264     with 'MooseX::Getopt';
265 }
266
267 # With DerivedApp, the Getopt role was applied at a different level
268 # than the ConfigFromFile role
269 {
270     lives_ok { DerivedApp::Getopt->new_with_options } 'Can create DerivedApp';
271 }
272
273 sub app_ok {
274     my $app = shift;
275
276     is( $app->required_from_config, 'from_config_1',
277         '... required_from_config is from_config_1 as expected' );
278
279     is( $app->optional_from_config, 'from_config_2',
280         '... optional_from_config is from_config_2 as expected' );
281
282     is( $app->required_from_argv, '1',
283         '... required_from_argv is 1 as expected' );
284 }
285
286 done_testing;
287