Checkpoint
This commit is contained in:
parent
9db1c66781
commit
724e911a6f
17 changed files with 288 additions and 95 deletions
|
@ -2,11 +2,13 @@
|
|||
|
||||
# This script is expected to be run from the root of the project.
|
||||
|
||||
WATCH_ALONG=0
|
||||
|
||||
# Paths to the two implementations
|
||||
GPL="src/gpl"
|
||||
SPL="swipl"
|
||||
|
||||
GPL_FLAGS=("--debug")
|
||||
GPL_FLAGS=("--error")
|
||||
SPL_FLAGS=("--quiet" "-t" "'true'")
|
||||
|
||||
# Directory containing test files
|
||||
|
@ -14,7 +16,11 @@ TEST_DIR="examples"
|
|||
|
||||
# Temporary files for storing outputs
|
||||
GPL_OUT=$(mktemp)
|
||||
GPL_ERR=$(mktemp)
|
||||
SPL_OUT=$(mktemp)
|
||||
SPL_ERR=$(mktemp)
|
||||
|
||||
touch "$GPL_OUT" "$GPL_ERR" "$SPL_OUT" "$SPL_ERR"
|
||||
|
||||
# Flag to track if all tests pass
|
||||
PASSED=0
|
||||
|
@ -22,27 +28,43 @@ FAILED=0
|
|||
|
||||
# Iterate over all test files in the test directory
|
||||
#for TESTFILE in $(find ${TEST_DIR} -type f); do
|
||||
files=("examples/program.pl" "examples/basics/disjunction.pl" "examples/basics/fraternity.pl")
|
||||
files=(
|
||||
"examples/program.pl"
|
||||
"examples/basics/disjunction.pl"
|
||||
"examples/basics/fraternity.pl"
|
||||
"examples/basics/unification.pl"
|
||||
"examples/basics/write.pl"
|
||||
)
|
||||
for TESTFILE in "${files[@]}"; do
|
||||
# Run both programs with the test file
|
||||
"${SPL}" "${SPL_FLAGS[@]}" "$TESTFILE" > "${SPL_OUT}" 2>&1
|
||||
"${GPL}" "${GPL_FLAGS[@]}" -s "$TESTFILE" > "${GPL_OUT}" 2>&1
|
||||
"${SPL}" "${SPL_FLAGS[@]}" "$TESTFILE" > "${SPL_OUT}" 2> "${SPL_ERR}"
|
||||
"${GPL}" "${GPL_FLAGS[@]}" -s "$TESTFILE" > "${GPL_OUT}" 2> "${GPL_ERR}"
|
||||
|
||||
# Compare the outputs
|
||||
if diff -q "$SPL_OUT" "$GPL_OUT" > /dev/null; then
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo "Test failed! Outputs differ for $TESTFILE"
|
||||
printf "\nTest:\n%s\n" "$(cat "$TESTFILE")"
|
||||
printf "\nExpected:\n%s\n" "$(cat "$SPL_OUT")"
|
||||
printf "\nGot:\n%s\n" "$(cat "$GPL_OUT")"
|
||||
was_different="$(
|
||||
diff -q "$SPL_OUT" "$GPL_OUT" > /dev/null
|
||||
echo $?
|
||||
)"
|
||||
if [[ "${was_different}" -ne 0 || "${WATCH_ALONG}" -eq 1 ]]; then
|
||||
if [ "${was_different}" -ne 0 ]; then
|
||||
message="TEST FAILED"
|
||||
fi
|
||||
printf "%s for %s\n" "${message:="Result"}" "${TESTFILE}"
|
||||
printf "\nTest:\n%s\n" "$(cat "${TESTFILE}")"
|
||||
printf "\nExpected:\n%s\n" "$(cat "${SPL_OUT}" && cat "${SPL_ERR}")"
|
||||
printf "\nGot:\n%s\n" "$(cat "${GPL_OUT}" && cat "${GPL_ERR}")"
|
||||
echo "-----------------------------------------"
|
||||
fi
|
||||
|
||||
if [ "${was_different}" -ne 0 ]; then
|
||||
FAILED=$((FAILED + 1))
|
||||
else
|
||||
PASSED=$((PASSED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean up temporary files
|
||||
rm "$SPL_OUT" "$GPL_OUT"
|
||||
rm "$SPL_OUT" "$GPL_OUT" "$SPL_ERR" "$GPL_ERR"
|
||||
|
||||
# Final result, summary
|
||||
if [ $FAILED -eq 0 ]; then
|
||||
|
|
46
tests/e2e/Examples.kt
Normal file
46
tests/e2e/Examples.kt
Normal file
|
@ -0,0 +1,46 @@
|
|||
package e2e
|
||||
|
||||
import interpreter.FileLoader
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import prolog.Program
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
|
||||
class Examples {
|
||||
private val loader = FileLoader()
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
Program.reset()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fraternity() {
|
||||
val inputFile = "examples/basics/fraternity.pl"
|
||||
|
||||
loader.load(inputFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unification() {
|
||||
val inputFile = "examples/basics/unification.pl"
|
||||
|
||||
loader.load(inputFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun write() {
|
||||
val expected = "gpl zegt: dag(wereld)\n"
|
||||
|
||||
val outStream = ByteArrayOutputStream()
|
||||
System.setOut(PrintStream(outStream))
|
||||
|
||||
val inputFile = "examples/basics/write.pl"
|
||||
|
||||
// Compare the stdio output with the expected output
|
||||
loader.load(inputFile)
|
||||
assertEquals(expected, outStream.toString())
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package e2e
|
||||
|
||||
class myClass {
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package parser
|
||||
|
||||
import com.github.h0tk3y.betterParse.combinators.use
|
||||
import com.github.h0tk3y.betterParse.grammar.Grammar
|
||||
import com.github.h0tk3y.betterParse.grammar.parseToEnd
|
||||
import com.github.h0tk3y.betterParse.parser.Parser
|
||||
|
@ -13,7 +14,7 @@ import prolog.ast.terms.Structure
|
|||
|
||||
class OperatorParserTests {
|
||||
class OperatorParser: TermsGrammar() {
|
||||
override val rootParser: Parser<CompoundTerm> by operator
|
||||
override val rootParser: Parser<CompoundTerm> by body use { this as CompoundTerm }
|
||||
}
|
||||
|
||||
private var parser = OperatorParser() as Grammar<CompoundTerm>
|
||||
|
|
|
@ -40,7 +40,7 @@ class LogicGrammarTests {
|
|||
|
||||
assertEquals(1, result.size, "Expected 1 fact")
|
||||
assertTrue(result[0] is Fact, "Expected a fact")
|
||||
assertEquals(input, "${result[0].toString()}.", "Expected fact to be '$input'")
|
||||
assertEquals(input, "${result[0]}.", "Expected fact to be '$input'")
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -125,9 +125,12 @@ class LogicGrammarTests {
|
|||
|
||||
assertEquals(1, result.size, "Expected 1 rule")
|
||||
val rule = result[0] as Rule
|
||||
assertInstanceOf(CompoundTerm::class.java, rule.body, "Expected body to be a conjunction")
|
||||
val conjunction = rule.body as CompoundTerm
|
||||
assertEquals("invited/2", (conjunction.arguments[0] as CompoundTerm).functor, "Expected functor 'invited/2'")
|
||||
assertEquals("guest/2", rule.head.functor, "Expected functor 'guest/2'")
|
||||
assertEquals(",/2", (rule.body as CompoundTerm).functor, "Expected functor ',/2'")
|
||||
val l1 = (rule.body as CompoundTerm).arguments[0] as CompoundTerm
|
||||
assertEquals(",/2", l1.functor, "Expected functor ',/2'")
|
||||
val l2 = l1.arguments[0] as CompoundTerm
|
||||
assertEquals("invited/2", l2.functor, "Expected functor 'invited/2'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -2,10 +2,11 @@ package parser.grammars
|
|||
|
||||
import com.github.h0tk3y.betterParse.grammar.Grammar
|
||||
import com.github.h0tk3y.betterParse.grammar.parseToEnd
|
||||
import com.github.h0tk3y.betterParse.parser.Parser
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
|
@ -17,7 +18,6 @@ import prolog.ast.terms.Structure
|
|||
import prolog.ast.terms.Term
|
||||
import prolog.ast.terms.Variable
|
||||
import prolog.logic.equivalent
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class TermsGrammarTests {
|
||||
private lateinit var parser: Grammar<Term>
|
||||
|
@ -32,7 +32,7 @@ class TermsGrammarTests {
|
|||
fun `parse atom`(name: String) {
|
||||
val result = parser.parseToEnd(name)
|
||||
|
||||
Assertions.assertEquals(Atom(name), result, "Expected atom '$name'")
|
||||
assertEquals(Atom(name), result, "Expected atom '$name'")
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -52,7 +52,7 @@ class TermsGrammarTests {
|
|||
|
||||
val expected = input.substring(1, input.length - 1)
|
||||
|
||||
Assertions.assertEquals(Atom(expected), result, "Expected atom")
|
||||
assertEquals(Atom(expected), result, "Expected atom")
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -60,7 +60,7 @@ class TermsGrammarTests {
|
|||
fun `parse variable`(name: String) {
|
||||
val result = parser.parseToEnd(name)
|
||||
|
||||
Assertions.assertEquals(Variable(name), result, "Expected atom '$name'")
|
||||
assertEquals(Variable(name), result, "Expected atom '$name'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,10 +69,7 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(Structure(Atom("f"), emptyList()), result, emptyMap()),
|
||||
"Expected atom 'f'"
|
||||
)
|
||||
assertEquals(Structure(Atom("f"), emptyList()), result, "Expected atom 'f'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -81,10 +78,7 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(Structure(Atom("f"), listOf(Atom("a"))), result, emptyMap()),
|
||||
"Expected atom 'f(a)'"
|
||||
)
|
||||
assertEquals(Structure(Atom("f"), listOf(Atom("a"))), result, "Expected atom 'f(a)'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -93,8 +87,9 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))), result, emptyMap()),
|
||||
assertEquals(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Atom("b"))),
|
||||
result,
|
||||
"Expected atom 'f(a, b)'"
|
||||
)
|
||||
}
|
||||
|
@ -105,7 +100,7 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
assertTrue(
|
||||
equivalent(Structure(Atom("f"), listOf(Atom("a"), Variable("X"))), result, emptyMap()),
|
||||
"Expected atom 'f(a, X)'"
|
||||
)
|
||||
|
@ -179,4 +174,59 @@ class TermsGrammarTests {
|
|||
fun `parse unification`(input: String) {
|
||||
assertDoesNotThrow { parser.parseToEnd(input) }
|
||||
}
|
||||
|
||||
@Nested
|
||||
class `Operator precedence` {
|
||||
private lateinit var parser: Grammar<Term>
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
parser = TermsGrammar() as Grammar<Term>
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse addition and multiplication`() {
|
||||
val input = "1 + 2 * 3"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("+"), listOf(Integer(1), Structure(Atom("*"), listOf(Integer(2), Integer(3))))),
|
||||
result,
|
||||
"Expected addition and multiplication"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse multiplication and addition`() {
|
||||
val input = "1 * 2 + 3"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("+"), listOf(Structure(Atom("*"), listOf(Integer(1), Integer(2))), Integer(3))),
|
||||
result,
|
||||
"Expected multiplication and addition"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `complex expression`() {
|
||||
val input = "1 + 2 * 3 - 4 / 5"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(
|
||||
Atom("-"),
|
||||
listOf(
|
||||
Structure(Atom("+"), listOf(Integer(1), Structure(Atom("*"), listOf(Integer(2), Integer(3))))),
|
||||
Structure(Atom("/"), listOf(Integer(4), Integer(5)))
|
||||
)
|
||||
),
|
||||
result,
|
||||
"Expected complex expression"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -390,5 +390,27 @@ class EvaluationTests {
|
|||
assertEquals(1, subs5.size, "Expected 1 substitution, especially without 'Person'")
|
||||
assertEquals(Atom("bob"), subs5[Variable("X")], "Expected bob")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `likes_italian_food(Person)`() {
|
||||
val result = Program.query(Structure(Atom("likes_italian_food"), listOf(Variable("Person")))).toList()
|
||||
|
||||
assertEquals(3, result.size, "Expected 3 results")
|
||||
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
val subs3 = result[0].getOrNull()!!
|
||||
assertEquals(1, subs3.size, "Expected 1 substitution")
|
||||
assertEquals(Atom("alice"), subs3[Variable("Person")], "Expected alice")
|
||||
|
||||
assertTrue(result[1].isSuccess, "Expected success")
|
||||
val subs4 = result[1].getOrNull()!!
|
||||
assertEquals(1, subs4.size, "Expected 1 substitution")
|
||||
assertEquals(Atom("alice"), subs4[Variable("Person")], "Expected alice")
|
||||
|
||||
assertTrue(result[2].isSuccess, "Expected success")
|
||||
val subs5 = result[2].getOrNull()!!
|
||||
assertEquals(1, subs5.size, "Expected 1 substitution")
|
||||
assertEquals(Atom("bob"), subs5[Variable("Person")], "Expected bob")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
package prolog.builtins
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertInstanceOf
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Disabled
|
||||
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.CompoundTerm
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
import prolog.ast.arithmetic.Integer
|
||||
import prolog.ast.terms.Variable
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
|
||||
class IoOperatorsTests {
|
||||
private var outStream = ByteArrayOutputStream()
|
||||
|
|
Reference in a new issue