From 864c5b173a72e269fa6f009c51326c78a042d260 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 10 Oct 2026 11:40:25 +0100 Subject: Parse empty table definition --- examples/18-database/src/data.hob | 4 +- hobgoblin/src/ast/untyped.hob | 21 +++++++++ .../UntypedDatabaseSchemaDefinitionNode.java | 28 ++++++++++-- .../UntypedDatabaseSchemaStatementNode.java | 18 ++++++++ .../ast/untyped/UntypedTableDefinitionNode.java | 44 ++++++++++++++++++ .../zwobble/hobgoblin/compiler/parser/Parser.java | 36 +++++++++++++++ ...UntypedDatabaseSchemaDefinitionNodeMatcher.java | 6 +++ .../untyped/UntypedTableDefinitionNodeMatcher.java | 53 ++++++++++++++++++++++ .../ParserDatabaseSchemaDefinitionTests.java | 31 ++++++++++++- .../parser/ParserTableDefinitionTests.java | 24 ++++++++++ 10 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaStatementNode.java create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java create mode 100644 src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNodeMatcher.java create mode 100644 src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserTableDefinitionTests.java diff --git a/examples/18-database/src/data.hob b/examples/18-database/src/data.hob index 6ee3813..3c3ba47 100644 --- a/examples/18-database/src/data.hob +++ b/examples/18-database/src/data.hob @@ -4,7 +4,9 @@ struct StructWithInt32 { } databaseSchema Data { -// table structs: StructWithInt32; + table structs { +// row StructWithInt32; + } // // query fetchAllStructs() { // select(structs) diff --git a/hobgoblin/src/ast/untyped.hob b/hobgoblin/src/ast/untyped.hob index 1152abb..150f78c 100644 --- a/hobgoblin/src/ast/untyped.hob +++ b/hobgoblin/src/ast/untyped.hob @@ -2,6 +2,8 @@ import {DocComment} from ast; import {Source} from sources; import {NamespaceName} from types; +// == Namespaces == + struct UntypedNamespaceNode { field namespaceName: NamespaceName; field imports: List[UntypedImportNode]; @@ -16,6 +18,8 @@ struct UntypedImportNode { field source: Source; } +// == Namespace statements == + sum UntypedNamespaceStatementNode { variant UntypedDatabaseSchemaDefinitionNode; variant UntypedEnumDefinitionNode; @@ -29,6 +33,7 @@ sum UntypedNamespaceStatementNode { struct UntypedDatabaseSchemaDefinitionNode { field name: String; + field body: List[UntypedDatabaseSchemaStatementNode]; field docComment: DocComment; field source: Source; } @@ -79,11 +84,27 @@ struct UntypedSumVariantDefinitionNode { field source: Source; } +// == Database schema statements == + +sum UntypedDatabaseSchemaStatementNode { + variant UntypedTableDefinitionNode; +} + +struct UntypedTableDefinitionNode { + field name: String; + field docComment: DocComment; + field source: Source; +} + +// == Type params == + struct UntypedTypeParamNode { field name: String; field source: Source; } +// == Type-level expressions == + sum UntypedTypeLevelExpressionNode { variant UntypedConstructedTypeNode; variant UntypedTypeLevelReferenceNode; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNode.java index 7695a42..8f9b2e4 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNode.java @@ -7,32 +7,50 @@ package org.zwobble.hobgoblin.compiler.ast.untyped; public record UntypedDatabaseSchemaDefinitionNode( String name, + java.util.List body, org.zwobble.hobgoblin.compiler.ast.DocComment docComment, org.zwobble.hobgoblin.compiler.sources.Source source ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode { public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource()); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder("", java.util.List.of(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource()); } public record Builder( String name, + java.util.List body, org.zwobble.hobgoblin.compiler.ast.DocComment docComment, org.zwobble.hobgoblin.compiler.sources.Source source ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode.Builder { public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode build() { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode(name, docComment, source); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode(name, body, docComment, source); } public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder withName(String name) { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder withBody(java.util.List body) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder addBodyElement(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode bodyElement) { + var body = new java.util.ArrayList(this.body); + body.add(bodyElement); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder addBodyElement(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode.Builder bodyElement) { + var body = new java.util.ArrayList(this.body); + body.add(bodyElement.build()); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); } public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); } public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source); } // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode.Builder body diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaStatementNode.java new file mode 100644 index 0000000..da1400c --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaStatementNode.java @@ -0,0 +1,18 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode imports + +public sealed interface UntypedDatabaseSchemaStatementNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode { + public interface Builder { + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode build(); + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode.Builder body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode.Builder body + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode body +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java new file mode 100644 index 0000000..4841ef8 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java @@ -0,0 +1,44 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode imports + +public record UntypedTableDefinitionNode( + String name, + org.zwobble.hobgoblin.compiler.ast.DocComment docComment, + org.zwobble.hobgoblin.compiler.sources.Source source +) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder arbitrary() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource()); + } + + public record Builder( + String name, + org.zwobble.hobgoblin.compiler.ast.DocComment docComment, + org.zwobble.hobgoblin.compiler.sources.Source source + ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode.Builder { + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode build() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode(name, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withName(String name) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, docComment, source); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, docComment, source); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder body + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode body +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java index 9e3c423..96448c6 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java @@ -19,6 +19,8 @@ public class Parser { private Parser() { } + // == Namespaces == + public static UntypedNamespaceNode parseNamespace( SourceText sourceText, NamespaceName namespaceName @@ -98,6 +100,8 @@ public class Parser { return new UntypedImportNode(importedNames, ancestorDepth, namespaceName, source); } + // == Namespace statements == + static UntypedNamespaceStatementNode parseNamespaceStatement( TokenIterator tokens ) { @@ -128,6 +132,12 @@ public class Parser { var name = parseIdentifier(tokens); tokens.skip(TokenType.SYMBOL_BRACE_OPEN); + var body = parseMany( + () -> tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE), + () -> parseDatabaseSchemaStatement(tokens), + () -> true + ); + tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); var end = tokens.endPosition(); @@ -135,6 +145,7 @@ public class Parser { return new UntypedDatabaseSchemaDefinitionNode( name, + body, docComment, source ); @@ -345,6 +356,29 @@ public class Parser { ); } + // == Database schema statements == + + static UntypedDatabaseSchemaStatementNode parseDatabaseSchemaStatement(TokenIterator tokens) { + var start = tokens.startPosition(); + + var docComment = parseDocComment(tokens); + tokens.skip(TokenType.IDENTIFIER, "table"); + var name = parseIdentifier(tokens); + tokens.skip(TokenType.SYMBOL_BRACE_OPEN); + tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); + + var end = tokens.endPosition(); + var source = createSource(start, end); + + return new UntypedTableDefinitionNode( + name, + docComment, + source + ); + } + + // == Type params == + private static Optional> parseTypeParams(TokenIterator tokens) { if (!tokens.trySkip(TokenType.SYMBOL_SQUARE_OPEN)) { return Optional.empty(); @@ -370,6 +404,8 @@ public class Parser { return Optional.of(typeParams); } + // == Type-level expressions == + static UntypedTypeLevelExpressionNode parseTypeLevelExpression( TokenIterator tokens ) { diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNodeMatcher.java index cb132e0..1654ed6 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNodeMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedDatabaseSchemaDefinitionNodeMatcher.java @@ -36,6 +36,12 @@ public final class UntypedDatabaseSchemaDefinitionNodeMatcher implements org.zwo return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNodeMatcher(submatchers); } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNodeMatcher withBody(org.zwobble.precisely.Matcher> body) { + var submatchers = new java.util.ArrayList>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("body", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode::body, (org.zwobble.precisely.Matcher) body)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNodeMatcher(submatchers); + } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher docComment) { var submatchers = new java.util.ArrayList>(this.submatchers); submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment)); diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNodeMatcher.java new file mode 100644 index 0000000..4c016a3 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNodeMatcher.java @@ -0,0 +1,53 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher imports + +public final class UntypedTableDefinitionNodeMatcher implements org.zwobble.precisely.Matcher { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher isUntypedTableDefinitionNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher(java.util.List.of()); + } + + private final java.util.List> submatchers; + + private UntypedTableDefinitionNodeMatcher( + java.util.List> submatchers + ) { + this.submatchers = submatchers; + } + + public org.zwobble.precisely.MatchResult match(java.lang.Object actual) { + return this.toMatcher().match(actual); + } + + public org.zwobble.precisely.TextTree describe() { + return this.toMatcher().describe(); + } + + private org.zwobble.precisely.Matcher toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher withName(org.zwobble.precisely.Matcher name) { + var submatchers = new java.util.ArrayList>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher docComment) { + var submatchers = new java.util.ArrayList>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher withSource(org.zwobble.precisely.Matcher source) { + var submatchers = new java.util.ArrayList>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserDatabaseSchemaDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserDatabaseSchemaDefinitionTests.java index a43d616..8241eda 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserDatabaseSchemaDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserDatabaseSchemaDefinitionTests.java @@ -1,12 +1,13 @@ package org.zwobble.hobgoblin.compiler.parser; import org.junit.jupiter.api.Test; -import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode; import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNodeMatcher.isUntypedDatabaseSchemaDefinitionNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher.isUntypedTableDefinitionNode; import static org.zwobble.hobgoblin.compiler.parser.ParserTesting.parseString; import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.*; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isSequence; public class ParserDatabaseSchemaDefinitionTests { @Test @@ -22,6 +23,32 @@ public class ParserDatabaseSchemaDefinitionTests { assertThat(node, isUntypedDatabaseSchemaDefinitionNode() .withName(equalTo("BlogApp")) + .withBody(isSequence()) + ); + } + + @Test + public void schemaWithStatements() { + var source = """ + databaseSchema BlogApp { + table Post { + } + + table Author { + } + }"""; + + var node = parseString( + source, + Parser::parseNamespaceStatement + ); + + assertThat(node, isUntypedDatabaseSchemaDefinitionNode() + .withName(equalTo("BlogApp")) + .withBody(isSequence( + isUntypedTableDefinitionNode().withName(equalTo("Post")), + isUntypedTableDefinitionNode().withName(equalTo("Author")) + )) ); } } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserTableDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserTableDefinitionTests.java new file mode 100644 index 0000000..b39d203 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserTableDefinitionTests.java @@ -0,0 +1,24 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNodeMatcher.isUntypedTableDefinitionNode; +import static org.zwobble.hobgoblin.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; + +public class ParserTableDefinitionTests { + @Test + public void minimalTable() { + var source = """ + table Post { + }"""; + + var node = parseString( + source, + Parser::parseDatabaseSchemaStatement + ); + + assertThat(node, isUntypedTableDefinitionNode().withName(equalTo("Post"))); + } +} -- cgit v1.2.3