package better_parser import com.github.h0tk3y.betterParse.grammar.Grammar import com.github.h0tk3y.betterParse.grammar.parseToEnd import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import prolog.ast.arithmetic.Float import prolog.ast.arithmetic.Integer import prolog.ast.terms.Atom import prolog.ast.terms.Structure import prolog.ast.terms.Term import prolog.ast.terms.Variable import prolog.logic.equivalent class SimplePrologPrologParserTests { private lateinit var parser: Grammar @BeforeEach fun setup() { parser = SimplePrologParser() as Grammar } @ParameterizedTest @ValueSource(strings = ["a", "foo", "foo1", "fooBar", "foo_bar"]) fun `parse atom`(name: String) { val result = parser.parseToEnd(name) assertEquals(Atom(name), result, "Expected atom '$name'") } @ParameterizedTest @ValueSource(strings = ["X", "X1", "X_1"]) fun `parse variable`(name: String) { val result = parser.parseToEnd(name) assertEquals(Variable(name), result, "Expected atom '$name'") } @Test fun `empty compound term`() { val input = "f()" val result = parser.parseToEnd(input) assertTrue( equivalent(Structure(Atom("f"), emptyList()), result, emptyMap()), "Expected atom 'f'" ) } @Test fun `parse compound term f(a)`() { val input = "f(a)" val result = parser.parseToEnd(input) assertTrue( equivalent(Structure(Atom("f"), listOf(Atom("a"))), result, emptyMap()), "Expected atom 'f(a)'" ) } @Test fun `parse compound term f(a, b)`() { val input = "f(a, b)" val result = parser.parseToEnd(input) assertTrue( equivalent(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))), result, emptyMap()), "Expected atom 'f(a, b)'" ) } @Test fun `parse compound term with variable f(a, X)`() { val input = "f(a, X)" val result = parser.parseToEnd(input) assertTrue( equivalent(Structure(Atom("f"), listOf(Atom("a"), Variable("X"))), result, emptyMap()), "Expected atom 'f(a, X)'" ) } @Test fun `parse nested compound term f(a, g(b))`() { val input = "f(a, g(b))" val result = parser.parseToEnd(input) assertTrue( equivalent( Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Atom("b"))))), result, emptyMap() ), "Expected atom 'f(a, g(b))'" ) } @Test fun `parse compound term with variable f(a, g(X))`() { val input = "f(a, g(X))" val result = parser.parseToEnd(input) assertTrue( equivalent( Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Variable("X"))))), result, emptyMap() ), "Expected atom 'f(a, g(X))'" ) } @ParameterizedTest @ValueSource(ints = [-987654321, -543, -21, -1, 0, 1, 5, 12, 345, 123456789]) fun `parse integer`(number: Int) { val input = number.toString() val result = parser.parseToEnd(input) assertEquals(Integer(number), result, "Expected integer '$number'") } @Test fun `parse float`() { val input = "42.0" val result = parser.parseToEnd(input) assertTrue( equivalent(Float(42.0f), result, emptyMap()), "Expected float '42.0'" ) } @Test fun `parse negative float`() { val input = "-42.0" val result = parser.parseToEnd(input) assertTrue( equivalent(Float(-42.0f), result, emptyMap()), "Expected float '-42.0'" ) } }