From 2eb66e95804bc903009f186288d9538236141d55 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:34:39 -0400 Subject: Add additional tests. Remove trailing whitespace. --- SCons/Tool/MSCommon/MSVC/ConfigTests.py | 62 ++++++++++ SCons/Tool/MSCommon/MSVC/DispatcherTests.py | 126 +++++++++++++++++++++ SCons/Tool/MSCommon/MSVC/PolicyTests.py | 168 ++++++++++++++++++++++++++++ SCons/Tool/MSCommon/__init__.py | 4 +- SCons/Tool/MSCommon/vcTests.py | 2 +- test/MSVC/MSVC_NOTFOUND_POLICY.py | 28 ----- test/MSVC/MSVC_SCRIPTERROR_POLICY.py | 28 ----- test/MSVC/msvc_cache_force_defaults.py | 2 +- 8 files changed, 360 insertions(+), 60 deletions(-) create mode 100644 SCons/Tool/MSCommon/MSVC/ConfigTests.py create mode 100644 SCons/Tool/MSCommon/MSVC/DispatcherTests.py create mode 100644 SCons/Tool/MSCommon/MSVC/PolicyTests.py diff --git a/SCons/Tool/MSCommon/MSVC/ConfigTests.py b/SCons/Tool/MSCommon/MSVC/ConfigTests.py new file mode 100644 index 0000000..570861c --- /dev/null +++ b/SCons/Tool/MSCommon/MSVC/ConfigTests.py @@ -0,0 +1,62 @@ +# MIT License +# +# Copyright 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. + +""" +Test constants and initialized data structures for Microsoft Visual C/C++. +""" + +import unittest + +from SCons.Tool.MSCommon import vc +from SCons.Tool.MSCommon.MSVC import Config +from SCons.Tool.MSCommon.MSVC.Exceptions import MSVCInternalError + +_VCVER = vc._VCVER +_MSVC_VERSION_INTERNAL = Config.MSVC_VERSION_INTERNAL + +class ConfigTests(unittest.TestCase): + + def test_vcver(self): + # all vc._VCVER in Config.MSVC_VERSION_SUFFIX + _ADD_VCVER = list(_VCVER) + _ADD_VCVER.append('99.9') + vc._VCVER = _ADD_VCVER + with self.assertRaises(MSVCInternalError): + Config.verify() + vc._VCVER = _VCVER + + def test_msvc_version_internal(self): + # all vc._VCVER numstr in Config.MSVC_VERSION_INTERNAL + _DEL_MSVC_VERSION_INTERNAL = dict(_MSVC_VERSION_INTERNAL) + del _DEL_MSVC_VERSION_INTERNAL['14.3'] + Config.MSVC_VERSION_INTERNAL = _DEL_MSVC_VERSION_INTERNAL + with self.assertRaises(MSVCInternalError): + Config.verify() + Config.MSVC_VERSION_INTERNAL = _MSVC_VERSION_INTERNAL + + def test_verify(self): + Config.verify() + +if __name__ == "__main__": + unittest.main() + diff --git a/SCons/Tool/MSCommon/MSVC/DispatcherTests.py b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py new file mode 100644 index 0000000..01379fc --- /dev/null +++ b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py @@ -0,0 +1,126 @@ +# MIT License +# +# Copyright 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. + +""" +Test internal method dispatcher for Microsoft Visual C/C++. +""" + +import unittest + +from SCons.Tool.MSCommon import MSVC +MSVC.Dispatcher.register_modulename(__name__) + +# current module - not callable +_reset = None +reset = None +_verify = None +verify = None + +reset_count = 0 +verify_count = 0 + +class StaticMethods: + + @staticmethod + def _reset(): + global reset_count + reset_count += 1 + + @staticmethod + def reset(): + global reset_count + reset_count += 1 + + @staticmethod + def _verify(): + global verify_count + verify_count += 1 + + @staticmethod + def verify(): + global verify_count + verify_count += 1 + +class ClassMethods: + + @classmethod + def _reset(cls): + global reset_count + reset_count += 1 + + @classmethod + def reset(cls): + global reset_count + reset_count += 1 + + @classmethod + def _verify(cls): + global verify_count + verify_count += 1 + + @classmethod + def verify(cls): + global verify_count + verify_count += 1 + +class NotCallable: + + _reset = None + reset = None + + _verify = None + _verify = None + +MSVC.Dispatcher.register_class(StaticMethods) +MSVC.Dispatcher.register_class(ClassMethods) +MSVC.Dispatcher.register_class(NotCallable) + +class DispatcherTests(unittest.TestCase): + + def test_dispatcher_reset(self): + global reset_count + MSVC.Dispatcher.reset() + self.assertTrue(reset_count == 4, "MSVC.Dispatcher.reset() count failed") + reset_count = 0 + + def test_dispatcher_verify(self): + global verify_count + MSVC.Dispatcher.verify() + self.assertTrue(verify_count == 4, "MSVC.Dispatcher.verify() count failed") + verify_count = 0 + + def test_msvc_reset(self): + global reset_count + MSVC._reset() + self.assertTrue(reset_count == 4, "MSVC._reset() count failed") + reset_count = 0 + + def test_msvc_verify(self): + global verify_count + MSVC._verify() + self.assertTrue(verify_count == 4, "MSVC._verify() count failed") + verify_count = 0 + +if __name__ == "__main__": + unittest.main() + diff --git a/SCons/Tool/MSCommon/MSVC/PolicyTests.py b/SCons/Tool/MSCommon/MSVC/PolicyTests.py new file mode 100644 index 0000000..5126a6b --- /dev/null +++ b/SCons/Tool/MSCommon/MSVC/PolicyTests.py @@ -0,0 +1,168 @@ +# MIT License +# +# Copyright 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. + +""" +Test Microsoft Visual C/C++ policy handlers. +""" + +import unittest + +import SCons.Warnings + +from SCons.Tool.MSCommon.MSVC import Policy + +from SCons.Tool.MSCommon.MSVC.Exceptions import ( + MSVCArgumentError, + MSVCVersionNotFound, + MSVCScriptExecutionError, +) + +from SCons.Tool.MSCommon.MSVC.Warnings import ( + MSVCScriptExecutionWarning, +) + +class PolicyTests(unittest.TestCase): + + _prev_warnstate = None + _enabled = None + _warningAsException = None + + def push_warning_as_exception(self, Warning): + self._enabled = SCons.Warnings._enabled + self._warningAsException = SCons.Warnings._warningAsException + SCons.Warnings._enabled = [] + SCons.Warnings._warningAsException = 0 + SCons.Warnings.enableWarningClass(Warning) + self._prev_warnstate = SCons.Warnings.warningAsException() + + def pop_warning_as_exception(self): + _ = SCons.Warnings.warningAsException(self._prev_warnstate) + SCons.Warnings._enabled = self._enabled + SCons.Warnings._warningAsException = self._warningAsException + self._prev_warnstate = None + self._ebabled = None + self._warningAsException = None + + # msvc_set_notfound_policy, msvc_get_notfound_policy, and MSVC_NOTFOUND_POLICY + + def test_notfound_func_valid_symbols(self): + def_policy = Policy.msvc_get_notfound_policy() + last_policy = def_policy + for notfound_def in Policy.MSVC_NOTFOUND_DEFINITION_LIST: + for symbol in [notfound_def.symbol, notfound_def.symbol.lower(), notfound_def.symbol.upper()]: + prev_policy = Policy.msvc_set_notfound_policy(symbol) + self.assertTrue(prev_policy == last_policy, "prev_policy != last_policy") + cur_set_policy = Policy.msvc_set_notfound_policy() + cur_get_policy = Policy.msvc_get_notfound_policy() + self.assertTrue(cur_set_policy == cur_get_policy, "cur_set_policy != cur_get_policy") + last_policy = cur_get_policy + Policy.msvc_set_notfound_policy(def_policy) + + def test_notfound_func_invalid_symbol(self): + with self.assertRaises(MSVCArgumentError): + Policy.msvc_set_notfound_policy('Undefined') + + def test_notfound_handler_invalid_symbol(self): + with self.assertRaises(MSVCArgumentError): + Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': 'Undefined'}, '') + + def test_notfound_handler_ignore(self): + def_policy = Policy.msvc_set_notfound_policy('Ignore') + Policy.msvc_notfound_handler(None, '') + Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': None}, '') + Policy.msvc_set_notfound_policy(def_policy) + + def test_notfound_handler_warning(self): + # treat warning as exception for testing + self.push_warning_as_exception(SCons.Warnings.VisualCMissingWarning) + def_policy = Policy.msvc_set_notfound_policy('Warning') + with self.assertRaises(SCons.Warnings.VisualCMissingWarning): + Policy.msvc_notfound_handler(None, '') + Policy.msvc_set_notfound_policy('Ignore') + with self.assertRaises(SCons.Warnings.VisualCMissingWarning): + Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': 'Warning'}, '') + Policy.msvc_set_notfound_policy(def_policy) + self.pop_warning_as_exception() + + def test_notfound_handler_error(self): + def_policy = Policy.msvc_set_notfound_policy('Error') + with self.assertRaises(MSVCVersionNotFound): + Policy.msvc_notfound_handler(None, '') + Policy.msvc_set_notfound_policy('Ignore') + with self.assertRaises(MSVCVersionNotFound): + Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': 'Error'}, '') + Policy.msvc_set_notfound_policy(def_policy) + + # msvc_set_scripterror_policy, msvc_get_scripterror_policy, and MSVC_SCRIPTERROR_POLICY + + def test_scripterror_func_valid_symbols(self): + def_policy = Policy.msvc_get_scripterror_policy() + last_policy = def_policy + for scripterror_def in Policy.MSVC_SCRIPTERROR_DEFINITION_LIST: + for symbol in [scripterror_def.symbol, scripterror_def.symbol.lower(), scripterror_def.symbol.upper()]: + prev_policy = Policy.msvc_set_scripterror_policy(symbol) + self.assertTrue(prev_policy == last_policy, "prev_policy != last_policy") + cur_set_policy = Policy.msvc_set_scripterror_policy() + cur_get_policy = Policy.msvc_get_scripterror_policy() + self.assertTrue(cur_set_policy == cur_get_policy, "cur_set_policy != cur_get_policy") + last_policy = cur_get_policy + Policy.msvc_set_scripterror_policy(def_policy) + + def test_scripterror_func_invalid_symbol(self): + with self.assertRaises(MSVCArgumentError): + Policy.msvc_set_scripterror_policy('Undefined') + + def test_scripterror_handler_invalid_symbol(self): + with self.assertRaises(MSVCArgumentError): + Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': 'Undefined'}, '') + + def test_scripterror_handler_ignore(self): + def_policy = Policy.msvc_set_scripterror_policy('Ignore') + Policy.msvc_scripterror_handler(None, '') + Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': None}, '') + Policy.msvc_set_scripterror_policy(def_policy) + + def test_scripterror_handler_warning(self): + # treat warning as exception for testing + self.push_warning_as_exception(MSVCScriptExecutionWarning) + def_policy = Policy.msvc_set_scripterror_policy('Warning') + with self.assertRaises(MSVCScriptExecutionWarning): + Policy.msvc_scripterror_handler(None, '') + Policy.msvc_set_scripterror_policy('Ignore') + with self.assertRaises(MSVCScriptExecutionWarning): + Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': 'Warning'}, '') + Policy.msvc_set_scripterror_policy(def_policy) + self.pop_warning_as_exception() + + def test_scripterror_handler_error(self): + def_policy = Policy.msvc_set_scripterror_policy('Error') + with self.assertRaises(MSVCScriptExecutionError): + Policy.msvc_scripterror_handler(None, '') + Policy.msvc_set_scripterror_policy('Ignore') + with self.assertRaises(MSVCScriptExecutionError): + Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': 'Error'}, '') + Policy.msvc_set_scripterror_policy(def_policy) + +if __name__ == "__main__": + unittest.main() + diff --git a/SCons/Tool/MSCommon/__init__.py b/SCons/Tool/MSCommon/__init__.py index 9d2e14a..ee443d9 100644 --- a/SCons/Tool/MSCommon/__init__.py +++ b/SCons/Tool/MSCommon/__init__.py @@ -31,7 +31,7 @@ import SCons.Platform.win32 import SCons.Util # noqa: F401 from SCons.Tool.MSCommon.sdk import ( # noqa: F401 - mssdk_exists, + mssdk_exists, mssdk_setup_env, ) @@ -83,7 +83,7 @@ from .vc import ( # noqa: F401 from .MSVC.Util import ( # noqa: F401 msvc_version_components, msvc_extended_version_components, -) +) # Local Variables: # tab-width:4 diff --git a/SCons/Tool/MSCommon/vcTests.py b/SCons/Tool/MSCommon/vcTests.py index 9a4d1a5..dd2ba03 100644 --- a/SCons/Tool/MSCommon/vcTests.py +++ b/SCons/Tool/MSCommon/vcTests.py @@ -80,7 +80,7 @@ class MSVcTestCase(unittest.TestCase): @staticmethod def _createDummyCl(path, add_bin=True): """ - Creates a dummy cl.exe in the correct directory. + Creates a dummy cl.exe in the correct directory. It will create all missing parent directories as well Args: diff --git a/test/MSVC/MSVC_NOTFOUND_POLICY.py b/test/MSVC/MSVC_NOTFOUND_POLICY.py index d123c02..f5a8de2 100644 --- a/test/MSVC/MSVC_NOTFOUND_POLICY.py +++ b/test/MSVC/MSVC_NOTFOUND_POLICY.py @@ -33,34 +33,6 @@ test.skip_if_not_msvc() import textwrap -# Test global functions with valid symbols -test.write('SConstruct', textwrap.dedent( - """ - from SCons.Tool.MSCommon import msvc_set_notfound_policy - from SCons.Tool.MSCommon import msvc_get_notfound_policy - DefaultEnvironment(tools=[]) - for symbol in ['Error', 'Exception', 'Warn', 'Warning', 'Ignore', 'Suppress']: - for policy in [symbol, symbol.upper(), symbol.lower()]: - old_policy = msvc_set_notfound_policy(policy) - cur_policy = msvc_get_notfound_policy() - if msvc_set_notfound_policy(None) != msvc_get_notfound_policy(): - raise RuntimeError() - """ -)) -test.run(arguments='-Q -s', stdout='') - -# Test global function with invalid symbol -test.write('SConstruct', textwrap.dedent( - """ - from SCons.Tool.MSCommon import msvc_set_notfound_policy - DefaultEnvironment(tools=[]) - msvc_set_notfound_policy('Undefined') - """ -)) -test.run(arguments='-Q -s', status=2, stderr=None) -expect = "MSVCArgumentError: Value specified for MSVC_NOTFOUND_POLICY is not supported: 'Undefined'." -test.must_contain_all(test.stderr(), expect) - # Test construction variable with valid symbols test.write('SConstruct', textwrap.dedent( """ diff --git a/test/MSVC/MSVC_SCRIPTERROR_POLICY.py b/test/MSVC/MSVC_SCRIPTERROR_POLICY.py index 4d23595..9dcfb53 100644 --- a/test/MSVC/MSVC_SCRIPTERROR_POLICY.py +++ b/test/MSVC/MSVC_SCRIPTERROR_POLICY.py @@ -39,34 +39,6 @@ installed_versions = get_installed_vcs_components() default_version = installed_versions[0] -# Test global functions with valid symbols -test.write('SConstruct', textwrap.dedent( - """ - from SCons.Tool.MSCommon import msvc_set_scripterror_policy - from SCons.Tool.MSCommon import msvc_get_scripterror_policy - DefaultEnvironment(tools=[]) - for symbol in ['Error', 'Exception', 'Warn', 'Warning', 'Ignore', 'Suppress']: - for policy in [symbol, symbol.upper(), symbol.lower()]: - old_policy = msvc_set_scripterror_policy(policy) - cur_policy = msvc_get_scripterror_policy() - if msvc_set_scripterror_policy(None) != msvc_get_scripterror_policy(): - raise RuntimeError() - """ -)) -test.run(arguments='-Q -s', stdout='') - -# Test global function with invalid symbol -test.write('SConstruct', textwrap.dedent( - """ - from SCons.Tool.MSCommon import msvc_set_scripterror_policy - DefaultEnvironment(tools=[]) - msvc_set_scripterror_policy('Undefined') - """ -)) -test.run(arguments='-Q -s', status=2, stderr=None) -expect = "MSVCArgumentError: Value specified for MSVC_SCRIPTERROR_POLICY is not supported: 'Undefined'." -test.must_contain_all(test.stderr(), expect) - # Test construction variable with valid symbols test.write('SConstruct', textwrap.dedent( """ diff --git a/test/MSVC/msvc_cache_force_defaults.py b/test/MSVC/msvc_cache_force_defaults.py index a964405..7aee850 100644 --- a/test/MSVC/msvc_cache_force_defaults.py +++ b/test/MSVC/msvc_cache_force_defaults.py @@ -56,7 +56,7 @@ if default_version.msvc_vernum >= 14.0: DefaultEnvironment(tools=[]) env = Environment(tools=['msvc']) - envcache_keys = [] + envcache_keys = [] with open(cache_file, 'r') as file: envcache_list = json.load(file) envcache_keys = [tuple(d['key']) for d in envcache_list] -- cgit v0.12