aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org/shedlang/compiler/parser/ParserEffectDefinitionTests.java
blob: 40bd6a4c588d4b44143b78933fc54478b0576a15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package org.shedlang.compiler.parser;

import org.junit.jupiter.api.Test;
import org.shedlang.compiler.types.Visibility;

import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*;
import static org.shedlang.compiler.parser.ParserTesting.parseString;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.isSequence;

public class ParserEffectDefinitionTests {
    @Test
    public void canParseEffectName() {
        var source = """
            effect State {
            }""";

        var node = parseString(source, Parser::parseNamespaceStatement);

        assertThat(
            node,
            isUntypedEffectDefinitionNode()
                .withName("State")
        );
    }

    @Test
    public void defaultVisibilityIsPrivate() {
        var source = """
            effect State {
            }""";

        var node = parseString(source, Parser::parseNamespaceStatement);

        assertThat(
            node,
            isUntypedEffectDefinitionNode().withVisibility(Visibility.PRIVATE)
        );
    }

    @Test
    public void whenEffectIsPrefixedWithPubThenVisibilityIsPublic() {
        var source = """
            pub effect State {
            }""";

        var node = parseString(source, Parser::parseNamespaceStatement);

        assertThat(
            node,
            isUntypedEffectDefinitionNode().withVisibility(Visibility.PUBLIC)
        );
    }

    @Test
    public void canParseEffectWithNoFields() {
        var source = """
            effect State {
            }""";

        var node = parseString(source, Parser::parseNamespaceStatement);

        assertThat(
            node,
            isUntypedEffectDefinitionNode()
                .withFields(isSequence())
        );
    }

    @Test
    public void canParseEffectFields() {
        var source = """
            effect State {
                fun getValue() -> Int;
                fun setValue(Int) -> Unit;
            }""";

        var node = parseString(source, Parser::parseNamespaceStatement);

        assertThat(
            node,
            isUntypedEffectDefinitionNode()
                .withFields(isSequence(
                    isUntypedEffectDefinitionFieldNode(
                        "getValue",
                        isUntypedFunctionTypeNode()
                            .withParams(isUntypedFunctionTypeParamsNode(isSequence(), isSequence()))
                            .withReturnType(isUntypedTypeLevelReferenceNode("Int"))
                    ),
                    isUntypedEffectDefinitionFieldNode(
                        "setValue",
                        isUntypedFunctionTypeNode()
                            .withParams(isUntypedFunctionTypeParamsNode(
                                isSequence(isUntypedTypeLevelReferenceNode("Int")),
                                isSequence()
                            ))
                            .withReturnType(isUntypedTypeLevelReferenceNode("Unit"))
                    )
                ))
        );
    }
}