/*
* Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gololang;
import fr.insalyon.citi.golo.compiler.GoloCompilationException;
import org.testng.TestNGException;
import org.testng.annotations.Test;
import java.lang.invoke.MethodHandle;
import java.util.HashMap;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.containsString;
public class EvaluationEnvironmentTest {
private static final String SIMPLE_MODULE =
"module Foo\n\n" +
"function plop = -> \"Plop!\"\n\n";
private static final String SIMPLE_ANONYMOUS_MODULE = "function plop = -> \"Plop!\"\n\n";
@Test
public void module() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Class<?> module = (Class<?>) env.asModule(SIMPLE_MODULE);
assertThat(module, not(nullValue()));
assertThat((String) module.getMethod("plop").invoke(null), is("Plop!"));
}
@Test
public void anonymous_module() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Class<?> module = (Class<?>) env.anonymousModule(SIMPLE_ANONYMOUS_MODULE);
assertThat(module, not(nullValue()));
assertThat((String) module.getMethod("plop").invoke(null), is("Plop!"));
}
@Test
public void function() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Object result = env.asFunction("let x = 1\nreturn x + 2");
assertThat(result, instanceOf(MethodHandle.class));
MethodHandle func = (MethodHandle) result;
assertThat((Integer) func.invoke(), is(3));
}
@Test
public void function_with_arguments() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Object result = env.asFunction("return a + b", "a", "b");
assertThat(result, instanceOf(MethodHandle.class));
MethodHandle func = (MethodHandle) result;
assertThat(func.type().parameterCount(), is(2));
assertThat((Integer) func.invoke(10, 5), is(15));
}
@Test
public void run() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Object result = env.run("let x = 1\nreturn x + 2");
assertThat(result, instanceOf(Integer.class));
assertThat((Integer) result, is(3));
}
@Test
public void run_with_context() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
Object result = env.run("return a + b", new HashMap<String, Object>() {
{
put("a", 11);
put("b", 9);
}
});
assertThat(result, instanceOf(Integer.class));
assertThat((Integer) result, is(20));
}
@Test(expectedExceptions = RuntimeException.class)
public void run_error() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
env.run("returnz false");
}
@Test
public void run_with_imports() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment().imports("java.lang.Math");
String snippet = "return max(1, 2)";
Object result = env.run(snippet);
assertThat(result, instanceOf(Integer.class));
assertThat((Integer) result, is(2));
env.clearImports();
try {
env.run(snippet);
throw new TestNGException("A RuntimeException should have been raised");
} catch (RuntimeException ignored) {
}
}
@Test
public void defunc() throws Throwable {
EvaluationEnvironment env = new EvaluationEnvironment();
String code = "|a, b| -> a + b";
Object result = env.def(code);
assertThat(result, instanceOf(MethodHandle.class));
MethodHandle func = (MethodHandle) result;
assertThat(func.type().parameterCount(), is(2));
assertThat((Integer) func.invoke(10, 5), is(15));
}
@Test
public void check_source_present_with_compilation_error() {
EvaluationEnvironment env = new EvaluationEnvironment();
try {
env.def("boom");
throw new TestNGException("A GoloCompilationException should have been raised");
} catch (GoloCompilationException e) {
assertThat(e.getSourceCode(), notNullValue());
assertThat(e.getSourceCode(), both(containsString("boom")).and(containsString("module anonymous")));
}
}
}