Refactor the Instruction parser into an Expression one.
Now support more arithmeric operator (mainly *, /) and recurcive bracket
This commit is contained in:
parent
409acf748f
commit
ce51a3be0a
19 changed files with 824 additions and 448 deletions
|
|
@ -1,138 +0,0 @@
|
|||
package com.pixelized.desktop.lwa.parser
|
||||
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.Instruction
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFails
|
||||
|
||||
class InstructionParserTest {
|
||||
|
||||
@Test
|
||||
fun testDiceInstructionParse() {
|
||||
val parser = ArithmeticParser()
|
||||
|
||||
fun test(
|
||||
instruction: String,
|
||||
expectedModifier: Instruction.Dice.Modifier?,
|
||||
expectedQuantity: Int,
|
||||
expectedFaces: Int,
|
||||
) {
|
||||
val dice = parser.parse(value = instruction).first()
|
||||
|
||||
assert(dice is Instruction.Dice) {
|
||||
"Instruction should be ArithmeticInstruction.Dice but was: ${dice::class.java.simpleName}"
|
||||
}
|
||||
(dice as? Instruction.Dice)?.let {
|
||||
assert(dice.modifier == expectedModifier) {
|
||||
"$instruction modifier should be:\"$expectedModifier\", but was: ${dice.modifier}"
|
||||
}
|
||||
assert(dice.quantity == expectedQuantity) {
|
||||
"$instruction quantity should be \"$expectedQuantity\" but was ${dice.quantity}"
|
||||
}
|
||||
assert(dice.faces == expectedFaces) {
|
||||
"$instruction faces should be \"$expectedFaces\" but was ${dice.faces}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test(
|
||||
instruction = "1d100",
|
||||
expectedModifier = null,
|
||||
expectedQuantity = 1,
|
||||
expectedFaces = 100,
|
||||
)
|
||||
test(
|
||||
instruction = "a2d6",
|
||||
expectedModifier = Instruction.Dice.Modifier.ADVANTAGE,
|
||||
expectedQuantity = 2,
|
||||
expectedFaces = 6,
|
||||
)
|
||||
test(
|
||||
instruction = "d1d2",
|
||||
expectedModifier = Instruction.Dice.Modifier.DISADVANTAGE,
|
||||
expectedQuantity = 1,
|
||||
expectedFaces = 2,
|
||||
)
|
||||
test(
|
||||
instruction = "e6d6",
|
||||
expectedModifier = Instruction.Dice.Modifier.EMPHASIS,
|
||||
expectedQuantity = 6,
|
||||
expectedFaces = 6,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWordInstructionParse() {
|
||||
val parser = ArithmeticParser()
|
||||
|
||||
ArithmeticParser.words.map { instruction ->
|
||||
val word = parser.parse(value = instruction).first()
|
||||
|
||||
assert(word is Instruction.Word) {
|
||||
"Instruction should be ArithmeticInstruction.Word but was: ${word::class.java.simpleName}"
|
||||
}
|
||||
(word as? Instruction.Word)?.let {
|
||||
assert(it.type.name == instruction) {
|
||||
"Instruction should be $instruction, but was ${it.type.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFlatInstructionParse() {
|
||||
val parser = ArithmeticParser()
|
||||
|
||||
"100".let { instruction ->
|
||||
val flat = parser.parse(value = instruction).first()
|
||||
|
||||
assert(flat is Instruction.Flat) {
|
||||
"Instruction should be ArithmeticInstruction.Flat but was: ${flat::class.java.simpleName}"
|
||||
}
|
||||
(flat as? Instruction.Flat)?.let {
|
||||
assert("${it.value}" == instruction) {
|
||||
"Instruction should be $instruction, but was ${it.value}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRollParse() {
|
||||
val parser = ArithmeticParser()
|
||||
|
||||
fun test(
|
||||
instruction: Instruction,
|
||||
expectedInstruction: Instruction,
|
||||
) {
|
||||
assert(instruction == expectedInstruction) {
|
||||
"Arithmetic instruction should be $expectedInstruction but was: $instruction"
|
||||
}
|
||||
}
|
||||
|
||||
val instructions = parser.parse(
|
||||
value = "1+1d6+2-BDC+BDD",
|
||||
)
|
||||
|
||||
test(
|
||||
instruction = instructions[0],
|
||||
expectedInstruction = Instruction.Flat(sign = 1, value = 1),
|
||||
)
|
||||
test(
|
||||
instruction = instructions[1],
|
||||
expectedInstruction = Instruction.Dice(sign = 1, modifier = null, quantity = 1, faces = 6),
|
||||
)
|
||||
test(
|
||||
instruction = instructions[2],
|
||||
expectedInstruction = Instruction.Flat(sign = 1, value = 2),
|
||||
)
|
||||
test(
|
||||
instruction = instructions[3],
|
||||
expectedInstruction = Instruction.Word(sign = -1, type = Instruction.Word.Type.BDC),
|
||||
)
|
||||
test(
|
||||
instruction = instructions[4],
|
||||
expectedInstruction = Instruction.Word(sign = 1, type = Instruction.Word.Type.BDD),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.pixelized.desktop.lwa.parser.dice
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
class DiceParserTest {
|
||||
|
||||
@Test
|
||||
fun testInvalidExpression() {
|
||||
val parser = DiceParser()
|
||||
parser.test(expression = "", expected = null)
|
||||
parser.test(expression = " ", expected = null)
|
||||
parser.test(expression = "1", expected = null)
|
||||
parser.test(expression = "d6", expected = null)
|
||||
parser.test(expression = "ad6", expected = null)
|
||||
parser.test(expression = "dd6", expected = null)
|
||||
parser.test(expression = "ed6", expected = null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFaces() {
|
||||
val parser = DiceParser()
|
||||
parser.test(expression = "1d4", expected = Dice(modifier = null, quantity = 1, faces = 4))
|
||||
parser.test(expression = "1d6", expected = Dice(modifier = null, quantity = 1, faces = 6))
|
||||
parser.test(expression = "1d8", expected = Dice(modifier = null, quantity = 1, faces = 8))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQuantity() {
|
||||
val parser = DiceParser()
|
||||
parser.test(expression = "2d6", expected = Dice(modifier = null, quantity = 2, faces = 6))
|
||||
parser.test(expression = "3d6", expected = Dice(modifier = null, quantity = 3, faces = 6))
|
||||
parser.test(expression = "4d6", expected = Dice(modifier = null, quantity = 4, faces = 6))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWhitespace() {
|
||||
val parser = DiceParser()
|
||||
parser.test(expression = " 2d6", expected = Dice(modifier = null, quantity = 2, faces = 6))
|
||||
parser.test(expression = "2d6 ", expected = Dice(modifier = null, quantity = 2, faces = 6))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testModifier() {
|
||||
val parser = DiceParser()
|
||||
parser.test(
|
||||
expression = "a1d6",
|
||||
expected = Dice(modifier = Dice.Modifier.ADVANTAGE, quantity = 1, faces = 6)
|
||||
)
|
||||
parser.test(
|
||||
expression = "d1d6",
|
||||
expected = Dice(modifier = Dice.Modifier.DISADVANTAGE, quantity = 1, faces = 6)
|
||||
)
|
||||
parser.test(
|
||||
expression = "e1d6",
|
||||
expected = Dice(modifier = Dice.Modifier.EMPHASIS, quantity = 1, faces = 6)
|
||||
)
|
||||
}
|
||||
|
||||
private fun DiceParser.test(
|
||||
expression: String,
|
||||
expected: Dice?,
|
||||
) {
|
||||
val result = parse(expression = expression)
|
||||
assert(result == expected) {
|
||||
"DiceParser.parse(expression=$expression) is expected to return:$expected, but was:$result"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package com.pixelized.desktop.lwa.parser.expression
|
||||
|
||||
import com.pixelized.desktop.lwa.parser.dice.DiceParser
|
||||
import com.pixelized.desktop.lwa.parser.expression.ExpressionParser.Error
|
||||
import com.pixelized.desktop.lwa.parser.word.WordParser
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class ExpressionParserTest {
|
||||
|
||||
@Test
|
||||
fun testInvalidExpression() {
|
||||
val parser = ExpressionParser(
|
||||
diceParser = DiceParser(),
|
||||
wordParser = WordParser(),
|
||||
)
|
||||
parser.test("", null)
|
||||
parser.test(" ", null)
|
||||
assertFailsWith(Error.UnRecognizedToken::class) {
|
||||
parser.test("pouet", null)
|
||||
}
|
||||
assertFailsWith(Error.ExpectedTokenCharacter::class) {
|
||||
parser.test("1+", null)
|
||||
}
|
||||
assertFailsWith(Error.ExpectedOperator::class) {
|
||||
parser.test("(153", null)
|
||||
}
|
||||
assertFailsWith(Error.ExpectedOperator::class) {
|
||||
parser.test("min(1+1)", null)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testArithmeticExpression() {
|
||||
val parser = ExpressionParser(
|
||||
diceParser = DiceParser(),
|
||||
wordParser = WordParser(),
|
||||
)
|
||||
parser.test(
|
||||
expression = "-1",
|
||||
expected = Expression.Inversion(Expression.Flat(1)),
|
||||
)
|
||||
parser.test(
|
||||
expression = "+1",
|
||||
expected = Expression.Flat(1),
|
||||
)
|
||||
parser.test(
|
||||
expression = "1+2",
|
||||
expected = Expression.Add(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
parser.test(
|
||||
expression = "1-2",
|
||||
expected = Expression.Minus(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
parser.test(
|
||||
expression = "1*2",
|
||||
expected = Expression.Prod(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
parser.test(
|
||||
expression = "1/2",
|
||||
expected = Expression.Div(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFunctionExpression() {
|
||||
val parser = ExpressionParser(
|
||||
diceParser = DiceParser(),
|
||||
wordParser = WordParser(),
|
||||
)
|
||||
parser.test(
|
||||
expression = "min(1,2)",
|
||||
expected = Expression.Minimum(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
parser.test(
|
||||
expression = "max(1,2)",
|
||||
expected = Expression.Maximum(Expression.Flat(1), Expression.Flat(2))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testArithmeticPriorityExpression() {
|
||||
val parser = ExpressionParser(
|
||||
diceParser = DiceParser(),
|
||||
wordParser = WordParser(),
|
||||
)
|
||||
parser.test(
|
||||
expression = "(1+2)*3",
|
||||
expected = Expression.Prod(
|
||||
Expression.Add(Expression.Flat(1), Expression.Flat(2)),
|
||||
Expression.Flat(3),
|
||||
)
|
||||
)
|
||||
parser.test(
|
||||
expression = "1+2*3",
|
||||
expected = Expression.Add(
|
||||
Expression.Flat(1),
|
||||
Expression.Prod(Expression.Flat(2), Expression.Flat(3)),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun ExpressionParser.test(
|
||||
expression: String,
|
||||
expected: Expression?,
|
||||
) {
|
||||
val result = parse(input = expression)
|
||||
assert(result == expected) {
|
||||
"ExpressionParser.parse(input=$expression) is expected to return:$expected, but was:$result"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.pixelized.desktop.lwa.parser.word
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
class WordParserTest {
|
||||
|
||||
@Test
|
||||
fun testInvalidExpression() {
|
||||
val parser = WordParser()
|
||||
parser.test(expression = "", expected = null)
|
||||
parser.test(expression = " ", expected = null)
|
||||
parser.test(expression = "1", expected = null)
|
||||
parser.test(expression = "1d6", expected = null)
|
||||
parser.test(expression = "pouet", expected = null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testValidExpression() {
|
||||
val parser = WordParser()
|
||||
Word.Type.entries.forEach { type ->
|
||||
parser.test(expression = type.name, expected = Word(type))
|
||||
}
|
||||
}
|
||||
|
||||
private fun WordParser.test(
|
||||
expression: String,
|
||||
expected: Word?,
|
||||
) {
|
||||
val result = parse(value = expression)
|
||||
assert(result == expected) {
|
||||
"WordParser.parse(value=$expression) is expected to return:$expected, but was:$result"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue