#!/usr/bin/env python
# Copyright (c) 2012 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 jni_generator.py.

This test suite contains various tests for the JNI generator.
It exercises the low-level parser all the way up to the
code generator and ensures the output matches a golden
file.
"""

import difflib
import inspect
import optparse
import os
import sys
import unittest
import jni_generator
import jni_registration_generator
from jni_generator import CalledByNative
from jni_generator import IsMainDexJavaClass
from jni_generator import NativeMethod
from jni_generator import Param


SCRIPT_NAME = 'base/android/jni_generator/jni_generator.py'
INCLUDES = (
    'base/android/jni_generator/jni_generator_helper.h'
)

# Set this environment variable in order to regenerate the golden text
# files.
REBASELINE_ENV = 'REBASELINE'

class TestOptions(object):
  """The mock options object which is passed to the jni_generator.py script."""

  def __init__(self):
    self.namespace = None
    self.script_name = SCRIPT_NAME
    self.includes = INCLUDES
    self.ptr_type = 'long'
    self.cpp = 'cpp'
    self.javap = 'javap'
    self.native_exports_optional = True
    self.enable_profiling = False
    self.enable_tracing = False
    self.use_proxy_hash = False


class BaseTest(unittest.TestCase):

  @staticmethod
  def _MergeRegistrationForTests(results,
                                 header_guard='HEADER_GUARD',
                                 namespace='test'):

    results.sort(key=lambda d: d['FULL_CLASS_NAME'])

    combined_dict = {}
    for key in jni_registration_generator.MERGEABLE_KEYS:
      combined_dict[key] = ''.join(d.get(key, '') for d in results)

    combined_dict['HEADER_GUARD'] = header_guard
    combined_dict['NAMESPACE'] = namespace
    return combined_dict

  def _JoinScriptDir(self, path):
    script_dir = os.path.dirname(sys.argv[0])
    return os.path.join(script_dir, path)

  def _JoinGoldenPath(self, golden_file_name):
    return self._JoinScriptDir(os.path.join('golden', golden_file_name))

  def _ReadGoldenFile(self, golden_file_name):
    golden_file_name = self._JoinGoldenPath(golden_file_name)
    if not os.path.exists(golden_file_name):
      return None
    with file(golden_file_name, 'r') as f:
      return f.read()

  def _CreateJniHeaderFromFile(self, fname, qualified_clazz, options=None):
    content = file(self._JoinScriptDir(fname)).read()
    opts = options
    if opts is None:
      opts = TestOptions()

    jni_from_java = jni_generator.JNIFromJavaSource(content, qualified_clazz,
                                                    opts)
    return jni_from_java.GetContent()

  def AssertObjEquals(self, first, second):
    if isinstance(first, str):
      return self.assertEquals(first,second)
    dict_first = first.__dict__
    dict_second = second.__dict__
    self.assertEquals(dict_first.keys(), dict_second.keys())
    for key, value in dict_first.iteritems():
      if (type(value) is list and len(value) and
          isinstance(type(value[0]), object)):
        self.AssertListEquals(value, second.__getattribute__(key))
      else:
        actual = second.__getattribute__(key)
        self.assertEquals(value, actual,
                          'Key ' + key + ': ' + str(value) + '!=' + str(actual))

  def AssertListEquals(self, first, second):
    self.assertEquals(len(first), len(second))
    for i in xrange(len(first)):
      if isinstance(first[i], object):
        self.AssertObjEquals(first[i], second[i])
      else:
        self.assertEquals(first[i], second[i])

  def AssertTextEquals(self, golden_text, generated_text):
    if not self.CompareText(golden_text, generated_text):
      self.fail('Golden text mismatch.')

  def CompareText(self, golden_text, generated_text):

    def FilterText(text):
      return [
          l.strip()
          for l in text.split('\n')
          if not l.startswith('// Copyright')
      ]
    stripped_golden = FilterText(golden_text)
    stripped_generated = FilterText(generated_text)
    if stripped_golden == stripped_generated:
      return True
    print self.id()
    for line in difflib.context_diff(stripped_golden, stripped_generated):
      print line
    print '\n\nGenerated'
    print '=' * 80
    print generated_text
    print '=' * 80
    print 'Run with:'
    print 'REBASELINE=1', sys.argv[0]
    print 'to regenerate the data files.'

  def AssertGoldenTextEquals(self, generated_text, suffix='', golden_file=None):
    """Compares generated text with the corresponding golden_file

    By default compares generated_text with the file at
    script_dir/golden/{caller_name}[suffix].golden. If the parameter golden_file is
    provided it will instead compare the generated text with
    script_dir/golden/golden_file."""
    # This is the caller test method.
    caller = inspect.stack()[1][3]

    if golden_file is None:
      self.assertTrue(
          caller.startswith('test'),
          'AssertGoldenTextEquals can only be called from a '
          'test* method, not %s' % caller)
      golden_file = '%s%s.golden' % (caller, suffix)
    golden_text = self._ReadGoldenFile(golden_file)
    if os.environ.get(REBASELINE_ENV):
      if golden_text != generated_text:
        with file(self._JoinGoldenPath(golden_file), 'w') as f:
          f.write(generated_text)
      return
    # golden_text is None if no file is found. Better to fail than in
    # AssertTextEquals so we can give a clearer message.
    if golden_text is None:
      self.fail(
          'Golden file %s does not exist.' % self._JoinGoldenPath(golden_file))
    self.AssertTextEquals(golden_text, generated_text)


class TestGenerator(BaseTest):

  def testInspectCaller(self):
    def willRaise():
      # This function can only be called from a test* method.
      self.AssertGoldenTextEquals('')
    self.assertRaises(AssertionError, willRaise)

  def testNatives(self):
    test_data = """"
    import android.graphics.Bitmap;
    import android.view.View;

    interface OnFrameAvailableListener {}
    private native int nativeInit();
    private native void nativeDestroy(int nativeChromeBrowserProvider);
    private native long nativeAddBookmark(
            int nativeChromeBrowserProvider,
            String url, String title, boolean isFolder, long parentId);
    private static native String nativeGetDomainAndRegistry(String url);
    private static native void nativeCreateHistoricalTabFromState(
            byte[] state, int tab_index);
    private native byte[] nativeGetStateAsByteArray(View view);
    private static native String[] nativeGetAutofillProfileGUIDs();
    private native void nativeSetRecognitionResults(
            int sessionId, String[] results);
    private native long nativeAddBookmarkFromAPI(
            int nativeChromeBrowserProvider,
            String url, Long created, Boolean isBookmark,
            Long date, byte[] favicon, String title, Integer visits);
    native int nativeFindAll(String find);
    private static native OnFrameAvailableListener nativeGetInnerClass();
    private native Bitmap nativeQueryBitmap(
            int nativeChromeBrowserProvider,
            String[] projection, String selection,
            String[] selectionArgs, String sortOrder);
    private native void nativeGotOrientation(
            int nativeDataFetcherImplAndroid,
            double alpha, double beta, double gamma);
    private static native Throwable nativeMessWithJavaException(Throwable e);
    """
    jni_params = jni_generator.JniParams(
        'org/chromium/example/jni_generator/SampleForTests')
    jni_params.ExtractImportsAndInnerClasses(test_data)
    natives = jni_generator.ExtractNatives(test_data, 'int')
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False, name='Destroy',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='long', static=False, name='AddBookmark',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='boolean',
                                   name='isFolder'),
                             Param(datatype='long',
                                   name='parentId')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='String', static=True,
                     name='GetDomainAndRegistry',
                     params=[Param(datatype='String',
                                   name='url')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=True,
                     name='CreateHistoricalTabFromState',
                     params=[Param(datatype='byte[]',
                                   name='state'),
                             Param(datatype='int',
                                   name='tab_index')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='byte[]', static=False,
                     name='GetStateAsByteArray',
                     params=[Param(datatype='View', name='view')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='String[]', static=True,
                     name='GetAutofillProfileGUIDs', params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False,
                     name='SetRecognitionResults',
                     params=[Param(datatype='int', name='sessionId'),
                             Param(datatype='String[]', name='results')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='long', static=False,
                     name='AddBookmarkFromAPI',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='Long',
                                   name='created'),
                             Param(datatype='Boolean',
                                   name='isBookmark'),
                             Param(datatype='Long',
                                   name='date'),
                             Param(datatype='byte[]',
                                   name='favicon'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='Integer',
                                   name='visits')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='int', static=False,
                     name='FindAll',
                     params=[Param(datatype='String',
                                   name='find')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='OnFrameAvailableListener', static=True,
                     name='GetInnerClass',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='Bitmap',
                     static=False,
                     name='QueryBitmap',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String[]',
                                   name='projection'),
                             Param(datatype='String',
                                   name='selection'),
                             Param(datatype='String[]',
                                   name='selectionArgs'),
                             Param(datatype='String',
                                   name='sortOrder'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='void', static=False,
                     name='GotOrientation',
                     params=[Param(datatype='int',
                                   name='nativeDataFetcherImplAndroid'),
                             Param(datatype='double',
                                   name='alpha'),
                             Param(datatype='double',
                                   name='beta'),
                             Param(datatype='double',
                                   name='gamma'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='content::DataFetcherImplAndroid'),
        NativeMethod(return_type='Throwable', static=True,
                     name='MessWithJavaException',
                     params=[Param(datatype='Throwable', name='e')],
                     java_class_name=None,
                     type='function')
    ]
    self.AssertListEquals(golden_natives, natives)
    h1 = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                              natives, [], [], jni_params,
                                              TestOptions())
    self.AssertGoldenTextEquals(h1.GetContent())
    h2 = jni_registration_generator.HeaderGenerator(
        '',
        'org/chromium/TestJni',
        natives,
        jni_params,
        True,
        use_proxy_hash=False)
    content = TestGenerator._MergeRegistrationForTests([h2.Generate()])

    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content, use_hash=False),
        suffix='Registrations')

  def testInnerClassNatives(self):
    test_data = """
    class MyInnerClass {
      @NativeCall("MyInnerClass")
      private native int nativeInit();
    }
    """
    natives = jni_generator.ExtractNatives(test_data, 'int')
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyInnerClass',
                     type='function')
    ]
    self.AssertListEquals(golden_natives, natives)
    jni_params = jni_generator.JniParams('')
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [], [], jni_params,
                                             TestOptions())
    self.AssertGoldenTextEquals(h.GetContent())

  def testInnerClassNativesMultiple(self):
    test_data = """
    class MyInnerClass {
      @NativeCall("MyInnerClass")
      private native int nativeInit();
    }
    class MyOtherInnerClass {
      @NativeCall("MyOtherInnerClass")
      private native int nativeInit();
    }
    """
    natives = jni_generator.ExtractNatives(test_data, 'int')
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyInnerClass',
                     type='function'),
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyOtherInnerClass',
                     type='function')
    ]
    self.AssertListEquals(golden_natives, natives)
    jni_params = jni_generator.JniParams('')
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [], [], jni_params,
                                             TestOptions())
    self.AssertGoldenTextEquals(h.GetContent())

  def testInnerClassNativesBothInnerAndOuter(self):
    test_data = """
    class MyOuterClass {
      private native int nativeInit();
      class MyOtherInnerClass {
        @NativeCall("MyOtherInnerClass")
        private native int nativeInit();
      }
    }
    """
    natives = jni_generator.ExtractNatives(test_data, 'int')
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyOtherInnerClass',
                     type='function')
    ]
    self.AssertListEquals(golden_natives, natives)
    jni_params = jni_generator.JniParams('')
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [], [], jni_params,
                                             TestOptions())
    self.AssertGoldenTextEquals(h.GetContent())

    h2 = jni_registration_generator.HeaderGenerator(
        '',
        'org/chromium/TestJni',
        natives,
        jni_params,
        True,
        use_proxy_hash=False)
    content = TestGenerator._MergeRegistrationForTests([h2.Generate()])

    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content, use_hash=False),
        suffix='Registrations')

  def testCalledByNatives(self):
    test_data = """"
    import android.graphics.Bitmap;
    import android.view.View;
    import java.io.InputStream;
    import java.util.List;

    class InnerClass {}

    @CalledByNative
    @SomeOtherA
    @SomeOtherB
    public InnerClass showConfirmInfoBar(int nativeInfoBar,
            String buttonOk, String buttonCancel, String title, Bitmap icon) {
        InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext,
                                             buttonOk, buttonCancel,
                                             title, icon);
        return infobar;
    }
    @CalledByNative
    InnerClass showAutoLoginInfoBar(int nativeInfoBar,
            String realm, String account, String args) {
        AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext,
                realm, account, args);
        if (infobar.displayedAccountCount() == 0)
            infobar = null;
        return infobar;
    }
    @CalledByNative("InfoBar")
    void dismiss();
    @SuppressWarnings("unused")
    @CalledByNative
    private static boolean shouldShowAutoLogin(View view,
            String realm, String account, String args) {
        AccountManagerContainer accountManagerContainer =
            new AccountManagerContainer((Activity)contentView.getContext(),
            realm, account, args);
        String[] logins = accountManagerContainer.getAccountLogins(null);
        return logins.length != 0;
    }
    @CalledByNative
    static InputStream openUrl(String url) {
        return null;
    }
    @CalledByNative
    private void activateHardwareAcceleration(final boolean activated,
            final int iPid, final int iType,
            final int iPrimaryID, final int iSecondaryID) {
      if (!activated) {
          return
      }
    }
    @CalledByNative
    public static @Status int updateStatus(@Status int status) {
        return getAndUpdateStatus(status);
    }
    @CalledByNativeUnchecked
    private void uncheckedCall(int iParam);

    @CalledByNative
    public byte[] returnByteArray();

    @CalledByNative
    public boolean[] returnBooleanArray();

    @CalledByNative
    public char[] returnCharArray();

    @CalledByNative
    public short[] returnShortArray();

    @CalledByNative
    public int[] returnIntArray();

    @CalledByNative
    public long[] returnLongArray();

    @CalledByNative
    public double[] returnDoubleArray();

    @CalledByNative
    public Object[] returnObjectArray();

    @CalledByNative
    public byte[][] returnArrayOfByteArray();

    @CalledByNative
    public Bitmap.CompressFormat getCompressFormat();

    @CalledByNative
    public List<Bitmap.CompressFormat> getCompressFormatList();
    """
    jni_params = jni_generator.JniParams('org/chromium/Foo')
    jni_params.ExtractImportsAndInnerClasses(test_data)
    called_by_natives = jni_generator.ExtractCalledByNatives(jni_params,
                                                             test_data)
    golden_called_by_natives = [
        CalledByNative(
            return_type='InnerClass',
            system_class=False,
            static=False,
            name='showConfirmInfoBar',
            method_id_var_name='showConfirmInfoBar',
            java_class_name='',
            params=[Param(datatype='int', name='nativeInfoBar'),
                    Param(datatype='String', name='buttonOk'),
                    Param(datatype='String', name='buttonCancel'),
                    Param(datatype='String', name='title'),
                    Param(datatype='Bitmap', name='icon')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='InnerClass',
            system_class=False,
            static=False,
            name='showAutoLoginInfoBar',
            method_id_var_name='showAutoLoginInfoBar',
            java_class_name='',
            params=[Param(datatype='int', name='nativeInfoBar'),
                    Param(datatype='String', name='realm'),
                    Param(datatype='String', name='account'),
                    Param(datatype='String', name='args')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='dismiss',
            method_id_var_name='dismiss',
            java_class_name='InfoBar',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='boolean',
            system_class=False,
            static=True,
            name='shouldShowAutoLogin',
            method_id_var_name='shouldShowAutoLogin',
            java_class_name='',
            params=[Param(datatype='View', name='view'),
                    Param(datatype='String', name='realm'),
                    Param(datatype='String', name='account'),
                    Param(datatype='String', name='args')],
            env_call=('Boolean', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='InputStream',
            system_class=False,
            static=True,
            name='openUrl',
            method_id_var_name='openUrl',
            java_class_name='',
            params=[Param(datatype='String', name='url')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='activateHardwareAcceleration',
            method_id_var_name='activateHardwareAcceleration',
            java_class_name='',
            params=[Param(datatype='boolean', name='activated'),
                    Param(datatype='int', name='iPid'),
                    Param(datatype='int', name='iType'),
                    Param(datatype='int', name='iPrimaryID'),
                    Param(datatype='int', name='iSecondaryID'),
                   ],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
          return_type='int',
          system_class=False,
          static=True,
          name='updateStatus',
          method_id_var_name='updateStatus',
          java_class_name='',
          params=[Param(annotations=['@Status'], datatype='int',
                        name='status')],
          env_call=('Integer', ''),
          unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='uncheckedCall',
            method_id_var_name='uncheckedCall',
            java_class_name='',
            params=[Param(datatype='int', name='iParam')],
            env_call=('Void', ''),
            unchecked=True,
        ),
        CalledByNative(
            return_type='byte[]',
            system_class=False,
            static=False,
            name='returnByteArray',
            method_id_var_name='returnByteArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='boolean[]',
            system_class=False,
            static=False,
            name='returnBooleanArray',
            method_id_var_name='returnBooleanArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='char[]',
            system_class=False,
            static=False,
            name='returnCharArray',
            method_id_var_name='returnCharArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='short[]',
            system_class=False,
            static=False,
            name='returnShortArray',
            method_id_var_name='returnShortArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='int[]',
            system_class=False,
            static=False,
            name='returnIntArray',
            method_id_var_name='returnIntArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='long[]',
            system_class=False,
            static=False,
            name='returnLongArray',
            method_id_var_name='returnLongArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='double[]',
            system_class=False,
            static=False,
            name='returnDoubleArray',
            method_id_var_name='returnDoubleArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='Object[]',
            system_class=False,
            static=False,
            name='returnObjectArray',
            method_id_var_name='returnObjectArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='byte[][]',
            system_class=False,
            static=False,
            name='returnArrayOfByteArray',
            method_id_var_name='returnArrayOfByteArray',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='Bitmap.CompressFormat',
            system_class=False,
            static=False,
            name='getCompressFormat',
            method_id_var_name='getCompressFormat',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='List<Bitmap.CompressFormat>',
            system_class=False,
            static=False,
            name='getCompressFormatList',
            method_id_var_name='getCompressFormatList',
            java_class_name='',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
    ]
    self.AssertListEquals(golden_called_by_natives, called_by_natives)
    h = jni_generator.InlHeaderFileGenerator(
        '', 'org/chromium/TestJni', [], called_by_natives, [], jni_params,
        TestOptions())
    self.AssertGoldenTextEquals(h.GetContent())

  def testCalledByNativeParseError(self):
    try:
      jni_params = jni_generator.JniParams('')
      jni_generator.ExtractCalledByNatives(jni_params, """
@CalledByNative
public static int foo(); // This one is fine

@CalledByNative
scooby doo
""")
      self.fail('Expected a ParseError')
    except jni_generator.ParseError, e:
      self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines)

  def testFullyQualifiedClassName(self):
    contents = """
// Copyright (c) 2010 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.

package org.chromium.content.browser;

import org.chromium.base.BuildInfo;
"""
    self.assertEquals('org/chromium/content/browser/Foo',
                      jni_generator.ExtractFullyQualifiedJavaClassName(
                          'org/chromium/content/browser/Foo.java', contents))
    self.assertEquals('org/chromium/content/browser/Foo',
                      jni_generator.ExtractFullyQualifiedJavaClassName(
                          'frameworks/Foo.java', contents))
    self.assertRaises(SyntaxError,
                      jni_generator.ExtractFullyQualifiedJavaClassName,
                      'com/foo/Bar', 'no PACKAGE line')

  def testMethodNameMangling(self):
    jni_params = jni_generator.JniParams('')
    self.assertEquals('closeV',
        jni_generator.GetMangledMethodName(jni_params, 'close', [], 'void'))
    self.assertEquals('readI_AB_I_I',
        jni_generator.GetMangledMethodName(jni_params, 'read',
            [Param(name='p1',
                   datatype='byte[]'),
             Param(name='p2',
                   datatype='int'),
             Param(name='p3',
                   datatype='int'),],
             'int'))
    self.assertEquals('openJIIS_JLS',
        jni_generator.GetMangledMethodName(jni_params, 'open',
            [Param(name='p1',
                   datatype='java/lang/String'),],
             'java/io/InputStream'))

  def testFromJavaPGenerics(self):
    contents = """
public abstract class java.util.HashSet<T> extends java.util.AbstractSet<E>
      implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
    public void dummy();
      Signature: ()V
    public java.lang.Class<?> getClass();
      Signature: ()Ljava/lang/Class<*>;
}
"""
    jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
                                                TestOptions())
    self.assertEquals(2, len(jni_from_javap.called_by_natives))
    self.AssertGoldenTextEquals(jni_from_javap.GetContent())

  def testSnippnetJavap6_7_8(self):
    content_javap6 = """
public class java.util.HashSet {
public boolean add(java.lang.Object);
 Signature: (Ljava/lang/Object;)Z
}
"""

    content_javap7 = """
public class java.util.HashSet {
public boolean add(E);
  Signature: (Ljava/lang/Object;)Z
}
"""

    content_javap8 = """
public class java.util.HashSet {
  public boolean add(E);
    descriptor: (Ljava/lang/Object;)Z
}
"""

    jni_from_javap6 = jni_generator.JNIFromJavaP(content_javap6.split('\n'),
                                                 TestOptions())
    jni_from_javap7 = jni_generator.JNIFromJavaP(content_javap7.split('\n'),
                                                 TestOptions())
    jni_from_javap8 = jni_generator.JNIFromJavaP(content_javap8.split('\n'),
                                                 TestOptions())
    self.assertTrue(jni_from_javap6.GetContent())
    self.assertTrue(jni_from_javap7.GetContent())
    self.assertTrue(jni_from_javap8.GetContent())
    # Ensure the javap7 is correctly parsed and uses the Signature field rather
    # than the "E" parameter.
    self.AssertTextEquals(jni_from_javap6.GetContent(),
                          jni_from_javap7.GetContent())
    # Ensure the javap8 is correctly parsed and uses the descriptor field.
    self.AssertTextEquals(jni_from_javap7.GetContent(),
                          jni_from_javap8.GetContent())

  def testFromJavaP(self):
    contents = self._ReadGoldenFile('testInputStream.javap')
    jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
                                                TestOptions())
    self.assertEquals(10, len(jni_from_javap.called_by_natives))
    self.AssertGoldenTextEquals(jni_from_javap.GetContent())

  def testConstantsFromJavaP(self):
    for f in ['testMotionEvent.javap', 'testMotionEvent.javap7']:
      contents = self._ReadGoldenFile(f)
      jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
                                                  TestOptions())
      self.assertEquals(86, len(jni_from_javap.called_by_natives))
      self.AssertGoldenTextEquals(jni_from_javap.GetContent())

  def testREForNatives(self):
    # We should not match "native SyncSetupFlow" inside the comment.
    test_data = """
    /**
     * Invoked when the setup process is complete so we can disconnect from the
     * native-side SyncSetupFlowHandler.
     */
    public void destroy() {
        Log.v(TAG, "Destroying native SyncSetupFlow");
        if (mNativeSyncSetupFlow != 0) {
            nativeSyncSetupEnded(mNativeSyncSetupFlow);
            mNativeSyncSetupFlow = 0;
        }
    }
    private native void nativeSyncSetupEnded(
        int nativeAndroidSyncSetupFlowHandler);
    """
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, 'foo/bar', TestOptions())

  def testRaisesOnNonJNIMethod(self):
    test_data = """
    class MyInnerClass {
      private int Foo(int p0) {
      }
    }
    """
    self.assertRaises(SyntaxError,
                      jni_generator.JNIFromJavaSource,
                      test_data, 'foo/bar', TestOptions())

  def testJniSelfDocumentingExample(self):
    generated_text = self._CreateJniHeaderFromFile(
        'java/src/org/chromium/example/jni_generator/SampleForTests.java',
        'org/chromium/example/jni_generator/SampleForTests')
    self.AssertGoldenTextEquals(
        generated_text, golden_file='SampleForTests_jni.golden')

  def testNoWrappingPreprocessorLines(self):
    test_data = """
    package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday;

    class ReallyLongClassNamesAreAllTheRage {
        private static native int nativeTest();
    }
    """
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, ('com/google/lookhowextremelylongiam/snarf/'
                    'icankeepthisupallday/ReallyLongClassNamesAreAllTheRage'),
        TestOptions())
    jni_lines = jni_from_java.GetContent().split('\n')
    line = filter(lambda line: line.lstrip().startswith('#ifndef'),
                  jni_lines)[0]
    self.assertTrue(len(line) > 80,
                    ('Expected #ifndef line to be > 80 chars: ', line))

  def testImports(self):
    import_header = """
// Copyright (c) 2012 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.

package org.chromium.content.app;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.Surface;

import java.util.ArrayList;

import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.content.app.ContentMain;
import org.chromium.content.browser.SandboxedProcessConnection;
import org.chromium.content.common.ISandboxedProcessCallback;
import org.chromium.content.common.ISandboxedProcessService;
import org.chromium.content.common.WillNotRaise.AnException;
import org.chromium.content.common.WillRaise.AnException;

import static org.chromium.Bar.Zoo;

class Foo {
  public static class BookmarkNode implements Parcelable {
  }
  public interface PasswordListObserver {
  }
}
    """
    jni_params = jni_generator.JniParams('org/chromium/content/app/Foo')
    jni_params.ExtractImportsAndInnerClasses(import_header)
    self.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in
                    jni_params._imports)
    self.assertTrue('Lorg/chromium/Bar/Zoo' in
                    jni_params._imports)
    self.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in
                    jni_params._inner_classes)
    self.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in
                    jni_params._inner_classes)
    self.assertEquals('Lorg/chromium/content/app/ContentMain$Inner;',
                      jni_params.JavaToJni('ContentMain.Inner'))
    self.assertRaises(SyntaxError,
                      jni_params.JavaToJni, 'AnException')

  def testJniParamsJavaToJni(self):
    jni_params = jni_generator.JniParams('')
    self.AssertTextEquals('I', jni_params.JavaToJni('int'))
    self.AssertTextEquals('[B', jni_params.JavaToJni('byte[]'))
    self.AssertTextEquals('[Ljava/nio/ByteBuffer;',
                          jni_params.JavaToJni('java/nio/ByteBuffer[]'))

  def testNativesLong(self):
    test_options = TestOptions()
    test_options.ptr_type = 'long'
    test_data = """"
    private native void nativeDestroy(long nativeChromeBrowserProvider);
    """
    jni_params = jni_generator.JniParams('')
    jni_params.ExtractImportsAndInnerClasses(test_data)
    natives = jni_generator.ExtractNatives(test_data, test_options.ptr_type)
    golden_natives = [
        NativeMethod(return_type='void', static=False, name='Destroy',
                     params=[Param(datatype='long',
                                   name='nativeChromeBrowserProvider')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider',
                     ptr_type=test_options.ptr_type),
    ]
    self.AssertListEquals(golden_natives, natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [], [], jni_params,
                                             test_options)
    self.AssertGoldenTextEquals(h.GetContent())

  def testMainDexAnnotation(self):
    mainDexEntries = [
      '@MainDex public class Test {',
      '@MainDex public class Test{',
      """@MainDex
         public class Test {
      """,
      """@MainDex public class Test
         {
      """,
      '@MainDex /* This class is a test */ public class Test {',
      '@MainDex public class Test implements java.io.Serializable {',
      '@MainDex public class Test implements java.io.Serializable, Bidule {',
      '@MainDex public class Test extends BaseTest {',
      """@MainDex
         public class Test extends BaseTest implements Bidule {
      """,
      """@MainDex
         public class Test extends BaseTest implements Bidule, Machin, Chose {
      """,
      """@MainDex
         public class Test implements Testable<java.io.Serializable> {
      """,
      '@MainDex public class Test implements Testable<java.io.Serializable> {',
      '@a.B @MainDex @C public class Test extends Testable<Serializable> {',
      """public class Test extends Testable<java.io.Serializable> {
         @MainDex void func() {}
      """,
    ]
    for entry in mainDexEntries:
      self.assertEquals(True, IsMainDexJavaClass(entry), entry)

  def testNoMainDexAnnotation(self):
    noMainDexEntries = [
      'public class Test {',
      '@NotMainDex public class Test {',
      '// @MainDex public class Test {',
      '/* @MainDex */ public class Test {',
      'public class Test implements java.io.Serializable {',
      '@MainDexNot public class Test {',
      'public class Test extends BaseTest {'
    ]
    for entry in noMainDexEntries:
      self.assertEquals(False, IsMainDexJavaClass(entry))

  def testNativeExportsOnlyOption(self):
    test_data = """
    package org.chromium.example.jni_generator;

    /** The pointer to the native Test. */
    long nativeTest;

    class Test {
        private static native int nativeStaticMethod(long nativeTest, int arg1);
        private native int nativeMethod(long nativeTest, int arg1);
        @CalledByNative
        private void testMethodWithParam(int iParam);
        @CalledByNative
        private String testMethodWithParamAndReturn(int iParam);
        @CalledByNative
        private static int testStaticMethodWithParam(int iParam);
        @CalledByNative
        private static double testMethodWithNoParam();
        @CalledByNative
        private static String testStaticMethodWithNoParam();

        class MyInnerClass {
          @NativeCall("MyInnerClass")
          private native int nativeInit();
        }
        class MyOtherInnerClass {
          @NativeCall("MyOtherInnerClass")
          private native int nativeInit();
        }
    }
    """
    options = TestOptions()
    options.native_exports_optional = False
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, 'org/chromium/example/jni_generator/SampleForTests', options)
    self.AssertGoldenTextEquals(jni_from_java.GetContent())

  def testOuterInnerRaises(self):
    test_data = """
    package org.chromium.media;

    @CalledByNative
    static int getCaptureFormatWidth(VideoCapture.CaptureFormat format) {
        return format.getWidth();
    }
    """
    def willRaise():
      jni_generator.JNIFromJavaSource(
          test_data,
          'org/chromium/media/VideoCaptureFactory',
          TestOptions())
    self.assertRaises(SyntaxError, willRaise)

  def testSingleJNIAdditionalImport(self):
    test_data = """
    package org.chromium.foo;

    @JNIAdditionalImport(Bar.class)
    class Foo {

    @CalledByNative
    private static void calledByNative(Bar.Callback callback) {
    }

    private static native void nativeDoSomething(Bar.Callback callback);
    }
    """
    jni_from_java = jni_generator.JNIFromJavaSource(test_data,
                                                    'org/chromium/foo/Foo',
                                                    TestOptions())
    self.AssertGoldenTextEquals(jni_from_java.GetContent())

  def testMultipleJNIAdditionalImport(self):
    test_data = """
    package org.chromium.foo;

    @JNIAdditionalImport({Bar1.class, Bar2.class})
    class Foo {

    @CalledByNative
    private static void calledByNative(Bar1.Callback callback1,
                                       Bar2.Callback callback2) {
    }

    private static native void nativeDoSomething(Bar1.Callback callback1,
                                                 Bar2.Callback callback2);
    }
    """
    jni_from_java = jni_generator.JNIFromJavaSource(test_data,
                                                    'org/chromium/foo/Foo',
                                                    TestOptions())
    self.AssertGoldenTextEquals(jni_from_java.GetContent())

  def testTracing(self):
    test_data = """
    package org.chromium.foo;

    @JNINamespace("org::chromium_foo")
    class Foo {

    @CalledByNative
    Foo();

    @CalledByNative
    void callbackFromNative();

    native void nativeInstanceMethod(long nativeInstance);

    static native void nativeStaticMethod();
    }
    """
    options_with_tracing = TestOptions()
    options_with_tracing.enable_tracing = True
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, 'org/chromium/foo/Foo', options_with_tracing)
    self.AssertGoldenTextEquals(jni_from_java.GetContent())

  def testStaticBindingCaller(self):
    test_data = """
    package org.chromium.foo;

    class Bar {
      static native void nativeShouldBindCaller(@JCaller Object caller);
      static native void nativeShouldBindCaller(@JCaller Object caller, int a);
      static native void nativeFoo(@JCaller Bar caller,
                          long nativeNativeObject);
      static native void nativeFoo(@JCaller Bar caller,
                          long nativeNativeObject, int a);
      native void nativeCallNativeMethod(long nativePtr);
    }
    """

    jni_from_java = jni_generator.JNIFromJavaSource(
      test_data, 'org/chromium/foo/Foo', TestOptions())
    self.AssertGoldenTextEquals(jni_from_java.GetContent())


class ProxyTestGenerator(BaseTest):

  def _BuildRegDictFromSample(self, options=None):
    if options is None:
      options = TestOptions()

    path = self._JoinScriptDir(
        'java/src/org/chromium/example/jni_generator/SampleForAnnotationProcessor.java'
    )
    reg_dict = jni_registration_generator._DictForPath(path)
    reg_dict = self._MergeRegistrationForTests([reg_dict])

    return reg_dict

  def testProxyNativesWithNatives(self):
    test_data = """
    package org.chromium.foo;

    class Foo {

    @JniStaticNatives
    interface Natives {
       void foo();
       String bar(String s, int y, char x, short z);
       String[] foobar(String[] a);
    }

    void justARegularFunction();

    native void nativeInstanceMethod(long nativeInstance);
    static native void nativeStaticMethod();

    }
    """
    options_with_tracing = TestOptions()
    options_with_tracing.enable_tracing = True
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, 'org/chromium/foo/Foo', options_with_tracing)
    self.AssertGoldenTextEquals(jni_from_java.GetContent())

  def testEscapingProxyNatives(self):
    test_data = """
    class SampleProxyJni {
      @JniStaticNatives
      interface Natives {
        void foo_bar();
        void foo__bar();
      }
    }
    """
    qualified_clazz = 'org/chromium/example/SampleProxyJni'

    natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
        qualified_clazz, test_data, 'long')

    golden_natives = [
        NativeMethod(
            return_type='void',
            static=True,
            name='foo_bar',
            params=[],
            java_class_name=None,
            is_proxy=True,
            proxy_name='org_chromium_example_SampleProxyJni_foo_1bar',
            type='function'),
        NativeMethod(
            return_type='void',
            static=True,
            name='foo__bar',
            params=[],
            java_class_name=None,
            is_proxy=True,
            proxy_name='org_chromium_example_SampleProxyJni_foo_1_1bar',
            type='function'),
    ]

    self.AssertListEquals(natives, golden_natives)

  def testProxyNativesMainDex(self):
    test_data = """
    @MainDex
    class Foo() {
      @JniStaticNatives
      interface Natives {
        void thisismaindex();
      }
      void dontmatchme();
      public static void metoo();
      public static native void this_is_a_non_proxy_native();
    }
    """

    non_main_dex_test_data = """
    class Bar() {
      @JniStaticNatives
      interface Natives {
        void foo();
        void bar();
      }
    }
    """
    qualified_clazz = 'test/foo/Foo'
    jni_params = TestOptions()

    natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
        qualified_clazz, test_data, 'long')

    golden_natives = [
        NativeMethod(
            return_type='void',
            static=True,
            name='thisismaindex',
            params=[],
            java_class_name=None,
            is_proxy=True,
            proxy_name='test_foo_Foo_thisismaindex',
            type='function'),
    ]

    self.AssertListEquals(natives, golden_natives)

    jni_params = jni_generator.JniParams(qualified_clazz)
    main_dex_header = jni_registration_generator.HeaderGenerator(
        '',
        qualified_clazz,
        natives,
        jni_params,
        main_dex=True,
        use_proxy_hash=False).Generate()
    content = TestGenerator._MergeRegistrationForTests([main_dex_header])

    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content, use_hash=False))

    other_qualified_clazz = 'test/foo/Bar'
    other_natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
        other_qualified_clazz, non_main_dex_test_data, 'long')

    jni_params = jni_generator.JniParams(other_qualified_clazz)
    non_main_dex_header = jni_registration_generator.HeaderGenerator(
        '',
        other_qualified_clazz,
        other_natives,
        jni_params,
        main_dex=False,
        use_proxy_hash=False).Generate()

    content = TestGenerator._MergeRegistrationForTests([main_dex_header] +
                                                       [non_main_dex_header])

    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content, use_hash=False),
        'AndNonMainDex')

  def testProxyNatives(self):
    test_data = """
    class SampleProxyJni {
      private void do_not_match();
      @JniStaticNatives
      interface Natives {
        void foo();
        int bar(int x, int y);
        String foobar(String x, String y);
      }
      void dontmatchme();
      public static void metoo();
      public static native void this_is_a_non_proxy_native();
    }
    """

    bad_spaced_test_data = """
    class SampleProxyJni{
      @JniStaticNatives interface 
      Natives 
      
      
      { void     foo(); 
      int              bar(int        
      x,  int y); String    
        foobar(String x, String y); 
      }

    }
    """

    qualified_clazz = 'org/chromium/example/SampleProxyJni'

    natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
        qualified_clazz, test_data, 'long')
    bad_spacing_natives = jni_generator.ProxyHelpers \
      .ExtractStaticProxyNatives(qualified_clazz, bad_spaced_test_data, 'long')
    golden_natives = [
        NativeMethod(
            return_type='void',
            static=True,
            name='foo',
            params=[],
            java_class_name=None,
            is_proxy=True,
            proxy_name='org_chromium_example_SampleProxyJni_foo',
            type='function'),
        NativeMethod(
            return_type='int',
            static=True,
            name='bar',
            params=[
                Param(datatype='int', name='x'),
                Param(datatype='int', name='y')
            ],
            java_class_name=None,
            is_proxy=True,
            proxy_name='org_chromium_example_SampleProxyJni_bar',
            type='function'),
        NativeMethod(
            return_type='String',
            static=True,
            name='foobar',
            params=[
                Param(datatype='String', name='x'),
                Param(datatype='String', name='y')
            ],
            java_class_name=None,
            is_proxy=True,
            proxy_name='org_chromium_example_SampleProxyJni_foobar',
            type='function'),
    ]
    self.AssertListEquals(golden_natives, natives)
    self.AssertListEquals(golden_natives, bad_spacing_natives)

    jni_params = jni_generator.JniParams(qualified_clazz)
    h1 = jni_generator.InlHeaderFileGenerator('', qualified_clazz, natives, [],
                                              [], jni_params, TestOptions())
    self.AssertGoldenTextEquals(h1.GetContent())
    h2 = jni_registration_generator.HeaderGenerator(
        '', qualified_clazz, natives, jni_params, False, use_proxy_hash=False)
    content = TestGenerator._MergeRegistrationForTests([h2.Generate()])

    proxy_opts = jni_registration_generator.ProxyOptions()
    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateProxyJavaFromDict(content, proxy_opts),
        suffix='Java')

    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content, proxy_opts.use_hash),
        suffix='Registrations')

  def testProxyHashedExample(self):
    opts = TestOptions()
    opts.use_proxy_hash = True
    path = 'java/src/org/chromium/example/jni_generator/SampleForAnnotationProcessor.java'

    generated_text = self._CreateJniHeaderFromFile(
        path, 'org/chromium/example/jni_generator/SampleForAnnotationProcessor',
        opts)
    self.AssertGoldenTextEquals(
        generated_text,
        golden_file='HashedSampleForAnnotationProcessor_jni.golden')

    reg_dict = jni_registration_generator._DictForPath(
        self._JoinScriptDir(path))
    reg_dict = self._MergeRegistrationForTests([reg_dict])

    proxy_opts = jni_registration_generator.ProxyOptions()
    self.AssertGoldenTextEquals(
        jni_registration_generator.CreateProxyJavaFromDict(
            reg_dict, proxy_opts),
        golden_file='HashedSampleForAnnotationProcessorGenJni.golden')

  def testProxyJniExample(self):
    generated_text = self._CreateJniHeaderFromFile(
        'java/src/org/chromium/example/jni_generator/SampleForAnnotationProcessor.java',
        'org/chromium/example/jni_generator/SampleForAnnotationProcessor')
    self.AssertGoldenTextEquals(
        generated_text, golden_file='SampleForAnnotationProcessor_jni.golden')

  def testGenJniFlags(self):
    reg_dict = self._BuildRegDictFromSample()
    proxy_options = jni_registration_generator.ProxyOptions()
    content = jni_registration_generator.CreateProxyJavaFromDict(
        reg_dict, proxy_options)
    self.AssertGoldenTextEquals(content, 'Disabled')

    proxy_options = jni_registration_generator.ProxyOptions(enable_mocks=True)
    content = jni_registration_generator.CreateProxyJavaFromDict(
        reg_dict, proxy_options)
    self.AssertGoldenTextEquals(content, 'MocksEnabled')

    proxy_options = jni_registration_generator.ProxyOptions(
        enable_mocks=True, require_mocks=True)
    content = jni_registration_generator.CreateProxyJavaFromDict(
        reg_dict, proxy_options)
    self.AssertGoldenTextEquals(content, 'MocksRequired')


def TouchStamp(stamp_path):
  dir_name = os.path.dirname(stamp_path)
  if not os.path.isdir(dir_name):
    os.makedirs(dir_name)

  with open(stamp_path, 'a'):
    os.utime(stamp_path, None)


def main(argv):
  parser = optparse.OptionParser()
  parser.add_option('--stamp', help='Path to touch on success.')
  parser.add_option(
      '-v', '--verbose', action='store_true', help='Whether to output details.')
  options, _ = parser.parse_args(argv[1:])

  test_result = unittest.main(
      argv=argv[0:1],
      exit=False,
      verbosity=(2 if options.verbose else 1))

  if test_result.result.wasSuccessful() and options.stamp:
    TouchStamp(options.stamp)

  return not test_result.result.wasSuccessful()


if __name__ == '__main__':
  sys.exit(main(sys.argv))
