Skip to content

Commit 2b48e01

Browse files
committed
[GR-22168] Increase JSRuntime test coverage.
PullRequest: js/1448
2 parents cfbe26b + 4431b04 commit 2b48e01

File tree

12 files changed

+241
-44
lines changed

12 files changed

+241
-44
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
6+
*/
7+
/*
8+
* Test otherwise uncovered functionality in JSRuntime.
9+
*/
10+
11+
load('../assert.js');
12+
13+
//coverage for toNumberFromPrimitive
14+
var a = [1,2,3];
15+
Object.defineProperty(a, 'length', { value: '42' });
16+
assertFail(()=>{Object.defineProperty(a, 'length', { value: Debug.createLazyString('1234567890','12345678901234567890') })}, "Invalid array length");
17+
assertFail(()=>{Object.defineProperty(a, 'length', { value: Symbol('42') })}, "Cannot convert a Symbol");
18+
assertFail(()=>{Object.defineProperty(a, 'length', { value: BigInt('42') })}, "Cannot convert a BigInt");
19+
20+
21+
//coverage for toString
22+
assertFail(()=>{Debug.createLazyString(Symbol('42'), 'test')}, "Cannot convert a Symbol");
23+
assertSame('12345678901234567890test', Debug.createLazyString(BigInt('12345678901234567890'), 'test'));
24+
assertTrue(Debug.createLazyString('ABC', new (Java.type('java.lang.Object'))()).indexOf('ABCjava.lang.Object@') == 0);
25+
true;

graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/runtime/JSRuntimeTest.java

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import static org.junit.Assert.assertFalse;
4545
import static org.junit.Assert.assertSame;
4646
import static org.junit.Assert.assertTrue;
47+
import static org.junit.Assert.fail;
4748

4849
import java.math.BigInteger;
4950

@@ -81,13 +82,16 @@
8182
import com.oracle.truffle.js.runtime.builtins.JSSet;
8283
import com.oracle.truffle.js.runtime.builtins.JSString;
8384
import com.oracle.truffle.js.runtime.builtins.JSUserObject;
85+
import com.oracle.truffle.js.runtime.objects.JSLazyString;
8486
import com.oracle.truffle.js.runtime.objects.Null;
8587
import com.oracle.truffle.js.runtime.objects.Undefined;
8688
import com.oracle.truffle.js.test.JSTest;
8789
import com.oracle.truffle.js.test.polyglot.ForeignTestMap;
8890

8991
public class JSRuntimeTest extends JSTest {
9092

93+
private static final double BIGDELTA = 0.00001;
94+
9195
@Override
9296
public void setup() {
9397
super.setup();
@@ -110,6 +114,20 @@ public void testEqual() {
110114
assertFalse(JSRuntime.equal(true, Undefined.instance));
111115
assertFalse(JSRuntime.equal(Undefined.instance, 1));
112116
assertTrue(JSRuntime.equal(Float.MAX_VALUE, Float.MAX_VALUE));
117+
118+
DynamicObject obj = JSUserObject.create(context);
119+
assertFalse(JSRuntime.equal(obj, Null.instance));
120+
assertFalse(JSRuntime.equal(obj, Undefined.instance));
121+
assertFalse(JSRuntime.equal(Null.instance, obj));
122+
assertFalse(JSRuntime.equal(Undefined.instance, obj));
123+
assertTrue(JSRuntime.equal(obj, obj));
124+
assertFalse(JSRuntime.equal(obj, JSUserObject.create(context)));
125+
126+
BigInt bi1a = new BigInt(new BigInteger("0123456789"));
127+
BigInt bi1b = new BigInt(new BigInteger("0123456789"));
128+
BigInt bi2 = new BigInt(new BigInteger("9876543210"));
129+
assertTrue(JSRuntime.equal(bi1a, bi1b));
130+
assertFalse(JSRuntime.equal(bi1a, bi2));
113131
}
114132

115133
@Test
@@ -133,6 +151,8 @@ public void testQuote() {
133151

134152
@Test
135153
public void testImportValue() {
154+
testHelper.getJSContext(); // initialize JSContext
155+
136156
assertEquals(Null.instance, JSRuntime.importValue(null));
137157

138158
assertEquals(42, JSRuntime.importValue(42));
@@ -143,6 +163,17 @@ public void testImportValue() {
143163
// same for now, might not hold eternally
144164
assertSame(42, JSRuntime.importValue((byte) 42));
145165
assertSame(42, JSRuntime.importValue((short) 42));
166+
167+
assertSame(42, JSRuntime.importValue(42L));
168+
assertEquals(BigInt.valueOf(Long.MAX_VALUE), JSRuntime.importValue(Long.MAX_VALUE));
169+
assertEquals(42.0, (double) JSRuntime.importValue((float) 42), BIGDELTA);
170+
171+
try {
172+
JSRuntime.importValue(new Object());
173+
fail();
174+
} catch (Exception ex) {
175+
assertTrue(ex.getMessage().contains("not supported in JavaScript"));
176+
}
146177
}
147178

148179
@Test
@@ -339,4 +370,167 @@ public void testNodeToString() {
339370
assertTrue(str.contains("DualNode"));
340371
assertTrue(str.contains(":program"));
341372
}
373+
374+
@Test
375+
public void testToLength() {
376+
// toLength(double)
377+
assertTrue(JSRuntime.toLength(-3.14) == 0);
378+
assertTrue(JSRuntime.toLength(JSRuntime.MAX_SAFE_INTEGER * 2) == JSRuntime.MAX_SAFE_INTEGER);
379+
assertTrue(JSRuntime.toLength(Math.PI) == Math.PI);
380+
381+
// toLength(int)
382+
assertTrue(JSRuntime.toLength(-3) == 0);
383+
assertTrue(JSRuntime.toLength(42) == 42);
384+
}
385+
386+
@Test
387+
public void testLength() {
388+
testHelper.getJSContext(); // intializes Context
389+
390+
// lengthIntl(CharSequence)
391+
assertEquals(3, JSRuntime.length("ABC"));
392+
assertEquals(42, JSRuntime.length(new TestCharSequence()));
393+
assertEquals(40, JSRuntime.length(createLazyString()));
394+
}
395+
396+
private static CharSequence createLazyString() {
397+
return JSLazyString.create("01234567890123456789", "01234567890123456789");
398+
}
399+
400+
@Test
401+
public void testCharAt() {
402+
testHelper.getJSContext(); // initializes Context
403+
404+
// charAt(CharSequence, int)
405+
assertEquals('A', JSRuntime.charAt("ABC", 0));
406+
assertEquals('A', JSRuntime.charAt(new TestCharSequence(), 0));
407+
assertEquals('0', JSRuntime.charAt(createLazyString(), 0));
408+
}
409+
410+
private static class TestCharSequence implements CharSequence {
411+
@Override
412+
public int length() {
413+
return 42;
414+
}
415+
416+
@Override
417+
public char charAt(int index) {
418+
return 'A';
419+
}
420+
421+
@Override
422+
public CharSequence subSequence(int start, int end) {
423+
return null;
424+
}
425+
}
426+
427+
@Test
428+
public void testToUInt8() {
429+
// toUInt8(Object)
430+
assertTrue(JSRuntime.toUInt8((Object) 3) == 3);
431+
assertTrue(JSRuntime.toUInt8((Object) 3.14) == 3);
432+
assertTrue(JSRuntime.toUInt8((Object) Double.POSITIVE_INFINITY) == 0);
433+
}
434+
435+
@Test
436+
public void testToInt8() {
437+
// toInt8(Object)
438+
assertTrue(JSRuntime.toInt8((Object) 3) == 3);
439+
assertTrue(JSRuntime.toInt8((Object) 3.14) == 3);
440+
assertTrue(JSRuntime.toInt8((Object) Double.POSITIVE_INFINITY) == 0);
441+
}
442+
443+
@Test
444+
public void testToUInt16() {
445+
// toUInt16(Object)
446+
assertTrue(JSRuntime.toUInt16((Object) 3) == 3);
447+
assertTrue(JSRuntime.toUInt16((Object) 3.14) == 3);
448+
assertTrue(JSRuntime.toUInt16((Object) Double.POSITIVE_INFINITY) == 0);
449+
}
450+
451+
@Test
452+
public void testToInt16() {
453+
// toInt16(Object)
454+
assertTrue(JSRuntime.toInt16((Object) 3) == 3);
455+
assertTrue(JSRuntime.toInt16((Object) 3.14) == 3);
456+
assertTrue(JSRuntime.toInt16((Object) Double.POSITIVE_INFINITY) == 0);
457+
}
458+
459+
@Test
460+
public void testToInt32() {
461+
// toInt32(Object)
462+
assertTrue(JSRuntime.toInt32((Object) 3) == 3);
463+
assertTrue(JSRuntime.toInt32((Object) 3.14) == 3);
464+
assertTrue(JSRuntime.toInt32((Object) 3L) == 3);
465+
assertTrue(JSRuntime.toInt32((Object) Double.POSITIVE_INFINITY) == 0);
466+
}
467+
468+
@Test
469+
public void testToObject() {
470+
JSContext ctx = testHelper.getJSContext();
471+
472+
// toObjectFromPrimitive(Object)
473+
assertTrue(JSRuntime.toObject(ctx, true) != null);
474+
assertTrue(JSRuntime.toObject(ctx, "String") != null);
475+
assertTrue(JSRuntime.toObject(ctx, (float) 3.14) != null);
476+
}
477+
478+
@Test
479+
public void testToStringIsString() {
480+
testHelper.getJSContext(); // initialize JSContext
481+
482+
// toStringIsString(Object)
483+
assertEquals("ABC", JSRuntime.toStringIsString("ABC"));
484+
assertEquals(40, JSRuntime.toStringIsString(createLazyString()).length());
485+
}
486+
487+
@Test
488+
public void testTrimJSWhiteSpace() {
489+
// trimJSWhiteSpace(String)
490+
assertEquals("A", JSRuntime.trimJSWhiteSpace(" A "));
491+
assertEquals("A", JSRuntime.trimJSWhiteSpace("A "));
492+
assertEquals("A", JSRuntime.trimJSWhiteSpace(" A"));
493+
assertEquals("A", JSRuntime.trimJSWhiteSpace("A"));
494+
assertEquals("A", JSRuntime.trimJSWhiteSpace(" A "));
495+
assertEquals("AB", JSRuntime.trimJSWhiteSpace("AB "));
496+
assertEquals("AB", JSRuntime.trimJSWhiteSpace(" AB"));
497+
assertEquals("AB", JSRuntime.trimJSWhiteSpace("AB"));
498+
assertEquals("", JSRuntime.trimJSWhiteSpace(" "));
499+
assertEquals("", JSRuntime.trimJSWhiteSpace(""));
500+
}
501+
502+
@Test
503+
public void testIntValue() {
504+
// intValue(Number)
505+
assertEquals(42, JSRuntime.intValue(42));
506+
assertEquals(42, JSRuntime.intValue(42.3));
507+
assertEquals(42, JSRuntime.intValue(42L));
508+
}
509+
510+
@Test
511+
public void testFloatValue() {
512+
// floatValue(Number)
513+
assertEquals(42, JSRuntime.floatValue(42), BIGDELTA);
514+
assertEquals(42.3, JSRuntime.floatValue(42.3), BIGDELTA);
515+
assertEquals(42, JSRuntime.floatValue(42L), BIGDELTA);
516+
}
517+
518+
@Test
519+
public void testMathCeil() {
520+
// mathCeil(double)
521+
assertTrue(Double.isNaN(JSRuntime.mathCeil(Double.NaN)));
522+
assertTrue(JSRuntime.isNegativeZero(JSRuntime.mathCeil(-0.0)));
523+
}
524+
525+
@Test
526+
public void testExportValue() {
527+
testHelper.getJSContext(); // initialize JSContext
528+
529+
// exportValue(Object)
530+
assertEquals(42.0, (double) JSRuntime.exportValue(SafeInteger.valueOf(42)), BIGDELTA);
531+
532+
Object exportedLazyString = JSRuntime.exportValue(createLazyString());
533+
assertTrue(exportedLazyString instanceof String);
534+
assertEquals(createLazyString().toString(), exportedLazyString);
535+
}
342536
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/ArrayPrototypeBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ protected final Object arraySpeciesCreate(Object originalArray, long length) {
518518
}
519519
if (!isConstructorNode.executeBoolean(ctor)) {
520520
errorBranch.enter();
521-
throw Errors.createTypeErrorNotAConstructor(ctor);
521+
throw Errors.createTypeErrorNotAConstructor(ctor, context);
522522
}
523523
return construct((DynamicObject) ctor, JSRuntime.longToIntOrDouble(length));
524524
}
@@ -567,7 +567,7 @@ protected final DynamicObject speciesConstructor(DynamicObject thisObj, DynamicO
567567
}
568568
if (!isConstructorNode.executeBoolean(speciesConstructor)) {
569569
errorBranch.enter();
570-
throw Errors.createTypeErrorNotAConstructor(speciesConstructor);
570+
throw Errors.createTypeErrorNotAConstructor(speciesConstructor, context);
571571
}
572572
return (DynamicObject) speciesConstructor;
573573
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/ReflectBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ protected Object reflectConstruct(Object target, Object argumentsList, Object[]
230230
@Cached IsConstructorNode isConstructorNode) {
231231
if (!isConstructorNode.executeBoolean(target)) {
232232
errorBranch.enter();
233-
throw Errors.createTypeErrorNotAConstructor(target);
233+
throw Errors.createTypeErrorNotAConstructor(target, getContext());
234234
}
235235
Object newTarget;
236236
if (optionalArgs.length == 0) {
@@ -239,7 +239,7 @@ protected Object reflectConstruct(Object target, Object argumentsList, Object[]
239239
newTarget = optionalArgs[0];
240240
if (!isConstructorNode.executeBoolean(newTarget)) {
241241
errorBranch.enter();
242-
throw Errors.createTypeErrorNotAConstructor(newTarget);
242+
throw Errors.createTypeErrorNotAConstructor(newTarget, getContext());
243243
}
244244
}
245245

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/TypedArrayFunctionBuiltins.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -103,7 +103,7 @@ public TypedArrayOfNode(JSContext context, JSBuiltin builtin) {
103103
@Specialization
104104
protected DynamicObject arrayOf(Object thisObj, Object... args) {
105105
if (!isTypedArrayConstructor(thisObj)) {
106-
throw Errors.createTypeErrorNotAConstructor(thisObj);
106+
throw Errors.createTypeErrorNotAConstructor(thisObj, getContext());
107107
}
108108
int len = args.length;
109109
DynamicObject newObj = getArraySpeciesConstructorNode().typedArrayCreate((DynamicObject) thisObj, len);
@@ -133,7 +133,7 @@ protected DynamicObject arrayFrom(Object thisObj, Object[] args) {
133133
Object thisArg = JSRuntime.getArgOrUndefined(args, 2);
134134

135135
if (!JSFunction.isConstructor(thisObj)) {
136-
throw Errors.createTypeErrorNotAConstructor(thisObj);
136+
throw Errors.createTypeErrorNotAConstructor(thisObj, getContext());
137137
}
138138
return arrayFromIntl(thisObj, source, mapFn, thisArg, false);
139139
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/JSNewNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public Object createFunctionTypeError(Object target) {
261261
if (context.isOptionNashornCompatibilityMode()) {
262262
throw Errors.createTypeErrorNotAFunction(targetForError, this);
263263
} else {
264-
throw Errors.createTypeErrorNotAConstructor(targetForError, this);
264+
throw Errors.createTypeErrorNotAConstructor(targetForError, this, context);
265265
}
266266
}
267267

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/SpecializedNewObjectNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,6 @@ static DynamicObject builtinConstructor(@SuppressWarnings("unused") DynamicObjec
142142

143143
@Specialization(guards = {"!isConstructor"})
144144
public DynamicObject throwNotConstructorFunctionTypeError(DynamicObject target, @SuppressWarnings("unused") Object proto) {
145-
throw Errors.createTypeErrorNotConstructible(target);
145+
throw Errors.createTypeErrorNotAConstructor(target, context);
146146
}
147147
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/promise/NewPromiseCapabilityNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public PromiseCapabilityRecord executeDefault() {
9393
public PromiseCapabilityRecord execute(DynamicObject constructor) {
9494
if (!isConstructor.executeBoolean(constructor)) {
9595
errorBranch.enter();
96-
throw Errors.createTypeErrorNotAConstructor(constructor);
96+
throw Errors.createTypeErrorNotAConstructor(constructor, context);
9797
}
9898
PromiseCapabilityRecord promiseCapability = PromiseCapabilityRecord.create(Undefined.instance, Undefined.instance, Undefined.instance);
9999
DynamicObject executor = getCapabilitiesExecutor(promiseCapability);

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/Errors.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,14 @@ public static JSException createTypeErrorNotAFunction(Object functionObj, Node o
135135
}
136136

137137
@TruffleBoundary
138-
public static JSException createTypeErrorNotAConstructor(Object object) {
139-
return createTypeErrorNotAConstructor(object, null);
138+
public static JSException createTypeErrorNotAConstructor(Object object, JSContext context) {
139+
return createTypeErrorNotAConstructor(object, null, context);
140140
}
141141

142142
@TruffleBoundary
143-
public static JSException createTypeErrorNotAConstructor(Object object, Node originatingNode) {
144-
return JSException.create(JSErrorType.TypeError, String.format("%s is not a constructor", JSRuntime.safeToString(object)), originatingNode);
143+
public static JSException createTypeErrorNotAConstructor(Object object, Node originatingNode, JSContext context) {
144+
String msg = String.format(context.isOptionNashornCompatibilityMode() ? "%s is not a constructor function" : "%s is not a constructor", JSRuntime.safeToString(object));
145+
return JSException.create(JSErrorType.TypeError, msg, originatingNode);
145146
}
146147

147148
@TruffleBoundary
@@ -379,13 +380,6 @@ private static String quoteKey(JSContext context, Object key) {
379380
return context.isOptionNashornCompatibilityMode() ? "\"" + key + "\"" : key.toString();
380381
}
381382

382-
@TruffleBoundary
383-
public static JSException createTypeErrorNotConstructible(DynamicObject functionObj) {
384-
assert JSFunction.isJSFunction(functionObj);
385-
String message = String.format("%s is not a constructor function", JSRuntime.toString(functionObj));
386-
return JSException.create(JSErrorType.TypeError, message);
387-
}
388-
389383
@TruffleBoundary
390384
public static JSException createTypeErrorCannotRedefineProperty(Object key) {
391385
assert JSRuntime.isPropertyKey(key);

0 commit comments

Comments
 (0)