aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-10-25 21:58:28 +0100
committerMichael Williamson <mike@zwobble.org>2023-10-25 21:59:51 +0100
commitce0b25de9fa8f7423391357db75bd72ad6c9e7df (patch)
tree7234f305f56cd9f146014794614dbd78daf30216 /src/test/java
parent693c3afe929b693de48346f281ce5b1d95d0fcdb (diff)
Extract tests for type-checking function signatures
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNodeMatcher.java56
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java4
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java57
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionSignatureTests.java95
4 files changed, 156 insertions, 56 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNodeMatcher.java
new file mode 100644
index 00000000..e93d45fe
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionSignatureNodeMatcher.java
@@ -0,0 +1,56 @@
+package org.shedlang.compiler.ast.typed;
+
+import org.pcollections.Empty;
+import org.pcollections.PVector;
+import org.shedlang.compiler.testing.MatcherBuilder;
+import org.shedlang.compiler.types.FunctionType;
+import org.zwobble.precisely.Matcher;
+
+import java.util.Optional;
+
+import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.has;
+
+public class TypedFunctionSignatureNodeMatcher extends MatcherBuilder<
+ TypedFunctionSignatureNode,
+ TypedFunctionSignatureNode,
+ TypedFunctionSignatureNodeMatcher
+> {
+ public static TypedFunctionSignatureNodeMatcher empty() {
+ return new TypedFunctionSignatureNodeMatcher(Empty.vector());
+ }
+
+ public TypedFunctionSignatureNodeMatcher(
+ PVector<Matcher<? super TypedFunctionSignatureNode>> submatchers
+ ) {
+ super(submatchers);
+ }
+
+ @Override
+ protected Class<TypedFunctionSignatureNode> expectedType() {
+ return TypedFunctionSignatureNode.class;
+ }
+
+ @Override
+ protected TypedFunctionSignatureNodeMatcher create(
+ PVector<Matcher<? super TypedFunctionSignatureNode>> submatchers
+ ) {
+ return new TypedFunctionSignatureNodeMatcher(submatchers);
+ }
+
+ public TypedFunctionSignatureNodeMatcher withEffect(Matcher<Optional<? extends TypedTypeLevelExpressionNode<?>>> effect) {
+ return with(has("effect", x -> x.effect(), effect));
+ }
+
+ public TypedFunctionSignatureNodeMatcher withParams(Matcher<TypedParamsNode> params) {
+ return with(has("params", x -> x.params(), params));
+ }
+
+ public TypedFunctionSignatureNodeMatcher withReturnType(Matcher<TypedTypeLevelExpressionNode<?>> returnType) {
+ return with(has("returnType", x -> x.returnType(), returnType));
+ }
+
+ public TypedFunctionSignatureNodeMatcher withType(FunctionType type) {
+ return with(has("type", x -> x.type(), equalTo(type)));
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
index 112b2f02..2723883e 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -125,6 +125,10 @@ public class TypedNodeMatchers {
);
}
+ public static TypedFunctionSignatureNodeMatcher isTypedFunctionSignatureNode() {
+ return TypedFunctionSignatureNodeMatcher.empty();
+ }
+
public static Matcher<TypedTypeLevelExpressionNode<?>> isTypedFunctionTypeNode(
Matcher<FunctionType> value
) {
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
index 00fa8e9e..3354f0bf 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
@@ -9,7 +9,6 @@ import org.shedlang.compiler.typechecker.errors.UnexpectedTypeError;
import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.Effects;
import org.shedlang.compiler.types.FunctionType;
-import org.shedlang.compiler.types.NamedParam;
import org.shedlang.compiler.types.Types;
import org.shedlang.compiler.util.P;
@@ -47,42 +46,9 @@ public class TypeCheckerFunctionDefinitionTests {
}
@Test
- public void paramsAreTypeChecked() {
- var untyped = UntypedFunctionDefinitionNode.builder()
- .addPositionalParam("x", Untyped.typeLevelReference("String"))
- .addNamedParam("y", Untyped.typeLevelReference("Int"))
- .withReturnType(Untyped.typeLevelReference("Unit"))
- .build();
- var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(
- Map.entry("Int", Types.metaType(Types.INT)),
- Map.entry("String", Types.metaType(Types.STRING)),
- Map.entry("Unit", Types.metaType(Types.UNIT))
- ));
-
- var typed = typeCheckNamespaceStatement(untyped, context);
-
- assertThat(
- typed.value(),
- isTypedFunctionDefinitionNode()
- .withParams(
- isTypedParamsNode(
- isSequence(isTypedParamNode("x", isTypedTypeLevelReferenceNode("String", Types.STRING))),
- isSequence(isTypedParamNode("y", isTypedTypeLevelReferenceNode("Int", Types.INT)))
- )
- )
- .withType(new FunctionType(
- List.of(Types.STRING),
- List.of(new NamedParam("y", Types.INT)),
- Effects.NONE,
- Types.UNIT
- ))
- );
- }
-
- @Test
public void paramsMustHaveUniqueNames() {
var untyped = UntypedFunctionDefinitionNode.builder()
+ .withName("f")
.addPositionalParam("x", Untyped.typeLevelReference("String"))
.addPositionalParam("x", Untyped.typeLevelReference("Int"))
.withReturnType(Untyped.typeLevelReference("Unit"))
@@ -103,27 +69,6 @@ public class TypeCheckerFunctionDefinitionTests {
}
@Test
- public void effectIsTypeChecked() {
- var untyped = UntypedFunctionDefinitionNode.builder()
- .withEffect(Untyped.typeLevelReference("Io"))
- .withReturnType(Untyped.typeLevelReference("Unit"))
- .build();
- var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(
- Map.entry("Io", Types.effectType(Effects.IO)),
- Map.entry("Unit", Types.metaType(Types.UNIT))
- ));
-
- var typed = typeCheckNamespaceStatement(untyped, context);
-
- assertThat(
- typed.value(),
- isTypedFunctionDefinitionNode()
- .withEffect(isOptionalOf(isTypedTypeLevelReferenceNode("Io", Effects.IO)))
- );
- }
-
- @Test
public void bodyIsTypeChecked() {
var untyped = UntypedFunctionDefinitionNode.builder()
.withReturnType(Untyped.typeLevelReference("Unit"))
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionSignatureTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionSignatureTests.java
new file mode 100644
index 00000000..512c5650
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionSignatureTests.java
@@ -0,0 +1,95 @@
+package org.shedlang.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.untyped.Untyped;
+import org.shedlang.compiler.ast.untyped.UntypedFunctionSignatureNode;
+import org.shedlang.compiler.types.Effects;
+import org.shedlang.compiler.types.FunctionType;
+import org.shedlang.compiler.types.NamedParam;
+import org.shedlang.compiler.types.Types;
+import org.shedlang.compiler.util.P;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*;
+import static org.shedlang.compiler.typechecker.TypeChecker.typeCheckFunctionSignature;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.*;
+
+public class TypeCheckerFunctionSignatureTests {
+ @Test
+ public void canTypeCheckMinimalFunctionSignature() {
+ var untyped = UntypedFunctionSignatureNode.builder()
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(Map.entry("Unit", Types.metaType(Types.UNIT))));
+
+ var typed = typeCheckFunctionSignature(untyped, context);
+
+ assertThat(
+ typed,
+ isTypedFunctionSignatureNode()
+ .withParams(isTypedParamsNode(isSequence(), isSequence()))
+ .withEffect(isOptionalEmpty())
+ .withReturnType(isTypedTypeLevelReferenceNode("Unit", Types.UNIT))
+ .withType(new FunctionType(List.of(), List.of(), Effects.NONE, Types.UNIT))
+ );
+ }
+
+ @Test
+ public void paramsAreTypeChecked() {
+ var untyped = UntypedFunctionSignatureNode.builder()
+ .addPositionalParam("x", Untyped.typeLevelReference("String"))
+ .addNamedParam("y", Untyped.typeLevelReference("Int"))
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(
+ Map.entry("Int", Types.metaType(Types.INT)),
+ Map.entry("String", Types.metaType(Types.STRING)),
+ Map.entry("Unit", Types.metaType(Types.UNIT))
+ ));
+
+ var typed = typeCheckFunctionSignature(untyped, context);
+
+ assertThat(
+ typed,
+ isTypedFunctionSignatureNode()
+ .withParams(
+ isTypedParamsNode(
+ isSequence(isTypedParamNode("x", isTypedTypeLevelReferenceNode("String", Types.STRING))),
+ isSequence(isTypedParamNode("y", isTypedTypeLevelReferenceNode("Int", Types.INT)))
+ )
+ )
+ .withType(new FunctionType(
+ List.of(Types.STRING),
+ List.of(new NamedParam("y", Types.INT)),
+ Effects.NONE,
+ Types.UNIT
+ ))
+ );
+ }
+
+ @Test
+ public void effectIsTypeChecked() {
+ var untyped = UntypedFunctionSignatureNode.builder()
+ .withEffect(Untyped.typeLevelReference("Io"))
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(
+ Map.entry("Io", Types.effectType(Effects.IO)),
+ Map.entry("Unit", Types.metaType(Types.UNIT))
+ ));
+
+ var typed = typeCheckFunctionSignature(untyped, context);
+
+ assertThat(
+ typed,
+ isTypedFunctionSignatureNode()
+ .withEffect(isOptionalOf(isTypedTypeLevelReferenceNode("Io", Effects.IO)))
+ );
+ }
+}