be more strict about what shells to test
[p5sagit/local-lib.git] / t / shell.t
1 use strict;
2 use warnings;
3 use Test::More;
4 use File::Spec;
5 use File::Basename qw(dirname);
6 use File::Temp ();
7 use Config;
8 use local::lib ();
9
10 my @paths = File::Spec->path;
11 sub which {
12   my $shell = shift;
13   my ($full) =
14     grep { -x }
15     map { File::Spec->catfile( $_, $shell) }
16     File::Spec->path;
17   return $full;
18 }
19
20 my $extra_lib = '-I"' . dirname(dirname($INC{'local/lib.pm'})) . '"';
21
22 my @shells;
23 for my $shell (
24   {
25     name => 'sh',
26   },
27   {
28     name => 'csh',
29     opt => '-f',
30   },
31   {
32     name => 'cmd.exe',
33     opt => '/Q /D /C',
34     ext => 'bat',
35     perl => qq{@"$^X"},
36     skip => $^O eq 'cygwin',
37   },
38   {
39     name => 'powershell.exe',
40     opt => '-NoProfile -ExecutionPolicy Unrestricted -File',
41     ext => 'ps1',
42     perl => qq{& '$^X'},
43     skip => $^O eq 'cygwin',
44   },
45 ) {
46   my $name = $shell->{name};
47   $shell->{shell} = which($name);
48   $shell->{ext}   ||= $name;
49   $shell->{perl}  ||= qq{"$^X"};
50   if (@ARGV) {
51     next
52       if !grep {$_ eq $name} @ARGV;
53     if (!$shell->{shell}) {
54       warn "unable to find executable for $name";
55       next;
56     }
57   }
58   elsif ($shell->{skip} || !$shell->{shell}) {
59     next;
60   }
61   push @shells, $shell;
62 }
63
64 if (!@shells) {
65   plan skip_all => 'no supported shells found';
66 }
67 plan tests => 6*@shells;
68
69 my $sep = $Config{path_sep};
70
71 my $root = File::Spec->rootdir;
72 for my $shell (@shells) {
73   my $ll = File::Temp->newdir();
74   my $ll_dir = local::lib->normalize_path("$ll");
75   local $ENV{PERL_LOCAL_LIB_ROOT};
76   delete $ENV{PERL_LOCAL_LIB_ROOT};
77   local $ENV{PATH} = $root;
78   local $ENV{PERL5LIB};
79   delete $ENV{PERL5LIB};
80   my $env = call_ll($shell, "$ll");
81   is $env->{PERL_LOCAL_LIB_ROOT}, $ll_dir,
82     "$shell->{name}: activate root";
83   is $env->{PATH}, local::lib->install_base_bin_path($ll_dir)."$sep$root",
84     "$shell->{name}: activate PATH";
85   is $env->{PERL5LIB}, local::lib->install_base_perl_path($ll_dir),
86     "$shell->{name}: activate PERL5LIB";
87
88   $ENV{$_} = $env->{$_} for qw(PATH PERL5LIB PERL_LOCAL_LIB_ROOT);
89   $env = call_ll($shell, '--deactivate', "$ll");
90
91   is $env->{PERL_LOCAL_LIB_ROOT}, undef,
92     "$shell->{name}: deactivate root";
93   is $env->{PATH}, $root,
94     "$shell->{name}: deactivate PATH";
95   is $env->{PERL5LIB}, undef,
96     "$shell->{name}: deactivate PERL5LIB";
97 }
98
99 sub call_ll {
100   my ($info, @options) = @_;
101   my $option = @options ? '='.join(',', @options) : '';
102
103   local $ENV{SHELL} = $info->{shell};
104
105   my $script
106     = `"$^X" $extra_lib -Mlocal::lib$option` . "\n"
107     . qq{$info->{perl} -Mt::lib::ENVDumper -e1\n};
108
109   my $file = File::Temp->new(
110     TEMPLATE => 'll-test-script-XXXXX',
111     TMPDIR   => 1,
112     SUFFIX   => '.'.$info->{ext},
113   );
114   print { $file } $script;
115   close $file;
116
117   my $opt = $info->{opt} ? "$info->{opt} " : '';
118   my $cmd = qq{"$info->{shell}" $opt"$file"};
119   my $out = `$cmd`;
120   if ($?) {
121     diag "script:\n$script";
122     diag "running:\n$cmd";
123     die "failed with code: $?";
124   }
125   my $VAR1;
126   eval $out or die "bad output: $@";
127   $VAR1;
128 }