# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 parser.py."""

import unittest

from webkitpy.common.system.log_testing import LoggingTestCase
from webkitpy.style.optparser import ArgumentParser
from webkitpy.style.optparser import ArgumentPrinter
from webkitpy.style.optparser import CommandOptionValues as ProcessorOptions
from webkitpy.style.optparser import DefaultCommandOptionValues


class ArgumentPrinterTest(unittest.TestCase):

    """Tests the ArgumentPrinter class."""

    _printer = ArgumentPrinter()

    def _create_options(self,
                        output_format='emacs',
                        min_confidence=3,
                        filter_rules=None,
                        git_commit=None):
        return ProcessorOptions(filter_rules=filter_rules,
                                git_commit=git_commit,
                                min_confidence=min_confidence,
                                output_format=output_format)

    def test_to_flag_string(self):
        options = self._create_options('vs7', 5, ['+foo', '-bar'], 'git')
        self.assertEqual('--filter=+foo,-bar --git-commit=git '
                         '--min-confidence=5 --output=vs7',
                         self._printer.to_flag_string(options))

        # This is to check that --filter and --git-commit do not
        # show up when not user-specified.
        options = self._create_options()
        self.assertEqual('--min-confidence=3 --output=emacs',
                         self._printer.to_flag_string(options))


class ArgumentParserTest(LoggingTestCase):

    """Test the ArgumentParser class."""

    class _MockStdErr(object):

        def write(self, _):
            # We do not want the usage string or style categories
            # to print during unit tests, so print nothing.
            return

    def _parse(self, args):
        """Call a test parser.parse()."""
        parser = self._create_parser()
        return parser.parse(args)

    def _create_defaults(self):
        """Return a DefaultCommandOptionValues instance for testing."""
        return DefaultCommandOptionValues(min_confidence=3,
                                          output_format='vs7')

    def _create_parser(self):
        """Return an ArgumentParser instance for testing."""
        default_options = self._create_defaults()

        all_categories = ['build', 'whitespace']

        mock_stderr = self._MockStdErr()

        return ArgumentParser(all_categories=all_categories,
                              base_filter_rules=[],
                              default_options=default_options,
                              mock_stderr=mock_stderr,
                              usage='test usage')

    def test_parse_documentation(self):
        parse = self._parse

        # FIXME: Test both the printing of the usage string and the
        #        filter categories help.

        # Request the usage string.
        self.assertRaises(SystemExit, parse, ['--help'])
        # Request default filter rules and available style categories.
        self.assertRaises(SystemExit, parse, ['--filter='])

    def test_parse_bad_values(self):
        parse = self._parse

        # Pass an unsupported argument.
        self.assertRaises(SystemExit, parse, ['--bad'])
        self.assertLog(['ERROR: no such option: --bad\n'])

        self.assertRaises(SystemExit, parse, ['--min-confidence=bad'])
        self.assertLog(['ERROR: option --min-confidence: '
                        "invalid integer value: 'bad'\n"])
        self.assertRaises(SystemExit, parse, ['--min-confidence=0'])
        self.assertLog(['ERROR: option --min-confidence: invalid integer: 0: '
                        'value must be between 1 and 5\n'])
        self.assertRaises(SystemExit, parse, ['--min-confidence=6'])
        self.assertLog(['ERROR: option --min-confidence: invalid integer: 6: '
                        'value must be between 1 and 5\n'])
        parse(['--min-confidence=1'])  # works
        parse(['--min-confidence=5'])  # works

        self.assertRaises(SystemExit, parse, ['--output=bad'])
        self.assertLog(['ERROR: option --output-format: invalid choice: '
                        "'bad' (choose from 'emacs', 'vs7')\n"])
        parse(['--output=vs7'])  # works

        # Pass a filter rule not beginning with + or -.
        self.assertRaises(SystemExit, parse, ['--filter=build'])
        self.assertLog(['ERROR: Invalid filter rule "build": '
                        'every rule must start with + or -.\n'])
        parse(['--filter=+build'])  # works

    def test_parse_default_arguments(self):
        parse = self._parse

        (files, options) = parse([])

        self.assertEqual(files, [])

        self.assertEqual(options.filter_rules, [])
        self.assertIsNone(options.git_commit)
        self.assertFalse(options.diff_files)
        self.assertFalse(options.is_verbose)
        self.assertEqual(options.min_confidence, 3)
        self.assertEqual(options.output_format, 'vs7')

    def test_parse_explicit_arguments(self):
        parse = self._parse

        # Pass non-default explicit values.
        _, options = parse(['--min-confidence=4'])
        self.assertEqual(options.min_confidence, 4)
        _, options = parse(['--output=emacs'])
        self.assertEqual(options.output_format, 'emacs')
        _, options = parse(['-g', 'commit'])
        self.assertEqual(options.git_commit, 'commit')
        _, options = parse(['--git-commit=commit'])
        self.assertEqual(options.git_commit, 'commit')
        _, options = parse(['--git-diff=commit'])
        self.assertEqual(options.git_commit, 'commit')
        _, options = parse(['--verbose'])
        self.assertTrue(options.is_verbose)
        _, options = parse(['--diff-files', 'file.txt'])
        self.assertTrue(options.diff_files)

        # Pass user_rules.
        _, options = parse(['--filter=+build,-whitespace'])
        self.assertEqual(options.filter_rules,
                         ['+build', '-whitespace'])

        # Pass spurious white space in user rules.
        _, options = parse(['--filter=+build, -whitespace'])
        self.assertEqual(options.filter_rules,
                         ['+build', '-whitespace'])

    def test_parse_files(self):
        parse = self._parse

        files, _ = parse(['foo.cpp'])
        self.assertEqual(files, ['foo.cpp'])

        # Pass multiple files.
        files, _ = parse(['--output=emacs', 'foo.cpp', 'bar.cpp'])
        self.assertEqual(files, ['foo.cpp', 'bar.cpp'])


class CommandOptionValuesTest(unittest.TestCase):

    """Tests CommandOptionValues class."""

    def test_init(self):
        """Test __init__ constructor."""
        # Check default parameters.
        options = ProcessorOptions()
        self.assertEqual(options.filter_rules, [])
        self.assertIsNone(options.git_commit)
        self.assertFalse(options.is_verbose)
        self.assertEqual(options.min_confidence, 1)
        self.assertEqual(options.output_format, 'emacs')

        # Check argument validation.
        self.assertRaises(ValueError, ProcessorOptions, output_format='bad')
        ProcessorOptions(output_format='emacs')  # No ValueError: works
        ProcessorOptions(output_format='vs7')  # works
        self.assertRaises(ValueError, ProcessorOptions, min_confidence=0)
        self.assertRaises(ValueError, ProcessorOptions, min_confidence=6)
        ProcessorOptions(min_confidence=1)  # works
        ProcessorOptions(min_confidence=5)  # works

        # Check attributes.
        options = ProcessorOptions(filter_rules=['+'],
                                   git_commit='commit',
                                   is_verbose=True,
                                   min_confidence=3,
                                   output_format='vs7')
        self.assertEqual(options.filter_rules, ['+'])
        self.assertEqual(options.git_commit, 'commit')
        self.assertTrue(options.is_verbose)
        self.assertEqual(options.min_confidence, 3)
        self.assertEqual(options.output_format, 'vs7')

    def test_eq(self):
        """Test __eq__ equality function."""
        self.assertTrue(ProcessorOptions().__eq__(ProcessorOptions()))

        # Also verify that a difference in any argument causes equality to fail.

        # Explicitly create a ProcessorOptions instance with all default
        # values.  We do this to be sure we are assuming the right default
        # values in our self.assertFalse() calls below.
        options = ProcessorOptions(filter_rules=[],
                                   git_commit=None,
                                   is_verbose=False,
                                   min_confidence=1,
                                   output_format='emacs')
        # Verify that we created options correctly.
        self.assertTrue(options.__eq__(ProcessorOptions()))

        self.assertFalse(options.__eq__(ProcessorOptions(filter_rules=['+'])))
        self.assertFalse(options.__eq__(ProcessorOptions(git_commit='commit')))
        self.assertFalse(options.__eq__(ProcessorOptions(is_verbose=True)))
        self.assertFalse(options.__eq__(ProcessorOptions(min_confidence=2)))
        self.assertFalse(options.__eq__(ProcessorOptions(output_format='vs7')))

    def test_ne(self):
        """Test __ne__ inequality function."""
        # By default, __ne__ always returns true on different objects.
        # Thus, just check the distinguishing case to verify that the
        # code defines __ne__.
        self.assertFalse(ProcessorOptions().__ne__(ProcessorOptions()))
