eaac22dd81a11b2120f65a951812d03ca29bed43
[scons.git] / test / Variables / Variables.py
1 #!/usr/bin/env python
2 #
3 # __COPYRIGHT__
4 #
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:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
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.
23 #
24
25 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26
27 import TestSCons
28 import string
29
30 test = TestSCons.TestSCons()
31
32 test.write('SConstruct', """
33 import string
34 env = Environment()
35 print env['CC']
36 print string.join(env['CCFLAGS'])
37 Default(env.Alias('dummy', None))
38 """)
39 test.run()
40 cc, ccflags = string.split(test.stdout(), '\n')[1:3]
41
42 test.write('SConstruct', """
43 import string
44
45 # test validator.  Change a key and add a new one to the environment
46 def validator(key, value, environ):
47     environ[key] = "v"
48     environ["valid_key"] = "v"
49
50
51 def old_converter (value):
52     return "old_converter"
53
54 def new_converter (value, env):
55     return "new_converter"
56
57
58 opts = Variables('custom.py')
59 opts.Add('RELEASE_BUILD',
60          'Set to 1 to build a release build',
61          0,
62          None,
63          int)
64
65 opts.Add('DEBUG_BUILD',
66          'Set to 1 to build a debug build',
67          1,
68          None,
69          int)
70
71 opts.Add('CC',
72          'The C compiler')
73
74 opts.Add('VALIDATE',
75          'An option for testing validation',
76          "notset",
77          validator,
78          None)
79
80 opts.Add('OLD_CONVERTER',
81          'An option for testing converters that take one parameter',
82          "foo",
83          None,
84          old_converter)
85
86 opts.Add('NEW_CONVERTER',
87          'An option for testing converters that take two parameters',
88          "foo",
89          None,
90          new_converter)
91
92 opts.Add('UNSPECIFIED',
93          'An option with no value')
94
95 def test_tool(env):
96     if env['RELEASE_BUILD']:
97         env.Append(CCFLAGS = '-O')
98     if env['DEBUG_BUILD']:
99         env.Append(CCFLAGS = '-g')
100
101
102 env = Environment(variables=opts, tools=['default', test_tool])
103
104 Help('Variables settable in custom.py or on the command line:\\n' + opts.GenerateHelpText(env))
105
106 print env['RELEASE_BUILD']
107 print env['DEBUG_BUILD']
108 print env['CC']
109 print string.join(env['CCFLAGS'])
110 print env['VALIDATE']
111 print env['valid_key']
112
113 # unspecified variables should not be set:
114 assert not env.has_key('UNSPECIFIED')
115
116 # undeclared variables should be ignored:
117 assert not env.has_key('UNDECLARED')
118
119 # calling Update() should not effect variables that
120 # are not declared on the variables object:
121 r = env['RELEASE_BUILD']
122 opts = Variables()
123 opts.Update(env)
124 assert env['RELEASE_BUILD'] == r
125
126 Default(env.Alias('dummy', None))
127
128 """)
129
130 def check(expect):
131     result = string.split(test.stdout(), '\n')
132     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
133
134 test.run()
135 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
136
137 test.run(arguments='RELEASE_BUILD=1')
138 check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
139
140 test.run(arguments='RELEASE_BUILD=1 DEBUG_BUILD=0')
141 check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
142
143 test.run(arguments='CC=not_a_c_compiler')
144 check(['0', '1', 'not_a_c_compiler', string.strip(ccflags + ' -g'), 'v', 'v'])
145
146 test.run(arguments='UNDECLARED=foo')
147 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
148
149 test.run(arguments='CCFLAGS=--taco')
150 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
151
152 test.write('custom.py', """
153 DEBUG_BUILD=0
154 RELEASE_BUILD=1
155 """)
156
157 test.run()
158 check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
159
160 test.run(arguments='DEBUG_BUILD=1')
161 check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
162
163 test.run(arguments='-h',
164          stdout = """\
165 scons: Reading SConscript files ...
166 1
167 0
168 %s
169 %s
170 v
171 v
172 scons: done reading SConscript files.
173 Variables settable in custom.py or on the command line:
174
175 RELEASE_BUILD: Set to 1 to build a release build
176     default: 0
177     actual: 1
178
179 DEBUG_BUILD: Set to 1 to build a debug build
180     default: 1
181     actual: 0
182
183 CC: The C compiler
184     default: None
185     actual: %s
186
187 VALIDATE: An option for testing validation
188     default: notset
189     actual: v
190
191 OLD_CONVERTER: An option for testing converters that take one parameter
192     default: foo
193     actual: old_converter
194
195 NEW_CONVERTER: An option for testing converters that take two parameters
196     default: foo
197     actual: new_converter
198
199 UNSPECIFIED: An option with no value
200     default: None
201     actual: None
202
203 Use scons -H for help about command-line options.
204 """%(cc, ccflags and ccflags + ' -O' or '-O', cc))
205
206 # Test saving of variables and multi loading
207 #
208 test.write('SConstruct', """
209 opts = Variables(['custom.py', 'variables.saved'])
210 opts.Add('RELEASE_BUILD',
211          'Set to 1 to build a release build',
212          0,
213          None,
214          int)
215
216 opts.Add('DEBUG_BUILD',
217          'Set to 1 to build a debug build',
218          1,
219          None,
220          int)
221
222 opts.Add('UNSPECIFIED',
223          'An option with no value')
224
225 env = Environment(variables = opts)
226
227 print env['RELEASE_BUILD']
228 print env['DEBUG_BUILD']
229
230 opts.Save('variables.saved', env)
231 """)
232
233 # Check the save file by executing and comparing against
234 # the expected dictionary
235 def checkSave(file, expected):
236     gdict = {}
237     ldict = {}
238     execfile(file, gdict, ldict)
239     assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict)
240
241 # First test with no command line variables
242 # This should just leave the custom.py settings
243 test.run()
244 check(['1','0'])
245 checkSave('variables.saved', { 'RELEASE_BUILD':1, 'DEBUG_BUILD':0})
246
247 # Override with command line arguments
248 test.run(arguments='DEBUG_BUILD=3')
249 check(['1','3'])
250 checkSave('variables.saved', {'RELEASE_BUILD':1, 'DEBUG_BUILD':3})
251
252 # Now make sure that saved variables are overridding the custom.py
253 test.run()
254 check(['1','3'])
255 checkSave('variables.saved', {'DEBUG_BUILD':3, 'RELEASE_BUILD':1})
256
257 # Load no variables from file(s)
258 # Used to test for correct output in save option file
259 test.write('SConstruct', """
260 opts = Variables()
261 opts.Add('RELEASE_BUILD',
262          'Set to 1 to build a release build',
263          '0',
264          None,
265          int)
266
267 opts.Add('DEBUG_BUILD',
268          'Set to 1 to build a debug build',
269          '1',
270          None,
271          int)
272
273 opts.Add('UNSPECIFIED',
274          'An option with no value')
275
276 opts.Add('LISTOPTION_TEST',
277          'testing list option persistence',
278          'none',
279          names = ['a','b','c',])
280
281 env = Environment(variables = opts)
282
283 print env['RELEASE_BUILD']
284 print env['DEBUG_BUILD']
285 print env['LISTOPTION_TEST']
286
287 opts.Save('variables.saved', env)
288 """)
289
290 # First check for empty output file when nothing is passed on command line
291 test.run()
292 check(['0','1'])
293 checkSave('variables.saved', {})
294
295 # Now specify one option the same as default and make sure it doesn't write out
296 test.run(arguments='DEBUG_BUILD=1')
297 check(['0','1'])
298 checkSave('variables.saved', {})
299
300 # Now specify same option non-default and make sure only it is written out
301 test.run(arguments='DEBUG_BUILD=0 LISTOPTION_TEST=a,b')
302 check(['0','0'])
303 checkSave('variables.saved',{'DEBUG_BUILD':0, 'LISTOPTION_TEST':'a,b'})
304
305 test.write('SConstruct', """
306 opts = Variables('custom.py')
307 opts.Add('RELEASE_BUILD',
308          'Set to 1 to build a release build',
309          0,
310          None,
311          int)
312
313 opts.Add('DEBUG_BUILD',
314          'Set to 1 to build a debug build',
315          1,
316          None,
317          int)
318
319 opts.Add('CC',
320          'The C compiler')
321
322 opts.Add('UNSPECIFIED',
323          'An option with no value')
324
325 env = Environment(variables=opts)
326
327 Help('Variables settable in custom.py or on the command line:\\n' + opts.GenerateHelpText(env,sort=cmp))
328
329 """)
330
331 test.run(arguments='-h',
332          stdout = """\
333 scons: Reading SConscript files ...
334 scons: done reading SConscript files.
335 Variables settable in custom.py or on the command line:
336
337 CC: The C compiler
338     default: None
339     actual: %s
340
341 DEBUG_BUILD: Set to 1 to build a debug build
342     default: 1
343     actual: 0
344
345 RELEASE_BUILD: Set to 1 to build a release build
346     default: 0
347     actual: 1
348
349 UNSPECIFIED: An option with no value
350     default: None
351     actual: None
352
353 Use scons -H for help about command-line options.
354 """%cc)
355
356 test.write('SConstruct', """
357 import SCons.Variables
358 env1 = Environment(variables = Variables())
359 env2 = Environment(variables = SCons.Variables.Variables())
360 """)
361
362 test.run()
363
364 test.pass_test()
365
366 # Local Variables:
367 # tab-width:4
368 # indent-tabs-mode:nil
369 # End:
370 # vim: set expandtab tabstop=4 shiftwidth=4: