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