org.unlaxer.tinyexpression.CalculatorImplTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tinyExpression-testbase Show documentation
Show all versions of tinyExpression-testbase Show documentation
a simple parser combinator inspired by RelaxNG
The newest version!
package org.unlaxer.tinyexpression;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.junit.Test;
import org.unlaxer.ParserTestBase;
import org.unlaxer.Token;
import org.unlaxer.TokenKind;
import org.unlaxer.TokenPrinter;
import org.unlaxer.listener.OutputLevel;
import org.unlaxer.tinyexpression.CalculationContext.Angle;
import net.arnx.jsonic.JSON;
public abstract class CalculatorImplTest extends ParserTestBase{
@Test
public void test() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"0",new BigDecimal("0")));
assertTrue(calc(context,"1+1",new BigDecimal("2")));
assertTrue(calc(context,"1+1/5",new BigDecimal("1.20")));
assertTrue(calc(context,"1+1/5",new BigDecimal("1.20")));
assertTrue(calc(context,"(1+1)/5",new BigDecimal("0.40")));
assertTrue(calc(context,"(1e1+1)*5",new BigDecimal("55")));
assertTrue(calc(context,"(1e1+1)*(5-3)",new BigDecimal("22")));
assertTrue(calc(context,"10/2/2.5*4.5",new BigDecimal("9.00")));
assertTrue(calc(context,"10/2+2.5*4.5",new BigDecimal("16.25")));
assertTrue(calc(context,"-10/2+2.5*4.5",new BigDecimal("6.25")));
assertTrue(calc(context,"sin(30)",new BigDecimal("0.5")));
assertTrue(calc(context,"sin(30)*2",new BigDecimal("1")));
assertTrue(calc(context,"cos(60)",new BigDecimal("0.5")));
assertTrue(calc(context,"tan(45)",new BigDecimal("1")));
assertTrue(calc(context,"sqrt(4)",new BigDecimal("2")));
//test recurring decimal
context = new NormalCalculationContext(10,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"1/0.11",new BigDecimal("9.0909090909")));
assertTrue(calc(context,"1/7",new BigDecimal("0.1428571429")));
}
@Test
public void testVariable() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("count", 12);
assertTrue(calc(context,"$count+10",new BigDecimal("22")));
}
@Test
public void testTernary() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("isExists", true);
// assertTrue(calc(context,"true?10:0",new BigDecimal("10")));
// assertTrue(calc(context,"false?10:0",new BigDecimal("0")));
assertTrue(calc(context,"if($isExists){10}else{0}",new BigDecimal("10")));
}
@Test
public void testTrueOrFalse() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if(true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false){10}else{0}",new BigDecimal("0")));
setLevel(OutputLevel.none);// if level is not none , then got stackOverflow Error!
assertTrue(calc(context,"if(not(false)){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(not(true)){10}else{0}",new BigDecimal("0")));
}
@Test
public void testGreaterOrLessOrEqual() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if(10==20){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(10==10){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10!=10){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(10!=20){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10>=10){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10>=20){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(10>20){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(10<20){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10<=20){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10<=10){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(10>10){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(10>5){30}else{0}",new BigDecimal("30")));
assertTrue(calc(context,"if(not(10>5)){30}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(not(not(10>5))){30}else{0}",new BigDecimal("30")));
assertTrue(calc(context,"if(not(not(2*5>5))){6*8}else{0}",new BigDecimal("48")));
assertTrue(calc(context,"if(not(not(0.7*5>5))){6*8}else{0.3*0.2}",new BigDecimal("0.06")));
assertTrue(calc(context,"if(not(not(0.7*5>5))){6*8}else{0.3*if(1>0){0.3}else{0.2}}",new BigDecimal("0.09")));
}
@Test
public void testAndOrOrOrXor() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if(true|true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false|true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false|false){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(true|true|false){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false|false|true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false|false|false|true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false|false|false|false){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(false&true){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(false&false){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(true^true){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(false^true){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if(false^false){10}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(1>0|10<20){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if((1>0|10<20)){10}else{0}",new BigDecimal("10")));
assertTrue(calc(context,"if((1>0|10<20)&(true)){10}else{0}",new BigDecimal("10")));
context.set("number_accessCountByIPAddressInShortPeriod", 0);
context.set("number_accessCountByCaulisCookieInShortPeriod", 0);
context.set("number_accessCountByIPAddressInMiddlePeriod", 0);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 0);
String formula = "if(($number_accessCountByIPAddressInShortPeriod>=15.0)|($number_accessCountByCaulisCookieInShortPeriod>=10.0)|($number_accessCountByIPAddressInMiddlePeriod>=60.0)|($number_accessCountByCaulisCookieInMiddlePeriod>=30.0)){1}else{0}";
assertTrue(calc(context,formula,new BigDecimal("0")));
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 100);
assertTrue(calc(context,formula,new BigDecimal("1")));
context.set("number_accessCountByIPAddressInMiddlePeriod", 100);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 0);
assertTrue(calc(context,formula,new BigDecimal("1")));
context.set("number_accessCountByCaulisCookieInShortPeriod", 100);
context.set("number_accessCountByIPAddressInMiddlePeriod", 0);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 0);
assertTrue(calc(context,formula,new BigDecimal("1")));
context.set("number_accessCountByIPAddressInShortPeriod", 100);
context.set("number_accessCountByCaulisCookieInShortPeriod", 0);
context.set("number_accessCountByIPAddressInMiddlePeriod", 0);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 0);
assertTrue(calc(context,formula,new BigDecimal("1")));
context.set("number_accessCountByIPAddressInShortPeriod", 0);
context.set("number_accessCountByCaulisCookieInShortPeriod", 0);
context.set("number_accessCountByIPAddressInMiddlePeriod", 100);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 100);
assertTrue(calc(context,formula,new BigDecimal("1")));
}
@Test
public void testCalculatorSpeed() {
String formula = "if(($number_accessCountByIPAddressInShortPeriod>=15.0)|($number_accessCountByCaulisCookieInShortPeriod>=10.0)|($number_accessCountByIPAddressInMiddlePeriod>=60.0)|($number_accessCountByCaulisCookieInMiddlePeriod>=30.0)){1}else{0}";
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("number_accessCountByIPAddressInShortPeriod", 0);
context.set("number_accessCountByCaulisCookieInShortPeriod", 0);
context.set("number_accessCountByIPAddressInMiddlePeriod", 100);
context.set("number_accessCountByCaulisCookieInMiddlePeriod", 100);
long start = System.nanoTime();
PreConstructedCalculator preConstructedCalculator = preConstructedCalculator(formula);
for(int i =0 ; i < 10000000; i++) {
preConstructedCalculator.calculate(context);
}
long duration = System.nanoTime() - start;
System.out.println(formula);
System.out.format("calculation time:%f(microsec)\n" , ((float)duration)/10000000000f);
}
public abstract PreConstructedCalculator preConstructedCalculator(String formula);
@Test
public void testMultipleVariableCondition() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("float_test_random", 0.2f);
context.set("boolean_test_random", false);
assertTrue(calc(context,"if($float_test_random<0.3&($boolean_test_random==false)){1}else{0}",new BigDecimal("1")));
context.set("float_test_random", 0.5f);
context.set("boolean_test_random", false);
assertTrue(calc(context,"if(($float_test_random<0.3)&($boolean_test_random==false)){1}else{0}",new BigDecimal("0")));
context.set("float_test_random", 0.5f);
context.set("boolean_test_random", false);
assertTrue(calc(context,"if(( $float_test_random < 0.3 ) ^ ( $boolean_test_random ==false)){ 1 }else{ 0 }",new BigDecimal("1")));
}
@Test
public void testOr() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
String formula ="if(($number_accessPeakCountByIPAddressInLongPeriod>=10.0)|($number_accessPeakCountByCaulisCookieInLongPeriod>=5.0)){1}else{0}";
context.set("number_accessPeakCountByIPAddressInLongPeriod", 0);
context.set("number_accessPeakCountByCaulisCookieInLongPeriod", 0);
assertTrue(calc(context,formula,new BigDecimal("0")));
context.set("number_accessPeakCountByIPAddressInLongPeriod", 10);
context.set("number_accessPeakCountByCaulisCookieInLongPeriod", 0);
assertTrue(calc(context,formula,new BigDecimal("1")));
context.set("number_accessPeakCountByIPAddressInLongPeriod", 0);
context.set("number_accessPeakCountByCaulisCookieInLongPeriod", 5);
assertTrue(calc(context,formula,new BigDecimal("1")));
}
boolean calc(CalculationContext calculationContext , String formula , BigDecimal expected){
Calculator calculator = preConstructedCalculator(formula);
testAllMatch(calculator.getParser(), formula);
CalculateResult calculateResult = calculator.calculate(calculationContext , formula);
calculateResult.errors.raisedException.ifPresent(error->error.printStackTrace());
BigDecimal x = calculateResult.answer.get();
System.out.format(" %s = %s \n" , formula , x.toString());
return
expected.compareTo(x) ==0 ||
// this is work around for rounding error on float calculation
expected.subtract(x).abs().floatValue() < 0.01;
}
// @Test
// public void testSuggestSinANdSqrt() {
//
// String formula = "1+1/s";
//
// CalculationContext context = new CalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
// CalculateResult result = calculator.calculate(context, formula);
// System.out.println(getJson(result.parseContext.suggestsByPosition));
//
// int position = formula.indexOf("s");//s is invalid token in '1+1/s'
// assertEquals(2, result.parseContext.suggestsByPosition.get(position).size());
//
// }
static String getJson(Object object){
JSON json = new JSON();
json.setPrettyPrint(true);
return json.format(object);
}
@Test(expected=IllegalArgumentException.class)
public void testUnfinishedFormula() {
String formula = "1+1/s";
PreConstructedCalculator calculator = preConstructedCalculator(formula);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
CalculateResult result = calculator.calculate(context, formula);
BigDecimal answer = result.answer.get();
assertEquals(new BigDecimal("2"), answer);
assertFalse(result.success);
assertEquals("1+1", result.parseContext.getConsumed(TokenKind.consumed));
assertEquals("/s", result.parseContext.getRemain(TokenKind.consumed));
}
@Test(expected=IllegalArgumentException.class)
public void testNotStartedFormula() {
String formula = "s/1+1";
PreConstructedCalculator calculator = preConstructedCalculator(formula);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
CalculateResult result = calculator.calculate(context, formula);
assertFalse(result.answer.isPresent());
assertFalse(result.success);
assertEquals("", result.parseContext.getConsumed(TokenKind.consumed));
assertEquals(formula, result.parseContext.getRemain(TokenKind.consumed));
//s 's successor was already inputed , suggests is empty
// FIXME
// assertTrue(result.parseContext.suggestsByPosition.isEmpty());
}
@Test
public void testTokenPosition() {
String formula = "(1+1)/3+sin(30)";
PreConstructedCalculator calculator = preConstructedCalculator(formula);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
CalculateResult result = calculator.calculate(context, formula);
assertTrue(result.answer.isPresent());
assertTrue(result.success);
assertEquals("(1+1)/3+sin(30)", result.parseContext.getConsumed(TokenKind.consumed));
assertEquals("", result.parseContext.getRemain(TokenKind.consumed));
assertTrue(result.token.isPresent());
Token token = result.token.get();
TokenPrinter.output(token,System.out);
}
@Test
public void testVariableIsNotPresent() {
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if($isExists){1}else{0}",new BigDecimal("0")));
context.set("isExists", true);
assertTrue(calc(context,"if($isExists){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"$count",new BigDecimal("0")));
context.set("count", 5);
assertTrue(calc(context,"$count",new BigDecimal("5")));
}
@Test
public void testVariableIsPresentOperator() {
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if(isPresent($isExists)){5}else{10}",new BigDecimal("10")));
assertTrue(calc(context,"if(not(isPresent($isExists))){5}else{10}",new BigDecimal("5")));
context.set("isExists", false);
assertTrue(calc(context,"if(isPresent($isExists)){5}else{10}",new BigDecimal("5")));
assertTrue(calc(context,"if(not(isPresent($isExists))){5}else{10}",new BigDecimal("10")));
assertTrue(calc(context,"if(isPresent($value)){5}else{10}",new BigDecimal("10")));
assertTrue(calc(context,"if(not(isPresent($value))){5}else{10}",new BigDecimal("5")));
context.set("value", 10);
assertTrue(calc(context,"if(isPresent($value)){5}else{10}",new BigDecimal("5")));
assertTrue(calc(context,"if(not(isPresent($value))){5}else{10}",new BigDecimal("10")));
assertTrue(calc(context,"if(isPresent($name)){5}else{10}",new BigDecimal("10")));
assertTrue(calc(context,"if(not(isPresent($name))){5}else{10}",new BigDecimal("5")));
context.set("name", "opa");
assertTrue(calc(context,"if(isPresent($name)){5}else{10}",new BigDecimal("5")));
assertTrue(calc(context,"if(not(isPresent($name))){5}else{10}",new BigDecimal("10")));
}
@Test
public void testStringVariable() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
// assertTrue(calc(context,"if($name==''){1}else{0}",new BigDecimal("1")));
context.set("name", "opa");
// 12345678901234567890123456
assertTrue(calc(context,"if($name==\"opa\"){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($name!='opa'){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($name==\"opaopa\"){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($name!='opaopa'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($nameNoSpecified==\"opa\"){1}else{0}",new BigDecimal("0")));
}
@Test
public void testStringLiteral() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
// assertTrue(calc(context,"if($name==''){1}else{0}",new BigDecimal("1")));
context.set("name", "opa");
// 12345678901234567890123456
assertTrue(calc(context,"if(\"opa\"==\"opa\"){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(\"opa\"!=\"opa\"){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(\"opa\"==\"opaopa\"){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(\"opa\"!=\"opaopa\"){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(\"opa\"==$name){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(\"opa\"!=$name){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($name!='opa'){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($name==\"opaopa\"){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($name!='opaopa'){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringConcat() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if((\"opa\"+'opa'+\"6969\")=='opaopa6969'){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringSlice() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
assertTrue(calc(context,"if('deadbeaf'[1:3]=='ea'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if('gateman'[::-1]=='nametag'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if('1a2b3'[::2]=='123'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if('1a2b3'[1::2]=='ab'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if('gateman'[::-1][0:4]=='name'){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringTrim() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("name", " opa 133\t");
assertTrue(calc(context,"if(trim($name)=='opa 133'){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringUpperAndLowerCase() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("name", "AlmondChocolate");
assertTrue(calc(context,"if(toUpperCase($name)=='ALMONDCHOCOLATE'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(toUpperCase(\"AlmondChocolate\")=='ALMONDCHOCOLATE'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(toUpperCase(($name))=='ALMONDCHOCOLATE'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(toUpperCase($name[0:6])=='ALMOND'){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(toLowerCase($name)!='almondchocolate'){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(toLowerCase(\"AlmondChocolate\")!='almondchocolate'){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(toLowerCase(($name))!='almondchocolate'){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(toLowerCase(($name)[0:6]+' is delicious')!='almond is delicious'){1}else{0}",new BigDecimal("0")));
}
@Test
public void testStringLength() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("name", "AlmondChocolate");
assertTrue(calc(context,"if(len($name)==15){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(len(\"AlmondChocolate\")==15){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(len($name)-5==10){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringIn() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("country", "jp");
{
String formula = "if($country.in('jp','ca','us')){1}else{0}";
PreConstructedCalculator calculator = preConstructedCalculator(formula);
Token rootToken = parse(calculator.getParser(),formula).getRootToken();
TokenPrinter.output(rootToken,System.out);
}
assertTrue(calc(context,"if($country.in('jp','ca','us')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(false|$country.in('jp','ca','us')){1}else{0}",new BigDecimal("1")));
{
String formula = "if((isPresent($country)&$country.in('russian-federation','china','taiwan-province-of-china','ukraine','korea-democratic-peoples-republic-of'))|(isPresent($calculated_TorNode)&$calculated_TorNode>0.0)|((isPresent($calculated_BlackIPAddressInThisSite)&$calculated_BlackIPAddressInThisSite>0.0)|(isPresent($calculated_BlackIPAddressInOtherSites)&$calculated_BlackIPAddressInOtherSites>0.0))|(isPresent($calculated_BrowserTypeIsTool)&$calculated_BrowserTypeIsTool>0.0)){1}else{0}";
PreConstructedCalculator calculator = preConstructedCalculator(formula);
Token rootToken = parse(calculator.getParser(),formula).getRootToken();
TokenPrinter.output(rootToken,System.out);
assertTrue(calc(context,formula,new BigDecimal("0")));
}
assertTrue(calc(context,"if($country.in('ca','jp','us')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($country.in('en','ca','us')){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if('cnjpuszn'[0:2].in('en','ca','us')){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if('cnjpuszn'[4:6].in('en','ca','us')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(not('cnjpuszn'[4:6].in('en','ca','us'))){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(not(toUpperCase('cnjpuszn')[4:6].in(toUpperCase('en'),toUpperCase('ca'),toUpperCase('us')))){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if(not(not(toUpperCase('cnjpuszn')[4:6].in(toUpperCase('en'),toUpperCase('ca'),toUpperCase('us'))))){1}else{0}",new BigDecimal("1")));
}
@Test
public void testStringMethods() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("message", "I even lost my cat.");
assertTrue(calc(context,"if($message.startsWith('I even')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($message.startsWith('i even')){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($message.endsWith('my cat.')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($message.endsWith('my cat')){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($message.contains('lost my ')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($message.contains('lose my ')){1}else{0}",new BigDecimal("0")));
assertTrue(calc(context,"if($message.contains('lose my '[0:3]+'t')){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if($message.contains('lose my '[0:3]+'e')){1}else{0}",new BigDecimal("0")));
}
@Test
public void testMatchCase() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
String formula="match { $country == 'en' -> 1 , $country == 'jp' -> 2 , $country == 'cn' -> 3 , \n default -> 0}";
assertTrue(calc(context,formula ,new BigDecimal("0")));
context.set("country", "en");
assertTrue(calc(context,formula ,new BigDecimal("1")));
context.set("country", "jp");
assertTrue(calc(context,formula ,new BigDecimal("2")));
context.set("country", "cn");
assertTrue(calc(context,formula ,new BigDecimal("3")));
context.set("country", "ca");
assertTrue(calc(context,formula ,new BigDecimal("0")));
formula="match { $country == 'en' -> 1*9 , $country == 'jp' -> 2*9 , $country == 'cn' -> 3*9 , \n default -> 30*3}";
assertTrue(calc(context,formula ,new BigDecimal("90")));
context.set("country", "en");
assertTrue(calc(context,formula ,new BigDecimal("9")));
context.set("country", "jp");
assertTrue(calc(context,formula ,new BigDecimal("18")));
context.set("country", "cn");
assertTrue(calc(context,formula ,new BigDecimal("27")));
context.set("country", "ca");
assertTrue(calc(context,formula ,new BigDecimal("90")));
}
@Test
public void testMin() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("count", 10);
assertTrue(calc(context,"if(min(0,0)==0){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min(-1,0)==-1){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min(-1,-2)==-2){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min(1,0)==0){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min($count,5)==5){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min($count,2*3)==6){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(min($count*0.5,2*3)==5){1}else{0}",new BigDecimal("1")));
}
@Test
public void testMax() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("count", 10);
assertTrue(calc(context,"if(max(0,0)==0){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max(-1,0)==0){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max(-1,-2)==-1){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max(1,0)==1){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max($count,5)==10){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max($count,4*3)==12){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(max($count*2,4*3)==20){1}else{0}",new BigDecimal("1")));
}
@Test
public void testRandom() {
setLevel(OutputLevel.detail);
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
context.set("count", 10);
assertTrue(calc(context,"if(random()<=1.0){1}else{0}",new BigDecimal("1")));
assertTrue(calc(context,"if(random()>=0){1}else{0}",new BigDecimal("1")));
}
@Test
public void testFunctions() {
String[][] functions = new String[][]{
{"OriginalSpec_AnyBlackList", "if((isPresent($calculated_BlackIPAddressInThisSite)&$calculated_BlackIPAddressInThisSite>0.0)|(isPresent($calculated_BlackCaulisCookieInThisSite)&$calculated_BlackCaulisCookieInThisSite>0.0)){10}else{if((isPresent($calculated_BlackIPAddressInOtherSites)&$calculated_BlackIPAddressInOtherSites>0.0)|(isPresent($calculated_BlackCaulisCookieInOtherSites)&$calculated_BlackCaulisCookieInOtherSites>0.0)){5}else{0}}"},
{"OriginalSpec_SuspiciousProvider", "if((isPresent($calculated_AccessFromDataCenter)&$calculated_AccessFromDataCenter>0.0)|(isPresent($calculated_TorNode)&$calculated_TorNode>0.0)|(isPresent($calculated_AnonymizingVpn)&$calculated_AnonymizingVpn>0.0)){10}else{0}"},
{"OriginalSpec_OtherProvider", "0"},
{"UnknownUsingEmulator", "if((isPresent($calculated_UnknownUsingEmulator)&$calculated_UnknownUsingEmulator>0.0)){10}else{0}"},
{"Jailbreak", "if((isPresent($calculated_Jailbreak)&$calculated_Jailbreak>0.0)){5}else{0}"},
{"OriginalSpec_OverseaAccess", "if(isPresent($country)&$country!='japan'){5}else{0}"},
{"OriginalSpec_NotJapaneseLanguage", "if(isPresent($splanguage)¬($splanguage.in('ja','ja-JP'))){5}else{0}"},
{"OriginalSpec_MultipleAccess", "if((isPresent($number_accessCountByIPAddressInShortPeriod)&$number_accessCountByIPAddressInShortPeriod>0.0)|(isPresent($number_accessCountByIPAddressInMiddlePeriod)&$number_accessCountByIPAddressInMiddlePeriod>0.0)|(isPresent($number_accessCountByCaulisCookieInShortPeriod)&$number_accessCountByCaulisCookieInShortPeriod>0.0)|(isPresent($number_accessCountByCaulisCookieInMiddlePeriod)&$number_accessCountByCaulisCookieInMiddlePeriod>0.0)|(isPresent($userCountGroupedByCookieOnThisSite)&$userCountGroupedByCookieOnThisSite>0.0)){5}else{0}"},
{"POST_PROCESS_OriginalSpec_totalScore", "$calculated_OriginalSpec_AnyBlackList+$calculated_OriginalSpec_SuspiciousProvider+$calculated_OriginalSpec_OtherProvider+if(isPresent($calculated_UnknownUsingEmulator)){$calculated_UnknownUsingEmulator}else{0}+if(isPresent($calculated_Jailbreak)){$calculated_Jailbreak}else{0}+$calculated_OriginalSpec_OverseaAccess+$calculated_OriginalSpec_NotJapaneseLanguage+$calculated_OriginalSpec_MultipleAccess"},
{"POST_PROCESS_OriginalSpec_ChineseLanguageOrNotJapanTimezone", "if((isPresent($priorityLanguage)&$priorityLanguage==\"zh-CN\")|(isPresent($timezone)&$timezone!=\"+9\")){1}else{0}"},
{"POST_PROCESS_OriginalSpec_RiskyCountry", "if(isPresent($country)&$country.in(\"korea-democratic-peoples-republic-of\",\"iran\",\"iran-islamic-republic-of\",\"cuba\",\"syria\",\"syrian-arab-republic\",\"sudan\")){1}else{0}"},
{"POST_PROCESS_RELATIVE_SUSPICIOUS", "if($ForcedRelativeSuspiciousValue1){1}else{if($ForcedRelativeSuspiciousValue5){5}else{if(($POST_PROCESS_OriginalSpec_RiskyCountry>0.0)|(isPresent($calculated_TorNode)&$calculated_TorNode>0.0)|(isPresent($calculated_BrowserTypeIsTool)&$calculated_BrowserTypeIsTool>0.0)){5}else{if(($POST_PROCESS_OriginalSpec_ChineseLanguageOrNotJapanTimezone>0.0)){4}else{if($default_RelativeSuspiciousValue==5){4}else{$default_RelativeSuspiciousValue}}}}}"},
{"POST_PROCESS_OriginalSpec_OverseaAccess", "if(isPresent($country)&$country!=\"japan\"){1}else{0}"},
{"POST_PROCESS_OriginalSpec_MultiUserAccessToOneAccount", "if(isPresent($cookieCountGroupedByUser)&$cookieCountGroupedByUser>=10.0){1}else{0}"},
{"POST_PROCESS_OriginalSpec_OneUserAccessToMultiAccount", "if(isPresent($userCountGroupedByCookieOnThisSite)&$userCountGroupedByCookieOnThisSite>=5){1}else{0}"},
{"POST_PROCESS_OriginalSpec_BlackListOnOtherSites", "if((isPresent($calculated_BlackIPAddressInOtherSites)&$calculated_BlackIPAddressInOtherSites>0.0)|(isPresent($calculated_BlackCaulisCookieInOtherSites)&$calculated_BlackCaulisCookieInOtherSites>0.0)){1}else{0}"},
{"POST_PROCESS_OriginalSpec_RiskyCountry", "if(isPresent($country)&$country.in(\"korea-democratic-peoples-republic-of\",\"iran\",\"iran-islamic-republic-of\")){1}else{0}"},
{"POST_PROCESS_RELATIVE_SUSPICIOUS", "if($ForcedRelativeSuspiciousValue1){1}else{if($ForcedRelativeSuspiciousValue5){5}else{if($default_RelativeSuspiciousValue==5){5}else{if($POST_PROCESS_OriginalSpec_RiskyCountry>0.0){5}else{if(($POST_PROCESS_OriginalSpec_OverseaAccess>0.0)|($POST_PROCESS_OriginalSpec_MultiUserAccessToOneAccount>0.0)|($POST_PROCESS_OriginalSpec_OneUserAccessToMultiAccount>0.0)|($POST_PROCESS_OriginalSpec_BlackListOnOtherSites>0.0)|(isPresent($calculated_BrowserTypeIsTool)&$calculated_BrowserTypeIsTool>0.0)){4}else{$default_RelativeSuspiciousValue}}}}}"},
{"OriginalSpec_ChineseLanguage", "if(isPresent($priorityLanguage)&$priorityLanguage==\"zh-CN\"){50}else{0}"},
{"OriginalSpec_AnyBlackList", "if((isPresent($calculated_BlackIPAddressInThisSite)&$calculated_BlackIPAddressInThisSite>0.0)|(isPresent($calculated_BlackCaulisCookieInThisSite)&$calculated_BlackCaulisCookieInThisSite>0.0)){10}else{if((isPresent($calculated_BlackIPAddressInOtherSites)&$calculated_BlackIPAddressInOtherSites>0.0)|(isPresent($calculated_BlackCaulisCookieInOtherSites)&$calculated_BlackCaulisCookieInOtherSites>0.0)){5}else{0}}"},
{"OriginalSpec_SuspiciousProvider", "if((isPresent($calculated_AccessFromDataCenter)&$calculated_AccessFromDataCenter>0.0)|(isPresent($calculated_TorNode)&$calculated_TorNode>0.0)|(isPresent($calculated_AnonymizingVpn)&$calculated_AnonymizingVpn>0.0)){10}else{0}"},
{"OriginalSpec_OtherProvider", "0"},
{"UnknownUsingEmulator", "if((isPresent($calculated_UnknownUsingEmulator)&$calculated_UnknownUsingEmulator>0.0)){10}else{0}"},
{"Jailbreak", "if((isPresent($calculated_Jailbreak)&$calculated_Jailbreak>0.0)){5}else{0}"},
{"OriginalSpec_OverseaAccess", "if(isPresent($country)&$country!='japan'){5}else{0}"},
{"OriginalSpec_NotJapaneseLanguage", "if(isPresent($splanguage)¬($splanguage.in('ja','ja-JP'))){5}else{0}"},
{"OriginalSpec_MultipleAccess", "if((isPresent($number_accessCountByIPAddressInShortPeriod)&$number_accessCountByIPAddressInShortPeriod>0.0)|(isPresent($number_accessCountByIPAddressInMiddlePeriod)&$number_accessCountByIPAddressInMiddlePeriod>0.0)|(isPresent($number_accessCountByCaulisCookieInShortPeriod)&$number_accessCountByCaulisCookieInShortPeriod>0.0)|(isPresent($number_accessCountByCaulisCookieInMiddlePeriod)&$number_accessCountByCaulisCookieInMiddlePeriod>0.0)|(isPresent($userCountGroupedByCookieOnThisSite)&$userCountGroupedByCookieOnThisSite>0.0)){5}else{0}"},
{"POST_PROCESS_OriginalSpec_totalScore", "$calculated_OriginalSpec_AnyBlackList+$calculated_OriginalSpec_SuspiciousProvider+$calculated_OriginalSpec_OtherProvider+if(isPresent($calculated_UnknownUsingEmulator)){$calculated_UnknownUsingEmulator}else{0}+if(isPresent($calculated_Jailbreak)){$calculated_Jailbreak}else{0}+$calculated_OriginalSpec_OverseaAccess+$calculated_OriginalSpec_NotJapaneseLanguage+$calculated_OriginalSpec_MultipleAccess"},
{"japanese","if(isPresent($splanguage)¬($splanguage.in('ja','ja-JP','日本語'))){5}else{0}"}
};
CalculationContext context = new NormalCalculationContext(2,RoundingMode.HALF_UP,Angle.DEGREE);
setLevel(OutputLevel.detail);
for (String[] tuple : functions) {
String title = tuple[0];
String function = tuple[1];
System.out.println(title);
assertTrue(calc(context,function ,new BigDecimal("0")));
}
}
public Class> getTestClass(){
return CalculatorImplTest.class;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy