OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Tests for jni_generator.py. | 6 """Tests for jni_generator.py. |
7 | 7 |
8 This test suite contains various tests for the JNI generator. | 8 This test suite contains various tests for the JNI generator. |
9 It exercises the low-level parser all the way up to the | 9 It exercises the low-level parser all the way up to the |
10 code generator and ensures the output matches a golden | 10 code generator and ensures the output matches a golden |
11 file. | 11 file. |
12 """ | 12 """ |
13 | 13 |
14 import difflib | 14 import difflib |
15 import inspect | 15 import inspect |
16 import os | 16 import os |
17 import sys | 17 import sys |
18 import unittest | 18 import unittest |
19 import jni_generator | 19 import jni_generator |
20 from jni_generator import CalledByNative, JniParams, NativeMethod, Param | 20 from jni_generator import CalledByNative, JniParams, NativeMethod, Param |
21 | 21 |
22 | 22 |
23 SCRIPT_NAME = 'base/android/jni_generator/jni_generator.py' | 23 SCRIPT_NAME = 'base/android/jni_generator/jni_generator.py' |
| 24 INCLUDES = ( |
| 25 'base/android/jni_generator/jni_generator_helper.h' |
| 26 ) |
24 | 27 |
25 # Set this environment variable in order to regenerate the golden text | 28 # Set this environment variable in order to regenerate the golden text |
26 # files. | 29 # files. |
27 REBASELINE_ENV = 'REBASELINE' | 30 REBASELINE_ENV = 'REBASELINE' |
28 | 31 |
29 class TestOptions(object): | 32 class TestOptions(object): |
30 """The mock options object which is passed to the jni_generator.py script.""" | 33 """The mock options object which is passed to the jni_generator.py script.""" |
31 | 34 |
32 def __init__(self): | 35 def __init__(self): |
33 self.namespace = None | 36 self.namespace = None |
34 self.script_name = SCRIPT_NAME | 37 self.script_name = SCRIPT_NAME |
| 38 self.includes = INCLUDES |
| 39 self.pure_native_methods = False |
35 self.ptr_type = 'int' | 40 self.ptr_type = 'int' |
| 41 self.jni_init_native_name = None |
| 42 self.eager_called_by_natives = False |
36 | 43 |
37 | 44 |
38 class TestGenerator(unittest.TestCase): | 45 class TestGenerator(unittest.TestCase): |
39 def assertObjEquals(self, first, second): | 46 def assertObjEquals(self, first, second): |
40 dict_first = first.__dict__ | 47 dict_first = first.__dict__ |
41 dict_second = second.__dict__ | 48 dict_second = second.__dict__ |
42 self.assertEquals(dict_first.keys(), dict_second.keys()) | 49 self.assertEquals(dict_first.keys(), dict_second.keys()) |
43 for key, value in dict_first.iteritems(): | 50 for key, value in dict_first.iteritems(): |
44 if (type(value) is list and len(value) and | 51 if (type(value) is list and len(value) and |
45 isinstance(type(value[0]), object)): | 52 isinstance(type(value[0]), object)): |
46 self.assertListEquals(value, second.__getattribute__(key)) | 53 self.assertListEquals(value, second.__getattribute__(key)) |
47 else: | 54 else: |
48 actual = second.__getattribute__(key) | 55 actual = second.__getattribute__(key) |
49 self.assertEquals(value, actual, | 56 self.assertEquals(value, actual, |
50 'Key ' + key + ': ' + str(value) + '!=' + str(actual)) | 57 'Key ' + key + ': ' + str(value) + '!=' + str(actual)) |
51 | 58 |
52 def assertListEquals(self, first, second): | 59 def assertListEquals(self, first, second): |
53 self.assertEquals(len(first), len(second)) | 60 self.assertEquals(len(first), len(second)) |
54 for i in xrange(len(first)): | 61 for i in xrange(len(first)): |
55 if isinstance(first[i], object): | 62 if isinstance(first[i], object): |
56 self.assertObjEquals(first[i], second[i]) | 63 self.assertObjEquals(first[i], second[i]) |
57 else: | 64 else: |
58 self.assertEquals(first[i], second[i]) | 65 self.assertEquals(first[i], second[i]) |
59 | 66 |
60 def assertTextEquals(self, golden_text, generated_text): | 67 def assertTextEquals(self, golden_text, generated_text): |
| 68 if not self.compareText(golden_text, generated_text): |
| 69 self.fail('Golden text mismatch.') |
| 70 |
| 71 def compareText(self, golden_text, generated_text): |
61 def FilterText(text): | 72 def FilterText(text): |
62 return [ | 73 return [ |
63 l.strip() for l in text.split('\n') | 74 l.strip() for l in text.split('\n') |
64 if not l.startswith('// Copyright') | 75 if not l.startswith('// Copyright') |
65 ] | 76 ] |
66 stripped_golden = FilterText(golden_text) | 77 stripped_golden = FilterText(golden_text) |
67 stripped_generated = FilterText(generated_text) | 78 stripped_generated = FilterText(generated_text) |
68 if stripped_golden != stripped_generated: | 79 if stripped_golden == stripped_generated: |
69 print self.id() | 80 return True |
70 for line in difflib.context_diff(stripped_golden, stripped_generated): | 81 print self.id() |
71 print line | 82 for line in difflib.context_diff(stripped_golden, stripped_generated): |
72 print '\n\nGenerated' | 83 print line |
73 print '=' * 80 | 84 print '\n\nGenerated' |
74 print generated_text | 85 print '=' * 80 |
75 print '=' * 80 | 86 print generated_text |
76 print 'Run with:' | 87 print '=' * 80 |
77 print 'REBASELINE=1', sys.argv[0] | 88 print 'Run with:' |
78 print 'to regenerate the data files.' | 89 print 'REBASELINE=1', sys.argv[0] |
79 self.fail('Golden text mismatch.') | 90 print 'to regenerate the data files.' |
80 | 91 |
81 def _ReadGoldenFile(self, golden_file): | 92 def _ReadGoldenFile(self, golden_file): |
82 if not os.path.exists(golden_file): | 93 if not os.path.exists(golden_file): |
83 return None | 94 return None |
84 with file(golden_file, 'r') as f: | 95 with file(golden_file, 'r') as f: |
85 return f.read() | 96 return f.read() |
86 | 97 |
87 def assertGoldenTextEquals(self, generated_text): | 98 def assertGoldenTextEquals(self, generated_text): |
88 script_dir = os.path.dirname(sys.argv[0]) | 99 script_dir = os.path.dirname(sys.argv[0]) |
89 # This is the caller test method. | 100 # This is the caller test method. |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 """ | 803 """ |
793 self.assertRaises(SyntaxError, | 804 self.assertRaises(SyntaxError, |
794 jni_generator.JNIFromJavaSource, | 805 jni_generator.JNIFromJavaSource, |
795 test_data, 'foo/bar', TestOptions()) | 806 test_data, 'foo/bar', TestOptions()) |
796 | 807 |
797 def testJniSelfDocumentingExample(self): | 808 def testJniSelfDocumentingExample(self): |
798 script_dir = os.path.dirname(sys.argv[0]) | 809 script_dir = os.path.dirname(sys.argv[0]) |
799 content = file(os.path.join(script_dir, | 810 content = file(os.path.join(script_dir, |
800 'java/src/org/chromium/example/jni_generator/SampleForTests.java') | 811 'java/src/org/chromium/example/jni_generator/SampleForTests.java') |
801 ).read() | 812 ).read() |
802 golden_content = file(os.path.join(script_dir, | 813 golden_file = os.path.join(script_dir, 'golden_sample_for_tests_jni.h') |
803 'golden_sample_for_tests_jni.h')).read() | 814 golden_content = file(golden_file).read() |
804 jni_from_java = jni_generator.JNIFromJavaSource( | 815 jni_from_java = jni_generator.JNIFromJavaSource( |
805 content, 'org/chromium/example/jni_generator/SampleForTests', | 816 content, 'org/chromium/example/jni_generator/SampleForTests', |
806 TestOptions()) | 817 TestOptions()) |
807 self.assertTextEquals(golden_content, jni_from_java.GetContent()) | 818 generated_text = jni_from_java.GetContent() |
| 819 if not self.compareText(golden_content, generated_text): |
| 820 if os.environ.get(REBASELINE_ENV): |
| 821 with file(golden_file, 'w') as f: |
| 822 f.write(generated_text) |
| 823 return |
| 824 self.fail('testJniSelfDocumentingExample') |
808 | 825 |
809 def testNoWrappingPreprocessorLines(self): | 826 def testNoWrappingPreprocessorLines(self): |
810 test_data = """ | 827 test_data = """ |
811 package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday; | 828 package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday; |
812 | 829 |
813 class ReallyLongClassNamesAreAllTheRage { | 830 class ReallyLongClassNamesAreAllTheRage { |
814 private static native int nativeTest(); | 831 private static native int nativeTest(); |
815 } | 832 } |
816 """ | 833 """ |
817 jni_from_java = jni_generator.JNIFromJavaSource( | 834 jni_from_java = jni_generator.JNIFromJavaSource( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 java_class_name=None, | 937 java_class_name=None, |
921 type='method', | 938 type='method', |
922 p0_type='ChromeBrowserProvider', | 939 p0_type='ChromeBrowserProvider', |
923 ptr_type=test_options.ptr_type), | 940 ptr_type=test_options.ptr_type), |
924 ] | 941 ] |
925 self.assertListEquals(golden_natives, natives) | 942 self.assertListEquals(golden_natives, natives) |
926 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', | 943 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
927 natives, [], test_options) | 944 natives, [], test_options) |
928 self.assertGoldenTextEquals(h.GetContent()) | 945 self.assertGoldenTextEquals(h.GetContent()) |
929 | 946 |
| 947 def testPureNativeMethodsOption(self): |
| 948 test_data = """ |
| 949 package org.chromium.example.jni_generator; |
| 950 |
| 951 /** The pointer to the native Test. */ |
| 952 int nativeTest; |
| 953 |
| 954 class Test { |
| 955 private static native int nativeMethod(int nativeTest, int arg1); |
| 956 } |
| 957 """ |
| 958 options = TestOptions() |
| 959 options.pure_native_methods = True |
| 960 jni_from_java = jni_generator.JNIFromJavaSource( |
| 961 test_data, 'org/chromium/example/jni_generator/Test', options) |
| 962 self.assertGoldenTextEquals(jni_from_java.GetContent()) |
| 963 |
| 964 def testJNIInitNativeNameOption(self): |
| 965 test_data = """ |
| 966 package org.chromium.example.jni_generator; |
| 967 |
| 968 /** The pointer to the native Test. */ |
| 969 int nativeTest; |
| 970 |
| 971 class Test { |
| 972 private static native boolean initNativeClass(); |
| 973 private static native int nativeMethod(int nativeTest, int arg1); |
| 974 } |
| 975 """ |
| 976 options = TestOptions() |
| 977 options.jni_init_native_name = 'initNativeClass' |
| 978 jni_from_java = jni_generator.JNIFromJavaSource( |
| 979 test_data, 'org/chromium/example/jni_generator/Test', options) |
| 980 self.assertGoldenTextEquals(jni_from_java.GetContent()) |
| 981 |
| 982 def testEagerCalledByNativesOption(self): |
| 983 test_data = """ |
| 984 package org.chromium.example.jni_generator; |
| 985 |
| 986 /** The pointer to the native Test. */ |
| 987 int nativeTest; |
| 988 |
| 989 class Test { |
| 990 private static native boolean initNativeClass(); |
| 991 private static native int nativeMethod(int nativeTest, int arg1); |
| 992 @CalledByNative |
| 993 private void testMethodWithParam(int iParam); |
| 994 @CalledByNative |
| 995 private static int testStaticMethodWithParam(int iParam); |
| 996 @CalledByNative |
| 997 private static double testMethodWithNoParam(); |
| 998 @CalledByNative |
| 999 private static String testStaticMethodWithNoParam(); |
| 1000 } |
| 1001 """ |
| 1002 options = TestOptions() |
| 1003 options.jni_init_native_name = 'initNativeClass' |
| 1004 options.eager_called_by_natives = True |
| 1005 jni_from_java = jni_generator.JNIFromJavaSource( |
| 1006 test_data, 'org/chromium/example/jni_generator/Test', options) |
| 1007 self.assertGoldenTextEquals(jni_from_java.GetContent()) |
930 | 1008 |
931 if __name__ == '__main__': | 1009 if __name__ == '__main__': |
932 unittest.main() | 1010 unittest.main() |
OLD | NEW |