1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * Tests for conversion of JavaScript arrays to Java arrays and the other 26 * way round. Also generally useful as a JavaScript-to-Java type conversion 27 * test. 28 * 29 * @test 30 * @run 31 */ 32 33 var x; // used for undefined 34 var testCount = 0; 35 36 function testF(inputValue, type, testFn) { 37 var x = Java.to([inputValue], type + "[]")[0]; 38 if(!testFn(x)) { 39 throw ("unexpected value: " + x) 40 } 41 ++testCount; 42 } 43 44 function test(inputValue, type, expectedValue) { 45 testF(inputValue, type, function(x) { return x === expectedValue }) 46 } 47 48 function testNaN(inputValue, type) { 49 testF(inputValue, type, isNaN) 50 } 51 52 // Those labeled "Correct?" are not clearly correct conversions. Those 53 // labeled "TypeError maybe?" could actually throw a TypeError, or only 54 // throw a TypeError when in strict mode. 55 // The case of ("false", "boolean") => true is particularly amusing. 56 57 test(x, "int", 0) // Correct? TypeError maybe? 58 test(null, "int", 0) // Correct? TypeError maybe? 59 test(1234, "int", 1234) 60 test("1234", "int", 1234) 61 test("1234.49", "int", 1234) 62 test("1234.51", "int", 1234) // truncates, not rounds 63 test(true, "int", 1) 64 test(false, "int", 0) 65 test("foo", "int", 0) // Correct? TypeError maybe? 66 67 test(x, "boolean", false) // Correct? TypeError maybe? 68 test(null, "boolean", false) // Correct? TypeError maybe? 69 test(0, "boolean", false) 70 test(1234, "boolean", true) 71 test("foo", "boolean", true) 72 test("", "boolean", false) 73 test("false", "boolean", true) // Correct? false maybe? 74 75 test(x, "java.lang.String", "undefined") // Correct? TypeError maybe? 76 test(null, "java.lang.String", null) 77 test(1234, "java.lang.String", "1234") 78 test(1234.5, "java.lang.String", "1234.5") 79 test(true, "java.lang.String", "true") 80 test(false, "java.lang.String", "false") 81 82 test(x, "java.lang.Integer", null) // Correct? TypeError maybe? 83 test(null, "java.lang.Integer", null) 84 test(1234, "java.lang.Integer", 1234) 85 test("1234", "java.lang.Integer", 1234) 86 test("1234.49", "java.lang.Integer", 1234) 87 test("1234.51", "java.lang.Integer", 1234) // truncates, not rounds 88 test(true, "java.lang.Integer", 1) 89 test(false, "java.lang.Integer", 0) 90 test("foo", "java.lang.Integer", 0) // Correct? TypeError maybe? 91 92 test(x, "java.lang.Boolean", null) // Correct? TypeError maybe? 93 test(null, "java.lang.Boolean", null) 94 test(0, "java.lang.Boolean", false) 95 test(1234, "java.lang.Boolean", true) 96 test("foo", "java.lang.Boolean", true) 97 test("", "java.lang.Boolean", false) 98 test("false", "java.lang.Boolean", true) // Correct? false maybe? 99 100 testNaN(x, "double") 101 test(null, "double", 0) 102 test(1234, "double", 1234) 103 test("1234", "double", 1234) 104 test("1234.5", "double", 1234.5) 105 test(true, "double", 1) 106 test(false, "double", 0) 107 testNaN("foo", "double") 108 109 testNaN(x, "java.lang.Double") 110 test(null, "java.lang.Double", null) 111 test(1234, "java.lang.Double", 1234) 112 test("1234", "java.lang.Double", 1234) 113 test("1234.5", "java.lang.Double", 1234.5) 114 test(true, "java.lang.Double", 1) 115 test(false, "java.lang.Double", 0) 116 testNaN("foo", "java.lang.Double") 117 118 test({ valueOf: function() { return 42; } }, "int", 42) 119 test({ valueOf: function() { return "42"; } }, "int", 42) 120 // If there's no valueOf, toString is used 121 test({ toString: function() { return "42"; } }, "int", 42) 122 // For numbers, valueOf takes precedence over toString 123 test({ valueOf: function() { return "42"; }, toString: function() { return "43"; } }, "int", 42) 124 125 test({ toString: function() { return "foo"; } }, "java.lang.String", "foo") 126 // Yep, even if we have valueOf, toString from prototype takes precedence 127 test({ valueOf: function() { return 42; } }, "java.lang.String", "[object Object]") 128 // Converting to string, toString takes precedence over valueOf 129 test({ valueOf: function() { return "42"; }, toString: function() { return "43"; } }, "java.lang.String", "43") 130 131 function assertCanConvert(sourceType, targetType) { 132 Java.to([new (Java.type(sourceType))()], targetType + "[]") 133 ++testCount; 134 } 135 136 function assertCantConvert(sourceType, targetType) { 137 try { 138 Java.to([new (Java.type(sourceType))()], targetType + "[]") 139 throw "no TypeError encountered" 140 } catch(e) { 141 if(!(e instanceof TypeError) || 142 !e.message.startsWith("Java.to conversion to array type")) { 143 throw e; 144 } 145 ++testCount; 146 } 147 } 148 149 // Arbitrary POJOs to JS Primitive type should work 150 assertCanConvert("java.util.BitSet", "int") 151 assertCanConvert("java.util.BitSet", "double") 152 assertCanConvert("java.util.BitSet", "long") 153 assertCanConvert("java.util.BitSet", "boolean") 154 assertCanConvert("java.util.BitSet", "java.lang.String") 155 156 // Arbitrary POJOs can't be converted to Java values 157 assertCantConvert("java.util.BitSet", "java.lang.Double") 158 assertCantConvert("java.util.BitSet", "java.lang.Long") 159 160 /*************************************************************************** 161 * Now testing the other way round - Java arrays & collections to JavaScript 162 **************************************************************************/ 163 164 function assert(x) { 165 if(!x) { 166 throw "Assertion failed" 167 } 168 ++testCount; 169 } 170 171 var intArray = new (Java.type("int[]"))(3) 172 intArray[0] = 1234; 173 intArray[1] = 42; 174 intArray[2] = 5; 175 var jsIntArray = Java.from(intArray) 176 assert(jsIntArray instanceof Array); 177 assert(jsIntArray[0] === 1234); 178 assert(jsIntArray[1] === 42); 179 assert(jsIntArray[2] === 5); 180 181 // The arrays are copies, they don't reflect each other 182 intArray[2] = 6; 183 assert(jsIntArray[2] === 5); 184 jsIntArray[2] = 7; 185 assert(intArray[2] === 6); 186 187 var byteArray = new (Java.type("byte[]"))(2) 188 byteArray[0] = -128; 189 byteArray[1] = 127; 190 var jsByteArray = Java.from(byteArray) 191 assert(jsByteArray instanceof Array); 192 assert(jsByteArray[0] === -128); 193 assert(jsByteArray[1] === 127); 194 195 var shortArray = new (Java.type("short[]"))(2) 196 shortArray[0] = -32768; 197 shortArray[1] = 32767; 198 var jsShortArray = Java.from(shortArray) 199 assert(jsShortArray instanceof Array); 200 assert(jsShortArray[0] === -32768); 201 assert(jsShortArray[1] === 32767); 202 203 var floatArray = new (Java.type("float[]"))(2) 204 floatArray[0] = java.lang.Float.MIN_VALUE; 205 floatArray[1] = java.lang.Float.MAX_VALUE; 206 var jsFloatArray = Java.from(floatArray) 207 assert(jsFloatArray instanceof Array); 208 assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE); 209 assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE); 210 211 var charArray = new (Java.type("char[]"))(3) 212 charArray[0] = "a"; 213 charArray[1] = "b"; 214 charArray[2] = "1"; 215 var jsCharArray = Java.from(charArray) 216 assert(jsCharArray instanceof Array); 217 assert(jsCharArray[0] === 97); 218 assert(jsCharArray[1] === 98); 219 assert(jsCharArray[2] === 49); 220 221 var booleanArray = new (Java.type("boolean[]"))(2) 222 booleanArray[0] = true; 223 booleanArray[1] = false; 224 var jsBooleanArray = Java.from(booleanArray) 225 assert(jsBooleanArray instanceof Array); 226 assert(jsBooleanArray[0] === true); 227 assert(jsBooleanArray[1] === false); 228 229 print(testCount + " tests completed ok")