This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
8746e0a5942865c5a58377f4b8db5d5ecc25bed3
[perl5.git] / cpan / ExtUtils-MakeMaker / t / Liblist_Kid.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use lib 't/lib';
7
8 # Liblist wants to be an object which has File::Spec capabilities, so we
9 # mock one.
10
11 BEGIN {
12     package MockEUMM;
13     use base 'File::Spec';    # what.
14     sub new { return bless {}, 'MockEUMM'; }
15 }
16
17 package liblist_kid_test;
18
19 use Test::More 'no_plan';
20 use ExtUtils::MakeMaker::Config;
21 use File::Spec;
22
23 run();
24
25 exit;
26
27 sub run {
28     use_ok( 'ExtUtils::Liblist::Kid' );
29
30     move_to_os_test_data_dir();
31     alias_kid_ext_for_convenience();
32
33     conf_reset();
34
35     return test_kid_win32() if $^O eq 'MSWin32';
36     return;
37 }
38
39 # This allows us to get a clean playing field and ensure that the current
40 # system configuration does not affect the test results.
41
42 sub conf_reset {
43     delete $Config{$_} for keys %Config;
44     delete $ENV{LIB};
45     delete $ENV{LIBRARY_PATH};
46
47     return;
48 }
49
50 # This keeps the directory paths in the tests short and allows easy
51 # separation of OS-specific files.
52
53 sub move_to_os_test_data_dir {
54     my %os_test_dirs = ( MSWin32 => 't/liblist/win32', );
55     return if !$os_test_dirs{$^O};
56
57     chdir $os_test_dirs{$^O} or die "Could not change to liblist test dir '$os_test_dirs{$^O}': $!";
58     return;
59 }
60
61 # With this we can use a short function name in the tests and use the same
62 # one everywhere.
63
64 sub alias_kid_ext_for_convenience {
65     my %os_ext_funcs = ( MSWin32 => \&ExtUtils::Liblist::Kid::_win32_ext, );
66     *_kid_ext = $os_ext_funcs{$^O} if $os_ext_funcs{$^O};
67
68     return;
69 }
70 sub _kid_ext;
71
72 # Since liblist is object-based, we need to provide a mock object.
73
74 sub _ext { _kid_ext( MockEUMM->new, @_ ); }
75
76 # tests go here
77
78 sub test_kid_win32 {
79
80     $Config{installarchlib} = 'lib';
81
82     is_deeply( [ _ext() ],                           [ '',                    '', '',                    '' ], 'empty input results in empty output' );
83     is_deeply( [ _ext( 'unreal_test' ) ],            [ '',                    '', '',                    '' ], 'non-existent file results in empty output' );
84     is_deeply( [ _ext( 'test' ) ],                   [ 'test.lib',            '', 'test.lib',            '' ], 'existent file results in a path to the file. .lib is default extension with empty %Config' );
85     is_deeply( [ _ext( 'c_test' ) ],                 [ 'lib\CORE\c_test.lib', '', 'lib\CORE\c_test.lib', '' ], '$Config{installarchlib}/CORE is the default search dir aside from cwd' );
86     is_deeply( [ _ext( 'double' ) ],                 [ 'double.lib',          '', 'double.lib',          '' ], 'once an instance of a lib is found, the search stops' );
87     is_deeply( [ _ext( 'test.lib' ) ],               [ 'test.lib',            '', 'test.lib',            '' ], 'the extension is not tacked on twice' );
88     is_deeply( [ _ext( 'test.a' ) ],                 [ 'test.a.lib',          '', 'test.a.lib',          '' ], 'but it will be tacked onto filenamess with other kinds of library extension' );
89     is_deeply( [ _ext( 'test test2' ) ],             [ 'test.lib test2.lib',  '', 'test.lib test2.lib',  '' ], 'multiple existing files end up separated by spaces' );
90     is_deeply( [ _ext( 'test test2 unreal_test' ) ], [ 'test.lib test2.lib',  '', 'test.lib test2.lib',  '' ], "some existing files don't cause false positives" );
91     is_deeply( [ _ext( '-l_test' ) ],                [ 'lib_test.lib',        '', 'lib_test.lib',        '' ], 'prefixing a lib with -l triggers a second search with prefix "lib" when gcc is not in use' );
92     is_deeply( [ _ext( '-l__test' ) ],               [ '__test.lib',          '', '__test.lib',          '' ], 'unprefixed lib files are found first when -l is used' );
93     is_deeply( [ _ext( '-llibtest' ) ],              [ '',                    '', '',                    '' ], 'if -l is used and the lib name is already prefixed no second search without the prefix is done' );
94     is_deeply( [ _ext( '-lunreal_test' ) ],          [ '',                    '', '',                    '' ], 'searching with -l for a non-existent library does not cause an endless loop' );
95     is_deeply( [ _ext( '"space lib"' ) ],            [ '"space lib.lib"',     '', '"space lib.lib"',     '' ], 'lib with spaces in the name can be found with the help of quotes' );
96     is_deeply( [ _ext( '"""space lib"""' ) ],        [ '"space lib.lib"',     '', '"space lib.lib"',     '' ], 'Text::Parsewords deals with extraneous quotes' );
97
98     is_deeply( [ scalar _ext( 'test' ) ], ['test.lib'], 'asking for a scalar gives a single string' );
99
100     is_deeply( [ _ext( undef,             0, 1 ) ], [ '',                                        '', '',                                        '', [] ],                      'asking for real names with empty input results in an empty extra array' );
101     is_deeply( [ _ext( 'unreal_test',     0, 1 ) ], [ '',                                        '', '',                                        '', [] ],                      'asking for real names with non-existent file results in an empty extra array' );
102     is_deeply( [ _ext( 'c_test',          0, 1 ) ], [ 'lib\CORE\c_test.lib',                     '', 'lib\CORE\c_test.lib',                     '', ['lib/CORE\c_test.lib'] ], 'asking for real names with an existent file in search dir results in an extra array with a mixed-os file path?!' );
103     is_deeply( [ _ext( 'test c_test',     0, 1 ) ], [ 'test.lib lib\CORE\c_test.lib',            '', 'test.lib lib\CORE\c_test.lib',            '', ['lib/CORE\c_test.lib'] ], 'files in cwd do not appear in the real name list?!' );
104     is_deeply( [ _ext( '-lc_test c_test', 0, 1 ) ], [ 'lib\CORE\c_test.lib lib\CORE\c_test.lib', '', 'lib\CORE\c_test.lib lib\CORE\c_test.lib', '', ['lib/CORE\c_test.lib'] ], 'finding the same lib in a search dir both with and without -l results in a single listing in the array' );
105
106     is_deeply( [ _ext( 'test :nosearch unreal_test test2' ) ],         [ 'test.lib unreal_test test2',     '', 'test.lib unreal_test test2',     '' ], ':nosearch can force passing through of filenames as they are' );
107     is_deeply( [ _ext( 'test :nosearch -lunreal_test test2' ) ],       [ 'test.lib unreal_test.lib test2', '', 'test.lib unreal_test.lib test2', '' ], 'lib names with -l after a :nosearch are suffixed with .lib and the -l is removed' );
108     is_deeply( [ _ext( 'test :nosearch unreal_test :search test2' ) ], [ 'test.lib unreal_test test2.lib', '', 'test.lib unreal_test test2.lib', '' ], ':search enables file searching again' );
109     is_deeply( [ _ext( 'test :meep test2' ) ],                         [ 'test.lib test2.lib',             '', 'test.lib test2.lib',             '' ], 'unknown :flags are safely ignored' );
110
111     my $curr = File::Spec->rel2abs( '' );
112     is_deeply( [ _ext( "-L$curr/dir dir_test" ) ], [ $curr . '\dir\dir_test.lib',         '', $curr . '\dir\dir_test.lib',         '' ], 'directories in -L parameters are searched' );
113     is_deeply( [ _ext( "-L/non_dir dir_test" ) ],  [ '',                                  '', '',                                  '' ], 'non-existent -L dirs are ignored safely' );
114     is_deeply( [ _ext( "-Ldir dir_test" ) ],       [ $curr . '\dir\dir_test.lib',         '', $curr . '\dir\dir_test.lib',         '' ], 'relative -L directories work' );
115     is_deeply( [ _ext( '-L"di r" dir_test' ) ],    [ '"' . $curr . '\di r\dir_test.lib"', '', '"' . $curr . '\di r\dir_test.lib"', '' ], '-L directories with spaces work' );
116
117     $Config{perllibs} = 'pl';
118     is_deeply( [ _ext( 'unreal_test' ) ],            [ 'pl.lib', '', 'pl.lib', '' ], '$Config{perllibs} adds extra libs to be searched' );
119     is_deeply( [ _ext( 'unreal_test :nodefault' ) ], [ '',       '', '',       '' ], ':nodefault flag prevents $Config{perllibs} from being added' );
120     delete $Config{perllibs};
121
122     $Config{libpth} = 'libpath';
123     is_deeply( [ _ext( 'lp_test' ) ], [ 'libpath\lp_test.lib', '', 'libpath\lp_test.lib', '' ], '$Config{libpth} adds extra search paths' );
124     delete $Config{libpth};
125
126     $Config{lib_ext} = '.meep';
127     is_deeply( [ _ext( 'test' ) ], [ 'test.meep', '', 'test.meep', '' ], '$Config{lib_ext} changes the lib extension to be searched for' );
128     delete $Config{lib_ext};
129
130     $Config{lib_ext} = '.a';
131     is_deeply( [ _ext( 'imp' ) ], [ 'imp.dll.a', '', 'imp.dll.a', '' ], '$Config{lib_ext} == ".a" will find *.dll.a too' );
132     delete $Config{lib_ext};
133
134     $Config{cc} = 'C:/MinGW/bin/gcc.exe';
135
136     is_deeply( [ _ext( 'test' ) ],                    [ 'test.lib',      '', 'test.lib',      '' ], '[gcc] searching for straight lib names remains unchanged' );
137     is_deeply( [ _ext( '-l__test' ) ],                [ 'lib__test.lib', '', 'lib__test.lib', '' ], '[gcc] lib-prefixed library files are found first when -l is in use' );
138     is_deeply( [ _ext( '-ltest' ) ],                  [ 'test.lib',      '', 'test.lib',      '' ], '[gcc] non-lib-prefixed library files are found on the second search when -l is in use' );
139     is_deeply( [ _ext( '-llibtest' ) ],               [ 'test.lib',      '', 'test.lib',      '' ], '[gcc] if -l is used and the lib name is already prefixed a second search without the lib is done' );
140     is_deeply( [ _ext( ':nosearch -lunreal_test' ) ], [ '-lunreal_test', '', '-lunreal_test', '' ], '[gcc] lib names with -l after a :nosearch remain as they are' );
141
142     $ENV{LIBRARY_PATH} = 'libpath';
143     is_deeply( [ _ext( 'lp_test' ) ], [ 'libpath\lp_test.lib', '', 'libpath\lp_test.lib', '' ], '[gcc] $ENV{LIBRARY_PATH} adds extra search paths' );
144     delete $ENV{LIBRARY_PATH};
145
146     $Config{cc} = 'c:/Programme/Microsoft Visual Studio 9.0/VC/bin/cl.exe';
147
148     is_deeply( [ _ext( 'test' ) ], [ 'test.lib', '', 'test.lib', '' ], '[vc] searching for straight lib names remains unchanged' );
149     is_deeply( [ _ext( ':nosearch -Lunreal_test' ) ], [ '-libpath:unreal_test', '', '-libpath:unreal_test', '' ], '[vc] lib dirs with -L after a :nosearch are prefixed with -libpath:' );
150     ok( !exists $ENV{LIB}, '[vc] $ENV{LIB} is not autovivified' );
151
152     $ENV{LIB} = 'vc';
153     is_deeply( [ _ext( 'vctest.lib' ) ], [ 'vc\vctest.lib', '', 'vc\vctest.lib', '' ], '[vc] $ENV{LIB} adds search paths' );
154
155     return;
156 }