package com.oracle.truffle.js.test.polyglot;
import static org.junit.Assert.assertEquals;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.Value;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.js.lang.JavaScriptLanguage;
import com.oracle.truffle.js.runtime.interop.JavaScriptLanguageView;
import com.oracle.truffle.js.test.JSTest;
public final class ForeignConsolePrintTest {
private Context ctx;
@Before
public void setup() {
ctx = JSTest.newContextBuilder().allowHostAccess(HostAccess.ALL).build();
}
@After
public void tearDown() {
ctx.close();
}
@Test
public void testForeignArray() {
final String script = "(function (a) { return '' + a; })";
final Value fun = ctx.eval(JavaScriptLanguage.ID, script);
Value res = fun.execute(new ArrayTruffleObject(new Object[]{0, 1, 2, 3, 4}));
String sRes = res.asString();
assertEquals("0,1,2,3,4", sRes);
}
@Test
public void testToDisplayString() {
ctx.enter();
try {
ctx.initialize(JavaScriptLanguage.ID);
final ForeignTestMap map = new ForeignTestMap();
map.getContainer().put("foo", "bar");
ForeignTestFunction f = new ForeignTestFunction("test", (arg) -> {
return arg[0] + ", " + arg[1];
});
map.getContainer().put("fun", f);
JavaScriptLanguageView jslv = JavaScriptLanguageView.create(map);
Object resWithSideEffects = InteropLibrary.getFactory().getUncached(jslv).toDisplayString(jslv, true);
Object resWithoutSideEffects = InteropLibrary.getFactory().getUncached(jslv).toDisplayString(jslv, false);
assertEquals("{foo: \"bar\", fun: function test()}", resWithSideEffects);
assertEquals("{foo: \"bar\", fun: f()}", resWithoutSideEffects);
} finally {
ctx.leave();
}
}
@Test
public void testForeignObject() {
final String script = "(function (a) { return '' + a; })";
final Value fun = ctx.eval(JavaScriptLanguage.ID, script);
final ForeignTestMap map = new ForeignTestMap();
map.getContainer().put("x", 42);
map.getContainer().put("y", "foo");
Value res = fun.execute(map);
String sRes = res.asString();
assertEquals("[object Object]", sRes);
}
@Test
public void testForeignArrayWithObjects() {
final String script = "(function (a) { return '' + a; })";
final Value fun = ctx.eval(JavaScriptLanguage.ID, script);
final ForeignTestMap map = new ForeignTestMap();
map.getContainer().put("x", 42);
map.getContainer().put("y", "foo");
ArrayTruffleObject arr = new ArrayTruffleObject(new Object[]{0, "string", map, 3, new ForeignTestFunction("test", (arg) -> {
return arg[0] + ", " + arg[1];
})});
Value res = fun.execute(arr);
String sRes = res.asString();
assertEquals("0,string,[object Object],3,function test() { [native code] }", sRes);
}
@ExportLibrary(InteropLibrary.class)
static final class ArrayTruffleObject implements TruffleObject {
private final Object[] array;
ArrayTruffleObject(Object[] array) {
this.array = array;
}
@SuppressWarnings("static-method")
@ExportMessage
boolean hasArrayElements() {
return true;
}
@ExportMessage
long getArraySize() {
return array.length;
}
@ExportMessage
Object readArrayElement(long index) throws UnsupportedMessageException {
if (!isArrayElementReadable(index)) {
throw UnsupportedMessageException.create();
}
return array[(int) index];
}
@ExportMessage
boolean isArrayElementReadable(long index) {
return index >= 0 && index < array.length;
}
}
}