Skip to content

Commit 4a06dd9

Browse files
authored
Painless: add tests for cached boxing (#24163)
We had a TODO about adding tests around cached boxing. In #24077 I tracked down the uncached boxing tests and saw the TODO. Cached boxing testing is a fairly small extension to that work.
1 parent 6658ff0 commit 4a06dd9

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import static java.util.Collections.singletonMap;
2525

26-
// TODO: Figure out a way to test autobox caching properly from methods such as Integer.valueOf(int);
2726
public class EqualsTests extends ScriptTestCase {
2827
public void testTypesEquals() {
2928
assertEquals(true, exec("return false === false;"));
@@ -133,14 +132,23 @@ public void testBranchEquals() {
133132
assertEquals(0, exec("def a = 1; Object b = new HashMap(); if (a === (Object)b) return 1; else return 0;"));
134133
}
135134

136-
public void testBranchEqualsDefAndPrimitive() {
135+
public void testEqualsDefAndPrimitive() {
137136
/* This test needs an Integer that isn't cached by Integer.valueOf so we draw one randomly. We can't use any fixed integer because
138137
* we can never be sure that the JVM hasn't configured itself to cache that Integer. It is sneaky like that. */
139138
int uncachedAutoboxedInt = randomValueOtherThanMany(i -> Integer.valueOf(i) == Integer.valueOf(i), ESTestCase::randomInt);
140139
assertEquals(true, exec("def x = params.i; int y = params.i; return x == y;", singletonMap("i", uncachedAutoboxedInt), true));
141140
assertEquals(false, exec("def x = params.i; int y = params.i; return x === y;", singletonMap("i", uncachedAutoboxedInt), true));
142141
assertEquals(true, exec("def x = params.i; int y = params.i; return y == x;", singletonMap("i", uncachedAutoboxedInt), true));
143142
assertEquals(false, exec("def x = params.i; int y = params.i; return y === x;", singletonMap("i", uncachedAutoboxedInt), true));
143+
144+
/* Now check that we use valueOf with the boxing used for comparing primitives to def. For this we need an
145+
* integer that is cached by Integer.valueOf. The JLS says 0 should always be cached. */
146+
int cachedAutoboxedInt = 0;
147+
assertSame(Integer.valueOf(cachedAutoboxedInt), Integer.valueOf(cachedAutoboxedInt));
148+
assertEquals(true, exec("def x = params.i; int y = params.i; return x == y;", singletonMap("i", cachedAutoboxedInt), true));
149+
assertEquals(true, exec("def x = params.i; int y = params.i; return x === y;", singletonMap("i", cachedAutoboxedInt), true));
150+
assertEquals(true, exec("def x = params.i; int y = params.i; return y == x;", singletonMap("i", cachedAutoboxedInt), true));
151+
assertEquals(true, exec("def x = params.i; int y = params.i; return y === x;", singletonMap("i", cachedAutoboxedInt), true));
144152
}
145153

146154
public void testBranchNotEquals() {
@@ -153,14 +161,23 @@ public void testBranchNotEquals() {
153161
assertEquals(1, exec("def a = 1; Object b = new HashMap(); if (a !== (Object)b) return 1; else return 0;"));
154162
}
155163

156-
public void testBranchNotEqualsDefAndPrimitive() {
164+
public void testNotEqualsDefAndPrimitive() {
157165
/* This test needs an Integer that isn't cached by Integer.valueOf so we draw one randomly. We can't use any fixed integer because
158166
* we can never be sure that the JVM hasn't configured itself to cache that Integer. It is sneaky like that. */
159167
int uncachedAutoboxedInt = randomValueOtherThanMany(i -> Integer.valueOf(i) == Integer.valueOf(i), ESTestCase::randomInt);
160168
assertEquals(false, exec("def x = params.i; int y = params.i; return x != y;", singletonMap("i", uncachedAutoboxedInt), true));
161169
assertEquals(true, exec("def x = params.i; int y = params.i; return x !== y;", singletonMap("i", uncachedAutoboxedInt), true));
162170
assertEquals(false, exec("def x = params.i; int y = params.i; return y != x;", singletonMap("i", uncachedAutoboxedInt), true));
163171
assertEquals(true, exec("def x = params.i; int y = params.i; return y !== x;", singletonMap("i", uncachedAutoboxedInt), true));
172+
173+
/* Now check that we use valueOf with the boxing used for comparing primitives to def. For this we need an
174+
* integer that is cached by Integer.valueOf. The JLS says 0 should always be cached. */
175+
int cachedAutoboxedInt = 0;
176+
assertSame(Integer.valueOf(cachedAutoboxedInt), Integer.valueOf(cachedAutoboxedInt));
177+
assertEquals(false, exec("def x = params.i; int y = params.i; return x != y;", singletonMap("i", cachedAutoboxedInt), true));
178+
assertEquals(false, exec("def x = params.i; int y = params.i; return x !== y;", singletonMap("i", cachedAutoboxedInt), true));
179+
assertEquals(false, exec("def x = params.i; int y = params.i; return y != x;", singletonMap("i", cachedAutoboxedInt), true));
180+
assertEquals(false, exec("def x = params.i; int y = params.i; return y !== x;", singletonMap("i", cachedAutoboxedInt), true));
164181
}
165182

166183
public void testRightHandNull() {

0 commit comments

Comments
 (0)