package function.builtin;

import static java.text.MessageFormat.format;
import static org.junit.Assert.assertEquals;
import static testutil.TestUtilities.evaluateString;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.Test;

import environment.RuntimeEnvironment;
import function.ArgumentValidator.TooFewArgumentsException;
import function.ArgumentValidator.TooManyArgumentsException;
import testutil.SymbolAndFunctionCleaner;

public class PRINTTest extends SymbolAndFunctionCleaner {

    private RuntimeEnvironment environment;
    private ByteArrayOutputStream outputStream;

    public PRINTTest() {
        this.environment = RuntimeEnvironment.getInstance();
    }

    private void assertPrinted(String expected) {
        assertEquals(expected, outputStream.toString());
    }

    @Override
    public void additionalSetUp() {
        outputStream = new ByteArrayOutputStream();
        environment.reset();
        environment.setOutput(new PrintStream(outputStream));
    }

    @Override
    public void additionalTearDown() {
        environment.reset();
    }

    @Test
    public void printStringWorks() {
        String output = "\"Hello, world!\"";

        evaluateString(format("(print {0})", output));
        assertPrinted(format("{0}\n", output));
    }

    @Test
    public void printSymbolWorks() {
        String output = "A";

        evaluateString(format("(print ''{0})", output));
        assertPrinted(format("{0}\n", output));
    }

    @Test(expected = TooManyArgumentsException.class)
    public void printWithTooManyArguments() {
        evaluateString("(print '1 '2)");
    }

    @Test(expected = TooFewArgumentsException.class)
    public void printWithTooFewArguments() {
        evaluateString("(print)");
    }

}
