This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
14d93e25dd4b66785f16d7b108c86df635cf070c
[perl5.git] / t / op / require_errors.t
1 #!perl
2
3 BEGIN {
4     chdir 't' if -d 't';
5     require './test.pl';
6     set_up_inc( qw(../lib) );
7 }
8
9 use strict;
10 use warnings;
11
12 plan(tests => 28);
13
14 my $nonfile = tempfile();
15
16 # The tests for ' ' and '.h' never did fail, but previously the error reporting
17 # code would read memory before the start of the SV's buffer
18
19 for my $file ($nonfile, ' ') {
20     eval {
21         require $file;
22     };
23
24     like $@, qr/^Can't locate $file in \@INC \(\@INC contains: @INC\) at/,
25         "correct error message for require '$file'";
26 }
27
28 eval "require $nonfile";
29
30 like $@, qr/^Can't locate $nonfile\.pm in \@INC \(you may need to install the $nonfile module\) \(\@INC contains: @INC\) at/,
31         "correct error message for require $nonfile";
32
33 eval "require ::$nonfile";
34
35 like $@, qr/^Bareword in require must not start with a double-colon:/,
36         "correct error message for require ::$nonfile";
37
38 eval {
39     require "$nonfile.ph";
40 };
41
42 like $@, qr/^Can't locate $nonfile\.ph in \@INC \(did you run h2ph\?\) \(\@INC contains: @INC\) at/;
43
44 for my $file ("$nonfile.h", ".h") {
45     eval {
46         require $file
47     };
48
49     like $@, qr/^Can't locate \Q$file\E in \@INC \(change \.h to \.ph maybe\?\) \(did you run h2ph\?\) \(\@INC contains: @INC\) at/,
50         "correct error message for require '$file'";
51 }
52
53 for my $file ("$nonfile.ph", ".ph") {
54     eval {
55         require $file
56     };
57
58     like $@, qr/^Can't locate \Q$file\E in \@INC \(did you run h2ph\?\) \(\@INC contains: @INC\) at/,
59         "correct error message for require '$file'";
60 }
61
62 eval 'require <foom>';
63 like $@, qr/^<> at require-statement should be quotes at /, 'require <> error';
64
65 my $module   = tempfile();
66 my $mod_file = "$module.pm";
67
68 open my $module_fh, ">", $mod_file or die $!;
69 print { $module_fh } "print 1; 1;\n";
70 close $module_fh;
71
72 chmod 0333, $mod_file;
73
74 SKIP: {
75     skip_if_miniperl("these modules may not be available to miniperl", 2);
76
77     push @INC, '../lib';
78     require Cwd;
79     require File::Spec::Functions;
80     if ($^O eq 'cygwin') {
81         require Win32;
82     }
83
84     # Going to try to switch away from root.  Might not work.
85     # (stolen from t/op/stat.t)
86     my $olduid = $>;
87     eval { $> = 1; };
88     skip "Can't test permissions meaningfully if you're superuser", 2
89         if ($^O eq 'cygwin' ? Win32::IsAdminUser() : $> == 0);
90
91     local @INC = ".";
92     eval "use $module";
93     like $@,
94         qr<^\QCan't locate $mod_file:>,
95         "special error message if the file exists but can't be opened";
96
97     SKIP: {
98         skip "Can't make the path absolute", 1
99             if !defined(Cwd::getcwd());
100
101         my $file = File::Spec::Functions::catfile(Cwd::getcwd(), $mod_file);
102         eval {
103             require($file);
104         };
105         like $@,
106             qr<^\QCan't locate $file:>,
107             "...even if we use a full path";
108     }
109
110     # switch uid back (may not be implemented)
111     eval { $> = $olduid; };
112 }
113
114 1 while unlink $mod_file;
115
116 # I can't see how to test the EMFILE case
117 # I can't see how to test the case of not displaying @INC in the message.
118 # (and does that only happen on VMS?)
119
120 # fail and print the full filename
121 eval { no warnings 'syscalls'; require "strict.pm\0invalid"; };
122 like $@, qr/^Can't locate strict\.pm\\0invalid: /, 'require nul check [perl #117265]';
123 {
124   my $WARN;
125   local $SIG{__WARN__} = sub { $WARN = shift };
126   {
127     my $ret = do "strict.pm\0invalid";
128     my $exc = $@;
129     my $err = $!;
130     is $ret, undef, 'do nulstring returns undef';
131     is $exc, '',    'do nulstring clears $@';
132     $! = $err;
133     ok $!{ENOENT},  'do nulstring fails with ENOENT';
134     like $WARN, qr{^Invalid \\0 character in pathname for do: strict\.pm\\0invalid at }, 'do nulstring warning';
135   }
136
137   $WARN = '';
138   eval { require "strict.pm\0invalid"; };
139   like $WARN, qr{^Invalid \\0 character in pathname for require: strict\.pm\\0invalid at }, 'nul warning';
140   like $@, qr{^Can't locate strict\.pm\\0invalid: }, 'nul error';
141
142   $WARN = '';
143   local @INC = @INC;
144   set_up_inc( "lib\0invalid" );
145   eval { require "unknown.pm" };
146   like $WARN, qr{^Invalid \\0 character in \@INC entry for require: lib\\0invalid at }, 'nul warning';
147 }
148 eval "require strict\0::invalid;";
149 like $@, qr/^syntax error at \(eval \d+\) line 1/, 'parse error with \0 in barewords module names';
150
151 # Refs and globs that stringify with embedded nulls
152 # These crashed from 5.20 to 5.24 [perl #128182].
153 eval { no warnings 'syscalls'; require eval "qr/\0/" };
154 like $@, qr/^Can't locate \(\?\^:\\0\):/,
155     'require ref that stringifies with embedded null';
156 eval { no strict; no warnings 'syscalls'; require *{"\0a"} };
157 like $@, qr/^Can't locate \*main::\\0a:/,
158     'require ref that stringifies with embedded null';
159
160 eval { require undef };
161 like $@, qr/^Missing or undefined argument to require /;
162
163 eval { do undef };
164 like $@, qr/^Missing or undefined argument to do /;
165
166 eval { require "" };
167 like $@, qr/^Missing or undefined argument to require /;
168
169 eval { do "" };
170 like $@, qr/^Missing or undefined argument to do /;
171
172 # non-searchable pathnames shouldn't mention @INC in the error
173
174 my $nonsearch = "./no_such_file.pm";
175
176 eval "require \"$nonsearch\"";
177
178 like $@, qr/^Can't locate \Q$nonsearch\E at/,
179         "correct error message for require $nonsearch";