JDK-8072426.js revision 1365:833a4df84bc7
1/*
2 * Copyright (c) 2015, 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 * JDK-8072426: Can't compare Java objects to strings or numbers
26 *
27 * @test
28 * @run
29 */
30
31Assert.assertTrue(java.math.RoundingMode.UP == "UP");
32
33var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject");
34
35// Adds an "isFunction" member to the JSObject that returns the specified value
36function addIsFunction(isFunction, obj) {
37    obj.isFunction = function() {
38        return isFunction;
39    };
40    return obj;
41}
42
43function makeJSObjectConstantFunction(value) {
44    return new JSObject(addIsFunction(true, {
45        call: function() {
46            return value;
47        }
48    }));
49}
50
51function makeJSObjectWithMembers(mapping) {
52    return new JSObject({
53        getMember: function(name) {
54            Assert.assertTrue(mapping.hasOwnProperty(name));
55            return mapping[name];
56        },
57        toNumber: function() {
58            // toNumber no longer invoked
59            Assert.fail();
60        }
61    });
62}
63
64// Test JSObjectLinker toInt32/toLong/toNumber
65function testNumericJSObject(kind, value) {
66    var obj = makeJSObjectWithMembers({
67            valueOf: makeJSObjectConstantFunction(value)
68        });
69
70    if (kind === "double") {
71        // There's no assertEquals(double actual, double expected). There's only
72        // assertEquals(double actual, double expected, double delta).
73        Assert["assertEquals(double,double,double)"](value, obj, 0);
74    } else {
75        Assert["assertEquals(" + kind + ", " + kind + ")"](value, obj);
76    }
77    Assert.assertTrue(value == Number(obj));
78}
79testNumericJSObject("int", 42);
80testNumericJSObject("long", 4294967296);
81testNumericJSObject("double", 1.2);
82
83// Test fallback from toNumber to toString for numeric conversion when toNumber doesn't exist
84(function() {
85    var obj = makeJSObjectWithMembers({
86        valueOf:  null, // Explicitly no valueOf
87        toString: makeJSObjectConstantFunction("123")
88    });
89    Assert["assertEquals(int,int)"](123, obj);
90})();
91
92// Test fallback from toNumber to toString for numeric conversion when toNumber isn't a callable
93(function() {
94    var obj = makeJSObjectWithMembers({
95        valueOf:  new JSObject(addIsFunction(false, {})),
96        toString: makeJSObjectConstantFunction("124")
97    });
98    Assert["assertEquals(int,int)"](124, obj);
99})();
100
101// Test fallback from toNumber to toString for numeric conversion when toNumber returns a non-primitive
102(function() {
103    var obj = makeJSObjectWithMembers({
104        valueOf:  makeJSObjectConstantFunction({}),
105        toString: makeJSObjectConstantFunction("125")
106    });
107    Assert["assertEquals(int,int)"](125, obj);
108})();
109
110// Test TypeError from toNumber to toString when both return a non-primitive
111(function() {
112    var obj = makeJSObjectWithMembers({
113        valueOf:  makeJSObjectConstantFunction({}),
114        toString: makeJSObjectConstantFunction({})
115    });
116    try {
117        Number(obj);
118        Assert.fail(); // must throw
119    } catch(e) {
120        Assert.assertTrue(e instanceof TypeError);
121    }
122})();
123
124// Test toString for string conversion
125(function() {
126    var obj = makeJSObjectWithMembers({
127        toString: makeJSObjectConstantFunction("Hello")
128    });
129    Assert.assertTrue("Hello" === String(obj));
130    Assert["assertEquals(String,String)"]("Hello", obj);
131})();
132
133// Test fallback from toString to valueOf for string conversion when toString doesn't exist
134(function() {
135    var obj = makeJSObjectWithMembers({
136        toString: null,
137        valueOf:  makeJSObjectConstantFunction("Hello1")
138    });
139    Assert.assertTrue("Hello1" === String(obj));
140    Assert["assertEquals(String,String)"]("Hello1", obj);
141})();
142
143// Test fallback from toString to valueOf for string conversion when toString is not callable
144(function() {
145    var obj = makeJSObjectWithMembers({
146        toString: new JSObject(addIsFunction(false, {})),
147        valueOf:  makeJSObjectConstantFunction("Hello2")
148    });
149    Assert["assertEquals(String,String)"]("Hello2", obj);
150})();
151
152// Test fallback from toString to valueOf for string conversion when toString returns non-primitive
153(function() {
154    var obj = makeJSObjectWithMembers({
155        toString: makeJSObjectConstantFunction({}),
156        valueOf:  makeJSObjectConstantFunction("Hello3")
157    });
158    Assert["assertEquals(String,String)"]("Hello3", obj);
159})();
160
161// Test toBoolean for JSObject
162(function() {
163    Assert["assertEquals(boolean,boolean)"](true, new JSObject({}));
164})();
165