summaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-10-16 08:44:55 +0100
committerMichael Williamson <mike@zwobble.org>2026-10-16 08:44:55 +0100
commit77c708cbb7a4fb49db50a8917bdcdd777eff6ccb (patch)
tree4aeb55e2ff372c980e3893302a0f0166f656d67c /src/test/java
parent8fe3ffe8c7aad4c3270b889bce0efaf4ab912157 (diff)
Check primary key field exists
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java2
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java9
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java41
3 files changed, 47 insertions, 5 deletions
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java
index 18b827b..64554c9 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java
@@ -42,7 +42,7 @@ public final class TypedTableDefinitionNodeMatcher implements org.zwobble.precis
return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
}
- public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withPrimaryKey(org.zwobble.precisely.Matcher<? super String> primaryKey) {
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withPrimaryKey(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.types.Field> primaryKey) {
var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
submatchers.add(org.zwobble.precisely.Matchers.has("primaryKey", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::primaryKey, (org.zwobble.precisely.Matcher) primaryKey));
return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java
index 574bf26..08fdd47 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java
@@ -4,11 +4,16 @@ import org.junit.jupiter.api.Test;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode;
+import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.sources.NullSource;
+import org.zwobble.hobgoblin.compiler.types.Field;
import org.zwobble.hobgoblin.compiler.types.NamespaceName;
import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
import org.zwobble.hobgoblin.compiler.types.Types;
+import java.util.List;
+import java.util.Optional;
+
import static org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher.isTypedDatabaseSchemaDefinitionNode;
import static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher.isTypedTableDefinitionNode;
import static org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerTesting.typeCheckNamespaceStatement;
@@ -27,6 +32,7 @@ public class TypeCheckerDatabaseSchemaDefinitionTests {
.withName("Author")
.build()
)
+ .withPrimaryKey("id")
.build()
)
.build();
@@ -34,6 +40,9 @@ public class TypeCheckerDatabaseSchemaDefinitionTests {
var namespaceContext = globalContext.enterNamespace(NamespaceName.of("App"));
var authorType = new SimpleStructType(NamespaceName.of("App"), "Author");
namespaceContext.declare("Author", Types.metaType(authorType), NullSource.INSTANCE);
+ namespaceContext.defineStructType(authorType, Optional.of(List.of(
+ new Field("id", NativeTypes.INT_32, NullSource.INSTANCE)
+ )));
var typed = typeCheckNamespaceStatement(untyped, namespaceContext);
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java
index a4e1cf4..a32945a 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java
@@ -3,12 +3,14 @@ package org.zwobble.hobgoblin.compiler.typechecker;
import org.junit.jupiter.api.Test;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode;
+import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.sources.NullSource;
+import org.zwobble.hobgoblin.compiler.typechecker.errors.NoSuchFieldError;
import org.zwobble.hobgoblin.compiler.typechecker.errors.TableRowTypeMustBeStructError;
-import org.zwobble.hobgoblin.compiler.types.NamespaceName;
-import org.zwobble.hobgoblin.compiler.types.SimpleNativeType;
-import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
-import org.zwobble.hobgoblin.compiler.types.Types;
+import org.zwobble.hobgoblin.compiler.types.*;
+
+import java.util.List;
+import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher.isTypedTableDefinitionNode;
@@ -25,11 +27,15 @@ public class TypeCheckerTableDefinitionTests {
.withName("Author")
.build()
)
+ .withPrimaryKey("id")
.build();
var globalContext = TypeCheckerContextArb.globalContext();
var namespaceContext = globalContext.enterNamespace(NamespaceName.of("App"));
var authorType = new SimpleStructType(NamespaceName.of("App"), "Author");
namespaceContext.declare("Author", Types.metaType(authorType), NullSource.INSTANCE);
+ namespaceContext.defineStructType(authorType, Optional.of(List.of(
+ new Field("id", NativeTypes.INT_32, NullSource.INSTANCE)
+ )));
var typed = typeCheckDatabaseSchemaStatement(untyped, namespaceContext);
@@ -60,4 +66,31 @@ public class TypeCheckerTableDefinitionTests {
assertThat(error.rowType(), equalTo(authorType));
}
+
+ @Test
+ public void whenPrimaryKeyIsNotStructFieldThenErrorIsThrown() {
+ var untyped = UntypedTableDefinitionNode.arbitrary()
+ .withName("authors")
+ .withRowType(UntypedTypeLevelReferenceNode.arbitrary()
+ .withName("Author")
+ .build()
+ )
+ .withPrimaryKey("id")
+ .build();
+ var globalContext = TypeCheckerContextArb.globalContext();
+ var namespaceContext = globalContext.enterNamespace(NamespaceName.of("App"));
+ var authorType = new SimpleStructType(NamespaceName.of("App"), "Author");
+ namespaceContext.declare("Author", Types.metaType(authorType), NullSource.INSTANCE);
+ namespaceContext.defineStructType(authorType, Optional.of(List.of(
+ new Field("author_id", NativeTypes.INT_32, NullSource.INSTANCE)
+ )));
+
+ var error = assertThrows(
+ NoSuchFieldError.class,
+ () -> typeCheckDatabaseSchemaStatement(untyped, namespaceContext)
+ );
+
+ assertThat(error.type(), equalTo(authorType));
+ assertThat(error.fieldName(), equalTo("id"));
+ }
}