blob: 0f2870a1138dc4e1451baffbbf84b4ad75d645db [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unittest for helpers module."""
import sys
import unittest
from gflags import _helpers
from gflags.flags_modules_for_testing import module_bar
from gflags.flags_modules_for_testing import module_foo
class FlagSuggestionTest(unittest.TestCase):
def setUp(self):
self.longopts = [
'fsplit-ivs-in-unroller=',
'fsplit-wide-types=',
'fstack-protector=',
'fstack-protector-all=',
'fstrict-aliasing=',
'fstrict-overflow=',
'fthread-jumps=',
'ftracer',
'ftree-bit-ccp',
'ftree-builtin-call-dce',
'ftree-ccp',
'ftree-ch']
def testDamerauLevenshteinId(self):
self.assertEqual(0, _helpers._DamerauLevenshtein('asdf', 'asdf'))
def testDamerauLevenshteinEmpty(self):
self.assertEqual(5, _helpers._DamerauLevenshtein('', 'kites'))
self.assertEqual(6, _helpers._DamerauLevenshtein('kitten', ''))
def testDamerauLevenshteinCommutative(self):
self.assertEqual(2, _helpers._DamerauLevenshtein('kitten', 'kites'))
self.assertEqual(2, _helpers._DamerauLevenshtein('kites', 'kitten'))
def testDamerauLevenshteinTransposition(self):
self.assertEqual(1, _helpers._DamerauLevenshtein('kitten', 'ktiten'))
def testMispelledSuggestions(self):
suggestions = _helpers.GetFlagSuggestions('fstack_protector_all',
self.longopts)
self.assertEqual(['fstack-protector-all'], suggestions)
def testAmbiguousPrefixSuggestion(self):
suggestions = _helpers.GetFlagSuggestions('fstack', self.longopts)
self.assertEqual(['fstack-protector', 'fstack-protector-all'], suggestions)
def testMisspelledAmbiguousPrefixSuggestion(self):
suggestions = _helpers.GetFlagSuggestions('stack', self.longopts)
self.assertEqual(['fstack-protector', 'fstack-protector-all'], suggestions)
def testCrazySuggestion(self):
suggestions = _helpers.GetFlagSuggestions('asdfasdgasdfa', self.longopts)
self.assertEqual([], suggestions)
class GetCallingModuleTest(unittest.TestCase):
"""Test whether we correctly determine the module which defines the flag."""
def testGetCallingModule(self):
self.assertEqual(_helpers.GetCallingModule(), sys.argv[0])
self.assertEqual(
module_foo.GetModuleName(),
'gflags.flags_modules_for_testing.module_foo')
self.assertEqual(
module_bar.GetModuleName(),
'gflags.flags_modules_for_testing.module_bar')
# We execute the following exec statements for their side-effect
# (i.e., not raising an error). They emphasize the case that not
# all code resides in one of the imported modules: Python is a
# really dynamic language, where we can dynamically construct some
# code and execute it.
code = ('from gflags import _helpers\n'
'module_name = _helpers.GetCallingModule()')
exec(code) # pylint: disable=exec-used
# Next two exec statements executes code with a global environment
# that is different from the global environment of any imported
# module.
exec(code, {}) # pylint: disable=exec-used
# vars(self) returns a dictionary corresponding to the symbol
# table of the self object. dict(...) makes a distinct copy of
# this dictionary, such that any new symbol definition by the
# exec-ed code (e.g., import flags, module_name = ...) does not
# affect the symbol table of self.
exec(code, dict(vars(self))) # pylint: disable=exec-used
# Next test is actually more involved: it checks not only that
# GetCallingModule does not crash inside exec code, it also checks
# that it returns the expected value: the code executed via exec
# code is treated as being executed by the current module. We
# check it twice: first time by executing exec from the main
# module, second time by executing it from module_bar.
global_dict = {}
exec(code, global_dict) # pylint: disable=exec-used
self.assertEqual(global_dict['module_name'],
sys.argv[0])
global_dict = {}
module_bar.ExecuteCode(code, global_dict)
self.assertEqual(
global_dict['module_name'],
'gflags.flags_modules_for_testing.module_bar')
def testGetCallingModuleWithIteritemsError(self):
# This test checks that GetCallingModule is using
# sys.modules.items(), instead of .iteritems().
orig_sys_modules = sys.modules
# Mock sys.modules: simulates error produced by importing a module
# in paralel with our iteration over sys.modules.iteritems().
class SysModulesMock(dict):
def __init__(self, original_content):
dict.__init__(self, original_content)
def iteritems(self):
# Any dictionary method is fine, but not .iteritems().
raise RuntimeError('dictionary changed size during iteration')
sys.modules = SysModulesMock(orig_sys_modules)
try:
# _GetCallingModule should still work as expected:
self.assertEqual(_helpers.GetCallingModule(), sys.argv[0])
self.assertEqual(
module_foo.GetModuleName(),
'gflags.flags_modules_for_testing.module_foo')
finally:
sys.modules = orig_sys_modules
class IsRunningTestTest(unittest.TestCase):
def testUnderTest(self):
self.assertTrue(_helpers.IsRunningTest())
def main():
unittest.main()
if __name__ == '__main__':
main()