#!/usr/bin/env python

# Copyright (c) 2009, 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.

"""Unit tests for the XML-format help generated by the gflags.py module."""

__author__ = 'salcianu@google.com (Alex Salcianu)'


import string
import StringIO
import sys
import xml.dom.minidom
import xml.sax.saxutils
import gflags_googletest as googletest
import gflags
from flags_modules_for_testing import module_bar


class _MakeXMLSafeTest(googletest.TestCase):

  def _Check(self, s, expected_output):
    self.assertEqual(gflags._MakeXMLSafe(s), expected_output)

  def testMakeXMLSafe(self):
    self._Check('plain text', 'plain text')
    self._Check('(x < y) && (a >= b)',
                '(x &lt; y) &amp;&amp; (a &gt;= b)')
    # Some characters with ASCII code < 32 are illegal in XML 1.0 and
    # are removed by us.  However, '\n', '\t', and '\r' are legal.
    self._Check('\x09\x0btext \x02 with\x0dsome \x08 good & bad chars',
                '\ttext  with\rsome  good &amp; bad chars')


def _ListSeparatorsInXMLFormat(separators, indent=''):
  """Generates XML encoding of a list of list separators.

  Args:
    separators: A list of list separators.  Usually, this should be a
      string whose characters are the valid list separators, e.g., ','
      means that both comma (',') and space (' ') are valid list
      separators.
    indent: A string that is added at the beginning of each generated
      XML element.

  Returns:
    A string.
  """
  result = ''
  separators = list(separators)
  separators.sort()
  for sep_char in separators:
    result += ('%s<list_separator>%s</list_separator>\n' %
               (indent, repr(sep_char)))
  return result


class WriteFlagHelpInXMLFormatTest(googletest.TestCase):
  """Test the XML-format help for a single flag at a time.

  There is one test* method for each kind of DEFINE_* declaration.
  """

  def setUp(self):
    # self.fv is a FlagValues object, just like gflags.FLAGS.  Each
    # test registers one flag with this FlagValues.
    self.fv = gflags.FlagValues()

  def _CheckFlagHelpInXML(self, flag_name, module_name,
                          expected_output, is_key=False):
    # StringIO.StringIO is a file object that writes into a memory string.
    sio = StringIO.StringIO()
    flag_obj = self.fv[flag_name]
    flag_obj.WriteInfoInXMLFormat(sio, module_name, is_key=is_key, indent=' ')
    self.assertMultiLineEqual(sio.getvalue(), expected_output)
    sio.close()

  def testFlagHelpInXML_Int(self):
    gflags.DEFINE_integer('index', 17, 'An integer flag', flag_values=self.fv)
    expected_output_pattern = (
        ' <flag>\n'
        '   <file>module.name</file>\n'
        '   <name>index</name>\n'
        '   <meaning>An integer flag</meaning>\n'
        '   <default>17</default>\n'
        '   <current>%d</current>\n'
        '   <type>int</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('index', 'module.name',
                             expected_output_pattern % 17)
    # Check that the output is correct even when the current value of
    # a flag is different from the default one.
    self.fv['index'].value = 20
    self._CheckFlagHelpInXML('index', 'module.name',
                             expected_output_pattern % 20)

  def testFlagHelpInXML_IntWithBounds(self):
    gflags.DEFINE_integer('nb_iters', 17, 'An integer flag',
                         lower_bound=5, upper_bound=27,
                         flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <key>yes</key>\n'
        '   <file>module.name</file>\n'
        '   <name>nb_iters</name>\n'
        '   <meaning>An integer flag</meaning>\n'
        '   <default>17</default>\n'
        '   <current>17</current>\n'
        '   <type>int</type>\n'
        '   <lower_bound>5</lower_bound>\n'
        '   <upper_bound>27</upper_bound>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('nb_iters', 'module.name',
                             expected_output, is_key=True)

  def testFlagHelpInXML_String(self):
    gflags.DEFINE_string('file_path', '/path/to/my/dir', 'A test string flag.',
                        flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>simple_module</file>\n'
        '   <name>file_path</name>\n'
        '   <meaning>A test string flag.</meaning>\n'
        '   <default>/path/to/my/dir</default>\n'
        '   <current>/path/to/my/dir</current>\n'
        '   <type>string</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('file_path', 'simple_module',
                             expected_output)

  def testFlagHelpInXML_StringWithXMLIllegalChars(self):
    gflags.DEFINE_string('file_path', '/path/to/\x08my/dir',
                        'A test string flag.', flag_values=self.fv)
    # '\x08' is not a legal character in XML 1.0 documents.  Our
    # current code purges such characters from the generated XML.
    expected_output = (
        ' <flag>\n'
        '   <file>simple_module</file>\n'
        '   <name>file_path</name>\n'
        '   <meaning>A test string flag.</meaning>\n'
        '   <default>/path/to/my/dir</default>\n'
        '   <current>/path/to/my/dir</current>\n'
        '   <type>string</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('file_path', 'simple_module',
                             expected_output)

  def testFlagHelpInXML_Boolean(self):
    gflags.DEFINE_boolean('use_hack', False, 'Use performance hack',
                         flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <key>yes</key>\n'
        '   <file>a_module</file>\n'
        '   <name>use_hack</name>\n'
        '   <meaning>Use performance hack</meaning>\n'
        '   <default>false</default>\n'
        '   <current>false</current>\n'
        '   <type>bool</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('use_hack', 'a_module',
                             expected_output, is_key=True)

  def testFlagHelpInXML_Enum(self):
    gflags.DEFINE_enum('cc_version', 'stable', ['stable', 'experimental'],
                      'Compiler version to use.', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>cc_version</name>\n'
        '   <meaning>&lt;stable|experimental&gt;: '
        'Compiler version to use.</meaning>\n'
        '   <default>stable</default>\n'
        '   <current>stable</current>\n'
        '   <type>string enum</type>\n'
        '   <enum_value>stable</enum_value>\n'
        '   <enum_value>experimental</enum_value>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('cc_version', 'tool', expected_output)

  def testFlagHelpInXML_CommaSeparatedList(self):
    gflags.DEFINE_list('files', 'a.cc,a.h,archive/old.zip',
                      'Files to process.', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>files</name>\n'
        '   <meaning>Files to process.</meaning>\n'
        '   <default>a.cc,a.h,archive/old.zip</default>\n'
        '   <current>[\'a.cc\', \'a.h\', \'archive/old.zip\']</current>\n'
        '   <type>comma separated list of strings</type>\n'
        '   <list_separator>\',\'</list_separator>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('files', 'tool', expected_output)

  def testListAsDefaultArgument_CommaSeparatedList(self):
    gflags.DEFINE_list('allow_users', ['alice', 'bob'],
                      'Users with access.', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>allow_users</name>\n'
        '   <meaning>Users with access.</meaning>\n'
        '   <default>alice,bob</default>\n'
        '   <current>[\'alice\', \'bob\']</current>\n'
        '   <type>comma separated list of strings</type>\n'
        '   <list_separator>\',\'</list_separator>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('allow_users', 'tool', expected_output)

  def testFlagHelpInXML_SpaceSeparatedList(self):
    gflags.DEFINE_spaceseplist('dirs', 'src libs bin',
                              'Directories to search.', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>dirs</name>\n'
        '   <meaning>Directories to search.</meaning>\n'
        '   <default>src libs bin</default>\n'
        '   <current>[\'src\', \'libs\', \'bin\']</current>\n'
        '   <type>whitespace separated list of strings</type>\n'
        'LIST_SEPARATORS'
        ' </flag>\n').replace('LIST_SEPARATORS',
                              _ListSeparatorsInXMLFormat(string.whitespace,
                                                         indent='   '))
    self._CheckFlagHelpInXML('dirs', 'tool', expected_output)

  def testFlagHelpInXML_MultiString(self):
    gflags.DEFINE_multistring('to_delete', ['a.cc', 'b.h'],
                             'Files to delete', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>to_delete</name>\n'
        '   <meaning>Files to delete;\n    '
        'repeat this option to specify a list of values</meaning>\n'
        '   <default>[\'a.cc\', \'b.h\']</default>\n'
        '   <current>[\'a.cc\', \'b.h\']</current>\n'
        '   <type>multi string</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('to_delete', 'tool', expected_output)

  def testFlagHelpInXML_MultiInt(self):
    gflags.DEFINE_multi_int('cols', [5, 7, 23],
                           'Columns to select', flag_values=self.fv)
    expected_output = (
        ' <flag>\n'
        '   <file>tool</file>\n'
        '   <name>cols</name>\n'
        '   <meaning>Columns to select;\n    '
        'repeat this option to specify a list of values</meaning>\n'
        '   <default>[5, 7, 23]</default>\n'
        '   <current>[5, 7, 23]</current>\n'
        '   <type>multi int</type>\n'
        ' </flag>\n')
    self._CheckFlagHelpInXML('cols', 'tool', expected_output)


# The next EXPECTED_HELP_XML_* constants are parts of a template for
# the expected XML output from WriteHelpInXMLFormatTest below.  When
# we assemble these parts into a single big string, we'll take into
# account the ordering between the name of the main module and the
# name of module_bar.  Next, we'll fill in the docstring for this
# module (%(usage_doc)s), the name of the main module
# (%(main_module_name)s) and the name of the module module_bar
# (%(module_bar_name)s).  See WriteHelpInXMLFormatTest below.
#
# NOTE: given the current implementation of _GetMainModule(), we
# already know the ordering between the main module and module_bar.
# However, there is no guarantee that _GetMainModule will never be
# changed in the future (especially since it's far from perfect).
EXPECTED_HELP_XML_START = """\
<?xml version="1.0"?>
<AllFlags>
  <program>gflags_helpxml_test.py</program>
  <usage>%(usage_doc)s</usage>
"""

EXPECTED_HELP_XML_FOR_FLAGS_FROM_MAIN_MODULE = """\
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>allow_users</name>
    <meaning>Users with access.</meaning>
    <default>alice,bob</default>
    <current>['alice', 'bob']</current>
    <type>comma separated list of strings</type>
    <list_separator>','</list_separator>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>cc_version</name>
    <meaning>&lt;stable|experimental&gt;: Compiler version to use.</meaning>
    <default>stable</default>
    <current>stable</current>
    <type>string enum</type>
    <enum_value>stable</enum_value>
    <enum_value>experimental</enum_value>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>cols</name>
    <meaning>Columns to select;
    repeat this option to specify a list of values</meaning>
    <default>[5, 7, 23]</default>
    <current>[5, 7, 23]</current>
    <type>multi int</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>dirs</name>
    <meaning>Directories to create.</meaning>
    <default>src libs bins</default>
    <current>['src', 'libs', 'bins']</current>
    <type>whitespace separated list of strings</type>
%(whitespace_separators)s  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>file_path</name>
    <meaning>A test string flag.</meaning>
    <default>/path/to/my/dir</default>
    <current>/path/to/my/dir</current>
    <type>string</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>files</name>
    <meaning>Files to process.</meaning>
    <default>a.cc,a.h,archive/old.zip</default>
    <current>['a.cc', 'a.h', 'archive/old.zip']</current>
    <type>comma separated list of strings</type>
    <list_separator>\',\'</list_separator>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>index</name>
    <meaning>An integer flag</meaning>
    <default>17</default>
    <current>17</current>
    <type>int</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>nb_iters</name>
    <meaning>An integer flag</meaning>
    <default>17</default>
    <current>17</current>
    <type>int</type>
    <lower_bound>5</lower_bound>
    <upper_bound>27</upper_bound>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>to_delete</name>
    <meaning>Files to delete;
    repeat this option to specify a list of values</meaning>
    <default>['a.cc', 'b.h']</default>
    <current>['a.cc', 'b.h']</current>
    <type>multi string</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(main_module_name)s</file>
    <name>use_hack</name>
    <meaning>Use performance hack</meaning>
    <default>false</default>
    <current>false</current>
    <type>bool</type>
  </flag>
"""

EXPECTED_HELP_XML_FOR_FLAGS_FROM_MODULE_BAR = """\
  <flag>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_t</name>
    <meaning>Sample int flag.</meaning>
    <default>4</default>
    <current>4</current>
    <type>int</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_u</name>
    <meaning>Sample int flag.</meaning>
    <default>5</default>
    <current>5</current>
    <type>int</type>
  </flag>
  <flag>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_v</name>
    <meaning>Sample int flag.</meaning>
    <default>6</default>
    <current>6</current>
    <type>int</type>
  </flag>
  <flag>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_x</name>
    <meaning>Boolean flag.</meaning>
    <default>true</default>
    <current>true</current>
    <type>bool</type>
  </flag>
  <flag>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_y</name>
    <meaning>String flag.</meaning>
    <default>default</default>
    <current>default</current>
    <type>string</type>
  </flag>
  <flag>
    <key>yes</key>
    <file>%(module_bar_name)s</file>
    <name>tmod_bar_z</name>
    <meaning>Another boolean flag from module bar.</meaning>
    <default>false</default>
    <current>false</current>
    <type>bool</type>
  </flag>
"""

EXPECTED_HELP_XML_END = """\
</AllFlags>
"""


class WriteHelpInXMLFormatTest(googletest.TestCase):
  """Big test of FlagValues.WriteHelpInXMLFormat, with several flags."""

  def testWriteHelpInXMLFormat(self):
    fv = gflags.FlagValues()
    # Since these flags are defined by the top module, they are all key.
    gflags.DEFINE_integer('index', 17, 'An integer flag', flag_values=fv)
    gflags.DEFINE_integer('nb_iters', 17, 'An integer flag',
                         lower_bound=5, upper_bound=27, flag_values=fv)
    gflags.DEFINE_string('file_path', '/path/to/my/dir', 'A test string flag.',
                        flag_values=fv)
    gflags.DEFINE_boolean('use_hack', False, 'Use performance hack',
                         flag_values=fv)
    gflags.DEFINE_enum('cc_version', 'stable', ['stable', 'experimental'],
                      'Compiler version to use.', flag_values=fv)
    gflags.DEFINE_list('files', 'a.cc,a.h,archive/old.zip',
                      'Files to process.', flag_values=fv)
    gflags.DEFINE_list('allow_users', ['alice', 'bob'],
                      'Users with access.', flag_values=fv)
    gflags.DEFINE_spaceseplist('dirs', 'src libs bins',
                              'Directories to create.', flag_values=fv)
    gflags.DEFINE_multistring('to_delete', ['a.cc', 'b.h'],
                             'Files to delete', flag_values=fv)
    gflags.DEFINE_multi_int('cols', [5, 7, 23],
                           'Columns to select', flag_values=fv)
    # Define a few flags in a different module.
    module_bar.DefineFlags(flag_values=fv)
    # And declare only a few of them to be key.  This way, we have
    # different kinds of flags, defined in different modules, and not
    # all of them are key flags.
    gflags.DECLARE_key_flag('tmod_bar_z', flag_values=fv)
    gflags.DECLARE_key_flag('tmod_bar_u', flag_values=fv)

    # Generate flag help in XML format in the StringIO sio.
    sio = StringIO.StringIO()
    fv.WriteHelpInXMLFormat(sio)

    # Check that we got the expected result.
    expected_output_template = EXPECTED_HELP_XML_START
    main_module_name = gflags._GetMainModule()
    module_bar_name = module_bar.__name__

    if main_module_name < module_bar_name:
      expected_output_template += EXPECTED_HELP_XML_FOR_FLAGS_FROM_MAIN_MODULE
      expected_output_template += EXPECTED_HELP_XML_FOR_FLAGS_FROM_MODULE_BAR
    else:
      expected_output_template += EXPECTED_HELP_XML_FOR_FLAGS_FROM_MODULE_BAR
      expected_output_template += EXPECTED_HELP_XML_FOR_FLAGS_FROM_MAIN_MODULE

    expected_output_template += EXPECTED_HELP_XML_END

    # XML representation of the whitespace list separators.
    whitespace_separators = _ListSeparatorsInXMLFormat(string.whitespace,
                                                       indent='    ')
    expected_output = (
        expected_output_template %
        {'usage_doc': sys.modules['__main__'].__doc__,
         'main_module_name': main_module_name,
         'module_bar_name': module_bar_name,
         'whitespace_separators': whitespace_separators})

    actual_output = sio.getvalue()
    self.assertMultiLineEqual(actual_output, expected_output)

    # Also check that our result is valid XML.  minidom.parseString
    # throws an xml.parsers.expat.ExpatError in case of an error.
    xml.dom.minidom.parseString(actual_output)


if __name__ == '__main__':
  googletest.main()
