diff options
Diffstat (limited to 'src/engine/SCons/Variables/VariablesTests.py')
-rw-r--r-- | src/engine/SCons/Variables/VariablesTests.py | 663 |
1 files changed, 663 insertions, 0 deletions
diff --git a/src/engine/SCons/Variables/VariablesTests.py b/src/engine/SCons/Variables/VariablesTests.py new file mode 100644 index 0000000..b89404b --- /dev/null +++ b/src/engine/SCons/Variables/VariablesTests.py @@ -0,0 +1,663 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Variables/VariablesTests.py 4577 2009/12/27 19:44:43 scons" + +import sys +import unittest +import TestSCons + +import SCons.Variables +import SCons.Subst +import SCons.Warnings + + +class Environment: + def __init__(self): + self.dict = {} + def subst(self, x): + return SCons.Subst.scons_subst(x, self, gvars=self.dict) + def __setitem__(self, key, value): + self.dict[key] = value + def __getitem__(self, key): + return self.dict[key] + def has_key(self, key): + return self.dict.has_key(key) + + +def check(key, value, env): + assert int(value) == 6 * 9, "key %s = %s" % (key, repr(value)) + +# Check saved option file by executing and comparing against +# the expected dictionary +def checkSave(file, expected): + gdict = {} + ldict = {} + exec open(file, 'rU').read() in gdict, ldict + assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict) + +class VariablesTestCase(unittest.TestCase): + + def test_keys(self): + """Test the Variables.keys() method""" + opts = SCons.Variables.Variables() + + opts.Add('VAR1') + opts.Add('VAR2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + keys = opts.keys() + assert keys == ['VAR1', 'VAR2'], keys + + def test_Add(self): + """Test adding to a Variables object""" + opts = SCons.Variables.Variables() + + opts.Add('VAR') + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + o = opts.options[0] + assert o.key == 'VAR' + assert o.help == '' + assert o.default is None + assert o.validator is None + assert o.converter is None + + o = opts.options[1] + assert o.key == 'ANSWER' + assert o.help == 'THE answer to THE question' + assert o.default == "42" + o.validator(o.key, o.converter(o.default), {}) + + def test_it(var, opts=opts): + exc_caught = None + try: + opts.Add(var) + except SCons.Errors.UserError: + exc_caught = 1 + assert exc_caught, "did not catch UserError for '%s'" % var + test_it('foo/bar') + test_it('foo-bar') + test_it('foo.bar') + + def test_AddVariables(self): + """Test adding a list of options to a Variables object""" + opts = SCons.Variables.Variables() + + opts.AddVariables(('VAR2',), + ('ANSWER2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12)) + + o = opts.options[0] + assert o.key == 'VAR2', o.key + assert o.help == '', o.help + assert o.default is None, o.default + assert o.validator is None, o.validator + assert o.converter is None, o.converter + + o = opts.options[1] + assert o.key == 'ANSWER2', o.key + assert o.help == 'THE answer to THE question', o.help + assert o.default == "42", o.default + o.validator(o.key, o.converter(o.default), {}) + + def test_Update(self): + """Test updating an Environment""" + + # Test that a default value is validated correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + env = Environment() + opts.Update(env, {}) + assert env['ANSWER'] == 54 + + # Test that a bad value from the file is used and + # validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + env = Environment() + exc_caught = None + try: + opts.Update(env, {}) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good value from the file is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=42') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "10", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + env = Environment() + opts.Update(env, {}) + assert env['ANSWER'] == 54 + + # Test that a bad value from an args dictionary passed to + # Update() is used and validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=10') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "12", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env, {'ANSWER':'54'}) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good value from an args dictionary + # passed to Update() is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=10') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "12", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {'ANSWER':'42'}) + assert env['ANSWER'] == 54 + + # Test against a former bug. If we supply a converter, + # but no default, the value should *not* appear in the + # Environment if no value is specified in the options file + # or args. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + help='THE answer to THE question', + converter=str) + + env = Environment() + opts.Update(env, {}) + assert not env.has_key('ANSWER') + + # Test that a default value of None is all right. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + "This is the answer", + None, + check) + + env = Environment() + opts.Update(env, {}) + assert not env.has_key('ANSWER') + + def test_args(self): + """Test updating an Environment with arguments overridden""" + + # Test that a bad (command-line) argument is used + # and the validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=42') + opts = SCons.Variables.Variables(file, {'ANSWER':54}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good (command-line) argument is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file, {'ANSWER':42}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "54", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + # Test that a (command-line) argument is overridden by a dictionary + # supplied to Update() and the dictionary value is validated correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file, {'ANSWER':54}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "54", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {'ANSWER':42}) + assert env['ANSWER'] == 54 + + def test_Save(self): + """Testing saving Variables""" + + test = TestSCons.TestSCons() + cache_file = test.workpath('cached.options') + opts = SCons.Variables.Variables() + + def bool_converter(val): + if val in [1, 'y']: val = 1 + if val in [0, 'n']: val = 0 + return val + + # test saving out empty file + opts.Add('OPT_VAL', + 'An option to test', + 21, + None, + None) + opts.Add('OPT_VAL_2', + default='foo') + opts.Add('OPT_VAL_3', + default=1) + opts.Add('OPT_BOOL_0', + default='n', + converter=bool_converter) + opts.Add('OPT_BOOL_1', + default='y', + converter=bool_converter) + opts.Add('OPT_BOOL_2', + default=0, + converter=bool_converter) + + env = Environment() + opts.Update(env, {'OPT_VAL_3' : 2}) + assert env['OPT_VAL'] == 21, env['OPT_VAL'] + assert env['OPT_VAL_2'] == 'foo', env['OPT_VAL_2'] + assert env['OPT_VAL_3'] == 2, env['OPT_VAL_3'] + assert env['OPT_BOOL_0'] == 0, env['OPT_BOOL_0'] + assert env['OPT_BOOL_1'] == 1, env['OPT_BOOL_1'] + assert env['OPT_BOOL_2'] == '0', env['OPT_BOOL_2'] + + env['OPT_VAL_2'] = 'bar' + env['OPT_BOOL_0'] = 0 + env['OPT_BOOL_1'] = 1 + env['OPT_BOOL_2'] = 2 + + opts.Save(cache_file, env) + checkSave(cache_file, { 'OPT_VAL_2' : 'bar', + 'OPT_VAL_3' : 2, + 'OPT_BOOL_2' : 2}) + + # Test against some old bugs + class Foo: + def __init__(self, x): + self.x = x + def __str__(self): + return self.x + + test = TestSCons.TestSCons() + cache_file = test.workpath('cached.options') + opts = SCons.Variables.Variables() + + opts.Add('THIS_USED_TO_BREAK', + 'An option to test', + "Default") + + opts.Add('THIS_ALSO_BROKE', + 'An option to test', + "Default2") + + opts.Add('THIS_SHOULD_WORK', + 'An option to test', + Foo('bar')) + + env = Environment() + opts.Update(env, { 'THIS_USED_TO_BREAK' : "Single'Quotes'In'String", + 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", + 'THIS_SHOULD_WORK' : Foo('baz') }) + opts.Save(cache_file, env) + checkSave(cache_file, { 'THIS_USED_TO_BREAK' : "Single'Quotes'In'String", + 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", + 'THIS_SHOULD_WORK' : 'baz' }) + + def test_GenerateHelpText(self): + """Test generating the default format help text""" + opts = SCons.Variables.Variables() + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('B', + 'b - alpha test', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('A', + 'a - alpha test', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {}) + + expect = """ +ANSWER: THE answer to THE question + default: 42 + actual: 54 + +B: b - alpha test + default: 42 + actual: 54 + +A: a - alpha test + default: 42 + actual: 54 +""" + + text = opts.GenerateHelpText(env) + assert text == expect, text + + expectAlpha = """ +A: a - alpha test + default: 42 + actual: 54 + +ANSWER: THE answer to THE question + default: 42 + actual: 54 + +B: b - alpha test + default: 42 + actual: 54 +""" + text = opts.GenerateHelpText(env, sort=cmp) + assert text == expectAlpha, text + + def test_FormatVariableHelpText(self): + """Test generating custom format help text""" + opts = SCons.Variables.Variables() + + def my_format(env, opt, help, default, actual, aliases): + return '%s %s %s %s %s\n' % (opt, default, actual, help, aliases) + + opts.FormatVariableHelpText = my_format + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('B', + 'b - alpha test', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('A', + 'a - alpha test', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {}) + + expect = """\ +ANSWER 42 54 THE answer to THE question ['ANSWER'] +B 42 54 b - alpha test ['B'] +A 42 54 a - alpha test ['A'] +""" + + text = opts.GenerateHelpText(env) + assert text == expect, text + + expectAlpha = """\ +A 42 54 a - alpha test ['A'] +ANSWER 42 54 THE answer to THE question ['ANSWER'] +B 42 54 b - alpha test ['B'] +""" + text = opts.GenerateHelpText(env, sort=cmp) + assert text == expectAlpha, text + + def test_Aliases(self): + """Test option aliases""" + # test alias as a tuple + opts = SCons.Variables.Variables() + opts.AddVariables( + (('ANSWER', 'ANSWERALIAS'), + 'THE answer to THE question', + "42"), + ) + + env = Environment() + opts.Update(env, {'ANSWER' : 'answer'}) + + assert env.has_key('ANSWER') + + env = Environment() + opts.Update(env, {'ANSWERALIAS' : 'answer'}) + + assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS') + + # test alias as a list + opts = SCons.Variables.Variables() + opts.AddVariables( + (['ANSWER', 'ANSWERALIAS'], + 'THE answer to THE question', + "42"), + ) + + env = Environment() + opts.Update(env, {'ANSWER' : 'answer'}) + + assert env.has_key('ANSWER') + + env = Environment() + opts.Update(env, {'ANSWERALIAS' : 'answer'}) + + assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS') + + + +class UnknownVariablesTestCase(unittest.TestCase): + + def test_unknown(self): + """Test the UnknownVariables() method""" + opts = SCons.Variables.Variables() + + opts.Add('ANSWER', + 'THE answer to THE question', + "42") + + args = { + 'ANSWER' : 'answer', + 'UNKNOWN' : 'unknown', + } + + env = Environment() + opts.Update(env, args) + + r = opts.UnknownVariables() + assert r == {'UNKNOWN' : 'unknown'}, r + assert env['ANSWER'] == 'answer', env['ANSWER'] + + def test_AddOptionUpdatesUnknown(self): + """Test updating of the 'unknown' dict""" + opts = SCons.Variables.Variables() + + opts.Add('A', + 'A test variable', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATER' : 'notaddedyet', + } + + env = Environment() + opts.Update(env,args) + + r = opts.UnknownVariables() + assert r == {'ADDEDLATER' : 'notaddedyet'}, r + assert env['A'] == 'a', env['A'] + + opts.Add('ADDEDLATER', + 'An option not present initially', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATER' : 'added', + } + + opts.Update(env, args) + + r = opts.UnknownVariables() + assert len(r) == 0, r + assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] + + def test_AddOptionWithAliasUpdatesUnknown(self): + """Test updating of the 'unknown' dict (with aliases)""" + opts = SCons.Variables.Variables() + + opts.Add('A', + 'A test variable', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATERALIAS' : 'notaddedyet', + } + + env = Environment() + opts.Update(env,args) + + r = opts.UnknownVariables() + assert r == {'ADDEDLATERALIAS' : 'notaddedyet'}, r + assert env['A'] == 'a', env['A'] + + opts.AddVariables( + (('ADDEDLATER', 'ADDEDLATERALIAS'), + 'An option not present initially', + "1"), + ) + + args['ADDEDLATERALIAS'] = 'added' + + opts.Update(env, args) + + r = opts.UnknownVariables() + assert len(r) == 0, r + assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] + + +if __name__ == "__main__": + suite = unittest.TestSuite() + tclasses = [ VariablesTestCase, + UnknownVariablesTestCase ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(map(tclass, names)) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |