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.
28 import SCons
.Variables
31 from TestCmd
import IS_WINDOWS
34 IS_ROOT
= os
.geteuid() == 0
35 except AttributeError:
39 class PathVariableTestCase(unittest
.TestCase
):
40 def test_PathVariable(self
) -> None:
41 """Test PathVariable creation"""
42 opts
= SCons
.Variables
.Variables()
43 opts
.Add(SCons
.Variables
.PathVariable('test',
44 'test build variable help',
48 assert o
.key
== 'test', o
.key
49 assert o
.help == 'test build variable help ( /path/to/test )', repr(o
.help)
50 assert o
.default
== '/default/path', o
.default
51 assert o
.validator
is not None, o
.validator
52 assert o
.converter
is None, o
.converter
54 def test_PathExists(self
):
55 """Test the PathExists validator"""
56 opts
= SCons
.Variables
.Variables()
57 opts
.Add(SCons
.Variables
.PathVariable('test',
58 'test build variable help',
60 SCons
.Variables
.PathVariable
.PathExists
))
62 test
= TestCmd
.TestCmd(workdir
='')
63 test
.write('exists', 'exists\n')
66 o
.validator('X', test
.workpath('exists'), {})
68 dne
= test
.workpath('does_not_exist')
69 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
70 o
.validator('X', dne
, {})
72 self
.assertEqual(str(e
), f
"Path for variable 'X' does not exist: {dne}")
74 def test_PathIsDir(self
):
75 """Test the PathIsDir validator"""
76 opts
= SCons
.Variables
.Variables()
77 opts
.Add(SCons
.Variables
.PathVariable('test',
78 'test build variable help',
80 SCons
.Variables
.PathVariable
.PathIsDir
))
82 test
= TestCmd
.TestCmd(workdir
='')
84 test
.write('file', "file\n")
87 o
.validator('X', test
.workpath('dir'), {})
89 f
= test
.workpath('file')
90 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
91 o
.validator('X', f
, {})
93 self
.assertEqual(str(e
), f
"Directory path for variable 'X' is a file: {f}")
95 dne
= test
.workpath('does_not_exist')
96 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
97 o
.validator('X', dne
, {})
99 self
.assertEqual(str(e
), f
"Directory path for variable 'X' does not exist: {dne}")
101 def test_PathIsDirCreate(self
):
102 """Test the PathIsDirCreate validator."""
103 opts
= SCons
.Variables
.Variables()
104 opts
.Add(SCons
.Variables
.PathVariable('test',
105 'test build variable help',
107 SCons
.Variables
.PathVariable
.PathIsDirCreate
))
109 test
= TestCmd
.TestCmd(workdir
='')
110 test
.write('file', "file\n")
114 d
= test
.workpath('dir')
115 o
.validator('X', d
, {})
116 assert os
.path
.isdir(d
)
118 f
= test
.workpath('file')
119 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
120 o
.validator('X', f
, {})
122 self
.assertEqual(str(e
), f
"Path for variable 'X' is a file, not a directory: {f}")
125 @unittest.skipIf(IS_ROOT
, "Skip creating bad directory if running as root.")
126 def test_PathIsDirCreate_bad_dir(self
):
127 """Test the PathIsDirCreate validator with an uncreatable dir.
129 Split from :meth:`test_PathIsDirCreate` to be able to skip on root.
130 We want to be able to skip only this one testcase and run the rest.
132 opts
= SCons
.Variables
.Variables()
134 SCons
.Variables
.PathVariable(
136 'test build variable help',
138 SCons
.Variables
.PathVariable
.PathIsDirCreate
,
142 test
= TestCmd
.TestCmd(workdir
='')
145 # pick a directory path that can't be mkdir'd
147 f
= r
'\\noserver\noshare\yyy\zzz'
150 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
151 o
.validator('X', f
, {})
153 self
.assertEqual(str(e
), f
"Path for variable 'X' could not be created: {f}")
156 def test_PathIsFile(self
):
157 """Test the PathIsFile validator."""
158 opts
= SCons
.Variables
.Variables()
159 opts
.Add(SCons
.Variables
.PathVariable('test',
160 'test build variable help',
162 SCons
.Variables
.PathVariable
.PathIsFile
))
164 test
= TestCmd
.TestCmd(workdir
='')
166 test
.write('file', "file\n")
169 o
.validator('X', test
.workpath('file'), {})
171 d
= test
.workpath('d')
172 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
173 o
.validator('X', d
, {})
175 self
.assertEqual(str(e
), f
"File path for variable 'X' does not exist: {d}")
177 dne
= test
.workpath('does_not_exist')
178 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
179 o
.validator('X', dne
, {})
181 self
.assertEqual(str(e
), f
"File path for variable 'X' does not exist: {dne}")
183 def test_PathAccept(self
) -> None:
184 """Test the PathAccept validator"""
185 opts
= SCons
.Variables
.Variables()
186 opts
.Add(SCons
.Variables
.PathVariable('test',
187 'test build variable help',
189 SCons
.Variables
.PathVariable
.PathAccept
))
191 test
= TestCmd
.TestCmd(workdir
='')
193 test
.write('file', "file\n")
196 o
.validator('X', test
.workpath('file'), {})
198 d
= test
.workpath('d')
199 o
.validator('X', d
, {})
201 dne
= test
.workpath('does_not_exist')
202 o
.validator('X', dne
, {})
204 def test_validator(self
):
205 """Test the PathVariable validator argument"""
206 opts
= SCons
.Variables
.Variables()
207 opts
.Add(SCons
.Variables
.PathVariable('test',
208 'test variable help',
211 test
= TestCmd
.TestCmd(workdir
='')
212 test
.write('exists', 'exists\n')
215 o
.validator('X', test
.workpath('exists'), {})
217 dne
= test
.workpath('does_not_exist')
218 with self
.assertRaises(SCons
.Errors
.UserError
) as cm
:
219 o
.validator('X', dne
, {})
221 self
.assertEqual(str(e
), f
"Path for variable 'X' does not exist: {dne}")
223 class ValidatorError(Exception):
226 def my_validator(key
, val
, env
):
227 raise ValidatorError(f
"my_validator() got called for {key!r}, {val!r}!")
229 opts
= SCons
.Variables
.Variables()
230 opts
.Add(SCons
.Variables
.PathVariable('test2',
232 '/default/path/again',
235 with self
.assertRaises(ValidatorError
) as cm
:
236 o
.validator('Y', 'value', {})
238 self
.assertEqual(str(e
), "my_validator() got called for 'Y', 'value'!")
241 if __name__
== "__main__":
246 # indent-tabs-mode:nil
248 # vim: set expandtab tabstop=4 shiftwidth=4: