#!/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

class TestGenerator(unittest.TestCase):
  def assertObjEquals(self, 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 _ReadGoldenFile(self, golden_file):
    if not os.path.exists(golden_file):
      return None
    with file(golden_file, 'r') as f:
      return f.read()

  def assertGoldenTextEquals(self, generated_text, suffix=''):
    script_dir = os.path.dirname(sys.argv[0])
    # This is the caller test method.
    caller = inspect.stack()[1][3]
    self.assertTrue(caller.startswith('test'),
                    'assertGoldenTextEquals can only be called from a '
                    'test* method, not %s' % caller)
    golden_file = os.path.join(script_dir, '%s%s.golden' % (caller, suffix))
    golden_text = self._ReadGoldenFile(golden_file)
    if os.environ.get(REBASELINE_ENV):
      if golden_text != generated_text:
        with file(golden_file, 'w') as f:
          f.write(generated_text)
      return
    self.assertTextEquals(golden_text, generated_text)

  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)
    content = h2.Generate()
    for k in jni_registration_generator.MERGEABLE_KEYS:
      content[k] = content.get(k, '')
    content['HEADER_GUARD'] = 'HEADER_GUARD'
    content['NAMESPACE'] = 'test'

    self.assertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content),
        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)
    content = h2.Generate()
    for k in jni_registration_generator.MERGEABLE_KEYS:
      content[k] = content.get(k, '')
    content['HEADER_GUARD'] = 'HEADER_GUARD'
    content['NAMESPACE'] = 'test'

    self.assertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content),
        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(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(os.path.join(os.path.dirname(sys.argv[0]),
        '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(os.path.join(os.path.dirname(sys.argv[0]),
          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):
    script_dir = os.path.dirname(sys.argv[0])
    content = file(os.path.join(script_dir,
        'java/src/org/chromium/example/jni_generator/SampleForTests.java')
        ).read()
    golden_file = os.path.join(script_dir, 'SampleForTests_jni.golden')
    golden_content = file(golden_file).read()
    jni_from_java = jni_generator.JNIFromJavaSource(
        content, 'org/chromium/example/jni_generator/SampleForTests',
        TestOptions())
    generated_text = jni_from_java.GetContent()
    if not self.compareText(golden_content, generated_text):
      if os.environ.get(REBASELINE_ENV):
        with file(golden_file, 'w') as f:
          f.write(generated_text)
        return
      self.fail('testJniSelfDocumentingExample')

  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 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('--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))
