# 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.logtesting 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=[],
                        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.assertEquals('--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.assertEquals('--min-confidence=3 --output=emacs',
                          self._printer.to_flag_string(options))


class ArgumentParserTest(LoggingTestCase):

    """Test the ArgumentParser class."""

    class _MockStdErr(object):

        def write(self, message):
            # 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."""
        base_filter_rules = ["-", "+whitespace"]
        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.assertEquals(files, [])

        self.assertEquals(options.filter_rules, [])
        self.assertEquals(options.git_commit, None)
        self.assertEquals(options.diff_files, False)
        self.assertEquals(options.is_verbose, False)
        self.assertEquals(options.min_confidence, 3)
        self.assertEquals(options.output_format, 'vs7')

    def test_parse_explicit_arguments(self):
        parse = self._parse

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

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

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

    def test_parse_files(self):
        parse = self._parse

        (files, options) = parse(['foo.cpp'])
        self.assertEquals(files, ['foo.cpp'])

        # Pass multiple files.
        (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp'])
        self.assertEquals(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.assertEquals(options.filter_rules, [])
        self.assertEquals(options.git_commit, None)
        self.assertEquals(options.is_verbose, False)
        self.assertEquals(options.min_confidence, 1)
        self.assertEquals(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.assertEquals(options.filter_rules, ["+"])
        self.assertEquals(options.git_commit, "commit")
        self.assertEquals(options.is_verbose, True)
        self.assertEquals(options.min_confidence, 3)
        self.assertEquals(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()))

