Skip to content

Commit

Permalink
comparisons of vars should assume BigDecimals
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelkaczor committed Jan 23, 2021
1 parent 46f405d commit efecc04
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
11 changes: 5 additions & 6 deletions src/main/scala/br/com/virsox/scalexpr/ExpressionParser.scala
Expand Up @@ -238,13 +238,11 @@ class ExpressionParser extends DateParser {

def dateTimeTerm[_: P]: P[OrderingExpr[Instant] with SimpleExpression[Instant]] = P(dateTimeVariable | dateTimeLiteral)

def stringTerm[_: P]: P[OrderingExpr[String] with SimpleExpression[String]] = P(stringLiteral | stringVariable)

def relationalOperators[_: P]: P[Unit] = P(StringIn("==", "!=", "<=", ">=", "<", ">"))

// both sides need to be of the same type - there is no conversion
def strRelationalExpr[A: P]: P[RelationalExpression[String]] =
P(stringTerm ~ relationalOperators.! ~ stringTerm).map(evalRelational[String])
P((stringLiteral ~ relationalOperators.! ~ stringVariable) | (stringVariable ~ relationalOperators.! ~ stringLiteral))
.map(evalRelational[String])

def intRelationalExpr[A: P]: P[RelationalExpression[Int]] =
P(numExpr[A, Int] ~ relationalOperators.! ~ numExpr[A, Int]).map(evalRelational[Int])
Expand All @@ -258,8 +256,9 @@ class ExpressionParser extends DateParser {
def bigDecimalRelationalExpr[A: P]: P[RelationalExpression[BigDecimal]] =
P(numExpr[A, BigDecimal] ~ relationalOperators.! ~ numExpr[A, BigDecimal]).map(evalRelational[BigDecimal])

def dateTimeRelationalExpr[_: P]: P[RelationalExpression[Instant]] =
P(dateTimeTerm ~ relationalOperators.! ~ dateTimeTerm).map(evalRelational[Instant])
def dateTimeRelationalExpr[A: P]: P[RelationalExpression[Instant]] =
P((dateTimeLiteral ~ relationalOperators.! ~ dateTimeVariable) | (dateTimeVariable ~ relationalOperators.! ~ dateTimeLiteral))
.map(evalRelational[Instant])

def relationalExpr[_: P]: P[RelationalExpression[_ >: Instant with String with BigDecimal]] =
P(strRelationalExpr | dateTimeRelationalExpr | bigDecimalRelationalExpr)
Expand Down
21 changes: 14 additions & 7 deletions src/test/scala/br/com/virsox/scalexpr/ExpressionParserTest.scala
Expand Up @@ -82,7 +82,7 @@ class ExpressionParserTest extends AnyFlatSpec with Matchers {
)
}

it should "resolve variables in a double expression" in new Fixture {
it should "resolve double variables in a double expression" in new Fixture {
verify(parser.parseDoubleExpression("value + 3.0"), DoubleVar("value") + DoubleConstant(3.0))
}

Expand All @@ -93,18 +93,25 @@ class ExpressionParserTest extends AnyFlatSpec with Matchers {
)
}

"An ExpressionParser" should "parse equality expressions with Strings" in new Fixture {
it should "parse equality expressions with Strings" in new Fixture {
verify(parser.parseBooleanExpression("""name == "Wilson""""), StringVar("name") == StringConstant("Wilson"))
verify(parser.parseBooleanExpression("""name != "John""""), StringVar("name") != StringConstant("John"))
}

it should "parse relational expression" in new Fixture {
verify(
parser.parseRelationalExpression("""a > 5"""),
RelationalExpression(BigDecimalVar("a"), GreaterThan, BigDecimalConstant(5))
)
}

it should "parse comparison expressions with variables on both sides" in new Fixture {
verify(parser.parseBooleanExpression("""a == b"""), BigDecimalVar("a") == BigDecimalVar("b"))
verify(parser.parseBooleanExpression("""a > b"""), BigDecimalVar("a") > BigDecimalVar("b"))
}

it should "parse comparison expressions with Ints" in new Fixture {
verify(parser.parseBooleanExpression("""age == 19"""), BigDecimalVar("age") == BigDecimalConstant(19))
verify(parser.parseBooleanExpression("""age != 18"""), BigDecimalVar("age") != BigDecimalConstant(18))
verify(parser.parseBooleanExpression("""age > 5"""), BigDecimalVar("age") > BigDecimalConstant(5))
verify(parser.parseBooleanExpression("""age < 25"""), BigDecimalVar("age") < BigDecimalConstant(25))
verify(parser.parseBooleanExpression("""age >= 19"""), BigDecimalVar("age") >= BigDecimalConstant(19))
verify(parser.parseBooleanExpression("""age <= 19"""), BigDecimalVar("age") <= BigDecimalConstant(19))
}

it should "parse comparison expressions with Longs" in new Fixture {
Expand Down
26 changes: 12 additions & 14 deletions src/test/scala/br/com/virsox/scalexpr/ExpressionTest.scala
Expand Up @@ -5,7 +5,8 @@ import java.time.Instant
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

/*** Tests for expression evaluation */
/** * Tests for expression evaluation
*/
class ExpressionTest extends AnyFlatSpec with Matchers {

trait BooleanConstants {
Expand All @@ -17,16 +18,16 @@ class ExpressionTest extends AnyFlatSpec with Matchers {

"A logical expression" should "evaluate the && operator" in new BooleanConstants {
(consFalse1 && consFalse2).resolve() shouldBe false
(consFalse1 && consTrue1 ).resolve() shouldBe false
(consTrue1 && consFalse2).resolve() shouldBe false
(consTrue1 && consTrue2 ).resolve() shouldBe true
(consFalse1 && consTrue1).resolve() shouldBe false
(consTrue1 && consFalse2).resolve() shouldBe false
(consTrue1 && consTrue2).resolve() shouldBe true
}

it should "evaluate the || operator" in new BooleanConstants {
(consFalse1 || consFalse2).resolve() shouldBe false
(consFalse1 || consTrue1 ).resolve() shouldBe true
(consTrue1 || consFalse2).resolve() shouldBe true
(consTrue1 || consTrue2 ).resolve() shouldBe true
(consFalse1 || consTrue1).resolve() shouldBe true
(consTrue1 || consFalse2).resolve() shouldBe true
(consTrue1 || consTrue2).resolve() shouldBe true
}

// ---------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -125,7 +126,7 @@ class ExpressionTest extends AnyFlatSpec with Matchers {
}

it should "be used in arithmetic expressions" in {
val var1 = IntVar("age")
val var1 = IntVar("age")
val value = IntConstant(10)

val context = Map("age" -> 19, "name" -> "John")
Expand All @@ -140,9 +141,8 @@ class ExpressionTest extends AnyFlatSpec with Matchers {
(var1 + var2).resolve(context) shouldBe 40
}


it should "be used in relational expressions" in {
val var1 = IntVar("age")
val var1 = IntVar("age")
val value = IntConstant(10)

val context: Map[String, Any] = Map("age" -> 19)
Expand All @@ -152,10 +152,9 @@ class ExpressionTest extends AnyFlatSpec with Matchers {

// ---------------------------------------------------------------------------------------------------


trait TestWithDates {
val date1: Instant = Instant.parse("2015-12-01T10:00:00.000Z")
val date2 = Instant.parse("2010-10-10T10:00:00.000Z")
val date2 = Instant.parse("2010-10-10T10:00:00.000Z")

}

Expand All @@ -173,7 +172,7 @@ class ExpressionTest extends AnyFlatSpec with Matchers {
it should "evaluate when using date variables" in new TestWithDates {

val cons1 = DateTimeConstant(date1)
val var1 = DateTimeVar("since")
val var1 = DateTimeVar("since")

val context: Map[String, Any] = Map("since" -> date2)

Expand All @@ -183,5 +182,4 @@ class ExpressionTest extends AnyFlatSpec with Matchers {
(var1 > cons1).resolve(context) shouldBe false
}


}

0 comments on commit efecc04

Please sign in to comment.