mirror of
https://github.com/apple/pkl.git
synced 2026-03-24 01:51:19 +01:00
Typecheck Mapping/Listing members lazily (#628)
This changes how the language performs typechecks for mappings and listings. Currently, Pkl will shallow-force any Mapping and Listing to check it the type parameter (e.g. Listing<Person> means each element is checked to be an instance of Person). This changes the language to check each member's type when the member is accessed. This also adjust test runner to handle thrown errors from within tests. With the change to make mapping/listing typechecks lazy, we can now correctly handle thrown errors from within a single test case. This adjusts the test runner to consider any thrown errors as a failure for that specific test case.
This commit is contained in:
@@ -107,6 +107,140 @@ class CliTestRunnerTest {
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner with thrown error in facts`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["fail"] {
|
||||
throw("uh oh")
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val input = tempDir.resolve("test.pkl").writeString(code).toString()
|
||||
val out = StringWriter()
|
||||
val err = StringWriter()
|
||||
val opts = CliBaseOptions(sourceModules = listOf(input.toUri()), settings = URI("pkl:settings"))
|
||||
val testOpts = CliTestOptions()
|
||||
val runner = CliTestRunner(opts, testOpts, consoleWriter = out, errWriter = err)
|
||||
assertThatCode { runner.run() }.hasMessage("Tests failed.")
|
||||
|
||||
assertThat(out.toString().stripFileAndLines(tempDir))
|
||||
.isEqualToNormalizingNewlines(
|
||||
"""
|
||||
module test
|
||||
fail ❌
|
||||
Error:
|
||||
–– Pkl Error ––
|
||||
uh oh
|
||||
|
||||
5 | throw("uh oh")
|
||||
^^^^^^^^^^^^^^
|
||||
at test#facts["fail"][#1]
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner with thrown error in examples -- no expected output`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
["fail"] {
|
||||
throw("uh oh")
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val input = tempDir.resolve("test.pkl").writeString(code).toString()
|
||||
val out = StringWriter()
|
||||
val err = StringWriter()
|
||||
val opts = CliBaseOptions(sourceModules = listOf(input.toUri()), settings = URI("pkl:settings"))
|
||||
val testOpts = CliTestOptions()
|
||||
val runner = CliTestRunner(opts, testOpts, consoleWriter = out, errWriter = err)
|
||||
assertThatCode { runner.run() }.hasMessage("Tests failed.")
|
||||
|
||||
assertThat(out.toString().stripFileAndLines(tempDir))
|
||||
.isEqualTo(
|
||||
"""
|
||||
module test
|
||||
fail ❌
|
||||
Error:
|
||||
–– Pkl Error ––
|
||||
uh oh
|
||||
|
||||
5 | throw("uh oh")
|
||||
^^^^^^^^^^^^^^
|
||||
at test#examples["fail"][#1]
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner with thrown error in examples -- existing expected output`(
|
||||
@TempDir tempDir: Path
|
||||
) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
["fail"] {
|
||||
throw("uh oh")
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val input = tempDir.resolve("test.pkl").writeString(code).toString()
|
||||
tempDir
|
||||
.resolve("test.pkl-expected.pcf")
|
||||
.writeString(
|
||||
"""
|
||||
examples {
|
||||
["fail"] {
|
||||
"never compared to"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val out = StringWriter()
|
||||
val err = StringWriter()
|
||||
val opts = CliBaseOptions(sourceModules = listOf(input.toUri()), settings = URI("pkl:settings"))
|
||||
val testOpts = CliTestOptions()
|
||||
val runner = CliTestRunner(opts, testOpts, consoleWriter = out, errWriter = err)
|
||||
assertThatCode { runner.run() }.hasMessage("Tests failed.")
|
||||
|
||||
assertThat(out.toString().stripFileAndLines(tempDir))
|
||||
.isEqualToNormalizingNewlines(
|
||||
"""
|
||||
module test
|
||||
fail ❌
|
||||
Error:
|
||||
–– Pkl Error ––
|
||||
uh oh
|
||||
|
||||
5 | throw("uh oh")
|
||||
^^^^^^^^^^^^^^
|
||||
at test#examples["fail"][#1]
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner JUnit reports`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
@@ -149,6 +283,54 @@ class CliTestRunnerTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner JUnit reports, with thrown error`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["foo"] {
|
||||
9 == trace(9)
|
||||
"foo" == "foo"
|
||||
}
|
||||
["fail"] {
|
||||
throw("uh oh")
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val input = tempDir.resolve("test.pkl").writeString(code).toString()
|
||||
val opts = CliBaseOptions(sourceModules = listOf(input.toUri()), settings = URI("pkl:settings"))
|
||||
val testOpts = CliTestOptions(junitDir = tempDir)
|
||||
val runner = CliTestRunner(opts, testOpts)
|
||||
assertThatCode { runner.run() }.hasMessageContaining("failed")
|
||||
|
||||
val junitReport = tempDir.resolve("test.xml").readString().stripFileAndLines(tempDir)
|
||||
assertThat(junitReport)
|
||||
.isEqualTo(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite name="test" tests="2" failures="0">
|
||||
<testcase classname="test" name="foo"></testcase>
|
||||
<testcase classname="test" name="fail">
|
||||
<error message="uh oh">–– Pkl Error ––
|
||||
uh oh
|
||||
|
||||
9 | throw("uh oh")
|
||||
^^^^^^^^^^^^^^
|
||||
at test#facts["fail"][#1]
|
||||
</error>
|
||||
</testcase>
|
||||
<system-err><![CDATA[9 = 9
|
||||
]]></system-err>
|
||||
</testsuite>
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner duplicated JUnit reports`(@TempDir tempDir: Path) {
|
||||
val foo =
|
||||
|
||||
Reference in New Issue
Block a user