package openmods.calc;
import openmods.calc.CalcTestUtils.CalcCheck;
import openmods.calc.CalcTestUtils.SymbolStub;
import openmods.calc.types.bool.BoolCalculatorFactory;
import org.junit.Test;
public class BoolCalculatorTest {
private final Calculator<Boolean, ExprType> sut = BoolCalculatorFactory.createDefault();
public CalcCheck<Boolean> prefix(String value) {
return CalcCheck.create(sut, value, ExprType.PREFIX);
}
public CalcCheck<Boolean> infix(String value) {
return CalcCheck.create(sut, value, ExprType.INFIX);
}
public CalcCheck<Boolean> postfix(String value) {
return CalcCheck.create(sut, value, ExprType.POSTFIX);
}
public CalcCheck<Boolean> compiled(IExecutable<Boolean> expr) {
return CalcCheck.create(sut, expr);
}
@Test
public void testBasicPrefix() {
prefix("(& true false)").expectResult(false);
prefix("(& 1 0)").expectResult(false);
prefix("(and true false)").expectResult(false);
prefix("(and 1 0)").expectResult(false);
prefix("(| true false)").expectResult(true);
prefix("(| 1 0)").expectResult(true);
prefix("(or true false)").expectResult(true);
prefix("(or 1 0)").expectResult(true);
}
@Test
public void testBasicPostfix() {
postfix("true false &").expectResult(false);
postfix("1 0 &").expectResult(false);
postfix("true false and").expectResult(false);
postfix("1 0 and").expectResult(false);
postfix("true false |").expectResult(true);
postfix("1 0 |").expectResult(true);
postfix("true false or").expectResult(true);
postfix("1 0 or").expectResult(true);
}
@Test
public void testPostfixSymbols() {
sut.environment.setGlobalSymbol("a", false);
postfix("a").expectResult(false);
postfix("a$0").expectResult(false);
postfix("a$,1").expectResult(false);
postfix("a$0,1").expectResult(false);
postfix("@a").expectResult(false);
}
@Test(expected = RuntimeException.class)
public void testPostfixFunctionGet() {
postfix("@abs").execute();
}
@Test
public void testPostfixStackOperations() {
postfix("true dup &").expectResult(true);
postfix("false dup |").expectResult(false);
postfix("true false false pop ^").expectResult(true);
postfix("true false =>").expectResult(false);
postfix("true false swap =>").expectResult(true);
}
@Test
public void testPostfixDupWithArgs() {
postfix("true true false dup$2").expectResults(true, true, false, true, false);
}
@Test
public void testPostfixDupWithReturns() {
postfix("true false dup$,4").expectResults(true, false, false, false, false);
}
@Test
public void testPostfixPopWithArgs() {
postfix("true false false true pop$3").expectResults(true);
}
@Test
public void testBasicInfix() {
infix("true & false").expectResult(false);
infix("1 & 0").expectResult(false);
infix("true and false").expectResult(false);
infix("1 and 0").expectResult(false);
infix("true | false").expectResult(true);
infix("1 | 0").expectResult(true);
infix("true or false").expectResult(true);
infix("1 or 0").expectResult(true);
}
@Test
public void testParserSwitch() {
infix("true & prefix(false)").expectResult(false);
infix("true & prefix((| false true))").expectResult(true);
prefix("(& true (infix false))").expectResult(false);
prefix("(& true (infix false | true))").expectResult(true);
}
@Test
public void testConstantEvaluatingBrackets() {
final SymbolStub<Boolean> stub = new SymbolStub<Boolean>()
.allowCalls()
.expectArgs(true, false)
.verifyArgCount()
.setReturns(false, false, true)
.verifyReturnCount();
sut.environment.setGlobalSymbol("dummy", stub);
final IExecutable<Boolean> expr = sut.compilers.compile(ExprType.POSTFIX, "[true false dummy$2,3]");
stub.checkCallCount(1);
compiled(expr).expectResults(false, false, true);
stub.checkCallCount(1);
}
@Test
public void testConstantEvaluatingSymbol() {
final SymbolStub<Boolean> stub = new SymbolStub<Boolean>()
.allowCalls()
.expectArgs(false, true)
.verifyArgCount()
.setReturns(true)
.verifyReturnCount();
sut.environment.setGlobalSymbol("dummy", stub);
final IExecutable<Boolean> expr = sut.compilers.compile(ExprType.INFIX, "const(dummy(false, true) => false)");
stub.checkCallCount(1);
compiled(expr).expectResults(false);
stub.checkCallCount(1);
compiled(expr).expectResults(false);
stub.checkCallCount(1);
}
@Test
public void testSimpleLet() {
infix("let([x:true,y:false], x | y)").expectResult(true);
prefix("(let [(:x false) (:y false)] (| x y))").expectResult(false);
}
@Test
public void testFailSymbol() {
infix("fail('welp')").expectThrow(ExecutionErrorException.class, "welp");
infix("fail()").expectThrow(ExecutionErrorException.class, null);
}
}