#!/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()
