JavaBridgeArrayTest.java revision a02191e04bc25c4935f804f2c080ae28663d096d
1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser; 6 7import android.test.suitebuilder.annotation.SmallTest; 8 9import org.chromium.base.test.util.Feature; 10 11/** 12 * Part of the test suite for the Java Bridge. This class tests the general use of arrays. 13 * 14 * The conversions should follow 15 * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in 16 * which the implementation differs from the spec are marked with 17 * LIVECONNECT_COMPLIANCE. 18 * FIXME: Consider making our implementation more compliant, if it will not 19 * break backwards-compatibility. See b/4408210. 20 */ 21public class JavaBridgeArrayTest extends JavaBridgeTestBase { 22 private class TestObject extends Controller { 23 private boolean mBooleanValue; 24 private int mIntValue; 25 private String mStringValue; 26 27 private int[] mIntArray; 28 private int[][] mIntIntArray; 29 30 private boolean mWasArrayMethodCalled; 31 32 public synchronized void setBooleanValue(boolean x) { 33 mBooleanValue = x; 34 notifyResultIsReady(); 35 } 36 public synchronized void setIntValue(int x) { 37 mIntValue = x; 38 notifyResultIsReady(); 39 } 40 public synchronized void setStringValue(String x) { 41 mStringValue = x; 42 notifyResultIsReady(); 43 } 44 45 public synchronized boolean waitForBooleanValue() { 46 waitForResult(); 47 return mBooleanValue; 48 } 49 public synchronized int waitForIntValue() { 50 waitForResult(); 51 return mIntValue; 52 } 53 public synchronized String waitForStringValue() { 54 waitForResult(); 55 return mStringValue; 56 } 57 58 public synchronized void setIntArray(int[] x) { 59 mIntArray = x; 60 notifyResultIsReady(); 61 } 62 public synchronized void setIntIntArray(int[][] x) { 63 mIntIntArray = x; 64 notifyResultIsReady(); 65 } 66 67 public synchronized int[] waitForIntArray() { 68 waitForResult(); 69 return mIntArray; 70 } 71 public synchronized int[][] waitForIntIntArray() { 72 waitForResult(); 73 return mIntIntArray; 74 } 75 76 public synchronized int[] arrayMethod() { 77 mWasArrayMethodCalled = true; 78 return new int[] {42, 43, 44}; 79 } 80 81 public synchronized boolean wasArrayMethodCalled() { 82 return mWasArrayMethodCalled; 83 } 84 } 85 86 private TestObject mTestObject; 87 88 @Override 89 protected void setUp() throws Exception { 90 super.setUp(); 91 mTestObject = new TestObject(); 92 setUpContentView(mTestObject, "testObject"); 93 } 94 95 @SmallTest 96 @Feature({"AndroidWebView", "Android-JavaBridge"}) 97 public void testArrayLength() throws Throwable { 98 executeJavaScript("testObject.setIntArray([42, 43, 44]);"); 99 int[] result = mTestObject.waitForIntArray(); 100 assertEquals(3, result.length); 101 assertEquals(42, result[0]); 102 assertEquals(43, result[1]); 103 assertEquals(44, result[2]); 104 } 105 106 @SmallTest 107 @Feature({"AndroidWebView", "Android-JavaBridge"}) 108 public void testPassNull() throws Throwable { 109 executeJavaScript("testObject.setIntArray(null);"); 110 assertNull(mTestObject.waitForIntArray()); 111 } 112 113 @SmallTest 114 @Feature({"AndroidWebView", "Android-JavaBridge"}) 115 public void testPassUndefined() throws Throwable { 116 executeJavaScript("testObject.setIntArray(undefined);"); 117 assertNull(mTestObject.waitForIntArray()); 118 } 119 120 @SmallTest 121 @Feature({"AndroidWebView", "Android-JavaBridge"}) 122 public void testPassEmptyArray() throws Throwable { 123 executeJavaScript("testObject.setIntArray([]);"); 124 assertEquals(0, mTestObject.waitForIntArray().length); 125 } 126 127 // Note that this requires being able to pass a string from JavaScript to 128 // Java. 129 @SmallTest 130 @Feature({"AndroidWebView", "Android-JavaBridge"}) 131 public void testPassArrayToStringMethod() throws Throwable { 132 // LIVECONNECT_COMPLIANCE: Should call toString() on array. 133 executeJavaScript("testObject.setStringValue([42, 42, 42]);"); 134 assertEquals("undefined", mTestObject.waitForStringValue()); 135 } 136 137 // Note that this requires being able to pass an integer from JavaScript to 138 // Java. 139 @SmallTest 140 @Feature({"AndroidWebView", "Android-JavaBridge"}) 141 public void testPassArrayToNonStringNonArrayMethod() throws Throwable { 142 // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. 143 executeJavaScript("testObject.setIntValue([42, 42, 42]);"); 144 assertEquals(0, mTestObject.waitForIntValue()); 145 } 146 147 @SmallTest 148 @Feature({"AndroidWebView", "Android-JavaBridge"}) 149 public void testPassNonArrayToArrayMethod() throws Throwable { 150 // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. 151 executeJavaScript("testObject.setIntArray(42);"); 152 assertNull(mTestObject.waitForIntArray()); 153 } 154 155 @SmallTest 156 @Feature({"AndroidWebView", "Android-JavaBridge"}) 157 public void testObjectWithLengthProperty() throws Throwable { 158 executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); 159 int[] result = mTestObject.waitForIntArray(); 160 assertEquals(3, result.length); 161 assertEquals(0, result[0]); 162 assertEquals(42, result[1]); 163 assertEquals(0, result[2]); 164 } 165 166 @SmallTest 167 @Feature({"AndroidWebView", "Android-JavaBridge"}) 168 public void testNonNumericLengthProperty() throws Throwable { 169 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 170 // should raise a JavaScript exception. 171 executeJavaScript("testObject.setIntArray({length: \"foo\"});"); 172 assertNull(mTestObject.waitForIntArray()); 173 } 174 175 @SmallTest 176 @Feature({"AndroidWebView", "Android-JavaBridge"}) 177 public void testLengthOutOfBounds() throws Throwable { 178 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 179 // should raise a JavaScript exception. 180 executeJavaScript("testObject.setIntArray({length: -1});"); 181 assertNull(mTestObject.waitForIntArray()); 182 183 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 184 // should raise a JavaScript exception. 185 long length = Integer.MAX_VALUE + 1L; 186 executeJavaScript("testObject.setIntArray({length: " + length + "});"); 187 assertNull(mTestObject.waitForIntArray()); 188 189 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 190 // should raise a JavaScript exception. 191 length = Integer.MAX_VALUE + 1L - Integer.MIN_VALUE + 1L; 192 executeJavaScript("testObject.setIntArray({length: " + length + "});"); 193 assertNull(mTestObject.waitForIntArray()); 194 } 195 196 @SmallTest 197 @Feature({"AndroidWebView", "Android-JavaBridge"}) 198 public void testSparseArray() throws Throwable { 199 executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); 200 int[] result = mTestObject.waitForIntArray(); 201 assertEquals(4, result.length); 202 assertEquals(42, result[0]); 203 assertEquals(43, result[1]); 204 assertEquals(0, result[2]); 205 assertEquals(45, result[3]); 206 } 207 208 // Note that this requires being able to pass a boolean from JavaScript to 209 // Java. 210 @SmallTest 211 @Feature({"AndroidWebView", "Android-JavaBridge"}) 212 public void testMethodReturningArrayNotCalled() throws Throwable { 213 // We don't invoke methods which return arrays, but note that no 214 // exception is raised. 215 // LIVECONNECT_COMPLIANCE: Should call method and convert result to 216 // JavaScript array. 217 executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())"); 218 assertTrue(mTestObject.waitForBooleanValue()); 219 assertFalse(mTestObject.wasArrayMethodCalled()); 220 } 221 222 @SmallTest 223 @Feature({"AndroidWebView", "Android-JavaBridge"}) 224 public void testMultiDimensionalArrayMethod() throws Throwable { 225 // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. 226 executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); 227 assertNull(mTestObject.waitForIntIntArray()); 228 } 229 230 @SmallTest 231 @Feature({"AndroidWebView", "Android-JavaBridge"}) 232 public void testPassMultiDimensionalArray() throws Throwable { 233 // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. 234 executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); 235 int[] result = mTestObject.waitForIntArray(); 236 assertEquals(2, result.length); 237 assertEquals(0, result[0]); 238 assertEquals(0, result[1]); 239 } 240 241 // Verify that ArrayBuffers are not converted into arrays when passed to Java. 242 // The LiveConnect spec doesn't mention ArrayBuffers, so it doesn't seem to 243 // be a compliance issue. 244 @SmallTest 245 @Feature({"AndroidWebView", "Android-JavaBridge"}) 246 public void testPassArrayBuffer() throws Throwable { 247 executeJavaScript("buffer = new ArrayBuffer(16);"); 248 executeJavaScript("testObject.setIntArray(buffer);"); 249 assertNull(mTestObject.waitForIntArray()); 250 } 251 252 // Verify that ArrayBufferViews are not converted into arrays when passed to Java. 253 // The LiveConnect spec doesn't mention ArrayBufferViews, so it doesn't seem to 254 // be a compliance issue. 255 // Here, a DataView is used as an ArrayBufferView instance (since the latter is 256 // an interface and can't be instantiated directly). See also JavaBridgeArrayCoercionTest 257 // for typed arrays (that also subclass ArrayBufferView) tests. 258 @SmallTest 259 @Feature({"AndroidWebView", "Android-JavaBridge"}) 260 public void testPassDataView() throws Throwable { 261 executeJavaScript("buffer = new ArrayBuffer(16);"); 262 executeJavaScript("testObject.setIntArray(new DataView(buffer));"); 263 assertNull(mTestObject.waitForIntArray()); 264 } 265} 266