package function.builtin;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static testutil.TestUtilities.evaluateString;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

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

public class EXITTest extends SymbolAndFunctionCleaner {

    private static final String TERMINATED = "terminated";
    private RuntimeEnvironment environment;
    private Set<String> indicatorSet;

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

    private void assertTerminated() {
        assertTrue(indicatorSet.contains(TERMINATED));
    }

    private void assertNotTerminated() {
        assertFalse(indicatorSet.contains(TERMINATED));
    }

    @Override
    public void additionalSetUp() {
        indicatorSet = new HashSet<>();
        environment.reset();
        environment.setTerminationFunction(() -> indicatorSet.add(TERMINATED));
    }

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

    @Test
    public void exitWorks() {
        evaluateString("(exit)");
        assertTerminated();
    }

    @Test
    public void exitNotCalled_IndicatorSetIsClean() {
        assertNotTerminated();
    }

    @Test(expected = TooManyArgumentsException.class)
    public void exitWithTooManyArguments() {
        evaluateString("(exit 1)");
    }

}
