94 lines
4.0 KiB
Java
94 lines
4.0 KiB
Java
import de.hsrm.compiler.Klang.ContextAnalysis;
|
|
import de.hsrm.compiler.Klang.GetDefinitions;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
public class StructDefinitionTest {
|
|
@Test
|
|
void shouldNotThrowIfStructIsWellDefined() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct test { a: int; } function foo(): int { return 1; } foo();");
|
|
var ctxAnal = new ContextAnalysis(Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree));
|
|
|
|
// when / then
|
|
assertDoesNotThrow(() -> ctxAnal.visit(tree));
|
|
}
|
|
|
|
@Test
|
|
void shouldNotThrowIfStructFieldTypeIsReferringToEnum() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct test { a: bar; } enum bar {A,B,C} function foo(): int { return 1; } foo();");
|
|
var ctxAnal = new ContextAnalysis(Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree));
|
|
|
|
// when / then
|
|
assertDoesNotThrow(() -> ctxAnal.visit(tree));
|
|
}
|
|
|
|
@Test
|
|
void shouldNotThrowIfStructFieldTypeIsReferringToStruct() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct a { hello: int; } struct b { world: a; } function foo(): int { return 1; } foo();");
|
|
var ctxAnal = new ContextAnalysis(Helper.getFuncs(tree), Helper.getStructs(tree), Helper.getEnums(tree));
|
|
|
|
// when / then
|
|
assertDoesNotThrow(() -> ctxAnal.visit(tree));
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowExceptionIfStructFieldNameShadowsAStruct() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct bar { a: int; } struct baz { bar: int; } function foo(): 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:36 Struct field name bar shadows a struct of the same name.", e.getMessage());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowExceptionIfStructFieldNameShadowsAnEnum() {
|
|
// given
|
|
var tree = Helper.prepareParser("enum bar { A, B } struct baz { bar: int; } function foo(): 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:31 Struct field name bar shadows an enum of the same name.", e.getMessage());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowExceptionIfStructFieldTypeIsNotDefined() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct test { a: schwurbel; } function foo(): 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 shouldThrowExceptionIfStructFieldTypeIsReferringToAFunction() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct test { a: foo; } function foo(): 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 foo not defined.", e.getMessage());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowExceptionIfStructFieldNameIsDuplicated() {
|
|
// given
|
|
var tree = Helper.prepareParser("struct test { a: int; a: bool; } function foo(): int { return 1; } foo();");
|
|
var getDefs = new GetDefinitions(new HashMap<>(), new HashMap<>(), new HashMap<>());
|
|
|
|
// when / then
|
|
var e = assertThrows(RuntimeException.class, () -> getDefs.visit(tree));
|
|
assertEquals("Error in line 1:22 Duplicate struct field a in struct test.", e.getMessage());
|
|
}
|
|
} |