import de.hsrm.compiler.Klang.ContextAnalysis; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class FunctionDefinitionTest { @Test void shouldNotThrowIfReturnTypeIsReferringToAnEnum() { // given var tree = Helper.prepareParser(" enum bar {A,B,C} function foo(a: int): bar { return bar.A; } foo(1);"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then assertDoesNotThrow(() -> ctxAnal.visit(tree)); } @Test void shouldNotThrowIfParameterTypeIsReferringToAnEnum() { // given var tree = Helper.prepareParser(" enum bar {A,B,C} function foo(a: bar): int { return 1; } foo(bar.A);"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then assertDoesNotThrow(() -> ctxAnal.visit(tree)); } @Test void shouldThrowExceptionIfParameterTypeIsNotDefined() { // given var tree = Helper.prepareParser("function foo(a: schwurbel): int { return 1; } foo();"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then var e = assertThrows(RuntimeException.class, () -> ctxAnal.visit(tree)); assertEquals("Error in line 1:14 Type schwurbel not defined.", e.getMessage()); } @Test void shouldThrowExceptionIfReturnTypeIsNotDefined() { // given var tree = Helper.prepareParser("function foo(): schwurbel { return 1; } foo();"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then var e = assertThrows(RuntimeException.class, () -> ctxAnal.visit(tree)); assertEquals("Error in line 1:14 Type schwurbel not defined.", e.getMessage()); } @Test void shouldThrowExceptionIfReturnStatementIsMissing() { // given var tree = Helper.prepareParser("function foo(): int { let x: int; x = 0; } foo();"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then var e = assertThrows(RuntimeException.class, () -> ctxAnal.visit(tree)); assertEquals("Error in line 1:20 Function foo has to return something of type int.", e.getMessage()); } @Test void shouldThrowExceptionIfParameterNameMatchesEnumName() { // given var tree = Helper.prepareParser("enum Bar { A, B } function foo(Bar: int): int { return 1; } foo(1);"); var ctxAnal = new ContextAnalysis( Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree) ); // when / then var e = assertThrows(RuntimeException.class, () -> ctxAnal.visit(tree)); assertEquals("Error in line 1:31 Parameter name Bar duplicates an enum of the same name.", e.getMessage()); } }