aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-05 21:30:56 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-05 21:30:56 +0100
commitf497e7f884856ca91f3697886db559af070a92ba (patch)
tree153550411103c5e17f51855957bedc25f74f8449 /src/test/java
parent69c3b150b872e0e3bb75cafa21e5e2e2eea768cb (diff)
Parse function definition params
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java10
-rw-r--r--src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java119
2 files changed, 129 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java
index acddc159..ad6c8a49 100644
--- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java
@@ -52,6 +52,16 @@ public class UntypedNodeMatchers {
);
}
+ public static Matcher<UntypedParamNode> isUntypedParamNode(
+ String name,
+ Matcher<UntypedTypeLevelExpressionNode> type
+ ) {
+ return allOf(
+ has("name", x -> x.name(), equalTo(name)),
+ has("type", x -> x.type(), type)
+ );
+ }
+
public static Matcher<UntypedParamsNode> isUntypedParamsNode(
Matcher<Iterable<? extends UntypedParamNode>> positional,
Matcher<Iterable<? extends UntypedParamNode>> named
diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java
index f718bfca..607a06bf 100644
--- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java
+++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java
@@ -2,6 +2,7 @@ package org.shedlang.compiler.parser;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*;
import static org.shedlang.compiler.parser.ParserTesting.parseString;
import static org.zwobble.precisely.AssertThat.assertThat;
@@ -28,6 +29,124 @@ public class ParserFunctionDefinitionTests {
}
@Test
+ public void canParseFunctionWithSinglePositionalParam() {
+ var source = """
+ fun f(a: Int) -> Unit {
+ }""";
+
+ var node = parseString(source, Parser::parseNamespaceStatement);
+
+ assertThat(
+ node,
+ isUntypedFunctionDefinitionNode()
+ .withParams(isUntypedParamsNode(
+ isSequence(
+ isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int"))
+ ),
+ isSequence()
+ ))
+ );
+ }
+
+ @Test
+ public void canParseFunctionWithManyPositionalParams() {
+ var source = """
+ fun f(a: Int, b: String, c: Bool) -> Unit {
+ }""";
+
+ var node = parseString(source, Parser::parseNamespaceStatement);
+
+ assertThat(
+ node,
+ isUntypedFunctionDefinitionNode()
+ .withParams(isUntypedParamsNode(
+ isSequence(
+ isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")),
+ isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")),
+ isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool"))
+ ),
+ isSequence()
+ ))
+ );
+ }
+
+ @Test
+ public void canParseFunctionWithSingleNamedParam() {
+ var source = """
+ fun f(.a: Int) -> Unit {
+ }""";
+
+ var node = parseString(source, Parser::parseNamespaceStatement);
+
+ assertThat(
+ node,
+ isUntypedFunctionDefinitionNode()
+ .withParams(isUntypedParamsNode(
+ isSequence(),
+ isSequence(
+ isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int"))
+ )
+ ))
+ );
+ }
+
+ @Test
+ public void canParseFunctionWithManyNamedParams() {
+ var source = """
+ fun f(.a: Int, .b: String, .c: Bool) -> Unit {
+ }""";
+
+ var node = parseString(source, Parser::parseNamespaceStatement);
+
+ assertThat(
+ node,
+ isUntypedFunctionDefinitionNode()
+ .withParams(isUntypedParamsNode(
+ isSequence(),
+ isSequence(
+ isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")),
+ isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")),
+ isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool"))
+ )
+ ))
+ );
+ }
+
+ @Test
+ public void canParseNamedParamAfterPositionalParam() {
+ var source = """
+ fun f(a: Int, .b: String) -> Unit {
+ }""";
+
+ var node = parseString(source, Parser::parseNamespaceStatement);
+
+ assertThat(
+ node,
+ isUntypedFunctionDefinitionNode()
+ .withParams(isUntypedParamsNode(
+ isSequence(
+ isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int"))
+ ),
+ isSequence(
+ isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String"))
+ )
+ ))
+ );
+ }
+
+ @Test
+ public void cannotParsePositionalParamAfterNamedParam() {
+ var source = """
+ fun f(.a: Int, b: String) -> Unit {
+ }""";
+
+ assertThrows(
+ PositionalParamAfterNamedParamError.class,
+ () -> parseString(source, Parser::parseNamespaceStatement)
+ );
+ }
+
+ @Test
public void canParseFunctionWithEffect() {
var source = """
fun f() ! Io -> Unit {