From 24019585814742baa6c8bee85b8373be319fbaa8 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 6 Jun 2023 19:10:26 +0100 Subject: Parse string literals --- .../shedlang/compiler/ast/UntypedNodeMatchers.java | 17 +++++++ .../compiler/parser/ParserStringLiteralTests.java | 55 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/test/java/org/shedlang/compiler/ast/UntypedNodeMatchers.java create mode 100644 src/test/java/org/shedlang/compiler/parser/ParserStringLiteralTests.java (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/ast/UntypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/UntypedNodeMatchers.java new file mode 100644 index 00000000..6e0c7654 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/ast/UntypedNodeMatchers.java @@ -0,0 +1,17 @@ +package org.shedlang.compiler.ast; + +import org.zwobble.precisely.Matcher; + +import static org.zwobble.precisely.Matchers.*; + +public class UntypedNodeMatchers { + private UntypedNodeMatchers() { + } + + public static Matcher isUntypedStringLiteralNode(String value) { + return instanceOf( + UntypedStringLiteralNode.class, + has("value", x -> x.value(), equalTo(value)) + ); + } +} diff --git a/src/test/java/org/shedlang/compiler/parser/ParserStringLiteralTests.java b/src/test/java/org/shedlang/compiler/parser/ParserStringLiteralTests.java new file mode 100644 index 00000000..d625a603 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/parser/ParserStringLiteralTests.java @@ -0,0 +1,55 @@ +package org.shedlang.compiler.parser; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.sources.FileFragmentSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.shedlang.compiler.ast.UntypedNodeMatchers.isUntypedStringLiteralNode; +import static org.shedlang.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ParserStringLiteralTests { + @Test + public void canParseEmptyString() { + var source = "\"\""; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedStringLiteralNode("")); + } + + @Test + public void canParseStringWithUnescapedCharacters() { + var source = "\"abc 123 XYZ\""; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedStringLiteralNode("abc 123 XYZ")); + } + + @Test + public void canParseStringWithEscapedCharacters() { + var source = "\"\\n\\r\\t\\\\\\\"\""; + + var node = parseString(source, Parser::parseTopLevelExpression); + + assertThat(node, isUntypedStringLiteralNode("\n\r\t\\\"")); + } + + @Test + public void whenStringHasUnrecognisedEscapeSequenceThenExceptionIsThrown() { + var source = "\"a\\ab\""; + + var error = assertThrows( + UnrecognisedEscapeSequenceError.class, + () -> parseString(source, Parser::parseTopLevelExpression) + ); + + assertThat(error.getMessage(), equalTo("Unrecognised escape sequence: \\a")); + assertThat(error.getSource(), instanceOf(FileFragmentSource.class, allOf( + has("characterIndexStart", x -> x.characterIndexStart(), equalTo(1)), + has("characterIndexEnd", x -> x.characterIndexEnd(), equalTo(3)) + ))); + } +} -- cgit v1.2.3