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