package prolog.builtins 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.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 class IoOperatorsTests { private var outStream = ByteArrayOutputStream() @BeforeEach fun setup() { outStream = ByteArrayOutputStream() System.setOut(PrintStream(outStream)) } @Test fun dummyTest() { val message = "Hello, World!" print(message) assertEquals(message, outStream.toString(), "Output should match the message") } @ParameterizedTest @ValueSource(strings = [ "a", "hello", "a very special christmas", "1 2 3 piano" ]) fun `write atoms`(name: String) { val write = Write(Atom(name)) val result = write.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Should return one result") assertTrue(result[0].isSuccess, "Result should be successful") assertEquals(name, outStream.toString().trim(), "Output should match the atom") } @Test fun `write structure`() { val write = Write(CompoundTerm(Atom("person"), listOf(Atom("john"), Atom("doe")))) val result = write.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Should return one result") assertTrue(result[0].isSuccess, "Result should be successful") assertEquals("person(john, doe)", outStream.toString().trim(), "Output should match the structure") } @Test fun `write arithmetic`() { val a = Integer(1) val b = Variable("B") val c = Float(2.0f) val d = Variable("D") val mul = Multiply(c, d) val sub = Subtract(b, mul) val expr = EvaluatesTo(a, sub) val expected1 = "1 =:= B - (2.0 * D)" val expected2 = "=:=(1, -(B, *(2.0, D)))" val write = Write(expr) val result = write.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Should return one result") assertTrue(result[0].isSuccess, "Result should be successful") val output = outStream.toString().trim() assertTrue(output == expected1 || output == expected2, "Output should match the arithmetic expression") } }