package pp.s1184725.boppi.test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.junit.Test;

/**
 * Tests for simple (i.e. no functions involved) variable use.
 * 
 * @author Frank Wibbelink
 */
public class SimpleVariableTest {

	/**
	 * Correct variable use
	 */
	@Test
	public void correctVariableParsing() {
		BoppiTests.parseFile("simpleVariable.boppi");
		assertThat(BoppiTests.log, empty());
	}

	/**
	 * Variable use with syntax errors
	 */
	@Test
	public void wrongVariableParsing() {
		BoppiTests.parseString("var");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.parseString("var bool 5");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.parseString("var 'c' varname");
		assertThat(BoppiTests.log, not(empty()));

		BoppiTests.parseString("var bool; true true;");
		assertThat(BoppiTests.log, hasSize(2));
	}

	/**
	 * Correct variable scoping
	 */
	@Test
	public void correctScopeParsing() {
		BoppiTests.parseFile("simpleScope.boppi");
		assertThat(BoppiTests.log, empty());
	}

	/**
	 * Correct variable use
	 */
	@Test
	public void correctVariableChecking() {
		BoppiTests.checkFile("simpleVariable.boppi");
		assertThat(BoppiTests.log, is(empty()));
	}

	/**
	 * Variable use with type errors
	 */
	@Test
	public void wrongVariableChecking() {
		BoppiTests.checkString("var bool name; name := 5");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("undefinedName");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("var undefinedType name; 1");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("var bool endsWithDeclaration;");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("var bool var1; var var1 var2; var2 := 'c' ");
		assertThat(BoppiTests.log, hasSize(1));
	}

	/**
	 * Correct variable scoping
	 */
	@Test
	public void correctScopeChecking() {
		BoppiTests.checkFile("simpleScope.boppi");
		assertThat(BoppiTests.log, is(empty()));
	}

	/**
	 * Variable redeclaring and out-of-scope errors
	 */
	@Test
	public void wrongScopeChecking() {
		BoppiTests.checkString("var bool var1; var bool var1; 1");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("var bool var1; var char var1; 1");
		assertThat(BoppiTests.log, hasSize(1));

		BoppiTests.checkString("{ var int var1; var1 := 4}; var int var2; var1");
		assertThat(BoppiTests.log, hasSize(1));
	}

	/**
	 * Correct variable use
	 */
	@Test
	public void correctVariableGeneration() {
		BoppiTests.compileAndRunFile("simpleVariable.boppi");
		assertThat(BoppiTests.log, is(empty()));
	}

}
