From 7e8db16e18bf0899618772f3e28b69bcad752944 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 7 Nov 2021 21:18:18 +0100 Subject: [PATCH] moved to kotest assertions in compilerAst module tests --- compiler/build.gradle | 1 + compiler/compiler.iml | 3 + compilerAst/build.gradle | 2 - compilerAst/compilerAst.iml | 3 +- compilerAst/test/TestProg8Parser.kt | 163 +++++++++++++------------ compilerAst/test/TestSourceCode.kt | 64 +++++----- compilerAst/test/TestSubroutines.kt | 28 ++--- compilerAst/test/helpers/paths.kt | 20 ++- compilerAst/test/helpers_pathsTests.kt | 82 ++++++------- docs/source/todo.rst | 2 - 10 files changed, 194 insertions(+), 174 deletions(-) diff --git a/compiler/build.gradle b/compiler/build.gradle index 228d18773..bc08e979d 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -23,6 +23,7 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-cli:0.3.3' implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:1.1.12" + testImplementation 'io.kotest:kotest-runner-junit5-jvm:4.6.3' testImplementation "org.jetbrains.kotlin:kotlin-test-junit5" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2' testImplementation 'org.hamcrest:hamcrest:2.2' diff --git a/compiler/compiler.iml b/compiler/compiler.iml index 0a11b9cb7..2066e7a02 100644 --- a/compiler/compiler.iml +++ b/compiler/compiler.iml @@ -25,5 +25,8 @@ + + + \ No newline at end of file diff --git a/compilerAst/build.gradle b/compilerAst/build.gradle index 851af1f91..8990a513d 100644 --- a/compilerAst/build.gradle +++ b/compilerAst/build.gradle @@ -16,8 +16,6 @@ dependencies { implementation project(':parser') testImplementation 'io.kotest:kotest-runner-junit5-jvm:4.6.3' - testImplementation "org.jetbrains.kotlin:kotlin-test-junit5" - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2' } configurations.all { diff --git a/compilerAst/compilerAst.iml b/compilerAst/compilerAst.iml index 6d79055c8..3d3c487dc 100644 --- a/compilerAst/compilerAst.iml +++ b/compilerAst/compilerAst.iml @@ -14,7 +14,8 @@ - + + \ No newline at end of file diff --git a/compilerAst/test/TestProg8Parser.kt b/compilerAst/test/TestProg8Parser.kt index fbd0afe8c..8816b4f0e 100644 --- a/compilerAst/test/TestProg8Parser.kt +++ b/compilerAst/test/TestProg8Parser.kt @@ -1,6 +1,13 @@ package prog8tests.ast +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import io.kotest.matchers.string.shouldContain +import io.kotest.matchers.string.shouldStartWith +import io.kotest.matchers.types.instanceOf import prog8.ast.IFunctionCall import prog8.ast.Module import prog8.ast.Node @@ -22,7 +29,6 @@ import kotlin.io.path.Path import kotlin.io.path.isRegularFile import kotlin.io.path.name import kotlin.io.path.nameWithoutExtension -import kotlin.test.* class TestProg8Parser: FunSpec( { @@ -34,14 +40,14 @@ class TestProg8Parser: FunSpec( { // #40: Prog8ANTLRParser would report (throw) "missing at ''" val module = parseModule(src) - assertEquals(1, module.statements.size) + module.statements.size shouldBe 1 } test("is still accepted - #40, fixed by #45") { val nl = "\n" // say, Unix-style (different flavours tested elsewhere) val srcText = "foo {" + nl + "}" + nl // source does end with a newline (issue #40) val module = parseModule(SourceCode.Text(srcText)) - assertEquals(1, module.statements.size) + module.statements.size shouldBe 1 } } @@ -55,21 +61,21 @@ class TestProg8Parser: FunSpec( { // GOOD: 2nd block `bar` does start on a new line; however, a nl at the very end ain't needed val srcGood = "foo {" + nl + "}" + nl + "bar {" + nl + "}" - assertFailsWith { parseModule(SourceCode.Text(srcBad)) } + shouldThrow { parseModule(SourceCode.Text(srcBad)) } val module = parseModule(SourceCode.Text(srcGood)) - assertEquals(2, module.statements.size) + module.statements.size shouldBe 2 } test("is required between two Blocks or Directives - #47") { // block and block - assertFailsWith{ parseModule(SourceCode.Text(""" + shouldThrow{ parseModule(SourceCode.Text(""" blockA { } blockB { } """)) } // block and directive - assertFailsWith{ parseModule(SourceCode.Text(""" + shouldThrow{ parseModule(SourceCode.Text(""" blockB { } %import textio """)) } @@ -78,12 +84,12 @@ class TestProg8Parser: FunSpec( { // Leaving them in anyways. // dir and block - assertFailsWith{ parseModule(SourceCode.Text(""" + shouldThrow{ parseModule(SourceCode.Text(""" %import textio blockB { } """)) } - assertFailsWith{ parseModule(SourceCode.Text(""" + shouldThrow{ parseModule(SourceCode.Text(""" %import textio %import syslib """)) } } @@ -112,7 +118,7 @@ class TestProg8Parser: FunSpec( { nlUnix // end with newline (see testModuleSourceNeedNotEndWithNewline) val module = parseModule(SourceCode.Text(srcText)) - assertEquals(2, module.statements.size) + module.statements.size shouldBe 2 } } @@ -129,7 +135,7 @@ class TestProg8Parser: FunSpec( { } """ val module = parseModule(SourceCode.Text(srcText)) - assertEquals(1, module.statements.size) + module.statements.size shouldBe 1 } test("are ok between blocks - #47") { @@ -145,7 +151,7 @@ class TestProg8Parser: FunSpec( { } """ val module = parseModule(SourceCode.Text(srcText)) - assertEquals(2, module.statements.size) + module.statements.size shouldBe 2 } test("are ok after last block - #47") { @@ -159,7 +165,7 @@ class TestProg8Parser: FunSpec( { """ val module = parseModule(SourceCode.Text(srcText)) - assertEquals(1, module.statements.size) + module.statements.size shouldBe 1 } } @@ -170,20 +176,20 @@ class TestProg8Parser: FunSpec( { val text = "%import ${importedNoExt.name}" val module = parseModule(SourceCode.Text(text)) - assertEquals(1, module.statements.size) + module.statements.size shouldBe 1 } } context("EmptySourcecode") { test("from an empty string should result in empty Module") { val module = parseModule(SourceCode.Text("")) - assertEquals(0, module.statements.size) + module.statements.size shouldBe 0 } test("from an empty file should result in empty Module") { val path = assumeReadableFile(fixturesDir, "empty.p8") val module = parseModule(SourceCode.File(path)) - assertEquals(0, module.statements.size) + module.statements.size shouldBe 0 } } @@ -196,13 +202,13 @@ class TestProg8Parser: FunSpec( { val module = parseModule(SourceCode.Text(srcText)) // Note: assertContains has *actual* as first param - assertContains(module.name, Regex("^$")) + module.name shouldContain Regex("^$") } test("parsed from a file") { val path = assumeReadableFile(fixturesDir, "simple_main.p8") val module = parseModule(SourceCode.File(path)) - assertEquals(path.nameWithoutExtension, module.name) + module.name shouldBe path.nameWithoutExtension } } @@ -216,10 +222,10 @@ class TestProg8Parser: FunSpec( { 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)") - if (expEndCol != null) assertEquals(expEndCol, actual.endCol, ".position.endCol (0-based)") - if (expFile != null) assertEquals(expFile, actual.file, ".position.file") + if (expLine != null) actual.line shouldBe expLine + if (expStartCol != null) actual.startCol shouldBe expStartCol + if (expEndCol != null) actual.endCol shouldBe expEndCol + if (expFile != null) actual.file shouldBe expFile } fun assertPosition( @@ -230,11 +236,10 @@ class TestProg8Parser: FunSpec( { 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)") - if (expEndCol != null) assertEquals(expEndCol, actual.endCol, ".position.endCol (0-based)") - // Note: assertContains expects *actual* value first - if (expFile != null) assertContains(actual.file, expFile, ".position.file") + if (expLine != null) actual.line shouldBe expLine + if (expStartCol != null) actual.startCol shouldBe expStartCol + if (expEndCol != null) actual.endCol shouldBe expEndCol + if (expFile != null) actual.file shouldContain expFile } fun assertPositionOf( @@ -259,14 +264,14 @@ class TestProg8Parser: FunSpec( { test("in ParseError from bad string source code") { val srcText = "bad * { }\n" - val e = assertFailsWith { parseModule(SourceCode.Text(srcText)) } + val e = shouldThrow { parseModule(SourceCode.Text(srcText)) } assertPosition(e.position, Regex("^$"), 1, 4, 4) } test("in ParseError from bad file source code") { val path = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") - val e = assertFailsWith { parseModule(SourceCode.File(path)) } + val e = shouldThrow { parseModule(SourceCode.File(path)) } assertPosition(e.position, SourceCode.relative(path).toString(), 2, 6) } @@ -353,8 +358,8 @@ class TestProg8Parser: FunSpec( { val path = assumeReadableFile(fixturesDir, "simple_main.p8") val module = parseModule(SourceCode.File(path)) assertSomethingForAllNodes(module) { - assertFalse(Path(it.position.file).isAbsolute) - assertTrue(Path(it.position.file).isRegularFile()) + Path(it.position.file).isAbsolute shouldBe false + Path(it.position.file).isRegularFile() shouldBe true } } @@ -371,7 +376,7 @@ class TestProg8Parser: FunSpec( { """.trimIndent() val module = parseModule(SourceCode.Text(srcText)) assertSomethingForAllNodes(module) { - assertTrue(it.position.file.startsWith(SourceCode.stringSourcePrefix)) + it.position.file shouldStartWith SourceCode.stringSourcePrefix } } @@ -380,7 +385,7 @@ class TestProg8Parser: FunSpec( { val resource = SourceCode.Resource("prog8lib/math.p8") val module = parseModule(resource) assertSomethingForAllNodes(module) { - assertTrue(it.position.file.startsWith(SourceCode.libraryFilePrefix)) + it.position.file shouldStartWith SourceCode.libraryFilePrefix } } } @@ -402,9 +407,9 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance()[0] val funCall = startSub.statements.filterIsInstance().first() - assertIs(funCall.args[0]) + funCall.args[0] shouldBe(instanceOf()) val char = funCall.args[0] as CharLiteral - assertEquals('\n', char.value) + char.value shouldBe '\n' } test("on rhs of block-level var decl, no AltEnc") { @@ -419,8 +424,8 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance()[0] val rhs = decl.value as CharLiteral - assertEquals('x', rhs.value, "char literal's .value") - assertEquals(false, rhs.altEncoding, "char literal's .altEncoding") + rhs.value shouldBe 'x' + rhs.altEncoding shouldBe false } test("on rhs of block-level const decl, with AltEnc") { @@ -435,8 +440,8 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance()[0] val rhs = decl.value as CharLiteral - assertEquals('x', rhs.value, "char literal's .value") - assertEquals(true, rhs.altEncoding, "char literal's .altEncoding") + rhs.value shouldBe 'x' + rhs.altEncoding shouldBe true } test("on rhs of subroutine-level var decl, no AltEnc") { @@ -454,8 +459,8 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance()[0] val rhs = decl.value as CharLiteral - assertEquals('x', rhs.value, "char literal's .value") - assertEquals(false, rhs.altEncoding, "char literal's .altEncoding") + rhs.value shouldBe 'x' + rhs.altEncoding shouldBe false } test("on rhs of subroutine-level const decl, with AltEnc") { @@ -473,8 +478,8 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance()[0] val rhs = decl.value as CharLiteral - assertEquals('x', rhs.value, "char literal's .value") - assertEquals(true, rhs.altEncoding, "char literal's .altEncoding") + rhs.value shouldBe 'x' + rhs.altEncoding shouldBe true } } @@ -504,26 +509,26 @@ class TestProg8Parser: FunSpec( { .statements.filterIsInstance() .map { it.iterable } - assertEquals(5, iterables.size) + iterables.size shouldBe 5 val it0 = iterables[0] as RangeExpr - assertIs(it0.from, "parser should leave it as is") - assertIs(it0.to, "parser should leave it as is") + it0.from shouldBe instanceOf() + it0.to shouldBe instanceOf() val it1 = iterables[1] as StringLiteralValue - assertEquals("something", it1.value, "parser should leave it as is") + it1.value shouldBe "something" val it2 = iterables[2] as RangeExpr - assertIs(it2.from, "parser should leave it as is") - assertIs(it2.to, "parser should leave it as is") + it2.from shouldBe instanceOf() + it2.to shouldBe instanceOf() val it3 = iterables[3] as RangeExpr - assertIs(it3.from, "parser should leave it as is") - assertIs(it3.to, "parser should leave it as is") + it3.from shouldBe instanceOf() + it3.to shouldBe instanceOf() val it4 = iterables[4] as RangeExpr - assertIs(it4.from, "parser should leave it as is") - assertIs(it4.to, "parser should leave it as is") + it4.from shouldBe instanceOf() + it4.to shouldBe instanceOf() } } @@ -532,33 +537,33 @@ class TestProg8Parser: FunSpec( { val char2 = CharLiteral('z', true, Position.DUMMY) val program = Program("test", DummyFunctions, DummyMemsizer, AsciiStringEncoder) - assertEquals(65, char1.constValue(program).number.toInt()) - assertEquals(122, char2.constValue(program).number.toInt()) + char1.constValue(program).number.toInt() shouldBe 65 + char2.constValue(program).number.toInt() shouldBe 122 } test("testLiteralValueComparisons") { val ten = NumericLiteralValue(DataType.UWORD, 10, Position.DUMMY) val nine = NumericLiteralValue(DataType.UBYTE, 9, Position.DUMMY) - assertEquals(ten, ten) - assertNotEquals(ten, nine) - assertFalse(ten != ten) - assertTrue(ten != nine) + ten shouldBe ten + nine shouldNotBe ten + (ten != ten) shouldBe false + (ten != nine) shouldBe true - assertTrue(ten > nine) - assertTrue(ten >= nine) - assertTrue(ten >= ten) - assertFalse(ten > ten) + (ten > nine) shouldBe true + (ten >= nine) shouldBe true + (ten >= ten) shouldBe true + (ten > ten) shouldBe false - assertFalse(ten < nine) - assertFalse(ten <= nine) - assertTrue(ten <= ten) - assertFalse(ten < ten) + (ten < nine) shouldBe false + (ten <= nine) shouldBe false + (ten <= ten) shouldBe true + (ten < ten) shouldBe false val abc = StringLiteralValue("abc", false, Position.DUMMY) val abd = StringLiteralValue("abd", false, Position.DUMMY) - assertEquals(abc, abc) - assertTrue(abc!=abd) - assertFalse(abc!=abc) + abc shouldBe abc + (abc!=abd) shouldBe true + (abc!=abc) shouldBe false } test("testAnonScopeStillContainsVarsDirectlyAfterParse") { @@ -576,12 +581,18 @@ class TestProg8Parser: FunSpec( { val mainBlock = module.statements.single() as Block val start = mainBlock.statements.single() as Subroutine val repeatbody = (start.statements.single() as RepeatLoop).body - assertFalse(mainBlock.statements.any { it is VarDecl }, "no vars moved to main block") - assertFalse(start.statements.any { it is VarDecl }, "no vars moved to start sub") - assertTrue(repeatbody.statements[0] is VarDecl, "var is still in repeat block (anonymousscope)") + withClue("no vars moved to main block") { + mainBlock.statements.any { it is VarDecl } shouldBe false + } + withClue("no vars moved to start sub") { + start.statements.any { it is VarDecl } shouldBe false + } + withClue("\"var is still in repeat block (anonymousscope") { + repeatbody.statements[0] shouldBe instanceOf() + } val initvalue = (repeatbody.statements[0] as VarDecl).value as? NumericLiteralValue - assertEquals(99, initvalue?.number?.toInt()) - assertTrue(repeatbody.statements[1] is PostIncrDecr) + initvalue?.number?.toInt() shouldBe 99 + repeatbody.statements[1] shouldBe instanceOf() // the ast processing steps used in the compiler, will eventually move the var up to the containing scope (subroutine). } @@ -612,6 +623,6 @@ class TestProg8Parser: FunSpec( { val mainBlock = module.statements.single() as Block val start = mainBlock.statements.single() as Subroutine val labels = start.statements.filterIsInstance