jlaskey@3: /* jlaskey@7: * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. jlaskey@3: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. attila@962: * jlaskey@3: * This code is free software; you can redistribute it and/or modify it jlaskey@3: * under the terms of the GNU General Public License version 2 only, as jlaskey@3: * published by the Free Software Foundation. attila@962: * jlaskey@3: * This code is distributed in the hope that it will be useful, but WITHOUT jlaskey@3: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jlaskey@3: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jlaskey@3: * version 2 for more details (a copy is included in the LICENSE file that jlaskey@3: * accompanied this code). attila@962: * jlaskey@3: * You should have received a copy of the GNU General Public License version jlaskey@3: * 2 along with this work; if not, write to the Free Software Foundation, jlaskey@3: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. attila@962: * jlaskey@3: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jlaskey@3: * or visit www.oracle.com if you need additional information or have any jlaskey@3: * questions. jlaskey@3: */ jlaskey@3: jlaskey@3: /** jlaskey@3: * Tests for conversion of JavaScript arrays to Java arrays and the other attila@962: * way round. Also generally useful as a JavaScript-to-Java type conversion jlaskey@3: * test. jlaskey@3: * jlaskey@3: * @test jlaskey@3: * @run jlaskey@3: */ jlaskey@3: jlaskey@3: var x; // used for undefined jlaskey@3: var testCount = 0; jlaskey@3: jlaskey@3: function testF(inputValue, type, testFn) { attila@279: var x = Java.to([inputValue], type + "[]")[0]; jlaskey@3: if(!testFn(x)) { jlaskey@3: throw ("unexpected value: " + x) jlaskey@3: } jlaskey@3: ++testCount; jlaskey@3: } jlaskey@3: jlaskey@3: function test(inputValue, type, expectedValue) { jlaskey@3: testF(inputValue, type, function(x) { return x === expectedValue }) jlaskey@3: } jlaskey@3: jlaskey@3: function testNaN(inputValue, type) { jlaskey@3: testF(inputValue, type, isNaN) jlaskey@3: } jlaskey@3: attila@962: // Those labeled "Correct?" are not clearly correct conversions. Those attila@962: // labeled "TypeError maybe?" could actually throw a TypeError, or only attila@962: // throw a TypeError when in strict mode. jlaskey@3: // The case of ("false", "boolean") => true is particularly amusing. jlaskey@3: jlaskey@3: test(x, "int", 0) // Correct? TypeError maybe? jlaskey@3: test(null, "int", 0) // Correct? TypeError maybe? jlaskey@3: test(1234, "int", 1234) jlaskey@3: test("1234", "int", 1234) jlaskey@3: test("1234.49", "int", 1234) jlaskey@3: test("1234.51", "int", 1234) // truncates, not rounds jlaskey@3: test(true, "int", 1) jlaskey@3: test(false, "int", 0) jlaskey@3: test("foo", "int", 0) // Correct? TypeError maybe? jlaskey@3: jlaskey@3: test(x, "boolean", false) // Correct? TypeError maybe? jlaskey@3: test(null, "boolean", false) // Correct? TypeError maybe? jlaskey@3: test(0, "boolean", false) jlaskey@3: test(1234, "boolean", true) jlaskey@3: test("foo", "boolean", true) jlaskey@3: test("", "boolean", false) jlaskey@3: test("false", "boolean", true) // Correct? false maybe? jlaskey@3: jlaskey@3: test(x, "java.lang.String", "undefined") // Correct? TypeError maybe? jlaskey@3: test(null, "java.lang.String", null) jlaskey@3: test(1234, "java.lang.String", "1234") jlaskey@3: test(1234.5, "java.lang.String", "1234.5") jlaskey@3: test(true, "java.lang.String", "true") jlaskey@3: test(false, "java.lang.String", "false") jlaskey@3: jlaskey@3: test(x, "java.lang.Integer", null) // Correct? TypeError maybe? jlaskey@3: test(null, "java.lang.Integer", null) jlaskey@3: test(1234, "java.lang.Integer", 1234) jlaskey@3: test("1234", "java.lang.Integer", 1234) jlaskey@3: test("1234.49", "java.lang.Integer", 1234) jlaskey@3: test("1234.51", "java.lang.Integer", 1234) // truncates, not rounds jlaskey@3: test(true, "java.lang.Integer", 1) jlaskey@3: test(false, "java.lang.Integer", 0) jlaskey@3: test("foo", "java.lang.Integer", 0) // Correct? TypeError maybe? jlaskey@3: jlaskey@3: test(x, "java.lang.Boolean", null) // Correct? TypeError maybe? jlaskey@3: test(null, "java.lang.Boolean", null) jlaskey@3: test(0, "java.lang.Boolean", false) jlaskey@3: test(1234, "java.lang.Boolean", true) jlaskey@3: test("foo", "java.lang.Boolean", true) jlaskey@3: test("", "java.lang.Boolean", false) jlaskey@3: test("false", "java.lang.Boolean", true) // Correct? false maybe? jlaskey@3: jlaskey@3: testNaN(x, "double") jlaskey@3: test(null, "double", 0) jlaskey@3: test(1234, "double", 1234) jlaskey@3: test("1234", "double", 1234) jlaskey@3: test("1234.5", "double", 1234.5) jlaskey@3: test(true, "double", 1) jlaskey@3: test(false, "double", 0) jlaskey@3: testNaN("foo", "double") jlaskey@3: jlaskey@3: testNaN(x, "java.lang.Double") jlaskey@3: test(null, "java.lang.Double", null) jlaskey@3: test(1234, "java.lang.Double", 1234) jlaskey@3: test("1234", "java.lang.Double", 1234) jlaskey@3: test("1234.5", "java.lang.Double", 1234.5) jlaskey@3: test(true, "java.lang.Double", 1) jlaskey@3: test(false, "java.lang.Double", 0) jlaskey@3: testNaN("foo", "java.lang.Double") jlaskey@3: jlaskey@3: test({ valueOf: function() { return 42; } }, "int", 42) jlaskey@3: test({ valueOf: function() { return "42"; } }, "int", 42) jlaskey@3: // If there's no valueOf, toString is used jlaskey@3: test({ toString: function() { return "42"; } }, "int", 42) jlaskey@3: // For numbers, valueOf takes precedence over toString jlaskey@3: test({ valueOf: function() { return "42"; }, toString: function() { return "43"; } }, "int", 42) jlaskey@3: jlaskey@3: test({ toString: function() { return "foo"; } }, "java.lang.String", "foo") jlaskey@3: // Yep, even if we have valueOf, toString from prototype takes precedence jlaskey@3: test({ valueOf: function() { return 42; } }, "java.lang.String", "[object Object]") jlaskey@3: // Converting to string, toString takes precedence over valueOf jlaskey@3: test({ valueOf: function() { return "42"; }, toString: function() { return "43"; } }, "java.lang.String", "43") jlaskey@3: sundar@1533: function assertCanConvert(sourceType, targetType) { sundar@1533: Java.to([new (Java.type(sourceType))()], targetType + "[]") sundar@1533: ++testCount; sundar@1533: } sundar@1533: jlaskey@3: function assertCantConvert(sourceType, targetType) { jlaskey@3: try { sundar@1533: Java.to([new (Java.type(sourceType))()], targetType + "[]") jlaskey@3: throw "no TypeError encountered" jlaskey@3: } catch(e) { sundar@1533: if(!(e instanceof TypeError) || sundar@1533: !e.message.startsWith("Java.to conversion to array type")) { jlaskey@3: throw e; jlaskey@3: } jlaskey@3: ++testCount; jlaskey@3: } jlaskey@3: } jlaskey@3: sundar@1533: // Arbitrary POJOs to JS Primitive type should work sundar@1533: assertCanConvert("java.util.BitSet", "int") sundar@1533: assertCanConvert("java.util.BitSet", "double") sundar@1533: assertCanConvert("java.util.BitSet", "long") sundar@1533: assertCanConvert("java.util.BitSet", "boolean") sundar@1533: assertCanConvert("java.util.BitSet", "java.lang.String") sundar@1533: jlaskey@3: // Arbitrary POJOs can't be converted to Java values jlaskey@3: assertCantConvert("java.util.BitSet", "java.lang.Double") jlaskey@3: assertCantConvert("java.util.BitSet", "java.lang.Long") jlaskey@3: jlaskey@3: /*************************************************************************** jlaskey@3: * Now testing the other way round - Java arrays & collections to JavaScript jlaskey@3: **************************************************************************/ jlaskey@3: jlaskey@3: function assert(x) { jlaskey@3: if(!x) { jlaskey@3: throw "Assertion failed" jlaskey@3: } jlaskey@3: ++testCount; jlaskey@3: } jlaskey@3: jlaskey@3: var intArray = new (Java.type("int[]"))(3) jlaskey@3: intArray[0] = 1234; jlaskey@3: intArray[1] = 42; jlaskey@3: intArray[2] = 5; attila@279: var jsIntArray = Java.from(intArray) jlaskey@3: assert(jsIntArray instanceof Array); jlaskey@3: assert(jsIntArray[0] === 1234); jlaskey@3: assert(jsIntArray[1] === 42); jlaskey@3: assert(jsIntArray[2] === 5); jlaskey@3: jlaskey@3: // The arrays are copies, they don't reflect each other jlaskey@3: intArray[2] = 6; jlaskey@3: assert(jsIntArray[2] === 5); jlaskey@3: jsIntArray[2] = 7; jlaskey@3: assert(intArray[2] === 6); jlaskey@3: jlaskey@3: var byteArray = new (Java.type("byte[]"))(2) jlaskey@3: byteArray[0] = -128; jlaskey@3: byteArray[1] = 127; attila@279: var jsByteArray = Java.from(byteArray) jlaskey@3: assert(jsByteArray instanceof Array); jlaskey@3: assert(jsByteArray[0] === -128); jlaskey@3: assert(jsByteArray[1] === 127); jlaskey@3: jlaskey@3: var shortArray = new (Java.type("short[]"))(2) jlaskey@3: shortArray[0] = -32768; jlaskey@3: shortArray[1] = 32767; attila@279: var jsShortArray = Java.from(shortArray) jlaskey@3: assert(jsShortArray instanceof Array); jlaskey@3: assert(jsShortArray[0] === -32768); jlaskey@3: assert(jsShortArray[1] === 32767); jlaskey@3: jlaskey@3: var floatArray = new (Java.type("float[]"))(2) jlaskey@3: floatArray[0] = java.lang.Float.MIN_VALUE; jlaskey@3: floatArray[1] = java.lang.Float.MAX_VALUE; attila@279: var jsFloatArray = Java.from(floatArray) jlaskey@3: assert(jsFloatArray instanceof Array); jlaskey@3: assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE); jlaskey@3: assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE); jlaskey@3: jlaskey@3: var charArray = new (Java.type("char[]"))(3) jlaskey@3: charArray[0] = "a"; jlaskey@3: charArray[1] = "b"; jlaskey@3: charArray[2] = "1"; attila@279: var jsCharArray = Java.from(charArray) jlaskey@3: assert(jsCharArray instanceof Array); jlaskey@3: assert(jsCharArray[0] === 97); jlaskey@3: assert(jsCharArray[1] === 98); jlaskey@3: assert(jsCharArray[2] === 49); jlaskey@3: jlaskey@3: var booleanArray = new (Java.type("boolean[]"))(2) jlaskey@3: booleanArray[0] = true; jlaskey@3: booleanArray[1] = false; attila@279: var jsBooleanArray = Java.from(booleanArray) jlaskey@3: assert(jsBooleanArray instanceof Array); jlaskey@3: assert(jsBooleanArray[0] === true); jlaskey@3: assert(jsBooleanArray[1] === false); jlaskey@3: jlaskey@3: print(testCount + " tests completed ok")