package com.oracle.truffle.js.test.instrumentation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.junit.Assert;
import org.junit.Test;
import com.oracle.truffle.api.instrumentation.Instrumenter;
import com.oracle.truffle.api.instrumentation.SourceFilter;
public class InternalTagInheritanceTest {
private static final String MAIN_SOURCE_NAME = "MainSource.js";
private static final String EVAL_SOURCE_NAME = "<eval>";
private static final String MAIN_SOURCE_TEMPLATE = "%d + %d + eval('%s');%s";
private static final String EVAL_SOURCE_TEMPLATE = "%d + %d + %d;%s";
private static final String IN_TEXT_NONINTERNAL_SOURCE_NAME = "SourceNameOverride.js";
private static final String IN_TEXT_INTERNAL_SOURCE_NAME = "internal:" + IN_TEXT_NONINTERNAL_SOURCE_NAME;
private static final String IN_TEXT_SOURCE_NAME_TEMPLATE = "//# sourceURL=%s";
private static final String IN_TEXT_INTERNAL_SOURCE_ANNOTATION = String.format(IN_TEXT_SOURCE_NAME_TEMPLATE, IN_TEXT_INTERNAL_SOURCE_NAME);
private static final String IN_TEXT_NONINTERNAL_SOURCE_ANNOTATION = String.format(IN_TEXT_SOURCE_NAME_TEMPLATE, IN_TEXT_NONINTERNAL_SOURCE_NAME);
@Test
public void testEval() throws IOException {
try (Context ctx = Context.create("js")) {
TestingExecutionInstrument instrument = ctx.getEngine().getInstruments().get(TestingExecutionInstrument.ID).lookup(TestingExecutionInstrument.class);
Instrumenter instrumenter = instrument.getEnvironment().getInstrumenter();
List<com.oracle.truffle.api.source.Source> sources = new ArrayList<>();
instrumenter.attachExecuteSourceListener(SourceFilter.ANY, event -> {
sources.add(event.getSource());
}, true);
boolean mainSourceInternal;
String mainSourceInTextSourceName;
for (int i = 0; i < 3; i++) {
mainSourceInTextSourceName = "";
if (i == 1) {
mainSourceInTextSourceName += IN_TEXT_NONINTERNAL_SOURCE_ANNOTATION;
} else if (i == 2) {
mainSourceInTextSourceName += IN_TEXT_INTERNAL_SOURCE_ANNOTATION;
}
for (int j = 0; j < 2; j++) {
mainSourceInternal = j == 1;
String evalSourceInTextSourceName;
for (int k = 0; k < 3; k++) {
evalSourceInTextSourceName = "";
if (k == 1) {
evalSourceInTextSourceName += IN_TEXT_NONINTERNAL_SOURCE_ANNOTATION;
} else if (k == 2) {
evalSourceInTextSourceName += IN_TEXT_INTERNAL_SOURCE_ANNOTATION;
}
String evalSource = String.format(EVAL_SOURCE_TEMPLATE, i, j, k, evalSourceInTextSourceName);
String mainSource = String.format(MAIN_SOURCE_TEMPLATE, i, j, evalSource, mainSourceInTextSourceName);
Source source = Source.newBuilder("js", mainSource, MAIN_SOURCE_NAME).internal(mainSourceInternal).build();
sources.clear();
Value val = ctx.eval(source);
Assert.assertEquals(2, sources.size());
com.oracle.truffle.api.source.Source interceptedMainSource = sources.get(0);
com.oracle.truffle.api.source.Source interceptedEvalSource = sources.get(1);
Assert.assertEquals(mainSource, interceptedMainSource.getCharacters());
switch (i) {
case 0:
Assert.assertEquals(MAIN_SOURCE_NAME, interceptedMainSource.getName());
Assert.assertEquals(j == 1, interceptedMainSource.isInternal());
break;
case 1:
Assert.assertEquals(IN_TEXT_NONINTERNAL_SOURCE_NAME, interceptedMainSource.getName());
Assert.assertEquals(j == 1, interceptedMainSource.isInternal());
break;
case 2:
Assert.assertEquals(IN_TEXT_INTERNAL_SOURCE_NAME, interceptedMainSource.getName());
Assert.assertTrue(interceptedMainSource.isInternal());
break;
default:
Assert.fail();
break;
}
Assert.assertEquals(evalSource, interceptedEvalSource.getCharacters());
switch (k) {
case 0:
Assert.assertEquals(EVAL_SOURCE_NAME, interceptedEvalSource.getName());
Assert.assertFalse(interceptedEvalSource.isInternal());
break;
case 1:
Assert.assertEquals(IN_TEXT_NONINTERNAL_SOURCE_NAME, interceptedEvalSource.getName());
Assert.assertFalse(interceptedEvalSource.isInternal());
break;
case 2:
Assert.assertEquals(IN_TEXT_INTERNAL_SOURCE_NAME, interceptedEvalSource.getName());
Assert.assertTrue(interceptedEvalSource.isInternal());
break;
default:
Assert.fail();
break;
}
Assert.assertEquals(i + j + i + j + k, val.asInt());
}
}
}
}
}
}