#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for enum_preprocess.py.

This test suite containss various tests for the C++ -> Java enum generator.
"""

import collections
import optparse
import os
import sys
import unittest

from java_cpp_enum import EnumDefinition, GenerateOutput, GetScriptName
from java_cpp_enum import HeaderParser

sys.path.append(os.path.join(os.path.dirname(__file__), "gyp"))
from util import build_utils

class TestPreprocess(unittest.TestCase):
  def testOutput(self):
    definition = EnumDefinition(original_enum_name='ClassName',
                                enum_package='some.package',
                                entries=[('E1', 1), ('E2', '2 << 2')])
    output = GenerateOutput('path/to/file', definition)
    expected = """
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is autogenerated by
//     %s
// From
//     path/to/file

package some.package;

public class ClassName {
  public static final int E1 = 1;
  public static final int E2 = 2 << 2;
}
"""
    self.assertEqual(expected % GetScriptName(), output)

  def testParseSimpleEnum(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum EnumName {
        VALUE_ZERO,
        VALUE_ONE,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('EnumName', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('VALUE_ZERO', 0),
                                              ('VALUE_ONE', 1)]),
                     definition.entries)

  def testParseBitShifts(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum EnumName {
        VALUE_ZERO = 1 << 0,
        VALUE_ONE = 1 << 1,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('EnumName', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('VALUE_ZERO', '1 << 0'),
                                              ('VALUE_ONE', '1 << 1')]),
                     definition.entries)

  def testParseClassNameOverride(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName
      enum EnumName {
        FOO
      };

      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OtherOverride
      enum PrefixTest {
        PREFIX_TEST_A,
        PREFIX_TEST_B,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(2, len(definitions))
    definition = definitions[0]
    self.assertEqual('OverrideName', definition.class_name)

    definition = definitions[1]
    self.assertEqual('OtherOverride', definition.class_name)
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 1)]),
                     definition.entries)

  def testParseTwoEnums(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum EnumOne {
        ENUM_ONE_A = 1,
        // Comment there
        ENUM_ONE_B = A,
      };

      enum EnumIgnore {
        C, D, E
      };

      // GENERATED_JAVA_ENUM_PACKAGE: other.package
      // GENERATED_JAVA_PREFIX_TO_STRIP: P_
      enum EnumTwo {
        P_A,
        P_B
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(2, len(definitions))
    definition = definitions[0]
    self.assertEqual('EnumOne', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('A', '1'),
                                              ('B', 'A')]),
                     definition.entries)

    definition = definitions[1]
    self.assertEqual('EnumTwo', definition.class_name)
    self.assertEqual('other.package', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 1)]),
                     definition.entries)

  def testParseThrowsOnUnknownDirective(self):
    test_data = """
      // GENERATED_JAVA_UNKNOWN: Value
      enum EnumName {
        VALUE_ONE,
      };
    """.split('\n')
    with self.assertRaises(Exception):
      HeaderParser(test_data).ParseDefinitions()

  def testParseEnumClass(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum class Foo {
        FOO_A,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('Foo', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('A', 0)]),
                     definition.entries)

  def testParseEnumStruct(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum struct Foo {
        FOO_A,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('Foo', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual(collections.OrderedDict([('A', 0)]),
                     definition.entries)

  def testParseFixedTypeEnum(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum Foo : int {
        FOO_A,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('Foo', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual('int', definition.fixed_type)
    self.assertEqual(collections.OrderedDict([('A', 0)]),
                     definition.entries)

  def testParseFixedTypeEnumClass(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum class Foo: unsigned short {
        FOO_A,
      };
    """.split('\n')
    definitions = HeaderParser(test_data).ParseDefinitions()
    self.assertEqual(1, len(definitions))
    definition = definitions[0]
    self.assertEqual('Foo', definition.class_name)
    self.assertEqual('test.namespace', definition.enum_package)
    self.assertEqual('unsigned short', definition.fixed_type)
    self.assertEqual(collections.OrderedDict([('A', 0)]),
                     definition.entries)

  def testParseUnknownFixedTypeRaises(self):
    test_data = """
      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
      enum class Foo: foo_type {
        FOO_A,
      };
    """.split('\n')
    with self.assertRaises(Exception):
      HeaderParser(test_data).ParseDefinitions()

  def testEnumValueAssignmentNoneDefined(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', None)
    definition.AppendEntry('C', None)
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 1),
                                              ('C', 2)]),
                     definition.entries)

  def testEnumValueAssignmentAllDefined(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', '1')
    definition.AppendEntry('B', '2')
    definition.AppendEntry('C', '3')
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', '1'),
                                              ('B', '2'),
                                              ('C', '3')]),
                     definition.entries)

  def testEnumValueAssignmentReferences(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', 'A')
    definition.AppendEntry('C', None)
    definition.AppendEntry('D', 'C')
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 0),
                                              ('C', 1),
                                              ('D', 1)]),
                     definition.entries)

  def testEnumValueAssignmentSet(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', '2')
    definition.AppendEntry('C', None)
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 2),
                                              ('C', 3)]),
                     definition.entries)

  def testEnumValueAssignmentSetReferences(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', 'A')
    definition.AppendEntry('C', 'B')
    definition.AppendEntry('D', None)
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 0),
                                              ('C', 0),
                                              ('D', 1)]),
                     definition.entries)

  def testEnumValueAssignmentRaises(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', 'foo')
    definition.AppendEntry('C', None)
    with self.assertRaises(Exception):
      definition.Finalize()

  def testExplicitPrefixStripping(self):
    definition = EnumDefinition(original_enum_name='c', enum_package='p')
    definition.AppendEntry('P_A', None)
    definition.AppendEntry('B', None)
    definition.AppendEntry('P_C', None)
    definition.AppendEntry('P_LAST', 'P_C')
    definition.prefix_to_strip = 'P_'
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 1),
                                              ('C', 2),
                                              ('LAST', 2)]),
                     definition.entries)

  def testImplicitPrefixStripping(self):
    definition = EnumDefinition(original_enum_name='ClassName',
                                enum_package='p')
    definition.AppendEntry('CLASS_NAME_A', None)
    definition.AppendEntry('CLASS_NAME_B', None)
    definition.AppendEntry('CLASS_NAME_C', None)
    definition.AppendEntry('CLASS_NAME_LAST', 'CLASS_NAME_C')
    definition.Finalize()
    self.assertEqual(collections.OrderedDict([('A', 0),
                                              ('B', 1),
                                              ('C', 2),
                                              ('LAST', 2)]),
                     definition.entries)

  def testImplicitPrefixStrippingRequiresAllConstantsToBePrefixed(self):
    definition = EnumDefinition(original_enum_name='Name',
                                enum_package='p')
    definition.AppendEntry('A', None)
    definition.AppendEntry('B', None)
    definition.AppendEntry('NAME_LAST', None)
    definition.Finalize()
    self.assertEqual(['A', 'B', 'NAME_LAST'], definition.entries.keys())

def main(argv):
  parser = optparse.OptionParser()
  parser.add_option("--stamp", help="File to touch on success.")
  options, _ = parser.parse_args(argv)

  suite = unittest.TestLoader().loadTestsFromTestCase(TestPreprocess)
  unittest.TextTestRunner(verbosity=0).run(suite)

  if options.stamp:
    build_utils.Touch(options.stamp)

if __name__ == '__main__':
  main(sys.argv[1:])
