JavaBridgeArrayTest.java revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 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