Commit | Line | Data |
---|---|---|
2d4cc5ff YO |
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 | } |