diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-05 21:30:56 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-05 21:30:56 +0100 |
| commit | f497e7f884856ca91f3697886db559af070a92ba (patch) | |
| tree | 153550411103c5e17f51855957bedc25f74f8449 /src/test/java | |
| parent | 69c3b150b872e0e3bb75cafa21e5e2e2eea768cb (diff) | |
Parse function definition params
Diffstat (limited to 'src/test/java')
| -rw-r--r-- | src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java | 10 | ||||
| -rw-r--r-- | src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java | 119 |
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 { |
