diff options
Diffstat (limited to 'src/test')
30 files changed, 1304 insertions, 28 deletions
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java index dbd1227..d1f177d 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java @@ -32,6 +32,7 @@ public class ExampleTests { var javaOutputPath = verifyJavaOutput(exampleSet); var rustOutputPath = verifyRustOutput(exampleSet); + verifySqlite3Output(exampleSet); verifyTypescriptOutput(exampleSet); var transient0OutputDirs = Stream.of(javaOutputPath, rustOutputPath) @@ -68,6 +69,18 @@ public class ExampleTests { return verifyOutput(exampleSet, "rust", List.of(List.of("cargo", "test"))); } + private void verifySqlite3Output( + ExampleSet exampleSet + ) throws NoSuchAlgorithmException, IOException, InterruptedException { + verifyOutput( + exampleSet, + "sqlite3", + List.of( + List.of("python3", "-m", "unittest", "test.py") + ) + ); + } + private Optional<Path> verifyTypescriptOutput(ExampleSet exampleSet) throws NoSuchAlgorithmException, IOException, InterruptedException { return verifyOutput(exampleSet, "typescript", List.of( List.of("pnpm", "install"), diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTableMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTableMatcher.java new file mode 100644 index 0000000..3aff4dc --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTableMatcher.java @@ -0,0 +1,41 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.typed; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher imports + +public final class RelationTableMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher isRelationTable() { + return new org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.RelationTable>> submatchers; + + private RelationTableMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.RelationTable>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher withTable(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.types.Table> table) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.RelationTable>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("table", org.zwobble.hobgoblin.compiler.ast.typed.RelationTable::table, (org.zwobble.precisely.Matcher) table)); + return new org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNodeMatcher.java new file mode 100644 index 0000000..d9a6bc5 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNodeMatcher.java @@ -0,0 +1,59 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.typed; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher imports + +public final class TypedQueryDefinitionNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher isTypedQueryDefinitionNode() { + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>> submatchers; + + private TypedQueryDefinitionNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher withName(org.zwobble.precisely.Matcher<? super String> name) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher withRelation(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.Relation> relation) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("relation", org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode::relation, (org.zwobble.precisely.Matcher) relation)); + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.DocComment> docComment) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment)); + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNodeMatcher.java new file mode 100644 index 0000000..a9ce6a5 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNodeMatcher.java @@ -0,0 +1,53 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher imports + +public final class UntypedCallNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher isUntypedCallNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode>> submatchers; + + private UntypedCallNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher withReceiver(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> receiver) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("receiver", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode::receiver, (org.zwobble.precisely.Matcher) receiver)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher withArgs(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode>> args) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("args", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode::args, (org.zwobble.precisely.Matcher) args)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNodeMatcher.java new file mode 100644 index 0000000..71356e8 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNodeMatcher.java @@ -0,0 +1,53 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher imports + +public final class UntypedFunctionExpressionNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher isUntypedFunctionExpressionNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode>> submatchers; + + private UntypedFunctionExpressionNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher withParams(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>> params) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("params", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode::params, (org.zwobble.precisely.Matcher) params)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher withBody(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> body) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("body", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode::body, (org.zwobble.precisely.Matcher) body)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNodeMatcher.java new file mode 100644 index 0000000..c11f7ef --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNodeMatcher.java @@ -0,0 +1,53 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher imports + +public final class UntypedMemberAccessNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher isUntypedMemberAccessNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode>> submatchers; + + private UntypedMemberAccessNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher withReceiver(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> receiver) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("receiver", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode::receiver, (org.zwobble.precisely.Matcher) receiver)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher withMemberName(org.zwobble.precisely.Matcher<? super String> memberName) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("memberName", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode::memberName, (org.zwobble.precisely.Matcher) memberName)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNodeMatcher.java new file mode 100644 index 0000000..c140fb2 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNodeMatcher.java @@ -0,0 +1,47 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher imports + +public final class UntypedParamNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher isUntypedParamNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>> submatchers; + + private UntypedParamNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher withName(org.zwobble.precisely.Matcher<? super String> name) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNodeMatcher.java new file mode 100644 index 0000000..adcc2d9 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNodeMatcher.java @@ -0,0 +1,59 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher imports + +public final class UntypedQueryDefinitionNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher isUntypedQueryDefinitionNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>> submatchers; + + private UntypedQueryDefinitionNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher withName(org.zwobble.precisely.Matcher<? super String> name) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher withStatements(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode>> statements) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("statements", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode::statements, (org.zwobble.precisely.Matcher) statements)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.DocComment> docComment) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNodeMatcher.java new file mode 100644 index 0000000..311f24d --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNodeMatcher.java @@ -0,0 +1,47 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher imports + +public final class UntypedReferenceNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher isUntypedReferenceNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode>> submatchers; + + private UntypedReferenceNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher withName(org.zwobble.precisely.Matcher<? super String> name) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNodeMatcher.java new file mode 100644 index 0000000..7825b0d --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNodeMatcher.java @@ -0,0 +1,47 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.ast.untyped; + +// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher imports + +public final class UntypedReturnNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher isUntypedReturnNode() { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode>> submatchers; + + private UntypedReturnNodeMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher withExpression(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> expression) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("expression", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode::expression, (org.zwobble.precisely.Matcher) expression)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode::source, (org.zwobble.precisely.Matcher) source)); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/CodeWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/CodeWriterTests.java index 2b3ad6d..9e3f900 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/CodeWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/CodeWriterTests.java @@ -1,7 +1,6 @@ -package org.zwobble.hobgoblin.compiler.output.lang; +package org.zwobble.hobgoblin.compiler.output; import org.junit.jupiter.api.Test; -import org.zwobble.hobgoblin.compiler.output.CodeWriter; import java.io.IOException; import java.io.StringWriter; @@ -18,7 +17,7 @@ public class CodeWriterTests { CodeWriter.writeTo( file, - "//", + new CodeWriter.CodeWriterConfig("//"), codeWriter -> { codeWriter.writeHeader(); codeWriter.write("Before"); @@ -51,7 +50,7 @@ public class CodeWriterTests { CodeWriter.writeTo( file, - "//", + new CodeWriter.CodeWriterConfig("//"), codeWriter -> { codeWriter.writeHeader(); codeWriter.write("Before"); @@ -89,7 +88,7 @@ public class CodeWriterTests { CodeWriter.writeTo( file, - "//", + new CodeWriter.CodeWriterConfig("//"), codeWriter -> { codeWriter.writeHeader(); codeWriter.writeCustomArea("head"); @@ -124,7 +123,7 @@ public class CodeWriterTests { CodeWriter.writeTo( file, - "//", + new CodeWriter.CodeWriterConfig("//"), codeWriter -> { codeWriter.writeHeader(); codeWriter.writeCustomArea("head"); @@ -135,4 +134,81 @@ public class CodeWriterTests { assertThat(stringWriter.toString(), equalTo("")); assertThat(file.isWriterOpened(), equalTo(false)); } + + @Test + public void strippingDoesNothingToFileWithoutHeader() { + var originalContents = """ + Hello, world! + """; + + var result = CodeWriter.stripFileContents( + originalContents, + new CodeWriter.CodeWriterConfig("//") + ); + + assertThat(result, equalTo(new CodeWriter.StripResult.Unchanged())); + } + + @Test + public void whenFileHasNoCustomAreasThenFileIsDeleted() { + var originalContents = """ + // Generated by hobgoblin. + + Hello, world! + """; + + var result = CodeWriter.stripFileContents( + originalContents, + new CodeWriter.CodeWriterConfig("//") + ); + + assertThat(result, equalTo(new CodeWriter.StripResult.Delete())); + } + + @Test + public void whenCustomAreasAreAllEmptyThenFileIsDeleted() { + var originalContents = """ + // Generated by hobgoblin. + + Before + // Custom area start: body + // Custom area end: body + After + """; + + var result = CodeWriter.stripFileContents( + originalContents, + new CodeWriter.CodeWriterConfig("//") + ); + + assertThat(result, equalTo(new CodeWriter.StripResult.Delete())); + } + + @Test + public void nonEmptyCustomAreasArePreserved() { + var originalContents = """ + // Generated by hobgoblin. + + Before + // Custom area start: head + Custom head. + // Custom area end: head + // Custom area start: body + // Custom area end: body + After + """; + + var result = CodeWriter.stripFileContents( + originalContents, + new CodeWriter.CodeWriterConfig("//") + ); + + assertThat(result, equalTo(new CodeWriter.StripResult.NewContent(""" + // Generated by hobgoblin. + + // Custom area start: head + Custom head. + // Custom area end: head + """))); + } } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriterTests.java index 42b075f..be45935 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriterTests.java @@ -105,6 +105,75 @@ public class SqlWriterTests { )); } + // === Select statements === + + @Test + public void minimalSelectStatement() throws IOException { + var sql = SqlSelectStatement.arbitrary() + .addColumn(SqlResultColumn.arbitrary() + .withExpression(ref("a")) + .withAlias(id("x")) + ) + .addColumn(SqlResultColumn.arbitrary() + .withExpression(ref("b")) + .withAlias(id("y")) + ) + .withFrom(id("blah")) + .build(); + + var string = write(writer -> writer.writeStatement(sql)); + + assertThat(string, equalTo(""" + SELECT + a AS x, + b AS y + FROM blah;""" + )); + } + + @Test + public void selectStatementWithSingleOrderByExpression() throws IOException { + var sql = SqlSelectStatement.arbitrary() + .addColumn(SqlResultColumn.arbitrary() + .withExpression(ref("a")) + .withAlias(id("x")) + ) + .withFrom(id("blah")) + .addOrderByElement(SqlOrderingTerm.arbitrary().withExpression(ref("b"))) + .build(); + + var string = write(writer -> writer.writeStatement(sql)); + + assertThat(string, equalTo(""" + SELECT + a AS x + FROM blah + ORDER BY b;""" + )); + } + + @Test + public void selectStatementWithMultipleOrderByExpressions() throws IOException { + var sql = SqlSelectStatement.arbitrary() + .addColumn(SqlResultColumn.arbitrary() + .withExpression(ref("a")) + .withAlias(id("x")) + ) + .withFrom(id("blah")) + .addOrderByElement(SqlOrderingTerm.arbitrary().withExpression(ref("b"))) + .addOrderByElement(SqlOrderingTerm.arbitrary().withExpression(ref("c"))) + .build(); + + var string = write(writer -> writer.writeStatement(sql)); + + assertThat(string, equalTo(""" + SELECT + a AS x + FROM blah + ORDER BY b, c;""" + )); + } + // == Table constraints == @Test @@ -130,6 +199,17 @@ public class SqlWriterTests { assertThat(string, equalTo("PRIMARY KEY (a, b)")); } + // === Expressions === + + @Test + public void ref() throws IOException { + var sql = ref("a"); + + var string = write(writer -> writer.writeExpression(sql)); + + assertThat(string, equalTo("a")); + } + // == Test utilities == private String write(SqlWriter.Write write) throws IOException { @@ -147,6 +227,9 @@ public class SqlWriterTests { private SqlIdentifier id(String value) { return new SqlIdentifier(value); + } + private SqlRef ref(String name) { + return new SqlRef(id(name)); } } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTermMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTermMatcher.java new file mode 100644 index 0000000..b947f47 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTermMatcher.java @@ -0,0 +1,41 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.output.lang.sql.ast; + +// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher imports + +public final class SqlOrderingTermMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher isSqlOrderingTerm() { + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>> submatchers; + + private SqlOrderingTermMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher withExpression(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression> expression) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("expression", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm::expression, (org.zwobble.precisely.Matcher) expression)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRefMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRefMatcher.java new file mode 100644 index 0000000..c56f266 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRefMatcher.java @@ -0,0 +1,41 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.output.lang.sql.ast; + +// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher imports + +public final class SqlRefMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher isSqlRef() { + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef>> submatchers; + + private SqlRefMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher withName(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier> name) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef::name, (org.zwobble.precisely.Matcher) name)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumnMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumnMatcher.java new file mode 100644 index 0000000..772b6c5 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumnMatcher.java @@ -0,0 +1,47 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.output.lang.sql.ast; + +// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher imports + +public final class SqlResultColumnMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher isSqlResultColumn() { + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>> submatchers; + + private SqlResultColumnMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher withExpression(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression> expression) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("expression", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn::expression, (org.zwobble.precisely.Matcher) expression)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher withAlias(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier> alias) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("alias", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn::alias, (org.zwobble.precisely.Matcher) alias)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatementMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatementMatcher.java new file mode 100644 index 0000000..db254ca --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatementMatcher.java @@ -0,0 +1,53 @@ +// Generated by hobgoblin. + +package org.zwobble.hobgoblin.compiler.output.lang.sql.ast; + +// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher imports +// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher imports + +public final class SqlSelectStatementMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> { + public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher isSqlSelectStatement() { + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher(java.util.List.of()); + } + + private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement>> submatchers; + + private SqlSelectStatementMatcher( + java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement>> 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<java.lang.Object> toMatcher() { + return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.class, this.submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher withColumns(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>> columns) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("columns", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement::columns, (org.zwobble.precisely.Matcher) columns)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher withFrom(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier> from) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("from", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement::from, (org.zwobble.precisely.Matcher) from)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher(submatchers); + } + + public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher withOrderBy(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>> orderBy) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("orderBy", org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement::orderBy, (org.zwobble.precisely.Matcher) orderBy)); + return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher(submatchers); + } + + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher body + // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher body +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserCallTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserCallTests.java new file mode 100644 index 0000000..64e84de --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserCallTests.java @@ -0,0 +1,61 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNodeMatcher.isUntypedCallNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +import static org.zwobble.hobgoblin.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ParserCallTests { + @Test + public void canParseCallWithNoArguments() { + var source = "f()"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedCallNode() + .withReceiver(isUntypedReferenceNode() + .withName(equalTo("f")) + ) + .withArgs(isSequence()) + ); + } + + @Test + public void canParseCallWithOnePositionalArgument() { + var source = "f(a)"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedCallNode() + .withReceiver(isUntypedReferenceNode() + .withName(equalTo("f")) + ) + .withArgs(isSequence( + isUntypedReferenceNode().withName(equalTo("a")) + )) + ); + } + + @Test + public void canParseCallWithMultiplePositionalArguments() { + var source = "f(a, b, c)"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedCallNode() + .withReceiver(isUntypedReferenceNode() + .withName(equalTo("f")) + ) + .withArgs(isSequence( + isUntypedReferenceNode().withName(equalTo("a")), + isUntypedReferenceNode().withName(equalTo("b")), + isUntypedReferenceNode().withName(equalTo("c")) + )) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserFunctionExpressionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserFunctionExpressionTests.java new file mode 100644 index 0000000..99cf3c0 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserFunctionExpressionTests.java @@ -0,0 +1,55 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNodeMatcher.isUntypedFunctionExpressionNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNodeMatcher.isUntypedParamNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +import static org.zwobble.hobgoblin.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ParserFunctionExpressionTests { + @Test + public void canParseFunctionExpressionWithNoParams() { + var source = "$() => x"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedFunctionExpressionNode() + .withParams(isSequence()) + .withBody(isUntypedReferenceNode().withName(equalTo("x"))) + ); + } + + @Test + public void canParseFunctionExpressionWithOneParam() { + var source = "$(a) => x"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedFunctionExpressionNode() + .withParams(isSequence( + isUntypedParamNode().withName(equalTo("a")) + )) + .withBody(isUntypedReferenceNode().withName(equalTo("x"))) + ); + } + @Test + public void canParseFunctionExpressionWithMultipleParams() { + var source = "$(a, b, c) => x"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedFunctionExpressionNode() + .withParams(isSequence( + isUntypedParamNode().withName(equalTo("a")), + isUntypedParamNode().withName(equalTo("b")), + isUntypedParamNode().withName(equalTo("c")) + )) + .withBody(isUntypedReferenceNode().withName(equalTo("x"))) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserMemberAccessTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserMemberAccessTests.java new file mode 100644 index 0000000..f096b93 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserMemberAccessTests.java @@ -0,0 +1,26 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNodeMatcher.isUntypedMemberAccessNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +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 ParserMemberAccessTests { + @Test + public void canParseMemberAccess() { + var source = "author.name"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedMemberAccessNode() + .withReceiver(isUntypedReferenceNode() + .withName(equalTo("author")) + ) + .withMemberName(equalTo("name")) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserQueryDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserQueryDefinitionTests.java new file mode 100644 index 0000000..e5b5a45 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserQueryDefinitionTests.java @@ -0,0 +1,74 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNodeMatcher.isUntypedQueryDefinitionNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher.isUntypedReturnNode; +import static org.zwobble.hobgoblin.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isSequence; + +public class ParserQueryDefinitionTests { + @Test + public void canParseQueryDefinitionWithNoStatements() { + var source = """ + query allAuthors() { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat(node, isUntypedQueryDefinitionNode() + .withName(equalTo("allAuthors")) + .withStatements(isSequence()) + ); + } + + @Test + public void canParseQueryDefinitionWithSingleStatement() { + var source = """ + query allAuthors() { + return x; + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat(node, isUntypedQueryDefinitionNode() + .withName(equalTo("allAuthors")) + .withStatements(isSequence( + isUntypedReturnNode() + .withExpression(isUntypedReferenceNode() + .withName(equalTo("x")) + ) + )) + ); + + } + + @Test + public void canParseQueryDefinitionWithMultipleStatements() { + var source = """ + query allAuthors() { + return x; + return y; + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat(node, isUntypedQueryDefinitionNode() + .withName(equalTo("allAuthors")) + .withStatements(isSequence( + isUntypedReturnNode() + .withExpression(isUntypedReferenceNode() + .withName(equalTo("x")) + ), + isUntypedReturnNode() + .withExpression(isUntypedReferenceNode() + .withName(equalTo("y")) + ) + )) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReferenceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReferenceTests.java new file mode 100644 index 0000000..fdd3add --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReferenceTests.java @@ -0,0 +1,22 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +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 ParserReferenceTests { + @Test + public void canParseReference() { + var source = "authors"; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedReferenceNode() + .withName(equalTo("authors")) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReturnTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReturnTests.java new file mode 100644 index 0000000..64ce562 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserReturnTests.java @@ -0,0 +1,25 @@ +package org.zwobble.hobgoblin.compiler.parser; + +import org.junit.jupiter.api.Test; + +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNodeMatcher.isUntypedReferenceNode; +import static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNodeMatcher.isUntypedReturnNode; +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 ParserReturnTests { + @Test + public void canParseReturn() { + var source = "return x;"; + + var node = parseString(source, Parser::parseStatement); + + assertThat(node, isUntypedReturnNode() + .withExpression(isUntypedReferenceNode() + .withName(equalTo("x")) + ) + ); + } +} + diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/TokenizerTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/TokenizerTests.java index 39aded5..86fb1f9 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/parser/TokenizerTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/TokenizerTests.java @@ -41,17 +41,6 @@ public class TokenizerTests { } @Test - public void keywordFromIsTokenized() { - var sourceText = SourceText.fromString("<string>", "from"); - - var tokens = Tokenizer.tokenize(sourceText); - - assertThat(tokens.tokens(), isSequence( - equalTo(new Token(TokenType.KEYWORD_FROM, sourceRange(sourceText, 0, 4))) - )); - } - - @Test public void keywordImportIsTokenized() { var sourceText = SourceText.fromString("<string>", "import"); @@ -173,6 +162,17 @@ public class TokenizerTests { } @Test + public void symbolDollarIsTokenized() { + var sourceText = SourceText.fromString("<string>", "$"); + + var tokens = Tokenizer.tokenize(sourceText); + + assertThat(tokens.tokens(), isSequence( + equalTo(new Token(TokenType.SYMBOL_DOLLAR, sourceRange(sourceText, 0, 1))) + )); + } + + @Test public void symbolDotIsTokenized() { var sourceText = SourceText.fromString("<string>", "."); @@ -195,6 +195,17 @@ public class TokenizerTests { } @Test + public void symbolFatArrowIsTokenized() { + var sourceText = SourceText.fromString("<string>", "=>"); + + var tokens = Tokenizer.tokenize(sourceText); + + assertThat(tokens.tokens(), isSequence( + equalTo(new Token(TokenType.SYMBOL_FAT_ARROW, sourceRange(sourceText, 0, 2))) + )); + } + + @Test public void symbolForwardSlashIsTokenized() { var sourceText = SourceText.fromString("<string>", "/"); 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 08fdd47..daecb54 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java @@ -6,20 +6,17 @@ 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 org.zwobble.hobgoblin.compiler.types.*; import java.util.List; +import java.util.Map; 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; import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.equalTo; -import static org.zwobble.precisely.Matchers.isSequence; +import static org.zwobble.precisely.Matchers.*; public class TypeCheckerDatabaseSchemaDefinitionTests { @Test @@ -54,5 +51,20 @@ public class TypeCheckerDatabaseSchemaDefinitionTests { .withRowType(equalTo(authorType)) )) ); + assertThat( + namespaceContext.lookupType("blogApp"), + isOptionalOf(equalTo(Types.databaseSchema(new DatabaseSchema(NamespaceName.of("App"), "blogApp")))) + ); + var typesInfo = namespaceContext.toTypesInfo(); + var schemaInfo = typesInfo.databaseSchemaInfo(new DatabaseSchema(NamespaceName.of("App"), "blogApp")); + assertThat(schemaInfo.tables().entrySet(), isSequence( + allOf( + has("key", Map.Entry::getKey, equalTo("authors")), + has("value", Map.Entry::getValue, allOf( + has("rowType", TableInfo::rowType, equalTo(authorType)), + has("primaryKey", TableInfo::primaryKey, equalTo(new Field("id", NativeTypes.INT_32, NullSource.INSTANCE))) + )) + ) + )); } } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerEvalExpressionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerEvalExpressionTests.java new file mode 100644 index 0000000..cf1e73c --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerEvalExpressionTests.java @@ -0,0 +1,95 @@ +package org.zwobble.hobgoblin.compiler.typechecker; + +import org.junit.jupiter.api.Test; +import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode; +import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode; +import org.zwobble.hobgoblin.compiler.builtins.NativeTypes; +import org.zwobble.hobgoblin.compiler.sources.NullSource; +import org.zwobble.hobgoblin.compiler.typechecker.errors.UndeclaredVariableError; +import org.zwobble.hobgoblin.compiler.typechecker.errors.UnexpectedTypeError; +import org.zwobble.hobgoblin.compiler.types.*; +import org.zwobble.hobgoblin.compiler.util.SequencedMaps; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; + +public class TypeCheckerEvalExpressionTests { + @Test + public void whenVariableIsTypeLevelValueThenCanEvaluateReference() { + var untyped = UntypedReferenceNode.arbitrary() + .withName("authors") + .build(); + var globalContext = TypeCheckerContextArb.globalContext(); + var namespaceName = NamespaceName.of("App"); + var namespaceContext = globalContext.enterNamespace(namespaceName); + var databaseSchema = new DatabaseSchema(namespaceName, "blogApp"); + var table = new Table(databaseSchema, "authors"); + namespaceContext.declare("authors", Types.table(table), NullSource.INSTANCE); + + var typed = TypeChecker.evalExpression(untyped, namespaceContext); + + assertThat(typed, equalTo(table)); + } + + @Test + public void whenVariableIsNotTypeLevelValueThenCannotEvaluateReference() { + var untyped = UntypedReferenceNode.arbitrary() + .withName("count") + .build(); + var globalContext = TypeCheckerContextArb.globalContext(); + var namespaceName = NamespaceName.of("App"); + var namespaceContext = globalContext.enterNamespace(namespaceName); + namespaceContext.declare("count", NativeTypes.INT_32, NullSource.INSTANCE); + + var error = assertThrows( + UnexpectedTypeError.class, + () -> TypeChecker.evalExpression(untyped, namespaceContext) + ); + + assertThat(error.expected(), equalTo(new TypeSet.TypeLevelValue())); + } + + @Test + public void whenVariableIsNotDeclaredThenCannotEvaluateReference() { + var untyped = UntypedReferenceNode.arbitrary() + .withName("count") + .build(); + var globalContext = TypeCheckerContextArb.globalContext(); + var namespaceName = NamespaceName.of("App"); + var namespaceContext = globalContext.enterNamespace(namespaceName); + + var error = assertThrows( + UndeclaredVariableError.class, + () -> TypeChecker.evalExpression(untyped, namespaceContext) + ); + + assertThat(error.variableName(), equalTo("count")); + } + + @Test + public void canReadMemberField() { + var untyped = UntypedMemberAccessNode.arbitrary() + .withReceiver(UntypedReferenceNode.arbitrary().withName("blogApp")) + .withMemberName("authors") + .build(); + var globalContext = TypeCheckerContextArb.globalContext(); + var namespaceName = NamespaceName.of("App"); + var namespaceContext = globalContext.enterNamespace(namespaceName); + var databaseSchema = new DatabaseSchema(namespaceName, "blogApp"); + namespaceContext.declare("blogApp", Types.databaseSchema(databaseSchema), NullSource.INSTANCE); + var table = new Table(databaseSchema, "authors"); + var rowType = new SimpleStructType(namespaceName, "Author"); + var idField = new Field("id", NativeTypes.INT_32, NullSource.INSTANCE); + var databaseSchemaInfo = new DatabaseSchemaInfo(SequencedMaps.ofEntries( + Map.entry("authors", new TableInfo(table, rowType, idField)) + )); + namespaceContext.defineDatabaseSchema(databaseSchema, databaseSchemaInfo); + + var typed = TypeChecker.evalExpression(untyped, namespaceContext); + + assertThat(typed, equalTo(table)); + } +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerMetaTypeTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerMetaTypeTests.java index 074d1df..713cd13 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerMetaTypeTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerMetaTypeTests.java @@ -27,7 +27,7 @@ public class TypeCheckerMetaTypeTests { () -> TypeChecker.typeCheckMetaType(untyped, context) ); - assertThat(error.expected(), equalTo(new TypeSet.MetaType())); + assertThat(error.expected(), equalTo(new TypeSet.TypeLevelValue())); assertThat(error.actual(), equalTo(nativeType)); } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerQueryDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerQueryDefinitionTests.java new file mode 100644 index 0000000..43ffb04 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerQueryDefinitionTests.java @@ -0,0 +1,42 @@ +package org.zwobble.hobgoblin.compiler.typechecker; + +import org.junit.jupiter.api.Test; +import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode; +import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode; +import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode; +import org.zwobble.hobgoblin.compiler.sources.NullSource; +import org.zwobble.hobgoblin.compiler.types.DatabaseSchema; +import org.zwobble.hobgoblin.compiler.types.NamespaceName; +import org.zwobble.hobgoblin.compiler.types.Table; +import org.zwobble.hobgoblin.compiler.types.Types; + +import static org.zwobble.hobgoblin.compiler.ast.typed.RelationTableMatcher.isRelationTable; +import static org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNodeMatcher.isTypedQueryDefinitionNode; +import static org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerTesting.typeCheckNamespaceStatement; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; + +public class TypeCheckerQueryDefinitionTests { + @Test + public void queryForAllTableRows() { + var untyped = UntypedQueryDefinitionNode.arbitrary() + .withName("allAuthors") + .addStatement(UntypedReturnNode.arbitrary().withExpression( + UntypedReferenceNode.arbitrary().withName("authors") + )) + .build(); + var globalContext = TypeCheckerContextArb.globalContext(); + var namespaceName = NamespaceName.of("App"); + var namespaceContext = globalContext.enterNamespace(namespaceName); + var databaseSchema = new DatabaseSchema(namespaceName, "blogApp"); + var table = new Table(databaseSchema, "authors"); + namespaceContext.declare("authors", Types.table(table), NullSource.INSTANCE); + + var typed = typeCheckNamespaceStatement(untyped, namespaceContext); + + assertThat(typed, isTypedQueryDefinitionNode() + .withName(equalTo("allAuthors")) + .withRelation(isRelationTable().withTable(equalTo(table))) + ); + } +} 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 a32945a..0dd911b 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java @@ -9,6 +9,7 @@ import org.zwobble.hobgoblin.compiler.typechecker.errors.NoSuchFieldError; import org.zwobble.hobgoblin.compiler.typechecker.errors.TableRowTypeMustBeStructError; import org.zwobble.hobgoblin.compiler.types.*; +import java.util.LinkedHashMap; import java.util.List; import java.util.Optional; @@ -37,11 +38,17 @@ public class TypeCheckerTableDefinitionTests { new Field("id", NativeTypes.INT_32, NullSource.INSTANCE) ))); - var typed = typeCheckDatabaseSchemaStatement(untyped, namespaceContext); + var typed = typeCheckDatabaseSchemaStatement( + untyped, + new DatabaseSchema(NamespaceName.of("App"), "blogApp"), + new DatabaseSchemaInfo(new LinkedHashMap<>()), + namespaceContext + ); assertThat(typed, isTypedTableDefinitionNode() .withName(equalTo("authors")) .withRowType(equalTo(authorType)) + .withPrimaryKey(equalTo(new Field("id", NativeTypes.INT_32, NullSource.INSTANCE))) ); } @@ -61,7 +68,12 @@ public class TypeCheckerTableDefinitionTests { var error = assertThrows( TableRowTypeMustBeStructError.class, - () -> typeCheckDatabaseSchemaStatement(untyped, namespaceContext) + () -> typeCheckDatabaseSchemaStatement( + untyped, + new DatabaseSchema(NamespaceName.of("App"), "blogApp"), + new DatabaseSchemaInfo(new LinkedHashMap<>()), + namespaceContext + ) ); assertThat(error.rowType(), equalTo(authorType)); @@ -87,7 +99,12 @@ public class TypeCheckerTableDefinitionTests { var error = assertThrows( NoSuchFieldError.class, - () -> typeCheckDatabaseSchemaStatement(untyped, namespaceContext) + () -> typeCheckDatabaseSchemaStatement( + untyped, + new DatabaseSchema(NamespaceName.of("App"), "blogApp"), + new DatabaseSchemaInfo(new LinkedHashMap<>()), + namespaceContext + ) ); assertThat(error.type(), equalTo(authorType)); diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java index 084be46..98f4f22 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java @@ -40,7 +40,7 @@ public class TypeCheckerTypeLevelReferenceTests { () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context) ); - assertThat(error.expected(), equalTo(new TypeSet.MetaType())); + assertThat(error.expected(), equalTo(new TypeSet.TypeLevelValue())); assertThat(error.actual(), equalTo(nativeType)); } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/util/SequencedMaps.java b/src/test/java/org/zwobble/hobgoblin/compiler/util/SequencedMaps.java new file mode 100644 index 0000000..b19d3d1 --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/util/SequencedMaps.java @@ -0,0 +1,23 @@ +package org.zwobble.hobgoblin.compiler.util; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.SequencedMap; + +public class SequencedMaps { + private SequencedMaps() { + } + + @SafeVarargs + public static <K, V> SequencedMap<K, V> ofEntries( + Map.Entry<K, V>... entries + ) { + var map = new LinkedHashMap<K, V>(entries.length); + + for (var entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + + return map; + } +} |
