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. jlaskey@3: * 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. jlaskey@3: * 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). jlaskey@3: * 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. jlaskey@3: * 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 jlaskey@3: * 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: jlaskey@3: // Those labeled "Correct?" are not clearly correct conversions. Those jlaskey@3: // labeled "TypeError maybe?" could actually throw a TypeError, or only jlaskey@3: // 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: jlaskey@3: function assertCantConvert(sourceType, targetType) { jlaskey@3: try { attila@279: Java.to([new Java.type(sourceType)()], targetType + "[]") jlaskey@3: throw "no TypeError encountered" jlaskey@3: } catch(e) { jlaskey@3: if(!(e instanceof TypeError)) { jlaskey@3: throw e; jlaskey@3: } jlaskey@3: ++testCount; jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: // Arbitrary POJOs can't be converted to Java values jlaskey@3: assertCantConvert("java.util.BitSet", "int") jlaskey@3: assertCantConvert("java.util.BitSet", "double") jlaskey@3: assertCantConvert("java.util.BitSet", "long") jlaskey@3: assertCantConvert("java.util.BitSet", "boolean") jlaskey@3: assertCantConvert("java.util.BitSet", "java.lang.String") 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")