Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / base / android / jni_generator / jni_generator_tests.py
bloba7ce537a6ccba2654fdb762167364ba3261949d3
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Tests for jni_generator.py.
8 This test suite contains various tests for the JNI generator.
9 It exercises the low-level parser all the way up to the
10 code generator and ensures the output matches a golden
11 file.
12 """
14 import difflib
15 import inspect
16 import os
17 import sys
18 import unittest
19 import jni_generator
20 from jni_generator import CalledByNative, JniParams, NativeMethod, Param
23 SCRIPT_NAME = 'base/android/jni_generator/jni_generator.py'
24 INCLUDES = (
25 'base/android/jni_generator/jni_generator_helper.h'
28 # Set this environment variable in order to regenerate the golden text
29 # files.
30 REBASELINE_ENV = 'REBASELINE'
32 class TestOptions(object):
33 """The mock options object which is passed to the jni_generator.py script."""
35 def __init__(self):
36 self.namespace = None
37 self.script_name = SCRIPT_NAME
38 self.includes = INCLUDES
39 self.pure_native_methods = False
40 self.ptr_type = 'long'
41 self.jni_init_native_name = None
42 self.eager_called_by_natives = False
43 self.cpp = 'cpp'
44 self.javap = 'javap'
45 self.native_exports = False
47 class TestGenerator(unittest.TestCase):
48 def assertObjEquals(self, first, second):
49 dict_first = first.__dict__
50 dict_second = second.__dict__
51 self.assertEquals(dict_first.keys(), dict_second.keys())
52 for key, value in dict_first.iteritems():
53 if (type(value) is list and len(value) and
54 isinstance(type(value[0]), object)):
55 self.assertListEquals(value, second.__getattribute__(key))
56 else:
57 actual = second.__getattribute__(key)
58 self.assertEquals(value, actual,
59 'Key ' + key + ': ' + str(value) + '!=' + str(actual))
61 def assertListEquals(self, first, second):
62 self.assertEquals(len(first), len(second))
63 for i in xrange(len(first)):
64 if isinstance(first[i], object):
65 self.assertObjEquals(first[i], second[i])
66 else:
67 self.assertEquals(first[i], second[i])
69 def assertTextEquals(self, golden_text, generated_text):
70 if not self.compareText(golden_text, generated_text):
71 self.fail('Golden text mismatch.')
73 def compareText(self, golden_text, generated_text):
74 def FilterText(text):
75 return [
76 l.strip() for l in text.split('\n')
77 if not l.startswith('// Copyright')
79 stripped_golden = FilterText(golden_text)
80 stripped_generated = FilterText(generated_text)
81 if stripped_golden == stripped_generated:
82 return True
83 print self.id()
84 for line in difflib.context_diff(stripped_golden, stripped_generated):
85 print line
86 print '\n\nGenerated'
87 print '=' * 80
88 print generated_text
89 print '=' * 80
90 print 'Run with:'
91 print 'REBASELINE=1', sys.argv[0]
92 print 'to regenerate the data files.'
94 def _ReadGoldenFile(self, golden_file):
95 if not os.path.exists(golden_file):
96 return None
97 with file(golden_file, 'r') as f:
98 return f.read()
100 def assertGoldenTextEquals(self, generated_text):
101 script_dir = os.path.dirname(sys.argv[0])
102 # This is the caller test method.
103 caller = inspect.stack()[1][3]
104 self.assertTrue(caller.startswith('test'),
105 'assertGoldenTextEquals can only be called from a '
106 'test* method, not %s' % caller)
107 golden_file = os.path.join(script_dir, caller + '.golden')
108 golden_text = self._ReadGoldenFile(golden_file)
109 if os.environ.get(REBASELINE_ENV):
110 if golden_text != generated_text:
111 with file(golden_file, 'w') as f:
112 f.write(generated_text)
113 return
114 self.assertTextEquals(golden_text, generated_text)
116 def testInspectCaller(self):
117 def willRaise():
118 # This function can only be called from a test* method.
119 self.assertGoldenTextEquals('')
120 self.assertRaises(AssertionError, willRaise)
122 def testNatives(self):
123 test_data = """"
124 interface OnFrameAvailableListener {}
125 private native int nativeInit();
126 private native void nativeDestroy(int nativeChromeBrowserProvider);
127 private native long nativeAddBookmark(
128 int nativeChromeBrowserProvider,
129 String url, String title, boolean isFolder, long parentId);
130 private static native String nativeGetDomainAndRegistry(String url);
131 private static native void nativeCreateHistoricalTabFromState(
132 byte[] state, int tab_index);
133 private native byte[] nativeGetStateAsByteArray(View view);
134 private static native String[] nativeGetAutofillProfileGUIDs();
135 private native void nativeSetRecognitionResults(
136 int sessionId, String[] results);
137 private native long nativeAddBookmarkFromAPI(
138 int nativeChromeBrowserProvider,
139 String url, Long created, Boolean isBookmark,
140 Long date, byte[] favicon, String title, Integer visits);
141 native int nativeFindAll(String find);
142 private static native OnFrameAvailableListener nativeGetInnerClass();
143 private native Bitmap nativeQueryBitmap(
144 int nativeChromeBrowserProvider,
145 String[] projection, String selection,
146 String[] selectionArgs, String sortOrder);
147 private native void nativeGotOrientation(
148 int nativeDataFetcherImplAndroid,
149 double alpha, double beta, double gamma);
151 jni_generator.JniParams.SetFullyQualifiedClass(
152 'org/chromium/example/jni_generator/SampleForTests')
153 jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
154 natives = jni_generator.ExtractNatives(test_data, 'int')
155 golden_natives = [
156 NativeMethod(return_type='int', static=False,
157 name='Init',
158 params=[],
159 java_class_name=None,
160 type='function'),
161 NativeMethod(return_type='void', static=False, name='Destroy',
162 params=[Param(datatype='int',
163 name='nativeChromeBrowserProvider')],
164 java_class_name=None,
165 type='method',
166 p0_type='ChromeBrowserProvider'),
167 NativeMethod(return_type='long', static=False, name='AddBookmark',
168 params=[Param(datatype='int',
169 name='nativeChromeBrowserProvider'),
170 Param(datatype='String',
171 name='url'),
172 Param(datatype='String',
173 name='title'),
174 Param(datatype='boolean',
175 name='isFolder'),
176 Param(datatype='long',
177 name='parentId')],
178 java_class_name=None,
179 type='method',
180 p0_type='ChromeBrowserProvider'),
181 NativeMethod(return_type='String', static=True,
182 name='GetDomainAndRegistry',
183 params=[Param(datatype='String',
184 name='url')],
185 java_class_name=None,
186 type='function'),
187 NativeMethod(return_type='void', static=True,
188 name='CreateHistoricalTabFromState',
189 params=[Param(datatype='byte[]',
190 name='state'),
191 Param(datatype='int',
192 name='tab_index')],
193 java_class_name=None,
194 type='function'),
195 NativeMethod(return_type='byte[]', static=False,
196 name='GetStateAsByteArray',
197 params=[Param(datatype='View', name='view')],
198 java_class_name=None,
199 type='function'),
200 NativeMethod(return_type='String[]', static=True,
201 name='GetAutofillProfileGUIDs', params=[],
202 java_class_name=None,
203 type='function'),
204 NativeMethod(return_type='void', static=False,
205 name='SetRecognitionResults',
206 params=[Param(datatype='int', name='sessionId'),
207 Param(datatype='String[]', name='results')],
208 java_class_name=None,
209 type='function'),
210 NativeMethod(return_type='long', static=False,
211 name='AddBookmarkFromAPI',
212 params=[Param(datatype='int',
213 name='nativeChromeBrowserProvider'),
214 Param(datatype='String',
215 name='url'),
216 Param(datatype='Long',
217 name='created'),
218 Param(datatype='Boolean',
219 name='isBookmark'),
220 Param(datatype='Long',
221 name='date'),
222 Param(datatype='byte[]',
223 name='favicon'),
224 Param(datatype='String',
225 name='title'),
226 Param(datatype='Integer',
227 name='visits')],
228 java_class_name=None,
229 type='method',
230 p0_type='ChromeBrowserProvider'),
231 NativeMethod(return_type='int', static=False,
232 name='FindAll',
233 params=[Param(datatype='String',
234 name='find')],
235 java_class_name=None,
236 type='function'),
237 NativeMethod(return_type='OnFrameAvailableListener', static=True,
238 name='GetInnerClass',
239 params=[],
240 java_class_name=None,
241 type='function'),
242 NativeMethod(return_type='Bitmap',
243 static=False,
244 name='QueryBitmap',
245 params=[Param(datatype='int',
246 name='nativeChromeBrowserProvider'),
247 Param(datatype='String[]',
248 name='projection'),
249 Param(datatype='String',
250 name='selection'),
251 Param(datatype='String[]',
252 name='selectionArgs'),
253 Param(datatype='String',
254 name='sortOrder'),
256 java_class_name=None,
257 type='method',
258 p0_type='ChromeBrowserProvider'),
259 NativeMethod(return_type='void', static=False,
260 name='GotOrientation',
261 params=[Param(datatype='int',
262 name='nativeDataFetcherImplAndroid'),
263 Param(datatype='double',
264 name='alpha'),
265 Param(datatype='double',
266 name='beta'),
267 Param(datatype='double',
268 name='gamma'),
270 java_class_name=None,
271 type='method',
272 p0_type='content::DataFetcherImplAndroid'),
274 self.assertListEquals(golden_natives, natives)
275 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
276 natives, [], [], TestOptions())
277 self.assertGoldenTextEquals(h.GetContent())
279 def testInnerClassNatives(self):
280 test_data = """
281 class MyInnerClass {
282 @NativeCall("MyInnerClass")
283 private native int nativeInit();
286 natives = jni_generator.ExtractNatives(test_data, 'int')
287 golden_natives = [
288 NativeMethod(return_type='int', static=False,
289 name='Init', params=[],
290 java_class_name='MyInnerClass',
291 type='function')
293 self.assertListEquals(golden_natives, natives)
294 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
295 natives, [], [], TestOptions())
296 self.assertGoldenTextEquals(h.GetContent())
298 def testInnerClassNativesMultiple(self):
299 test_data = """
300 class MyInnerClass {
301 @NativeCall("MyInnerClass")
302 private native int nativeInit();
304 class MyOtherInnerClass {
305 @NativeCall("MyOtherInnerClass")
306 private native int nativeInit();
309 natives = jni_generator.ExtractNatives(test_data, 'int')
310 golden_natives = [
311 NativeMethod(return_type='int', static=False,
312 name='Init', params=[],
313 java_class_name='MyInnerClass',
314 type='function'),
315 NativeMethod(return_type='int', static=False,
316 name='Init', params=[],
317 java_class_name='MyOtherInnerClass',
318 type='function')
320 self.assertListEquals(golden_natives, natives)
321 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
322 natives, [], [], TestOptions())
323 self.assertGoldenTextEquals(h.GetContent())
325 def testInnerClassNativesBothInnerAndOuter(self):
326 test_data = """
327 class MyOuterClass {
328 private native int nativeInit();
329 class MyOtherInnerClass {
330 @NativeCall("MyOtherInnerClass")
331 private native int nativeInit();
335 natives = jni_generator.ExtractNatives(test_data, 'int')
336 golden_natives = [
337 NativeMethod(return_type='int', static=False,
338 name='Init', params=[],
339 java_class_name=None,
340 type='function'),
341 NativeMethod(return_type='int', static=False,
342 name='Init', params=[],
343 java_class_name='MyOtherInnerClass',
344 type='function')
346 self.assertListEquals(golden_natives, natives)
347 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
348 natives, [], [], TestOptions())
349 self.assertGoldenTextEquals(h.GetContent())
351 def testCalledByNatives(self):
352 test_data = """"
353 import android.graphics.Bitmap;
354 import android.view.View;
355 import java.io.InputStream;
356 import java.util.List;
358 class InnerClass {}
360 @CalledByNative
361 InnerClass showConfirmInfoBar(int nativeInfoBar,
362 String buttonOk, String buttonCancel, String title, Bitmap icon) {
363 InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext,
364 buttonOk, buttonCancel,
365 title, icon);
366 return infobar;
368 @CalledByNative
369 InnerClass showAutoLoginInfoBar(int nativeInfoBar,
370 String realm, String account, String args) {
371 AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext,
372 realm, account, args);
373 if (infobar.displayedAccountCount() == 0)
374 infobar = null;
375 return infobar;
377 @CalledByNative("InfoBar")
378 void dismiss();
379 @SuppressWarnings("unused")
380 @CalledByNative
381 private static boolean shouldShowAutoLogin(View view,
382 String realm, String account, String args) {
383 AccountManagerContainer accountManagerContainer =
384 new AccountManagerContainer((Activity)contentView.getContext(),
385 realm, account, args);
386 String[] logins = accountManagerContainer.getAccountLogins(null);
387 return logins.length != 0;
389 @CalledByNative
390 static InputStream openUrl(String url) {
391 return null;
393 @CalledByNative
394 private void activateHardwareAcceleration(final boolean activated,
395 final int iPid, final int iType,
396 final int iPrimaryID, final int iSecondaryID) {
397 if (!activated) {
398 return
401 @CalledByNativeUnchecked
402 private void uncheckedCall(int iParam);
404 @CalledByNative
405 public byte[] returnByteArray();
407 @CalledByNative
408 public boolean[] returnBooleanArray();
410 @CalledByNative
411 public char[] returnCharArray();
413 @CalledByNative
414 public short[] returnShortArray();
416 @CalledByNative
417 public int[] returnIntArray();
419 @CalledByNative
420 public long[] returnLongArray();
422 @CalledByNative
423 public double[] returnDoubleArray();
425 @CalledByNative
426 public Object[] returnObjectArray();
428 @CalledByNative
429 public byte[][] returnArrayOfByteArray();
431 @CalledByNative
432 public Bitmap.CompressFormat getCompressFormat();
434 @CalledByNative
435 public List<Bitmap.CompressFormat> getCompressFormatList();
437 jni_generator.JniParams.SetFullyQualifiedClass('org/chromium/Foo')
438 jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
439 called_by_natives = jni_generator.ExtractCalledByNatives(test_data)
440 golden_called_by_natives = [
441 CalledByNative(
442 return_type='InnerClass',
443 system_class=False,
444 static=False,
445 name='showConfirmInfoBar',
446 method_id_var_name='showConfirmInfoBar',
447 java_class_name='',
448 params=[Param(datatype='int', name='nativeInfoBar'),
449 Param(datatype='String', name='buttonOk'),
450 Param(datatype='String', name='buttonCancel'),
451 Param(datatype='String', name='title'),
452 Param(datatype='Bitmap', name='icon')],
453 env_call=('Object', ''),
454 unchecked=False,
456 CalledByNative(
457 return_type='InnerClass',
458 system_class=False,
459 static=False,
460 name='showAutoLoginInfoBar',
461 method_id_var_name='showAutoLoginInfoBar',
462 java_class_name='',
463 params=[Param(datatype='int', name='nativeInfoBar'),
464 Param(datatype='String', name='realm'),
465 Param(datatype='String', name='account'),
466 Param(datatype='String', name='args')],
467 env_call=('Object', ''),
468 unchecked=False,
470 CalledByNative(
471 return_type='void',
472 system_class=False,
473 static=False,
474 name='dismiss',
475 method_id_var_name='dismiss',
476 java_class_name='InfoBar',
477 params=[],
478 env_call=('Void', ''),
479 unchecked=False,
481 CalledByNative(
482 return_type='boolean',
483 system_class=False,
484 static=True,
485 name='shouldShowAutoLogin',
486 method_id_var_name='shouldShowAutoLogin',
487 java_class_name='',
488 params=[Param(datatype='View', name='view'),
489 Param(datatype='String', name='realm'),
490 Param(datatype='String', name='account'),
491 Param(datatype='String', name='args')],
492 env_call=('Boolean', ''),
493 unchecked=False,
495 CalledByNative(
496 return_type='InputStream',
497 system_class=False,
498 static=True,
499 name='openUrl',
500 method_id_var_name='openUrl',
501 java_class_name='',
502 params=[Param(datatype='String', name='url')],
503 env_call=('Object', ''),
504 unchecked=False,
506 CalledByNative(
507 return_type='void',
508 system_class=False,
509 static=False,
510 name='activateHardwareAcceleration',
511 method_id_var_name='activateHardwareAcceleration',
512 java_class_name='',
513 params=[Param(datatype='boolean', name='activated'),
514 Param(datatype='int', name='iPid'),
515 Param(datatype='int', name='iType'),
516 Param(datatype='int', name='iPrimaryID'),
517 Param(datatype='int', name='iSecondaryID'),
519 env_call=('Void', ''),
520 unchecked=False,
522 CalledByNative(
523 return_type='void',
524 system_class=False,
525 static=False,
526 name='uncheckedCall',
527 method_id_var_name='uncheckedCall',
528 java_class_name='',
529 params=[Param(datatype='int', name='iParam')],
530 env_call=('Void', ''),
531 unchecked=True,
533 CalledByNative(
534 return_type='byte[]',
535 system_class=False,
536 static=False,
537 name='returnByteArray',
538 method_id_var_name='returnByteArray',
539 java_class_name='',
540 params=[],
541 env_call=('Void', ''),
542 unchecked=False,
544 CalledByNative(
545 return_type='boolean[]',
546 system_class=False,
547 static=False,
548 name='returnBooleanArray',
549 method_id_var_name='returnBooleanArray',
550 java_class_name='',
551 params=[],
552 env_call=('Void', ''),
553 unchecked=False,
555 CalledByNative(
556 return_type='char[]',
557 system_class=False,
558 static=False,
559 name='returnCharArray',
560 method_id_var_name='returnCharArray',
561 java_class_name='',
562 params=[],
563 env_call=('Void', ''),
564 unchecked=False,
566 CalledByNative(
567 return_type='short[]',
568 system_class=False,
569 static=False,
570 name='returnShortArray',
571 method_id_var_name='returnShortArray',
572 java_class_name='',
573 params=[],
574 env_call=('Void', ''),
575 unchecked=False,
577 CalledByNative(
578 return_type='int[]',
579 system_class=False,
580 static=False,
581 name='returnIntArray',
582 method_id_var_name='returnIntArray',
583 java_class_name='',
584 params=[],
585 env_call=('Void', ''),
586 unchecked=False,
588 CalledByNative(
589 return_type='long[]',
590 system_class=False,
591 static=False,
592 name='returnLongArray',
593 method_id_var_name='returnLongArray',
594 java_class_name='',
595 params=[],
596 env_call=('Void', ''),
597 unchecked=False,
599 CalledByNative(
600 return_type='double[]',
601 system_class=False,
602 static=False,
603 name='returnDoubleArray',
604 method_id_var_name='returnDoubleArray',
605 java_class_name='',
606 params=[],
607 env_call=('Void', ''),
608 unchecked=False,
610 CalledByNative(
611 return_type='Object[]',
612 system_class=False,
613 static=False,
614 name='returnObjectArray',
615 method_id_var_name='returnObjectArray',
616 java_class_name='',
617 params=[],
618 env_call=('Void', ''),
619 unchecked=False,
621 CalledByNative(
622 return_type='byte[][]',
623 system_class=False,
624 static=False,
625 name='returnArrayOfByteArray',
626 method_id_var_name='returnArrayOfByteArray',
627 java_class_name='',
628 params=[],
629 env_call=('Void', ''),
630 unchecked=False,
632 CalledByNative(
633 return_type='Bitmap.CompressFormat',
634 system_class=False,
635 static=False,
636 name='getCompressFormat',
637 method_id_var_name='getCompressFormat',
638 java_class_name='',
639 params=[],
640 env_call=('Void', ''),
641 unchecked=False,
643 CalledByNative(
644 return_type='List<Bitmap.CompressFormat>',
645 system_class=False,
646 static=False,
647 name='getCompressFormatList',
648 method_id_var_name='getCompressFormatList',
649 java_class_name='',
650 params=[],
651 env_call=('Void', ''),
652 unchecked=False,
655 self.assertListEquals(golden_called_by_natives, called_by_natives)
656 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
657 [], called_by_natives, [],
658 TestOptions())
659 self.assertGoldenTextEquals(h.GetContent())
661 def testCalledByNativeParseError(self):
662 try:
663 jni_generator.ExtractCalledByNatives("""
664 @CalledByNative
665 public static int foo(); // This one is fine
667 @CalledByNative
668 scooby doo
669 """)
670 self.fail('Expected a ParseError')
671 except jni_generator.ParseError, e:
672 self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines)
674 def testFullyQualifiedClassName(self):
675 contents = """
676 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
677 // Use of this source code is governed by a BSD-style license that can be
678 // found in the LICENSE file.
680 package org.chromium.content.browser;
682 import org.chromium.base.BuildInfo;
684 self.assertEquals('org/chromium/content/browser/Foo',
685 jni_generator.ExtractFullyQualifiedJavaClassName(
686 'org/chromium/content/browser/Foo.java', contents))
687 self.assertEquals('org/chromium/content/browser/Foo',
688 jni_generator.ExtractFullyQualifiedJavaClassName(
689 'frameworks/Foo.java', contents))
690 self.assertRaises(SyntaxError,
691 jni_generator.ExtractFullyQualifiedJavaClassName,
692 'com/foo/Bar', 'no PACKAGE line')
694 def testMethodNameMangling(self):
695 self.assertEquals('closeV',
696 jni_generator.GetMangledMethodName('close', [], 'void'))
697 self.assertEquals('readI_AB_I_I',
698 jni_generator.GetMangledMethodName('read',
699 [Param(name='p1',
700 datatype='byte[]'),
701 Param(name='p2',
702 datatype='int'),
703 Param(name='p3',
704 datatype='int'),],
705 'int'))
706 self.assertEquals('openJIIS_JLS',
707 jni_generator.GetMangledMethodName('open',
708 [Param(name='p1',
709 datatype='java/lang/String'),],
710 'java/io/InputStream'))
712 def testFromJavaPGenerics(self):
713 contents = """
714 public abstract class java.util.HashSet<T> extends java.util.AbstractSet<E>
715 implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
716 public void dummy();
717 Signature: ()V
720 jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
721 TestOptions())
722 self.assertEquals(1, len(jni_from_javap.called_by_natives))
723 self.assertGoldenTextEquals(jni_from_javap.GetContent())
725 def testSnippnetJavap6_7(self):
726 content_javap6 = """
727 public class java.util.HashSet {
728 public boolean add(java.lang.Object);
729 Signature: (Ljava/lang/Object;)Z
733 content_javap7 = """
734 public class java.util.HashSet {
735 public boolean add(E);
736 Signature: (Ljava/lang/Object;)Z
739 jni_from_javap6 = jni_generator.JNIFromJavaP(content_javap6.split('\n'),
740 TestOptions())
741 jni_from_javap7 = jni_generator.JNIFromJavaP(content_javap7.split('\n'),
742 TestOptions())
743 self.assertTrue(jni_from_javap6.GetContent())
744 self.assertTrue(jni_from_javap7.GetContent())
745 # Ensure the javap7 is correctly parsed and uses the Signature field rather
746 # than the "E" parameter.
747 self.assertTextEquals(jni_from_javap6.GetContent(),
748 jni_from_javap7.GetContent())
750 def testFromJavaP(self):
751 contents = self._ReadGoldenFile(os.path.join(os.path.dirname(sys.argv[0]),
752 'testInputStream.javap'))
753 jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
754 TestOptions())
755 self.assertEquals(10, len(jni_from_javap.called_by_natives))
756 self.assertGoldenTextEquals(jni_from_javap.GetContent())
758 def testConstantsFromJavaP(self):
759 for f in ['testMotionEvent.javap', 'testMotionEvent.javap7']:
760 contents = self._ReadGoldenFile(os.path.join(os.path.dirname(sys.argv[0]),
762 jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
763 TestOptions())
764 self.assertEquals(86, len(jni_from_javap.called_by_natives))
765 self.assertGoldenTextEquals(jni_from_javap.GetContent())
767 def testREForNatives(self):
768 # We should not match "native SyncSetupFlow" inside the comment.
769 test_data = """
771 * Invoked when the setup process is complete so we can disconnect from the
772 * native-side SyncSetupFlowHandler.
774 public void destroy() {
775 Log.v(TAG, "Destroying native SyncSetupFlow");
776 if (mNativeSyncSetupFlow != 0) {
777 nativeSyncSetupEnded(mNativeSyncSetupFlow);
778 mNativeSyncSetupFlow = 0;
781 private native void nativeSyncSetupEnded(
782 int nativeAndroidSyncSetupFlowHandler);
784 jni_from_java = jni_generator.JNIFromJavaSource(
785 test_data, 'foo/bar', TestOptions())
787 def testRaisesOnNonJNIMethod(self):
788 test_data = """
789 class MyInnerClass {
790 private int Foo(int p0) {
794 self.assertRaises(SyntaxError,
795 jni_generator.JNIFromJavaSource,
796 test_data, 'foo/bar', TestOptions())
798 def testJniSelfDocumentingExample(self):
799 script_dir = os.path.dirname(sys.argv[0])
800 content = file(os.path.join(script_dir,
801 'java/src/org/chromium/example/jni_generator/SampleForTests.java')
802 ).read()
803 golden_file = os.path.join(script_dir, 'golden_sample_for_tests_jni.h')
804 golden_content = file(golden_file).read()
805 jni_from_java = jni_generator.JNIFromJavaSource(
806 content, 'org/chromium/example/jni_generator/SampleForTests',
807 TestOptions())
808 generated_text = jni_from_java.GetContent()
809 if not self.compareText(golden_content, generated_text):
810 if os.environ.get(REBASELINE_ENV):
811 with file(golden_file, 'w') as f:
812 f.write(generated_text)
813 return
814 self.fail('testJniSelfDocumentingExample')
816 def testNoWrappingPreprocessorLines(self):
817 test_data = """
818 package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday;
820 class ReallyLongClassNamesAreAllTheRage {
821 private static native int nativeTest();
824 jni_from_java = jni_generator.JNIFromJavaSource(
825 test_data, ('com/google/lookhowextremelylongiam/snarf/'
826 'icankeepthisupallday/ReallyLongClassNamesAreAllTheRage'),
827 TestOptions())
828 jni_lines = jni_from_java.GetContent().split('\n')
829 line = filter(lambda line: line.lstrip().startswith('#ifndef'),
830 jni_lines)[0]
831 self.assertTrue(len(line) > 80,
832 ('Expected #ifndef line to be > 80 chars: ', line))
834 def testJarJarRemapping(self):
835 test_data = """
836 package org.chromium.example.jni_generator;
838 import org.chromium.example2.Test;
840 import org.chromium.example3.PrefixFoo;
841 import org.chromium.example3.Prefix;
842 import org.chromium.example3.Bar$Inner;
844 class Example {
845 private static native void nativeTest(Test t);
846 private static native void nativeTest2(PrefixFoo t);
847 private static native void nativeTest3(Prefix t);
848 private static native void nativeTest4(Bar$Inner t);
851 jni_generator.JniParams.SetJarJarMappings(
852 """rule org.chromium.example.** com.test.@1
853 rule org.chromium.example2.** org.test2.@1
854 rule org.chromium.example3.Prefix org.test3.Test
855 rule org.chromium.example3.Bar$** org.test3.TestBar$@1""")
856 jni_from_java = jni_generator.JNIFromJavaSource(
857 test_data, 'org/chromium/example/jni_generator/Example', TestOptions())
858 jni_generator.JniParams.SetJarJarMappings('')
859 self.assertGoldenTextEquals(jni_from_java.GetContent())
861 def testImports(self):
862 import_header = """
863 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
864 // Use of this source code is governed by a BSD-style license that can be
865 // found in the LICENSE file.
867 package org.chromium.content.app;
869 import android.app.Service;
870 import android.content.Context;
871 import android.content.Intent;
872 import android.graphics.SurfaceTexture;
873 import android.os.Bundle;
874 import android.os.IBinder;
875 import android.os.ParcelFileDescriptor;
876 import android.os.Process;
877 import android.os.RemoteException;
878 import android.util.Log;
879 import android.view.Surface;
881 import java.util.ArrayList;
883 import org.chromium.base.CalledByNative;
884 import org.chromium.base.JNINamespace;
885 import org.chromium.content.app.ContentMain;
886 import org.chromium.content.browser.SandboxedProcessConnection;
887 import org.chromium.content.common.ISandboxedProcessCallback;
888 import org.chromium.content.common.ISandboxedProcessService;
889 import org.chromium.content.common.WillNotRaise.AnException;
890 import org.chromium.content.common.WillRaise.AnException;
892 import static org.chromium.Bar.Zoo;
894 class Foo {
895 public static class BookmarkNode implements Parcelable {
897 public interface PasswordListObserver {
901 jni_generator.JniParams.SetFullyQualifiedClass(
902 'org/chromium/content/app/Foo')
903 jni_generator.JniParams.ExtractImportsAndInnerClasses(import_header)
904 self.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in
905 jni_generator.JniParams._imports)
906 self.assertTrue('Lorg/chromium/Bar/Zoo' in
907 jni_generator.JniParams._imports)
908 self.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in
909 jni_generator.JniParams._inner_classes)
910 self.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in
911 jni_generator.JniParams._inner_classes)
912 self.assertEquals('Lorg/chromium/content/app/ContentMain$Inner;',
913 jni_generator.JniParams.JavaToJni('ContentMain.Inner'))
914 self.assertRaises(SyntaxError,
915 jni_generator.JniParams.JavaToJni,
916 'AnException')
918 def testJniParamsJavaToJni(self):
919 self.assertTextEquals('I', JniParams.JavaToJni('int'))
920 self.assertTextEquals('[B', JniParams.JavaToJni('byte[]'))
921 self.assertTextEquals(
922 '[Ljava/nio/ByteBuffer;', JniParams.JavaToJni('java/nio/ByteBuffer[]'))
924 def testNativesLong(self):
925 test_options = TestOptions()
926 test_options.ptr_type = 'long'
927 test_data = """"
928 private native void nativeDestroy(long nativeChromeBrowserProvider);
930 jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
931 natives = jni_generator.ExtractNatives(test_data, test_options.ptr_type)
932 golden_natives = [
933 NativeMethod(return_type='void', static=False, name='Destroy',
934 params=[Param(datatype='long',
935 name='nativeChromeBrowserProvider')],
936 java_class_name=None,
937 type='method',
938 p0_type='ChromeBrowserProvider',
939 ptr_type=test_options.ptr_type),
941 self.assertListEquals(golden_natives, natives)
942 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
943 natives, [], [], test_options)
944 self.assertGoldenTextEquals(h.GetContent())
946 def testPureNativeMethodsOption(self):
947 test_data = """
948 package org.chromium.example.jni_generator;
950 /** The pointer to the native Test. */
951 long nativeTest;
953 class Test {
954 private static native long nativeMethod(long nativeTest, int arg1);
957 options = TestOptions()
958 options.pure_native_methods = True
959 jni_from_java = jni_generator.JNIFromJavaSource(
960 test_data, 'org/chromium/example/jni_generator/Test', options)
961 self.assertGoldenTextEquals(jni_from_java.GetContent())
963 def testJNIInitNativeNameOption(self):
964 test_data = """
965 package org.chromium.example.jni_generator;
967 /** The pointer to the native Test. */
968 long nativeTest;
970 class Test {
971 private static native boolean nativeInitNativeClass();
972 private static native int nativeMethod(long nativeTest, int arg1);
975 options = TestOptions()
976 options.jni_init_native_name = 'nativeInitNativeClass'
977 jni_from_java = jni_generator.JNIFromJavaSource(
978 test_data, 'org/chromium/example/jni_generator/Test', options)
979 self.assertGoldenTextEquals(jni_from_java.GetContent())
981 def testEagerCalledByNativesOption(self):
982 test_data = """
983 package org.chromium.example.jni_generator;
985 /** The pointer to the native Test. */
986 long nativeTest;
988 class Test {
989 private static native boolean nativeInitNativeClass();
990 private static native int nativeMethod(long nativeTest, int arg1);
991 @CalledByNative
992 private void testMethodWithParam(int iParam);
993 @CalledByNative
994 private static int testStaticMethodWithParam(int iParam);
995 @CalledByNative
996 private static double testMethodWithNoParam();
997 @CalledByNative
998 private static String testStaticMethodWithNoParam();
1001 options = TestOptions()
1002 options.jni_init_native_name = 'nativeInitNativeClass'
1003 options.eager_called_by_natives = True
1004 jni_from_java = jni_generator.JNIFromJavaSource(
1005 test_data, 'org/chromium/example/jni_generator/Test', options)
1006 self.assertGoldenTextEquals(jni_from_java.GetContent())
1008 def testNativeExportsOption(self):
1009 test_data = """
1010 package org.chromium.example.jni_generator;
1012 /** The pointer to the native Test. */
1013 long nativeTest;
1015 class Test {
1016 private static native boolean nativeInitNativeClass();
1017 private static native int nativeStaticMethod(long nativeTest, int arg1);
1018 private native int nativeMethod(long nativeTest, int arg1);
1019 @CalledByNative
1020 private void testMethodWithParam(int iParam);
1021 @CalledByNative
1022 private String testMethodWithParamAndReturn(int iParam);
1023 @CalledByNative
1024 private static int testStaticMethodWithParam(int iParam);
1025 @CalledByNative
1026 private static double testMethodWithNoParam();
1027 @CalledByNative
1028 private static String testStaticMethodWithNoParam();
1030 class MyInnerClass {
1031 @NativeCall("MyInnerClass")
1032 private native int nativeInit();
1034 class MyOtherInnerClass {
1035 @NativeCall("MyOtherInnerClass")
1036 private native int nativeInit();
1040 options = TestOptions()
1041 options.jni_init_native_name = 'nativeInitNativeClass'
1042 options.native_exports = True
1043 jni_from_java = jni_generator.JNIFromJavaSource(
1044 test_data, 'org/chromium/example/jni_generator/SampleForTests', options)
1045 self.assertGoldenTextEquals(jni_from_java.GetContent())
1047 def testOuterInnerRaises(self):
1048 test_data = """
1049 package org.chromium.media;
1051 @CalledByNative
1052 static int getCaptureFormatWidth(VideoCapture.CaptureFormat format) {
1053 return format.getWidth();
1056 def willRaise():
1057 jni_generator.JNIFromJavaSource(
1058 test_data,
1059 'org/chromium/media/VideoCaptureFactory',
1060 TestOptions())
1061 self.assertRaises(SyntaxError, willRaise)
1063 def testImplicitImport(self):
1064 test_data = """
1065 package org.chromium.android_webview;
1067 %(IMPORT)s
1069 @CalledByNative
1070 private static void clientCertificatesCleared(Runnable callback) {
1071 if (callbaback == null) return;
1072 callback.run();
1075 def generate(import_clause):
1076 jni_generator.JNIFromJavaSource(
1077 test_data % {'IMPORT': import_clause},
1078 'org/chromium/android_webview/AwContentStatics',
1079 TestOptions())
1080 # Ensure it raises without the import.
1081 self.assertRaises(SyntaxError, lambda: generate(''))
1083 # Ensure it's fine with the import.
1084 generate('import java.lang.Runnable;')
1086 def testSingleJNIAdditionalImport(self):
1087 test_data = """
1088 package org.chromium.foo;
1090 @JNIAdditionalImport(Bar.class)
1091 class Foo {
1093 @CalledByNative
1094 private static void calledByNative(Bar.Callback callback) {
1097 private static native void nativeDoSomething(Bar.Callback callback);
1100 jni_from_java = jni_generator.JNIFromJavaSource(test_data,
1101 'org/chromium/foo/Foo',
1102 TestOptions())
1103 self.assertGoldenTextEquals(jni_from_java.GetContent())
1105 def testMultipleJNIAdditionalImport(self):
1106 test_data = """
1107 package org.chromium.foo;
1109 @JNIAdditionalImport({Bar1.class, Bar2.class})
1110 class Foo {
1112 @CalledByNative
1113 private static void calledByNative(Bar1.Callback callback1,
1114 Bar2.Callback callback2) {
1117 private static native void nativeDoSomething(Bar1.Callback callback1,
1118 Bar2.Callback callback2);
1121 jni_from_java = jni_generator.JNIFromJavaSource(test_data,
1122 'org/chromium/foo/Foo',
1123 TestOptions())
1124 self.assertGoldenTextEquals(jni_from_java.GetContent())
1127 if __name__ == '__main__':
1128 unittest.main()