3 # Copyright The SCons Foundation
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 import SCons
.Scanner
.Prog
33 test
= TestCmd
.TestCmd(workdir
= '')
35 test
.subdir('d1', ['d1', 'd2'], 'dir', ['dir', 'sub'])
37 libs
= [ 'l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib',
38 'dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']
44 # define some helpers:
46 class DummyEnvironment
:
47 def __init__(self
, **kw
) -> None:
48 self
._dict
= {'LIBSUFFIXES' : '.lib'}
50 self
.fs
= SCons
.Node
.FS
.FS(test
.workpath(''))
52 def Dictionary(self
, *args
):
56 return self
._dict
[args
[0]]
58 return [self
._dict
[x
] for x
in args
]
60 def __contains__(self
, key
) -> bool:
61 return key
in self
.Dictionary()
63 def __getitem__(self
,key
):
64 return self
.Dictionary()[key
]
66 def __setitem__(self
,key
,value
) -> None:
67 self
.Dictionary()[key
] = value
69 def __delitem__(self
,key
) -> None:
70 del self
.Dictionary()[key
]
72 def subst(self
, s
, target
=None, source
=None, conv
=None):
73 return SCons
.Subst
.scons_subst(s
, self
, gvars
=self
._dict
, lvars
=self
._dict
)
75 def subst_path(self
, path
, target
=None, source
=None, conv
=None):
76 if not isinstance(path
, list):
78 return list(map(self
.subst
, path
))
80 def get_factory(self
, factory
):
81 return factory
or self
.fs
.File
83 def Dir(self
, filename
):
84 return self
.fs
.Dir(test
.workpath(filename
))
86 def File(self
, filename
):
87 return self
.fs
.File(test
.workpath(filename
))
90 def __init__(self
, name
) -> None:
92 def rexists(self
) -> bool:
94 def __str__(self
) -> str:
97 def deps_match(deps
, libs
):
98 deps
=sorted(map(str, deps
))
100 return list(map(os
.path
.normpath
, deps
)) == list(map(os
.path
.normpath
, libs
))
104 class ProgramScannerTestCase1(unittest
.TestCase
):
105 def runTest(self
) -> None:
106 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("") ],
107 LIBS
=[ 'l1', 'l2', 'l3' ])
108 s
= SCons
.Scanner
.Prog
.ProgramScanner()
110 deps
= s(DummyNode('dummy'), env
, path
)
111 assert deps_match(deps
, ['l1.lib']), list(map(str, deps
))
113 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("") ],
115 s
= SCons
.Scanner
.Prog
.ProgramScanner()
117 deps
= s(DummyNode('dummy'), env
, path
)
118 assert deps_match(deps
, ['l1.lib']), list(map(str, deps
))
120 f1
= env
.fs
.File(test
.workpath('f1'))
121 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("") ],
123 s
= SCons
.Scanner
.Prog
.ProgramScanner()
125 deps
= s(DummyNode('dummy'), env
, path
)
126 assert deps
[0] is f1
, deps
128 f2
= env
.fs
.File(test
.workpath('f1'))
129 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("") ],
131 s
= SCons
.Scanner
.Prog
.ProgramScanner()
133 deps
= s(DummyNode('dummy'), env
, path
)
134 assert deps
[0] is f2
, deps
137 class ProgramScannerTestCase2(unittest
.TestCase
):
138 def runTest(self
) -> None:
139 env
= DummyEnvironment(LIBPATH
=list(map(test
.workpath
,
140 ["", "d1", "d1/d2" ])),
141 LIBS
=[ 'l1', 'l2', 'l3' ])
142 s
= SCons
.Scanner
.Prog
.ProgramScanner()
144 deps
= s(DummyNode('dummy'), env
, path
)
145 assert deps_match(deps
, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), list(map(str, deps
))
147 class ProgramScannerTestCase3(unittest
.TestCase
):
148 def runTest(self
) -> None:
149 env
= DummyEnvironment(LIBPATH
=[test
.workpath("d1/d2"),
150 test
.workpath("d1")],
151 LIBS
='l2 l3'.split())
152 s
= SCons
.Scanner
.Prog
.ProgramScanner()
154 deps
= s(DummyNode('dummy'), env
, path
)
155 assert deps_match(deps
, ['d1/l2.lib', 'd1/d2/l3.lib']), list(map(str, deps
))
157 class ProgramScannerTestCase5(unittest
.TestCase
):
158 def runTest(self
) -> None:
159 class SubstEnvironment(DummyEnvironment
):
160 def subst(self
, arg
, target
=None, source
=None, conv
=None, path
=test
.workpath("d1")):
162 return test
.workpath("d1")
165 env
= SubstEnvironment(LIBPATH
=[ "$blah" ],
166 LIBS
='l2 l3'.split())
167 s
= SCons
.Scanner
.Prog
.ProgramScanner()
169 deps
= s(DummyNode('dummy'), env
, path
)
170 assert deps_match(deps
, [ 'd1/l2.lib' ]), list(map(str, deps
))
172 class ProgramScannerTestCase6(unittest
.TestCase
):
173 def runTest(self
) -> None:
174 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
175 LIBS
=['foo', 'sub/libbar', 'xyz.other'],
178 s
= SCons
.Scanner
.Prog
.ProgramScanner()
180 deps
= s(DummyNode('dummy'), env
, path
)
181 assert deps_match(deps
, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps
))
183 class ProgramScannerTestCase7(unittest
.TestCase
):
184 def runTest(self
) -> None:
185 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
186 LIBS
=['foo', '$LIBBAR', '$XYZ'],
191 s
= SCons
.Scanner
.Prog
.ProgramScanner()
193 deps
= s(DummyNode('dummy'), env
, path
)
194 assert deps_match(deps
, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps
))
196 class ProgramScannerTestCase8(unittest
.TestCase
):
197 def runTest(self
) -> None:
200 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
202 LIBPREFIXES
=['p1-', 'p2-'],
203 LIBSUFFIXES
=['.1', '2'])
204 s
= SCons
.Scanner
.Prog
.ProgramScanner(node_class
= DummyNode
)
206 deps
= s(DummyNode('dummy'), env
, path
)
207 assert deps
== [n1
], deps
210 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
212 LIBPREFIXES
=['p1-', 'p2-'],
213 LIBSUFFIXES
=['.1', '2'])
214 s
= SCons
.Scanner
.Prog
.ProgramScanner(node_class
= DummyNode
)
216 deps
= s(DummyNode('dummy'), env
, path
)
217 assert deps
== [n1
, n2
], deps
219 class ProgramScannerTestCase9(unittest
.TestCase
):
220 def runTest(self
) -> None:
221 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
222 LIBS
=['foo', '$LIBBAR'],
225 LIBBAR
=['sub/libbar', 'xyz.other'])
226 s
= SCons
.Scanner
.Prog
.ProgramScanner()
228 deps
= s(DummyNode('dummy'), env
, path
)
229 assert deps_match(deps
, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps
))
231 class ProgramScannerTestCase10(unittest
.TestCase
):
232 def runTest(self
) -> None:
233 env
= DummyEnvironment(LIBPATH
=[ test
.workpath("dir") ],
234 LIBS
=['foo', '$LIBBAR'],
237 LIBBAR
='sub/libbar $LIBBAR2',
238 LIBBAR2
=['xyz.other'])
239 s
= SCons
.Scanner
.Prog
.ProgramScanner()
241 deps
= s(DummyNode('dummy'), env
, path
)
242 assert deps_match(deps
, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps
))
245 suite
= unittest
.TestSuite()
246 suite
.addTest(ProgramScannerTestCase1())
247 suite
.addTest(ProgramScannerTestCase2())
248 suite
.addTest(ProgramScannerTestCase3())
249 suite
.addTest(ProgramScannerTestCase5())
250 suite
.addTest(ProgramScannerTestCase6())
251 suite
.addTest(ProgramScannerTestCase7())
252 suite
.addTest(ProgramScannerTestCase8())
253 suite
.addTest(ProgramScannerTestCase9())
254 suite
.addTest(ProgramScannerTestCase10())
257 if __name__
== "__main__":
262 # indent-tabs-mode:nil
264 # vim: set expandtab tabstop=4 shiftwidth=4: