test for shell output
[p5sagit/local-lib.git] / t / shell.t
1 use strict;
2 use warnings;
3 use Test::More;
4 use File::Spec;
5 use File::Temp ();
6 use Config;
7 use local::lib ();
8
9 my @paths = File::Spec->path;
10 my @ext = $^O eq 'MSWin32'  ? (split /\Q$Config{path_sep}/, $ENV{PATHEXT}) : ('');
11 sub which {
12   my $shell = shift;
13   for my $dir (@paths) {
14     my $file = File::Spec->catfile($dir||'.', $shell);
15     for my $ext (@ext) {
16       my $full = $file . $ext;
17       return $full
18         if -x $full;
19     }
20   }
21   return;
22 }
23
24 my @extra_lib = do {
25   my @paths = `$^X -le"print for \@INC"`;
26   chomp @paths;
27   my %paths;
28   @paths{@paths} = ();
29   grep { !exists $paths{$_} } @INC;
30 };
31
32 my $extra_lib = join ' ', map { qq{"-I$_"} } @extra_lib;
33
34 my @shells;
35 for my $shell (
36   {
37     name => 'sh',
38   },
39   {
40     name => 'csh',
41   },
42   {
43     name => 'cmd',
44     opt => '/c',
45     ext => 'bat',
46     perl => qq{@"$^X"},
47   },
48   {
49     name => 'powershell',
50     opt => '-ExecutionPolicy Unrestricted',
51     ext => 'ps1',
52     perl => qq{& '$^X'},
53   },
54 ) {
55   my $name = $shell->{name};
56   next
57     if @ARGV && !grep {$_ eq $name} @ARGV;
58   $shell->{shell} = which($name) || next;
59   $shell->{ext}   ||= $name;
60   $shell->{perl}  ||= qq{"$^X"};
61   push @shells, $shell;
62 }
63
64 if (!@shells) {
65   plan skip_all => 'no supported shells found';
66 }
67 plan tests => 4*@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   local $ENV{PATH} = $root;
77   local $ENV{PERL5LIB} = $ENV{PERL5LIB};
78   delete $ENV{PERL_LOCAL_LIB_ROOT};
79   my $env = call_ll($shell, "$ll");
80   is $env->{PERL_LOCAL_LIB_ROOT}, $ll_dir, "$shell->{name}: activate root";
81   is $env->{PATH}, local::lib->install_base_bin_path($ll_dir)."$sep$root", "$shell->{name}: activate PATH";
82
83   $ENV{$_} = $env->{$_} for qw(PATH PERL5LIB PERL_LOCAL_LIB_ROOT);
84   $env = call_ll($shell, '--deactivate', "$ll");
85
86   is $env->{PERL_LOCAL_LIB_ROOT}, undef, "$shell->{name}: deactivate root";
87   is $env->{PATH}, $root, "$shell->{name}: deactivate PATH";
88 }
89
90 sub call_ll {
91   my ($info, @options) = @_;
92   my $option = @options ? '='.join(',', @options) : '';
93
94   local $ENV{SHELL} = $info->{shell};
95
96   my $file = File::Temp->new('ll-test-script-XXXXX',
97     TMPDIR => 1,
98     SUFFIX => '.'.$info->{ext},
99   );
100
101   $file->print(scalar `"$^X" $extra_lib -Mlocal::lib$option` . "\n");
102   $file->print(qq{$info->{perl} -Mt::lib::ENVDumper -e1\n});
103   $file->close;
104
105   my $opt = $info->{opt} ? "$info->{opt} " : '';
106   my $out = `"$info->{shell}" $opt"$file"`;
107   if ($?) {
108     die "failed with code: $?";
109   }
110   my $VAR1;
111   eval $out or die "bad output: $@";
112   $VAR1;
113 }