* structure TestProg8Parser with @Nested

This commit is contained in:
meisl 2021-08-02 14:52:46 +02:00
parent ef0c4797bb
commit c2986eaf47

View File

@ -4,6 +4,7 @@ import prog8tests.helpers.*
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Nested
import kotlin.test.*
import kotlin.io.path.*
@ -19,6 +20,12 @@ import prog8.ast.expressions.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestProg8Parser {
@Nested
inner class Newline {
@Nested
inner class AtEnd {
@Test
fun testModuleSourceNeedNotEndWithNewline() {
val nl = "\n" // say, Unix-style (different flavours tested elsewhere)
@ -36,6 +43,7 @@ class TestProg8Parser {
val module = parseModule(SourceCode.of(srcText))
assertEquals(1, module.statements.size)
}
}
@Test
fun testAllBlocksButLastMustEndWithNewline() {
@ -52,6 +60,37 @@ class TestProg8Parser {
assertEquals(2, module.statements.size)
}
@Test
fun testNewlineBetweenTwoBlocksOrDirectivesStillRequired() {
// issue: #47
// block and block
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
blockA {
} blockB {
}
""")) }
// block and directive
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
blockB {
} %import textio
""")) }
// The following two are bogus due to directive *args* expected to follow the directive name.
// Leaving them in anyways.
// dir and block
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
%import textio blockB {
}
""")) }
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
%import textio %import syslib
""")) }
}
@Test
fun testWindowsAndMacNewlinesAreAlsoFine() {
val nlWin = "\r\n"
@ -79,6 +118,10 @@ class TestProg8Parser {
val module = parseModule(SourceCode.of(srcText))
assertEquals(2, module.statements.size)
}
}
@Nested
inner class EOLsInterleavedWithComments {
@Test
fun testInterleavedEolAndCommentBeforeFirstBlock() {
@ -126,38 +169,11 @@ class TestProg8Parser {
val module = parseModule(SourceCode.of(srcText))
assertEquals(1, module.statements.size)
}
@Test
fun testNewlineBetweenTwoBlocksOrDirectivesStillRequired() {
// issue: #47
// block and block
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
blockA {
} blockB {
}
""")) }
// block and directive
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
blockB {
} %import textio
""")) }
// The following two are bogus due to directive *args* expected to follow the directive name.
// Leaving them in anyways.
// dir and block
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
%import textio blockB {
}
""")) }
assertFailsWith<ParseError>{ parseModule(SourceCode.of("""
%import textio %import syslib
""")) }
}
@Nested
inner class ImportDirectives {
@Test
fun parseModuleShouldNotLookAtImports() {
val importedNoExt = assumeNotExists(fixturesDir, "i_do_not_exist")
@ -167,8 +183,11 @@ class TestProg8Parser {
assertEquals(1, module.statements.size)
}
}
@Nested
inner class EmptySourcecode {
@Test
fun testParseModuleWithEmptyString() {
val module = parseModule(SourceCode.of(""))
@ -181,7 +200,10 @@ class TestProg8Parser {
val module = parseModule(SourceCode.fromPath(path))
assertEquals(0, module.statements.size)
}
}
@Nested
inner class NameOfModule {
@Test
fun testModuleNameForSourceFromString() {
val srcText = """
@ -200,9 +222,19 @@ class TestProg8Parser {
val module = parseModule(SourceCode.fromPath(path))
assertEquals(path.nameWithoutExtension, module.name)
}
}
@Nested
inner class PositionOfAstNodesAndParseErrors {
fun assertPosition(actual: Position, expFile: String? = null, expLine: Int? = null, expStartCol: Int? = null, expEndCol: Int? = null) {
fun assertPosition(
actual: Position,
expFile: String? = null,
expLine: Int? = null,
expStartCol: Int? = null,
expEndCol: Int? = null
) {
require(!listOf(expLine, expStartCol, expEndCol).all { it == null })
if (expLine != null) assertEquals(expLine, actual.line, ".position.line (1-based)")
if (expStartCol != null) assertEquals(expStartCol, actual.startCol, ".position.startCol (0-based)")
@ -210,7 +242,13 @@ class TestProg8Parser {
if (expFile != null) assertEquals(expFile, actual.file, ".position.file")
}
fun assertPosition(actual: Position, expFile: Regex? = null, expLine: Int? = null, expStartCol: Int? = null, expEndCol: Int? = null) {
fun assertPosition(
actual: Position,
expFile: Regex? = null,
expLine: Int? = null,
expStartCol: Int? = null,
expEndCol: Int? = null
) {
require(!listOf(expLine, expStartCol, expEndCol).all { it == null })
if (expLine != null) assertEquals(expLine, actual.line, ".position.line (1-based)")
if (expStartCol != null) assertEquals(expStartCol, actual.startCol, ".position.startCol (0-based)")
@ -219,10 +257,22 @@ class TestProg8Parser {
if (expFile != null) assertContains(actual.file, expFile, ".position.file")
}
fun assertPositionOf(actual: Node, expFile: String? = null, expLine: Int? = null, expStartCol: Int? = null, expEndCol: Int? = null) =
fun assertPositionOf(
actual: Node,
expFile: String? = null,
expLine: Int? = null,
expStartCol: Int? = null,
expEndCol: Int? = null
) =
assertPosition(actual.position, expFile, expLine, expStartCol, expEndCol)
fun assertPositionOf(actual: Node, expFile: Regex? = null, expLine: Int? = null, expStartCol: Int? = null, expEndCol: Int? = null) =
fun assertPositionOf(
actual: Node,
expFile: Regex? = null,
expLine: Int? = null,
expStartCol: Int? = null,
expEndCol: Int? = null
) =
assertPosition(actual.position, expFile, expLine, expStartCol, expEndCol)
@ -282,6 +332,7 @@ class TestProg8Parser {
assertPositionOf(startSub, mpf, 2, 4) // TODO: endCol wrong!
}
/**
* TODO: this test is testing way too much at once
*/
@ -323,6 +374,10 @@ class TestProg8Parser {
assertPositionOf(whenStmt.choices[1], mpf, 8, 12) // TODO: endCol wrong!
assertPositionOf(whenStmt.choices[2], mpf, 9, 12) // TODO: endCol wrong!
}
}
@Nested
inner class CharLiterals {
@Test
fun testCharLitAsArg() {
@ -418,7 +473,10 @@ class TestProg8Parser {
assertEquals('x', rhs.value, "char literal's .value")
assertEquals(true, rhs.altEncoding, "char literal's .altEncoding")
}
}
@Nested
inner class Ranges {
@Test
fun testForloop() {
@ -468,3 +526,5 @@ class TestProg8Parser {
assertIs<NumericLiteralValue>(it4.to, "parser should leave it as is")
}
}
}