package com.laytonsmith.core;
import com.laytonsmith.abstraction.MCPlayer;
import com.laytonsmith.abstraction.MCServer;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.constructs.Token;
import com.laytonsmith.core.constructs.Variable;
import com.laytonsmith.core.environments.CommandHelperEnvironment;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.testing.StaticTest;
import static com.laytonsmith.testing.StaticTest.RunCommand;
import static com.laytonsmith.testing.StaticTest.SRun;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static com.laytonsmith.testing.StaticTest.RunCommand;
import static com.laytonsmith.testing.StaticTest.SRun;
//import org.powermock.api.mockito.PowerMockito;
//import org.powermock.core.classloader.annotations.PowerMockIgnore;
//import org.powermock.core.classloader.annotations.PrepareForTest;
//import org.powermock.modules.junit4.PowerMockRunner;
/**
*
*
*/
//@RunWith(PowerMockRunner.class)
//@PrepareForTest(CommandHelperPlugin.class)
//@PowerMockIgnore({"javax.xml.parsers.*", "com.sun.org.apache.xerces.internal.jaxp.*"})
public class MethodScriptCompilerTest {
MCServer fakeServer;
MCPlayer fakePlayer;
com.laytonsmith.core.environments.Environment env;
public MethodScriptCompilerTest() {
//StaticTest.InstallFakeServerFrontend();
}
@BeforeClass
public static void setUpClass() throws Exception {
StaticTest.InstallFakeServerFrontend();
}
@AfterClass
public static void tearDownClass() throws Exception {
new File("profiler.config").deleteOnExit();
}
@Before
public void setUp() throws Exception {
fakePlayer = StaticTest.GetOnlinePlayer();
fakeServer = StaticTest.GetFakeServer();
env = Static.GenerateStandaloneEnvironment();
env.getEnv(CommandHelperEnvironment.class).SetPlayer(fakePlayer);
}
@After
public void tearDown() {
}
/**
* Test of lex method, of class MethodScriptCompiler.
*/
@Test
public void testLex() throws Exception {
String config = "/cmd = msg('string')";
List e = null;
e = new ArrayList();
//This is the decomposed version of the above config
e.add(new Token(Token.TType.COMMAND, "/cmd", Target.UNKNOWN));
e.add(new Token(Token.TType.WHITESPACE, " ", Target.UNKNOWN));
e.add(new Token(Token.TType.ALIAS_END, "=", Target.UNKNOWN));
e.add(new Token(Token.TType.WHITESPACE, " ", Target.UNKNOWN));
e.add(new Token(Token.TType.FUNC_NAME, "msg", Target.UNKNOWN));
e.add(new Token(Token.TType.FUNC_START, "(", Target.UNKNOWN));
e.add(new Token(Token.TType.STRING, "string", Target.UNKNOWN));
e.add(new Token(Token.TType.FUNC_END, ")", Target.UNKNOWN));
e.add(new Token(Token.TType.NEWLINE, "\n", Target.UNKNOWN));
List result = MethodScriptCompiler.lex(config, null, false);
assertEquals(e, result);
String[] badConfigs = {
"'\\q'", //Bad escape sequences
"'\\m'",};
for (String c : badConfigs) {
try {
MethodScriptCompiler.lex(c, null, false);
//Shouldn't get here
fail(c + " should not have lexed, but did.");
} catch (ConfigCompileException ex) {
//Success!
}
}
}
@Test
public void testCompile() throws Exception {
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = msg('this is a string', if(true, 'and', 'another') 'function')", null, false)).get(0).compileRight();
try {
//extra parameter
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = msg('this is a string', if(true, 'and', 'another', 'oops') 'function')", null, false)).get(0).compileRight();
fail("Did not expect test to pass");
} catch (ConfigCompileException e) {
//passed
}
try {
//missing parenthesis
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = msg('this is a string', if(true, 'and', 'another') 'function'", null, false)).get(0).compileRight();
fail("Did not expect test to pass");
} catch (ConfigCompileException e) {
//passed
}
try {
//extra parenthesis
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = msg('this is a string', if(true, 'and', 'another') 'function')))))", null, false)).get(0).compileRight();
fail("Did not expect test to pass");
} catch (ConfigCompileException e) {
//passed
}
try {
//extra multiline end construct
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = msg('this is a string', if(true, 'and', 'another') 'function') <<<", null, false)).get(0).compileRight();
fail("Did not expect test to pass");
} catch (ConfigCompileException e) {
//passed
}
try{
//no multiline end construct
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("/cmd = >>>\nmsg('hi')\n", null, false)).get(0).compileRight();
fail("Did not expect no multiline end construct to pass");
} catch(ConfigCompileException e){
//passed
}
MethodScriptCompiler.compile(MethodScriptCompiler.lex("if(1, msg('') msg(''))", null, true));
}
@Test public void testLabel() throws Exception{
assertEquals(Static.GLOBAL_PERMISSION, MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("*:/cmd = die()", null, false)).get(0).compile().getLabel());
assertEquals(Static.GLOBAL_PERMISSION, MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("* : /cmd = die()", null, false)).get(0).compile().getLabel());
assertEquals("~lol/fun", MethodScriptCompiler.preprocess(MethodScriptCompiler.lex("~lol/fun: /cmd = die()", null, false)).get(0).compile().getLabel());
}
@Test
public void testCompile13() throws Exception{
MethodScriptCompiler.compile(MethodScriptCompiler.lex("msg ('hi')", null, true));
}
@Test public void testCompile14() throws Exception{
MethodScriptCompiler.compile(MethodScriptCompiler.lex("msg(('hi'))", null, true));
}
@Test
public void testCompile15() throws Exception{
try{
SRun("\n\nmsg(/, 'test')\n\n", fakePlayer);
} catch(ConfigCompileException e){
assertEquals("3", e.getLineNum());
}
}
@Test
public void testExecute1() throws Exception {
String script = "proc(_hello, @hello0,"
+ " msg(@hello0)"
+ " )"
+ " assign(@hello1, 'hello')"
+ " _hello(@hello1)";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute2() throws Exception {
String script =
"proc(_hello,\n"
+ " assign(@hello, 'hello')\n"
+ " return(@hello)\n"
+ ")\n"
+ "assign(@blah, 'blah')\n"
+ "assign(@blah, _hello())\n"
+ "msg(@blah)\n";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
/**
* Here we are testing for mismatched (or empty) square brackets. Essentially, it should throw an exception.
*/
@Test
public void testExecute3() {
try {
String script =
"[";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
fail("Test passed, but wasn't supposed to");
} catch (ConfigCompileException|ConfigCompileGroupException ex) {
//Passed
}
try {
String script =
"]";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
fail("Test passed, but wasn't supposed to");
} catch (ConfigCompileException|ConfigCompileGroupException ex) {
//Passed
}
}
@Test
public void testExecute4() throws Exception {
String script =
"proc(_hello,"
+ " return('hello')"
+ ")"
+ "msg(_hello())";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute5() throws Exception {
String script =
"proc(_hello,"
+ " return('hello')"
+ ")"
+ "msg(_hello())";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute6() throws Exception {
String script =
"#This is a comment invalid()'\"'' function\n"
+ "msg('hello')";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute7() throws Exception {
String script =
"msg('hello') #This is a comment too invalid()'\"'' function\n";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute9() throws Exception {
String script =
"msg('hello') /* This is a comment too invalid()'\"'' function\n"
+ "yup, still a comment. yay() */";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test(expected = ConfigCompileException.class)
public void testExecute10() throws Exception {
String script =
"msg('hello') /* This is a comment too invalid()'\"'' function\n"
+ "yup, still a comment. yay() This will fail though, because the comment is unended.";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
}
@Test(expected = ConfigCompileException.class)
public void testExecute11() throws Exception {
String script =
"msg('hello') 'unended string";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
}
@Test
public void testExecute12() throws Exception {
String script =
"msg('hello') /* This is a comment too invalid()'\"'' function\n"
+ "yup, still a comment. yay() */";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
}
@Test
public void testExecute13() throws Exception {
String script =
"assign(@a, array(0, 1, 2))"
+ "msg(@a[0])";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("0");
}
@Test
public void testExecute14() throws Exception {
String script =
"proc(_hello, assign(@i, 'world'),"
+ " return(@i)"
+ ")"
+ "msg(_hello('hello'))"
+ "msg(_hello())";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
verify(fakePlayer).sendMessage("world");
}
@Test public void testExecute15() throws Exception{
String script =
"assign(@i, 0)\n"
+ "msg('@i is currently' @i)\n"
+ "proc(_out, @i,\n"
+ " msg(trim('@i is currently' @i 'and @j is' @j))\n"
+ ")\n"
+ "_out('hello')\n"
+ "assign(@j, 'goodbye')\n"
+ "_out('world')\n";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("@i is currently 0");
verify(fakePlayer).sendMessage("@i is currently hello and @j is null");
verify(fakePlayer).sendMessage("@i is currently world and @j is null");
}
@Test public void testExecute16() throws Exception{
String script =
"proc(_myProc, @i, @j, @k, msg(trim(@i @j @k)))\n"
+ "_myProc()\n"
+ "_myProc(1)\n"
+ "_myProc(1, 2)\n"
+ "_myProc(1, 2, 3)\n"
+ "_myProc(1, 2, 3, 4)\n";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("1");
verify(fakePlayer).sendMessage("1 2");
verify(fakePlayer, times(2)).sendMessage("1 2 3");
}
@Test public void testExecute17() throws Exception{
String script =
"proc(_addition, @i, @j, msg(add(@i, @j)))\n"
+ "_addition(1, 1)\n"
+ "_addition(2, 2)";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
//verify(fakePlayer).sendMessage("null null null");
verify(fakePlayer).sendMessage("2");
verify(fakePlayer).sendMessage("4");
}
@Test public void testExecute18() throws Exception{
String script =
"proc(_myProc, msg(@arguments))\n"
+ "_myProc()\n"
+ "_myProc(1)\n"
+ "_myProc(1, 2)";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
//verify(fakePlayer).sendMessage("null null null");
verify(fakePlayer).sendMessage("{}");
verify(fakePlayer).sendMessage("{1}");
verify(fakePlayer).sendMessage("{1, 2}");
}
/**
* Variables are locked in when the procedure is defined
* @throws Exception
*/
@Test
public void testExecute19() throws Exception {
String script =
"assign(@j, 'world')\n"
+ "proc(_hello, assign(@i, @j),"
+ " return(@i)"
+ ")\n"
+ "assign(@j, 'goodbye')\n"
+ "msg(_hello('hello'))"
+ "msg(_hello())";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, null, null);
verify(fakePlayer).sendMessage("hello");
verify(fakePlayer).sendMessage("world");
}
@Test
public void testExecute20() throws Exception {
final AtomicBoolean bool = new AtomicBoolean(false);
String script =
"msg('hello') world";
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)), env, new MethodScriptComplete() {
@Override
public void done(String output) {
assertEquals("world", output.trim());
bool.set(true);
}
}, null);
verify(fakePlayer).sendMessage("hello");
assertTrue(bool.get());
}
@Test
public void testExecute21() throws Exception{
String script = "#*\n"
+ "msg('Not a comment')\n"
+ "#*#";
SRun(script, fakePlayer);
verify(fakePlayer).sendMessage("Not a comment");
}
@Test public void testExecute22() throws Exception{
SRun("msg('hi' (this is a thing))", fakePlayer);
verify(fakePlayer).sendMessage("hi this is a thing");
}
@Test
public void testCompile1() {
try {
String config = "/cmd [$p] $q = msg('')";
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0).compile();
fail("Test passed, but wasn't supposed to");
} catch (ConfigCompileException|ConfigCompileGroupException ex) {
//Passed
}
}
// @Test
// public void testCompileWithDoubleSlashCommand() throws Exception{
// AliasCore ac = mock(AliasCore.class);
// ac.autoIncludes = new ArrayList<File>();
// PowerMockito.mockStatic(CommandHelperPlugin.class);
// when(CommandHelperPlugin.getCore()).thenReturn(ac);
// assertEquals(ac, CommandHelperPlugin.getCore());
// String config = "//cmd blah = msg('success')";
// Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0);
// s.compile();
// env.getEnv(CommandHelperEnvironment.class).SetPlayer(fakePlayer);
// s.run(Arrays.asList(new Variable("$var", "hello", Target.UNKNOWN)), env, null);
// verify(fakePlayer).sendMessage("success");
// }
//
// @Test
// public void testCompileTwoAliases() throws Exception{
// AliasCore ac = mock(AliasCore.class);
// ac.autoIncludes = new ArrayList<File>();
// PowerMockito.mockStatic(CommandHelperPlugin.class);
// when(CommandHelperPlugin.getCore()).thenReturn(ac);
// assertEquals(ac, CommandHelperPlugin.getCore());
// String config = "/cmd1 = msg('success')\n"
// + " \n" //Spaces and tabs are here
// + "/cmd2 = msg('success')";
// env.getEnv(CommandHelperEnvironment.class).SetPlayer(fakePlayer);
// Script s1 = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0);
// s1.compile();
// s1.run(Arrays.asList(new Variable("$var", "hello", Target.UNKNOWN)), env, null);
// Script s2 = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(1);
// s2.compile();
// s2.run(Arrays.asList(new Variable("$var", "hello", Target.UNKNOWN)), env, null);
// verify(fakePlayer, times(2)).sendMessage("success");
// }
@Test
public void testCompile2() {
try {
String config = "/cmd [$p=player()] = msg('')";
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0).compile();
fail("Test passed, but wasn't supposed to");
} catch (ConfigCompileException|ConfigCompileGroupException ex) {
//Passed
}
}
@Test
public void testCompile4() throws Exception {
String config = "/cmd = >>>\n"
+ "msg('hello') #This is a comment too invalid()'\"'' function\n"
+ "<<<";
MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false));
}
@Test
public void testCompile5() throws Exception {
String config = "label:/cmd = >>>\n"
+ "msg('hello') #This is a comment too invalid()'\"'' function\n"
+ "<<<";
Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0);
s.compile();
assertEquals("label", s.getLabel());
}
@Test
public void testCompile6() throws Exception {
String config = "/cmd = >>>\n"
+ "msg(trim(hello 'world \\\\ \\' \\n'))"
+ "<<<";
RunCommand(config, fakePlayer, "/cmd");
verify(fakePlayer).sendMessage("hello world \\ '");
}
@Test
public void testCompile7() throws Exception {
String config = "/cmd = >>>\n"
+ "msg(hello) \\ msg(world)"
+ "<<<";
RunCommand(config, fakePlayer, "/cmd");
verify(fakePlayer).sendMessage("hello");
verify(fakePlayer).sendMessage("world");
}
//TODO: Make these tests possible
// @Test
// public void testCompile8() throws Exception {
// String config = "/cmd $one $ = >>>\n"
// + "msg($one) \\ msg($)"
// + "<<<";
//
// RunVars(Arrays.asList(new Variable[]{new Variable("$one", "first", false, false, Target.UNKNOWN),
// new Variable("$", "several variables", false, true, Target.UNKNOWN)}), config, fakePlayer);
// Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null), env).get(0);
// s.compile();
// s.run(Arrays.asList(new Variable[]{new Variable("$one", "first", false, false, Target.UNKNOWN),
// new Variable("$", "several variables", false, true, Target.UNKNOWN)}), env, null);
// verify(fakePlayer).sendMessage("first");
// verify(fakePlayer).sendMessage("several variables");
// }
//
// @Test
// public void testCompile9() throws Exception {
// String config = "/test [$var=1] = >>>\n"
// + "msg($var)"
// + "<<<";
// Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null), env).get(0);
// s.compile();
// assertTrue(s.match("/test 2"));
// s.run(Arrays.asList(new Variable[]{new Variable("$var", "2", true, false, Target.UNKNOWN)}), env, null);
// verify(fakePlayer).sendMessage("2");
// assertTrue(s.match("/test"));
// s.run(new ArrayList<Variable>(), env, null);
// verify(fakePlayer).sendMessage("1");
// }
@Test
public void testCompile10() throws Exception{
String config = "/test $var = >>>\n"
+ "msg($var)"
+ "<<<";
Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0);
s.compile();
assertTrue(s.match("/test 2"));
assertFalse(s.match("/test"));
s.run(Arrays.asList(new Variable[]{new Variable("$var", "2", true, false, Target.UNKNOWN)}), env, null);
}
//TODO: Make this test possible
// @Test public void testCompile11() throws Exception{
//
// CommandHelperPlugin.perms = mock(PermissionsResolverManager.class);
// when(CommandHelperPlugin.perms.hasPermission(fakePlayer.getVariableName(), "ch.alias.safe")).thenReturn(true);
// CommandHelperPlugin.myServer = fakeServer;
// when(fakeServer.getOnlinePlayers()).thenReturn(new MCPlayer[]{fakePlayer});
// String config = "safe:/test $var = >>>\n"
// + "all_players()\n"
// + "msg($var)\n"
// + "<<<";
// Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null), env).get(0);
// s.compile();
// assertEquals("safe", s.getLabel());
// assertTrue(s.match("/test 2"));
// s.run(Arrays.asList(new Variable[]{new Variable("$var", "2", true, false, Target.UNKNOWN)}), env, null);
// verify(fakePlayer).sendMessage("2");
// verify(CommandHelperPlugin.perms).hasPermission(fakePlayer.getVariableName(), "ch.alias.safe");
// }
@Test public void testCompile12() throws Exception{
String config = "/*/one = bad()*/\n"
+ "/two = msg('Good')\n";
Script s = MethodScriptCompiler.preprocess(MethodScriptCompiler.lex(config, null, false)).get(0);
s.compile();
assertFalse(s.match("/one"));
assertTrue(s.match("/two"));
}
@Test public void testUnicode() throws Exception{
SRun("msg('\\u0037 is win!')", fakePlayer);
verify(fakePlayer).sendMessage("7 is win!");
SRun("msg('\\u20ac')", fakePlayer);
verify(fakePlayer).sendMessage("€");
}
@Test public void testInfixMath1() throws Exception{
assertEquals("4", SRun("2 + 2", fakePlayer));
assertEquals("4", SRun("8 - 4", fakePlayer));
assertEquals("4", SRun("2 * 2", fakePlayer));
assertEquals("4", SRun("16/4", fakePlayer));
assertEquals("4.0", SRun("-0.5 + 4.5", fakePlayer));
}
@Test public void testInfixMath2() throws Exception{
assertEquals("2", SRun("-2 + 2 + 2", fakePlayer));
assertEquals("18", SRun("(2 + 4) * 3", fakePlayer));
assertEquals("14", SRun("2 + 4 * 3", fakePlayer));
}
@Test public void testInfixMath3() throws Exception{
assertEquals("8.0", SRun("2 ** 3", fakePlayer));
}
@Test public void testUnary() throws Exception{
assertEquals("1", SRun("2 + - 1", fakePlayer));
}
@Test public void testSymbolicConcat() throws Exception{
SRun("@hello = 'hello'\n"
+ "@world = 'world'\n"
+ "msg(@hello.@world)", fakePlayer);
verify(fakePlayer).sendMessage("helloworld");
}
@Test public void testSymbolicLogic1() throws Exception{
assertEquals("true", SRun("2 <= 5", fakePlayer));
assertEquals("false", SRun("2 === '2'", fakePlayer));
assertEquals("true", SRun("g(assign(@var, false)) !@var", fakePlayer));
}
@Test public void testSymbolicLogic2() throws Exception{
assertEquals("true", SRun("true || true", fakePlayer));
assertEquals("false", SRun("true && false", fakePlayer));
}
@Test public void testComplexSymbolicLogic() throws Exception{
assertEquals("true", SRun("2 == 2 && true", fakePlayer));
}
@Test public void testSymbolCompileError() throws Exception {
try{
SRun("(+ * 2)", fakePlayer);
fail("Did not expect test to pass");
} catch(ConfigCompileException e){
//pass
} catch(ConfigRuntimeException e){
//pass?
}
}
@Test public void testComplexSymbols() throws Exception{
SRun("assign(@var, 2) if((@var + 2) == 4, msg('Success!'))", fakePlayer);
verify(fakePlayer).sendMessage("Success!");
}
@Test public void testPostfix() throws Exception{
SRun("assign(@var, 2) msg(@var++) msg(@var)", fakePlayer);
verify(fakePlayer).sendMessage("2");
verify(fakePlayer).sendMessage("3");
}
@Test public void testPrefix() throws Exception{
SRun("assign(@var, 2) msg(++@var) msg(@var)", fakePlayer);
verify(fakePlayer, times(2)).sendMessage("3");
}
@Test public void testModulo() throws Exception{
assertEquals(Integer.toString(2 % 3), SRun("2 % 3", fakePlayer));
}
@Test public void TestOperationsWithFunction() throws Exception{
SRun("if(!and(false, false), msg('yes'))", fakePlayer);
verify(fakePlayer).sendMessage("yes");
}
@Test public void testArrayBooleanType() throws Exception{
assertEquals("true", SRun("boolean(array(1))", null));
assertEquals("false", SRun("boolean(array())", null));
}
@Test public void testParenthesisAfterQuotedString() throws Exception{
assertEquals("2 + 2 is 4", SRun("'2 + 2 is' (2 + 2)", fakePlayer));
}
@Test(expected=ConfigCompileException.class)
public void testCompileErrorOfStaticConstructOptimization() throws Exception{
MethodScriptCompiler.compile(MethodScriptCompiler.lex("2 / 0", null, true));
}
// If people complain that the old format is broken, I can see about re-adding this. For now,
// this is covered in the other exception handler test
// @Test public void testLineNumberCorrectInException1() throws Exception{
// String script =
// "try(\n" //Line 1
// + "assign(@a, array(1, 2))\n" //Line 2
// + "\n" //Line 3
// + "assign(@d, @a[2])\n" //Line 4
// + "\n" //Line 5
// + ", @e, msg(@e))\n"; //Line 6
// SRun(script, fakePlayer);
// verify(fakePlayer).sendMessage("4");
// }
@Test public void testLineNumberCorrectInException2() throws Exception{
String script =
"assign(@a, array(1, 2))\n" //Line 1
+ "\n" //Line 2
+ "assign(@d, @a[@b])\n"; //Line 3
try{
SRun(script, fakePlayer);
} catch(ConfigRuntimeException e){
assertEquals(3, e.getTarget().line());
}
}
@Test public void testLineNumberCorrectInException3() throws Exception{
String script =
"\n"
+ "assign(@a, array('aaa', 'bbb'))\n"
+ "assign(@b, 'test')\n"
+ "msg('test1')\n"
+ "assign(@d, @a[@b])\n"
+ "msg('test2')\n";
try{
SRun(script, fakePlayer);
} catch(ConfigRuntimeException e){
assertEquals(5, e.getTarget().line());
}
}
@Test public void testExtraParenthesis() throws Exception {
try{
SRun("\n"
+ "\n"
+ "player())\n", fakePlayer);
} catch(ConfigCompileException e){
assertEquals("3", e.getLineNum());
}
}
@Test(expected=ConfigCompileException.class)
public void testSpuriousSymbols() throws Exception{
SRun("2 +", fakePlayer);
}
@Test
public void testBraceIf() throws Exception{
SRun("if(true)\n\n"
+ "{\n"
+ "msg('success!')\n"
+ "}", fakePlayer);
verify(fakePlayer).sendMessage("success!");
}
@Test
public void testBraceElseIfElse() throws Exception{
SRun("if(false){"
+ "msg('fail')"
+ "} else if(true == true){"
+ "msg('success!')"
+ "} else {\n"
+ "msg('fail')"
+ "}", fakePlayer);
verify(fakePlayer).sendMessage("success!");
}
@Test
public void testBraceElseIfElseWithElseCondTrue() throws Exception{
SRun("if(false){"
+ "msg('fail')"
+ "} else if(false){"
+ "msg('fail')"
+ "} else {"
+ "msg('success!')"
+ "}", fakePlayer);
verify(fakePlayer).sendMessage("success!");
}
@Test(expected=ConfigCompileException.class)
public void testFailureOfBraces() throws Exception{
SRun("and(1){ 1 }", fakePlayer);
}
@Test(expected=ConfigCompileException.class)
public void testInnerElseInElseIf() throws Exception{
SRun("if(true){"
+ "msg('fail')"
+ "} else {"
+ "msg('fail')"
+ "} else if(true){"
+ "msg('fail')"
+ "}", fakePlayer);
}
@Test
public void testBracketsOnFor() throws Exception{
SRun("for(assign(@i, 0), @i < 5, @i++){\n"
+ "msg('worked')\n"
+ "}", fakePlayer);
verify(fakePlayer, times(5)).sendMessage("worked");
}
@Test
public void testBracketsOnForeach() throws Exception{
SRun("foreach(range(2), @i){\n"
+ "msg(@i)\n"
+ "}", fakePlayer);
verify(fakePlayer).sendMessage("0");
verify(fakePlayer).sendMessage("1");
}
@Test public void testWhitespaceInBetweenFunctionAndParen() throws Exception{
SRun("msg ('hi')", fakePlayer);
verify(fakePlayer).sendMessage("hi");
}
@Test public void testMultipleFunctionsWithBraces() throws Exception{
SRun("if(dyn(false)){\n"
+ "msg('nope')\n"
+ "} else {\n"
+ " msg('hi')\n"
+ " msg('hi')\n"
+ "}", fakePlayer);
verify(fakePlayer, times(2)).sendMessage("hi");
}
@Test
public void testArrayGetCatchesInvalidParameter() throws Exception {
try{
try {
SRun("1[4]", null);
fail("Did not expect test to pass");
} catch(ConfigCompileException e){
//Pass
}
try {
SRun("'string'['index']", null);
fail("Did not expect test to pass");
} catch(ConfigCompileException e){
//Pass
}
} catch(ConfigRuntimeException e){
fail("Expecting a compile error here, not a runtime exception");
}
}
@Test
public void testBlockComments1() throws Exception{
SRun( "/*\n"
+ " * Herp\n"
+ " * Derp\n"
+ " */\n"
+ "msg('hi');", fakePlayer);
}
@Test
public void testCommentsInStrings() throws Exception{
SRun("'#'", fakePlayer);
}
@Test
public void testCommentsInStrings2() throws Exception{
SRun("'/*'", fakePlayer);
}
@Test
public void testDoubleQuotesInSingleQuotes() throws Exception{
SRun("'This \"should work\" correctly, and not throw an exception'", null);
}
@Test public void testClosureToString1() throws Exception{
SRun("msg(closure(msg('')))", fakePlayer);
verify(fakePlayer).sendMessage("msg('')");
}
@Test public void testClosureToString2() throws Exception{
SRun("msg(closure('\\n'))", fakePlayer);
verify(fakePlayer).sendMessage("'\\n'");
}
@Test public void testClosureToString3() throws Exception{
SRun("msg(closure('\\\\'))", fakePlayer);
verify(fakePlayer).sendMessage("'\\\\'");
}
@Test public void testClosureToString4() throws Exception{
SRun("msg(closure('\\''))", fakePlayer);
verify(fakePlayer).sendMessage("'\\''");
}
@Test public void testCSlices() throws Exception{
assertEquals("-1", SRun("p(-1..-3[0])", null));
assertEquals("-2", SRun("p(-1..-3[1])", null));
assertEquals("-3", SRun("p(-1..-3[2])", null));
assertEquals("0", SRun("p(0..2[0])", null));
assertEquals("1", SRun("p(0..2[1])", null));
assertEquals("2", SRun("p(0..2[2])", null));
assertEquals("5", SRun("p(5..3[0])", null));
assertEquals("4", SRun("p(5..3[1])", null));
assertEquals("3", SRun("p(5..3[2])", null));
assertEquals("1", SRun("p(1..3[0])", null));
assertEquals("2", SRun("p(1..3[1])", null));
assertEquals("3", SRun("p(1..3[2])", null));
try{
SRun("1..2[10]", null);
fail("Expected an exception");
} catch (ConfigRuntimeException e){
//pass
}
assertEquals("2", SRun("array_size(1..2)", null));
assertEquals("true", SRun("array_contains(1..2, 1)", null));
assertEquals("false", SRun("array_contains(1..2, 3)", null));
assertEquals("true", SRun("array_contains(-1..-2, -2)", null));
assertEquals("false", SRun("array_contains(-1..-2, -3)", null));
assertEquals("true", SRun("array_index_exists(1..2, 0)", null));
assertEquals("false", SRun("array_index_exists(1..2, 2)", null));
}
@Test public void testWhitespaceAroundSymbol1() throws Exception{
assertEquals("true", SRun("false == false", null));
}
//This is accounted for in the new compiler branch, and will not be fixed in this branch.
// @Test public void testWhitespaceAroundSymbol2() throws Exception{
// assertEquals("true", SRun("false==false", null));
// }
//TODO: Once the lexer is rewritten, this should work
// @Test
// public void testAssignmentWithEquals1() throws Exception{
// SRun("@var=yep nope msg(@var)", fakePlayer);
// verify(fakePlayer).sendMessage("yep");
// }
//
// @Test
// public void testAssignmentWithEquals2() throws Exception{
// SRun("@var = yep nope msg(@var)", fakePlayer);
// verify(fakePlayer).sendMessage("yep");
// }
//
// @Test
// public void testAssignmentWithEquals3() throws Exception{
// SRun("@var = 'yep yep' msg(@var)", fakePlayer);
// verify(fakePlayer).sendMessage("yep yep");
// }
}