JavaBridgeReturnValuesTest.java revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 test checks that we correctly convert Java
13 * values to JavaScript values when returning them from the methods of injected Java objects.
14 *
15 * The conversions should follow
16 * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
17 * which the implementation differs from the spec are marked with
18 * LIVECONNECT_COMPLIANCE.
19 * FIXME: Consider making our implementation more compliant, if it will not
20 * break backwards-compatibility. See b/4408210.
21 */
22public class JavaBridgeReturnValuesTest extends JavaBridgeTestBase {
23    // An instance of this class is injected into the page to test returning
24    // Java values to JavaScript.
25    private class TestObject extends Controller {
26        private String mStringValue;
27        private boolean mBooleanValue;
28
29        // These four methods are used to control the test.
30        public synchronized void setStringValue(String x) {
31            mStringValue = x;
32            notifyResultIsReady();
33        }
34        public synchronized String waitForStringValue() {
35            waitForResult();
36            return mStringValue;
37        }
38        public synchronized void setBooleanValue(boolean x) {
39            mBooleanValue = x;
40            notifyResultIsReady();
41        }
42        public synchronized boolean waitForBooleanValue() {
43            waitForResult();
44            return mBooleanValue;
45        }
46
47        public boolean getBooleanValue() {
48            return true;
49        }
50        public byte getByteValue() {
51            return 42;
52        }
53        public char getCharValue() {
54            return '\u002A';
55        }
56        public short getShortValue() {
57            return 42;
58        }
59        public int getIntValue() {
60            return 42;
61        }
62        public long getLongValue() {
63            return 42L;
64        }
65        public float getFloatValue() {
66            return 42.1f;
67        }
68        public float getFloatValueNoDecimal() {
69            return 42.0f;
70        }
71        public double getDoubleValue() {
72            return 42.1;
73        }
74        public double getDoubleValueNoDecimal() {
75            return 42.0;
76        }
77        public String getStringValue() {
78            return "foo";
79        }
80        public String getEmptyStringValue() {
81            return "";
82        }
83        public String getNullStringValue() {
84            return null;
85        }
86        public Object getObjectValue() {
87            return new Object();
88        }
89        public Object getNullObjectValue() {
90            return null;
91        }
92        public CustomType getCustomTypeValue() {
93            return new CustomType();
94        }
95        public void getVoidValue() {
96        }
97    }
98
99    // A custom type used when testing passing objects.
100    private static class CustomType {
101    }
102
103    TestObject mTestObject;
104
105    @Override
106    protected void setUp() throws Exception {
107        super.setUp();
108        mTestObject = new TestObject();
109        setUpContentView(mTestObject, "testObject");
110    }
111
112    // Note that this requires that we can pass a JavaScript string to Java.
113    protected String executeJavaScriptAndGetStringResult(String script) throws Throwable {
114        executeJavaScript("testObject.setStringValue(" + script + ");");
115        return mTestObject.waitForStringValue();
116    }
117
118    // Note that this requires that we can pass a JavaScript boolean to Java.
119    private boolean executeJavaScriptAndGetBooleanResult(String script) throws Throwable {
120        executeJavaScript("testObject.setBooleanValue(" + script + ");");
121        return mTestObject.waitForBooleanValue();
122    }
123
124    @SmallTest
125    @Feature({"AndroidWebView", "Android-JavaBridge"})
126    public void testMethodReturnTypes() throws Throwable {
127        assertEquals("boolean",
128                executeJavaScriptAndGetStringResult("typeof testObject.getBooleanValue()"));
129        assertEquals("number",
130                executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()"));
131        // char values are returned to JavaScript as numbers.
132        assertEquals("number",
133                executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()"));
134        assertEquals("number",
135                executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()"));
136        assertEquals("number",
137                executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()"));
138        assertEquals("number",
139                executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()"));
140        assertEquals("number",
141                executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()"));
142        assertEquals("number",
143                executeJavaScriptAndGetStringResult("typeof testObject.getFloatValueNoDecimal()"));
144        assertEquals("number",
145                executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValue()"));
146        assertEquals("number",
147                executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValueNoDecimal()"));
148        assertEquals("string",
149                executeJavaScriptAndGetStringResult("typeof testObject.getStringValue()"));
150        assertEquals("string",
151                executeJavaScriptAndGetStringResult("typeof testObject.getEmptyStringValue()"));
152        // LIVECONNECT_COMPLIANCE: This should have type object.
153        assertEquals("undefined",
154                executeJavaScriptAndGetStringResult("typeof testObject.getNullStringValue()"));
155        assertEquals("object",
156                executeJavaScriptAndGetStringResult("typeof testObject.getObjectValue()"));
157        assertEquals("object",
158                executeJavaScriptAndGetStringResult("typeof testObject.getNullObjectValue()"));
159        assertEquals("object",
160                executeJavaScriptAndGetStringResult("typeof testObject.getCustomTypeValue()"));
161        assertEquals("undefined",
162                executeJavaScriptAndGetStringResult("typeof testObject.getVoidValue()"));
163    }
164
165    @SmallTest
166    @Feature({"AndroidWebView", "Android-JavaBridge"})
167    public void testMethodReturnValues() throws Throwable {
168        // We do the string comparison in JavaScript, to avoid relying on the
169        // coercion algorithm from JavaScript to Java.
170        assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()"));
171        assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()"));
172        // char values are returned to JavaScript as numbers.
173        assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()"));
174        assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()"));
175        assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()"));
176        assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()"));
177        assertTrue(executeJavaScriptAndGetBooleanResult(
178                "Math.abs(42.1 - testObject.getFloatValue()) < 0.001"));
179        assertTrue(executeJavaScriptAndGetBooleanResult(
180                "42.0 === testObject.getFloatValueNoDecimal()"));
181        assertTrue(executeJavaScriptAndGetBooleanResult(
182                "Math.abs(42.1 - testObject.getDoubleValue()) < 0.001"));
183        assertTrue(executeJavaScriptAndGetBooleanResult(
184                "42.0 === testObject.getDoubleValueNoDecimal()"));
185        assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()"));
186        assertEquals("", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()"));
187        assertTrue(executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()"));
188    }
189}
190