mirror of
https://github.com/apple/pkl.git
synced 2026-04-29 19:57:26 +02:00
Initial commit
This commit is contained in:
7
pkl-cli/src/test/files/projects/project1/PklProject
vendored
Normal file
7
pkl-cli/src/test/files/projects/project1/PklProject
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.nio.file.Path
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.cli.CliBaseOptions
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.core.packages.PackageUri
|
||||
|
||||
class CliDownloadPackageCommandTest {
|
||||
companion object {
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
fun beforeAll() {
|
||||
PackageServer.ensureStarted()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download packages`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris =
|
||||
listOf(
|
||||
PackageUri("package://localhost:12110/birds@0.5.0"),
|
||||
PackageUri("package://localhost:12110/fruit@1.0.5"),
|
||||
PackageUri("package://localhost:12110/fruit@1.1.0")
|
||||
),
|
||||
noTranstive = true
|
||||
)
|
||||
cmd.run()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.json")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.0.5/fruit@1.0.5.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.0.5/fruit@1.0.5.json")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.1.0/fruit@1.1.0.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.1.0/fruit@1.1.0.json")).exists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download packages with cache dir set by project`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
evaluatorSettings {
|
||||
moduleCacheDir = ".my-cache"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
workingDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris = listOf(PackageUri("package://localhost:12110/birds@0.5.0")),
|
||||
noTranstive = true
|
||||
)
|
||||
cmd.run()
|
||||
assertThat(tempDir.resolve(".my-cache/package-1/localhost:12110/birds@0.5.0/birds@0.5.0.zip"))
|
||||
.exists()
|
||||
assertThat(tempDir.resolve(".my-cache/package-1/localhost:12110/birds@0.5.0/birds@0.5.0.json"))
|
||||
.exists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download package while specifying checksum`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris =
|
||||
listOf(
|
||||
PackageUri(
|
||||
"package://localhost:12110/birds@0.5.0::sha256:3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
),
|
||||
),
|
||||
noTranstive = true
|
||||
)
|
||||
cmd.run()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.json")).exists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download package with invalid checksum`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris =
|
||||
listOf(
|
||||
PackageUri("package://localhost:12110/birds@0.5.0::sha256:intentionallyBogusChecksum"),
|
||||
),
|
||||
noTranstive = true
|
||||
)
|
||||
assertThatCode { cmd.run() }
|
||||
.hasMessage(
|
||||
"""
|
||||
Cannot download package `package://localhost:12110/birds@0.5.0` because the computed checksum for package metadata does not match the expected checksum.
|
||||
|
||||
Computed checksum: "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
Expected checksum: "intentionallyBogusChecksum"
|
||||
Asset URL: "https://localhost:12110/birds@0.5.0"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `disabling cacheing is an error`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions = CliBaseOptions(workingDir = tempDir, noCache = true),
|
||||
packageUris = listOf(PackageUri("package://localhost:12110/birds@0.5.0")),
|
||||
noTranstive = true
|
||||
)
|
||||
assertThatCode { cmd.run() }
|
||||
.hasMessage("Cannot download packages because no cache directory is specified.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download packages with bad checksum`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris = listOf(PackageUri("package://localhost:12110/badChecksum@1.0.0")),
|
||||
noTranstive = true
|
||||
)
|
||||
assertThatCode { cmd.run() }
|
||||
.hasMessageStartingWith(
|
||||
"Cannot download package `package://localhost:12110/badChecksum@1.0.0` because the computed checksum does not match the expected checksum."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download multiple failing packages`(@TempDir tempDir: Path) {
|
||||
val cmd =
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris =
|
||||
listOf(
|
||||
PackageUri("package://localhost:12110/badChecksum@1.0.0"),
|
||||
PackageUri("package://bogus.domain/notAPackage@1.0.0")
|
||||
),
|
||||
noTranstive = true
|
||||
)
|
||||
assertThatCode { cmd.run() }
|
||||
.hasMessage(
|
||||
"""
|
||||
Failed to download some packages.
|
||||
|
||||
Failed to download package://localhost:12110/badChecksum@1.0.0 because:
|
||||
Cannot download package `package://localhost:12110/badChecksum@1.0.0` because the computed checksum does not match the expected checksum.
|
||||
|
||||
Computed checksum: "0ec8a501e974802d0b71b8d58141e1e6eaa10bc2033e18200be3a978823d98aa"
|
||||
Expected checksum: "intentionally bogus checksum"
|
||||
Asset URL: "https://localhost:12110/badChecksum@1.0.0/badChecksum@1.0.0.zip"
|
||||
|
||||
Failed to download package://bogus.domain/notAPackage@1.0.0 because:
|
||||
Exception when making request `GET https://bogus.domain/notAPackage@1.0.0`:
|
||||
bogus.domain
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download package, including transitive dependencies`(@TempDir tempDir: Path) {
|
||||
CliDownloadPackageCommand(
|
||||
baseOptions =
|
||||
CliBaseOptions(
|
||||
moduleCacheDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
packageUris = listOf(PackageUri("package://localhost:12110/birds@0.5.0")),
|
||||
noTranstive = false
|
||||
)
|
||||
.run()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/birds@0.5.0/birds@0.5.0.json")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.0.5/fruit@1.0.5.zip")).exists()
|
||||
assertThat(tempDir.resolve("package-1/localhost:12110/fruit@1.0.5/fruit@1.0.5.json")).exists()
|
||||
}
|
||||
}
|
||||
1217
pkl-cli/src/test/kotlin/org/pkl/cli/CliEvaluatorTest.kt
Normal file
1217
pkl-cli/src/test/kotlin/org/pkl/cli/CliEvaluatorTest.kt
Normal file
File diff suppressed because it is too large
Load Diff
123
pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt
Normal file
123
pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import com.github.ajalt.clikt.core.BadParameterValue
|
||||
import com.github.ajalt.clikt.core.subcommands
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createDirectory
|
||||
import kotlin.io.path.createSymbolicLinkPointingTo
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.AssertionsForClassTypes.assertThatCode
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.cli.commands.EvalCommand
|
||||
import org.pkl.cli.commands.RootCommand
|
||||
import org.pkl.commons.writeString
|
||||
|
||||
class CliMainTest {
|
||||
|
||||
private val evalCmd = EvalCommand("")
|
||||
private val cmd = RootCommand("pkl", "pkl version 1", "").subcommands(evalCmd)
|
||||
|
||||
@Test
|
||||
fun `duplicate CLI option produces meaningful errror message`(@TempDir tempDir: Path) {
|
||||
val inputFile = tempDir.resolve("test.pkl").writeString("").toString()
|
||||
|
||||
assertThatCode {
|
||||
cmd.parse(arrayOf("eval", "--output-path", "path1", "--output-path", "path2", inputFile))
|
||||
}
|
||||
.hasMessage("Invalid value for \"--output-path\": Option cannot be repeated")
|
||||
|
||||
assertThatCode {
|
||||
cmd.parse(arrayOf("eval", "-o", "path1", "--output-path", "path2", inputFile))
|
||||
}
|
||||
.hasMessage("Invalid value for \"--output-path\": Option cannot be repeated")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `eval requires at least one file`() {
|
||||
assertThatCode { cmd.parse(arrayOf("eval")) }.hasMessage("""Missing argument "<modules>"""")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `output to symlinked directory works`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
x = 3
|
||||
|
||||
output {
|
||||
value = x
|
||||
renderer = new JsonRenderer {}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val inputFile = tempDir.resolve("test.pkl").writeString(code).toString()
|
||||
val outputFile = makeSymdir(tempDir, "out", "linkOut").resolve("test.pkl").toString()
|
||||
|
||||
assertThatCode { cmd.parse(arrayOf("eval", inputFile, "-o", outputFile)) }
|
||||
.doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot have multiple output with -o or -x`(@TempDir tempDir: Path) {
|
||||
val testIn = makeInput(tempDir)
|
||||
val testOut = tempDir.resolve("test").toString()
|
||||
val error =
|
||||
"""Invalid value for "--multiple-file-output-path": Option is mutually exclusive with -o, --output-path and -x, --expression."""
|
||||
|
||||
assertThatCode { cmd.parse(arrayOf("eval", "-m", testOut, "-x", "x", testIn)) }
|
||||
.hasMessage(error)
|
||||
|
||||
assertThatCode { cmd.parse(arrayOf("eval", "-m", testOut, "-o", "/tmp/test", testIn)) }
|
||||
.hasMessage(error)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `showing version works`() {
|
||||
assertThatCode { cmd.parse(arrayOf("--version")) }.hasMessage("pkl version 1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `file paths get parsed into URIs`(@TempDir tempDir: Path) {
|
||||
cmd.parse(arrayOf("eval", makeInput(tempDir, "my file.txt")))
|
||||
|
||||
val modules = evalCmd.baseOptions.baseOptions(evalCmd.modules).normalizedSourceModules
|
||||
assertThat(modules).hasSize(1)
|
||||
assertThat(modules[0].path).endsWith("my file.txt")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid URIs are not accepted`() {
|
||||
val ex = assertThrows<BadParameterValue> { cmd.parse(arrayOf("eval", "file:my file.txt")) }
|
||||
|
||||
assertThat(ex.message).contains("URI `file:my file.txt` has invalid syntax")
|
||||
}
|
||||
|
||||
private fun makeInput(tempDir: Path, fileName: String = "test.pkl"): String {
|
||||
val code = "x = 1"
|
||||
return tempDir.resolve(fileName).writeString(code).toString()
|
||||
}
|
||||
|
||||
private fun makeSymdir(baseDir: Path, name: String, linkName: String): Path {
|
||||
val dir = baseDir.resolve(name)
|
||||
val link = baseDir.resolve(linkName)
|
||||
dir.createDirectory()
|
||||
link.createSymbolicLinkPointingTo(dir)
|
||||
return link
|
||||
}
|
||||
}
|
||||
959
pkl-cli/src/test/kotlin/org/pkl/cli/CliProjectPackagerTest.kt
Normal file
959
pkl-cli/src/test/kotlin/org/pkl/cli/CliProjectPackagerTest.kt
Normal file
@@ -0,0 +1,959 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.io.StringWriter
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.io.path.createDirectories
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.cli.CliBaseOptions
|
||||
import org.pkl.commons.cli.CliException
|
||||
import org.pkl.commons.cli.CliTestOptions
|
||||
import org.pkl.commons.readString
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.runtime.CertificateUtils
|
||||
|
||||
class CliProjectPackagerTest {
|
||||
@Test
|
||||
fun `missing PklProject when inferring a project dir`(@TempDir tempDir: Path) {
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err).hasMessageStartingWith("No project visible to the working directory.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `missing PklProject when explict dir is provided`(@TempDir tempDir: Path) {
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err).hasMessageStartingWith("Directory $tempDir does not contain a PklProject file.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PklProject missing package section`(@TempDir tempDir: Path) {
|
||||
tempDir
|
||||
.resolve("PklProject")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err)
|
||||
.hasMessageStartingWith("No package was declared in project `${tempDir.toUri()}PklProject`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `failing apiTests`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"myTest.pkl",
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["1 == 2"] {
|
||||
1 == 2
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
apiTests { "myTest.pkl" }
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val buffer = StringWriter()
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = buffer
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err).hasMessageContaining("because its API tests are failing")
|
||||
assertThat(buffer.toString()).contains("1 == 2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `passing apiTests`(@TempDir tempDir: Path) {
|
||||
tempDir
|
||||
.resolve("myTest.pkl")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["1 == 1"] {
|
||||
1 == 1
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir
|
||||
.resolve("PklProject")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
apiTests { "myTest.pkl" }
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val buffer = StringWriter()
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = buffer
|
||||
)
|
||||
packager.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `apiTests that import dependencies`(@TempDir tempDir: Path) {
|
||||
val cacheDir = tempDir.resolve("cache")
|
||||
val projectDir = tempDir.resolve("myProject").createDirectories()
|
||||
PackageServer.populateCacheDir(cacheDir)
|
||||
projectDir
|
||||
.resolve("myTest.pkl")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:test"
|
||||
import "@birds/Bird.pkl"
|
||||
|
||||
examples {
|
||||
["Bird"] {
|
||||
new Bird { name = "Finch"; favoriteFruit { name = "Tangerine" } }
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir
|
||||
.resolve("PklProject")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
apiTests { "myTest.pkl" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir
|
||||
.resolve("PklProject.deps.json")
|
||||
.writeString(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.0.5",
|
||||
"checksums": {
|
||||
"sha256": "b4ea243de781feeab7921227591e6584db5d0673340f30fab2ffe8ad5c9f75f5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val buffer = StringWriter()
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = projectDir, moduleCacheDir = cacheDir),
|
||||
listOf(projectDir),
|
||||
CliTestOptions(),
|
||||
".out",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = buffer
|
||||
)
|
||||
packager.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `generate package`(@TempDir tempDir: Path) {
|
||||
val fooPkl =
|
||||
tempDir.writeFile(
|
||||
"a/b/foo.pkl",
|
||||
"""
|
||||
module foo
|
||||
|
||||
name: String
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val fooTxt =
|
||||
tempDir.writeFile(
|
||||
"c/d/foo.txt",
|
||||
"""
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
tempDir
|
||||
.resolve("PklProject")
|
||||
.writeString(
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val packager =
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
packager.run()
|
||||
val expectedMetadata = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0")
|
||||
val expectedMetadataChecksum = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0.sha256")
|
||||
val expectedArchive = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0.zip")
|
||||
val expectedArchiveChecksum = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0.zip.sha256")
|
||||
assertThat(expectedMetadata).exists()
|
||||
assertThat(expectedMetadata)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"name": "mypackage",
|
||||
"packageUri": "package://example.com/mypackage@1.0.0",
|
||||
"version": "1.0.0",
|
||||
"packageZipUrl": "https://foo.com",
|
||||
"packageZipChecksums": {
|
||||
"sha256": "7f515fbc4b229ba171fac78c7c3f2c2e68e2afebae8cfba042b12733943a2813"
|
||||
},
|
||||
"dependencies": {},
|
||||
"authors": []
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(expectedArchive).exists()
|
||||
assertThat(expectedArchive.zipFilePaths())
|
||||
.hasSameElementsAs(listOf("/", "/c", "/c/d", "/c/d/foo.txt", "/a", "/a/b", "/a/b/foo.pkl"))
|
||||
assertThat(expectedMetadataChecksum)
|
||||
.hasContent("203ef387f217a3caee7f19819ef2b50926929269241cb7b3a29d95237b2c7f4b")
|
||||
assertThat(expectedArchiveChecksum)
|
||||
.hasContent("7f515fbc4b229ba171fac78c7c3f2c2e68e2afebae8cfba042b12733943a2813")
|
||||
FileSystems.newFileSystem(URI("jar:" + expectedArchive.toUri()), mutableMapOf<String, String>())
|
||||
.use { fs ->
|
||||
assertThat(fs.getPath("a/b/foo.pkl")).hasSameTextualContentAs(fooPkl)
|
||||
assertThat(fs.getPath("c/d/foo.txt")).hasSameTextualContentAs(fooTxt)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `generate package with excludes`(@TempDir tempDir: Path) {
|
||||
tempDir.apply {
|
||||
writeEmptyFile("a/b/c/d.bin")
|
||||
writeEmptyFile("input/foo/bar.txt")
|
||||
writeEmptyFile("z.bin")
|
||||
writeEmptyFile("main.pkl")
|
||||
writeEmptyFile("main.test.pkl")
|
||||
writeEmptyFile("child/main.pkl")
|
||||
writeEmptyFile("child/main.test.pkl")
|
||||
}
|
||||
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
exclude {
|
||||
"*.bin"
|
||||
"child/main.pkl"
|
||||
"*.test.pkl"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
val expectedArchive = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0.zip")
|
||||
assertThat(expectedArchive.zipFilePaths())
|
||||
.hasSameElementsAs(
|
||||
listOf(
|
||||
"/",
|
||||
"/a",
|
||||
"/a/b",
|
||||
"/a/b/c",
|
||||
"/child",
|
||||
"/input",
|
||||
"/input/foo",
|
||||
"/input/foo/bar.txt",
|
||||
"/main.pkl",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `generate packages with local dependencies`(@TempDir tempDir: Path) {
|
||||
val projectDir = tempDir.resolve("project")
|
||||
val project2Dir = tempDir.resolve("project2")
|
||||
projectDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
["project2"] = import("../project2/PklProject")
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir.writeFile(
|
||||
"PklProject.deps.json",
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/project2@5": {
|
||||
"type": "local",
|
||||
"uri": "projectpackage://localhost:12110/project2@5.0.0",
|
||||
"path": "../project2"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
project2Dir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project2"
|
||||
baseUri = "package://localhost:12110/project2"
|
||||
version = "5.0.0"
|
||||
packageZipUrl = "https://foo.com/project2.zip"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
project2Dir.writeFile(
|
||||
"PklProject.deps.json",
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(projectDir, project2Dir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
val expectedMetadata = tempDir.resolve(".out/mypackage@1.0.0/mypackage@1.0.0")
|
||||
assertThat(expectedMetadata).exists()
|
||||
assertThat(expectedMetadata)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"name": "mypackage",
|
||||
"packageUri": "package://example.com/mypackage@1.0.0",
|
||||
"version": "1.0.0",
|
||||
"packageZipUrl": "https://foo.com",
|
||||
"packageZipChecksums": {
|
||||
"sha256": "7d08a65078e0bfc382c16fe1bb94546ab9a11e6f551087f362a4515ca98102fc"
|
||||
},
|
||||
"dependencies": {
|
||||
"birds": {
|
||||
"uri": "package://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"project2": {
|
||||
"uri": "package://localhost:12110/project2@5.0.0",
|
||||
"checksums": {
|
||||
"sha256": "ddebb806e5b218ebb1a2baa14ad206b46e7a0c1585fa9863a486c75592bc8b16"
|
||||
}
|
||||
}
|
||||
},
|
||||
"authors": []
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val project2Metadata = tempDir.resolve(".out/project2@5.0.0/project2@5.0.0")
|
||||
assertThat(project2Metadata).exists()
|
||||
assertThat(project2Metadata.readString())
|
||||
.isEqualTo(
|
||||
"""
|
||||
{
|
||||
"name": "project2",
|
||||
"packageUri": "package://localhost:12110/project2@5.0.0",
|
||||
"version": "5.0.0",
|
||||
"packageZipUrl": "https://foo.com/project2.zip",
|
||||
"packageZipChecksums": {
|
||||
"sha256": "7d08a65078e0bfc382c16fe1bb94546ab9a11e6f551087f362a4515ca98102fc"
|
||||
},
|
||||
"dependencies": {},
|
||||
"authors": []
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `generate package with local dependencies fails if local dep is not included for packaging`(
|
||||
@TempDir tempDir: Path
|
||||
) {
|
||||
val projectDir = tempDir.resolve("project")
|
||||
val project2Dir = tempDir.resolve("project2")
|
||||
projectDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
["project2"] = import("../project2/PklProject")
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir.writeFile(
|
||||
"PklProject.deps.json",
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/project2@5": {
|
||||
"type": "local",
|
||||
"uri": "projectpackage://localhost:12110/project2@5.0.0",
|
||||
"path": "../project2"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
project2Dir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project2"
|
||||
baseUri = "package://localhost:12110/project2"
|
||||
version = "5.0.0"
|
||||
packageZipUrl = "https://foo.com/project2.zip"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
project2Dir.writeFile(
|
||||
"PklProject.deps.json",
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThatCode {
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(projectDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
.hasMessageContaining("which is not included for packaging")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `import path verification -- relative path outside project dir`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"main.pkl",
|
||||
"""
|
||||
import "../foo.pkl"
|
||||
|
||||
res = foo
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val e =
|
||||
assertThrows<CliException> {
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
assertThat(e.message)
|
||||
.startsWith(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Path `../foo.pkl` includes path segments that are outside the project root directory.
|
||||
|
||||
1 | import "../foo.pkl"
|
||||
^^^^^^^^^^^^
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `import path verification -- absolute import from root dir`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"main.pkl",
|
||||
"""
|
||||
import "$tempDir/foo.pkl"
|
||||
|
||||
res = foo
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val e =
|
||||
assertThrows<CliException> {
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
assertThat(e.message)
|
||||
.startsWith(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Path `$tempDir/foo.pkl` includes path segments that are outside the project root directory.
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `import path verification -- absolute read from root dir`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"main.pkl",
|
||||
"""
|
||||
res = read("$tempDir/foo.pkl")
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val e =
|
||||
assertThrows<CliException> {
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
assertThat(e.message)
|
||||
.startsWith(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Path `$tempDir/foo.pkl` includes path segments that are outside the project root directory.
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `import path verification -- passing`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"foo/bar.pkl",
|
||||
"""
|
||||
import "baz.pkl"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mypackage"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/mypackage"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiple projects`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile("project1/main.pkl", "res = 1")
|
||||
tempDir.writeFile(
|
||||
"project1/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project1"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://example.com/project1"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
tempDir.writeFile("project2/main2.pkl", "res = 2")
|
||||
tempDir.writeFile(
|
||||
"project2/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project2"
|
||||
version = "2.0.0"
|
||||
baseUri = "package://example.com/project2"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val out = StringWriter()
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir.resolve("project1"), tempDir.resolve("project2")),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = true,
|
||||
consoleWriter = out
|
||||
)
|
||||
.run()
|
||||
assertThat(out.toString())
|
||||
.isEqualTo(
|
||||
"""
|
||||
.out/project1@1.0.0/project1@1.0.0.zip
|
||||
.out/project1@1.0.0/project1@1.0.0.zip.sha256
|
||||
.out/project1@1.0.0/project1@1.0.0
|
||||
.out/project1@1.0.0/project1@1.0.0.sha256
|
||||
.out/project2@2.0.0/project2@2.0.0.zip
|
||||
.out/project2@2.0.0/project2@2.0.0.zip.sha256
|
||||
.out/project2@2.0.0/project2@2.0.0
|
||||
.out/project2@2.0.0/project2@2.0.0.sha256
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(tempDir.resolve(".out/project1@1.0.0/project1@1.0.0.zip").zipFilePaths())
|
||||
.hasSameElementsAs(listOf("/", "/main.pkl"))
|
||||
assertThat(tempDir.resolve(".out/project2@2.0.0/project2@2.0.0.zip").zipFilePaths())
|
||||
.hasSameElementsAs(listOf("/", "/main2.pkl"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `publish checks`(@TempDir tempDir: Path) {
|
||||
PackageServer.ensureStarted()
|
||||
CertificateUtils.setupAllX509CertificatesGlobally(listOf(FileTestUtils.selfSignedCertificate))
|
||||
tempDir.writeFile("project/main.pkl", "res = 1")
|
||||
tempDir.writeFile(
|
||||
"project/PklProject",
|
||||
// intentionally conflict with localhost:12110/birds@0.5.0 from our test fixtures
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "birds"
|
||||
version = "0.5.0"
|
||||
baseUri = "package://localhost:12110/birds"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val e =
|
||||
assertThrows<CliException> {
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir.resolve("project")),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = false,
|
||||
consoleWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageStartingWith(
|
||||
"""
|
||||
Package `package://localhost:12110/birds@0.5.0` was already published with different contents.
|
||||
|
||||
Computed checksum: 7324e17214b6dcda63ebfb57d5a29b077af785c13bed0dc22b5138628a3f8d8f
|
||||
Published checksum: 3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `publish check when package is not yet published`(@TempDir tempDir: Path) {
|
||||
PackageServer.ensureStarted()
|
||||
CertificateUtils.setupAllX509CertificatesGlobally(listOf(FileTestUtils.selfSignedCertificate))
|
||||
tempDir.writeFile("project/main.pkl", "res = 1")
|
||||
tempDir.writeFile(
|
||||
"project/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "mangos"
|
||||
version = "1.0.0"
|
||||
baseUri = "package://localhost:12110/mangos"
|
||||
packageZipUrl = "https://foo.com"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val out = StringWriter()
|
||||
CliProjectPackager(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
listOf(tempDir.resolve("project")),
|
||||
CliTestOptions(),
|
||||
".out/%{name}@%{version}",
|
||||
skipPublishCheck = false,
|
||||
consoleWriter = out
|
||||
)
|
||||
.run()
|
||||
assertThat(out.toString())
|
||||
.isEqualTo(
|
||||
"""
|
||||
.out/mangos@1.0.0/mangos@1.0.0.zip
|
||||
.out/mangos@1.0.0/mangos@1.0.0.zip.sha256
|
||||
.out/mangos@1.0.0/mangos@1.0.0
|
||||
.out/mangos@1.0.0/mangos@1.0.0.sha256
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun Path.zipFilePaths(): List<String> {
|
||||
return FileSystems.newFileSystem(URI("jar:${toUri()}"), emptyMap<String, String>()).use { fs ->
|
||||
Files.walk(fs.getPath("/")).map { it.toString() }.collect(Collectors.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
439
pkl-cli/src/test/kotlin/org/pkl/cli/CliProjectResolverTest.kt
Normal file
439
pkl-cli/src/test/kotlin/org/pkl/cli/CliProjectResolverTest.kt
Normal file
@@ -0,0 +1,439 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.io.StringWriter
|
||||
import java.nio.file.Path
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.cli.CliBaseOptions
|
||||
import org.pkl.commons.cli.CliException
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
|
||||
class CliProjectResolverTest {
|
||||
companion object {
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
fun beforeAll() {
|
||||
PackageServer.ensureStarted()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `missing PklProject when inferring a project dir`(@TempDir tempDir: Path) {
|
||||
val packager =
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(workingDir = tempDir),
|
||||
emptyList(),
|
||||
consoleWriter = StringWriter(),
|
||||
errWriter = StringWriter()
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err).hasMessageStartingWith("No project visible to the working directory.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `missing PklProject when explict dir is provided`(@TempDir tempDir: Path) {
|
||||
val packager =
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(),
|
||||
listOf(tempDir),
|
||||
consoleWriter = StringWriter(),
|
||||
errWriter = StringWriter()
|
||||
)
|
||||
val err = assertThrows<CliException> { packager.run() }
|
||||
assertThat(err).hasMessageStartingWith("Directory $tempDir does not contain a PklProject file.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `basic project`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(
|
||||
workingDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
listOf(tempDir),
|
||||
consoleWriter = StringWriter(),
|
||||
errWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
val expectedOutput = tempDir.resolve("PklProject.deps.json")
|
||||
assertThat(expectedOutput)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.0.5",
|
||||
"checksums": {
|
||||
"sha256": "b4ea243de781feeab7921227591e6584db5d0673340f30fab2ffe8ad5c9f75f5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `basic project, inferred from working dir`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(
|
||||
workingDir = tempDir,
|
||||
caCertificates = listOf(FileTestUtils.selfSignedCertificate)
|
||||
),
|
||||
emptyList(),
|
||||
consoleWriter = StringWriter(),
|
||||
errWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
val expectedOutput = tempDir.resolve("PklProject.deps.json")
|
||||
assertThat(expectedOutput)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.0.5",
|
||||
"checksums": {
|
||||
"sha256": "b4ea243de781feeab7921227591e6584db5d0673340f30fab2ffe8ad5c9f75f5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `local dependencies`(@TempDir tempDir: Path) {
|
||||
val projectDir = tempDir.resolve("theproject")
|
||||
projectDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
["project2"] = import("../project2/PklProject")
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir.writeFile(
|
||||
"../project2/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project2"
|
||||
baseUri = "package://localhost:12110/package2"
|
||||
version = "5.0.0"
|
||||
packageZipUrl = "https://foo.com/package2.zip"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
["fruit"] {
|
||||
uri = "package://localhost:12110/fruit@1.0.5"
|
||||
}
|
||||
["project3"] = import("../project3/PklProject")
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
projectDir.writeFile(
|
||||
"../project3/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "project3"
|
||||
baseUri = "package://localhost:12110/package3"
|
||||
version = "5.0.0"
|
||||
packageZipUrl = "https://foo.com/package3.zip"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
["fruit"] {
|
||||
uri = "package://localhost:12110/fruit@1.1.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(caCertificates = listOf(FileTestUtils.selfSignedCertificate)),
|
||||
listOf(projectDir),
|
||||
consoleWriter = StringWriter(),
|
||||
errWriter = StringWriter()
|
||||
)
|
||||
.run()
|
||||
val expectedOutput = projectDir.resolve("PklProject.deps.json")
|
||||
assertThat(expectedOutput)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.1.0",
|
||||
"checksums": {
|
||||
"sha256": "98ad9fc407a79dc3fd5595e7a29c3803ade0a6957c18ec94b8a1624360b24f01"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/package2@5": {
|
||||
"type": "local",
|
||||
"uri": "projectpackage://localhost:12110/package2@5.0.0",
|
||||
"path": "../project2"
|
||||
},
|
||||
"package://localhost:12110/package3@5": {
|
||||
"type": "local",
|
||||
"uri": "projectpackage://localhost:12110/package3@5.0.0",
|
||||
"path": "../project3"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `local dependency overridden by remote dependency`(@TempDir tempDir: Path) {
|
||||
val projectDir = tempDir.resolve("theproject")
|
||||
projectDir.writeFile(
|
||||
"PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
["fruit"] = import("../fruit/PklProject")
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
projectDir.writeFile(
|
||||
"../fruit/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
package {
|
||||
name = "fruit"
|
||||
baseUri = "package://localhost:12110/fruit"
|
||||
version = "1.0.0"
|
||||
packageZipUrl = "https://foo.com/fruit.zip"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val consoleOut = StringWriter()
|
||||
val errOut = StringWriter()
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(caCertificates = listOf(FileTestUtils.selfSignedCertificate)),
|
||||
listOf(projectDir),
|
||||
consoleWriter = consoleOut,
|
||||
errWriter = errOut
|
||||
)
|
||||
.run()
|
||||
val expectedOutput = projectDir.resolve("PklProject.deps.json")
|
||||
assertThat(expectedOutput)
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.0.5",
|
||||
"checksums": {
|
||||
"sha256": "b4ea243de781feeab7921227591e6584db5d0673340f30fab2ffe8ad5c9f75f5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(errOut.toString())
|
||||
.isEqualTo(
|
||||
"WARN: local dependency `package://localhost:12110/fruit@1.0.0` was overridden to remote dependency `package://localhost:12110/fruit@1.0.5`.\n"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolving multiple projects`(@TempDir tempDir: Path) {
|
||||
tempDir.writeFile(
|
||||
"project1/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["birds"] {
|
||||
uri = "package://localhost:12110/birds@0.5.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
tempDir.writeFile(
|
||||
"project2/PklProject",
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
dependencies {
|
||||
["fruit"] {
|
||||
uri = "package://localhost:12110/fruit@1.1.0"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val consoleOut = StringWriter()
|
||||
val errOut = StringWriter()
|
||||
CliProjectResolver(
|
||||
CliBaseOptions(caCertificates = listOf(FileTestUtils.selfSignedCertificate)),
|
||||
listOf(tempDir.resolve("project1"), tempDir.resolve("project2")),
|
||||
consoleWriter = consoleOut,
|
||||
errWriter = errOut
|
||||
)
|
||||
.run()
|
||||
assertThat(consoleOut.toString())
|
||||
.isEqualTo(
|
||||
"""
|
||||
$tempDir/project1/PklProject.deps.json
|
||||
$tempDir/project2/PklProject.deps.json
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(tempDir.resolve("project1/PklProject.deps.json"))
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/birds@0": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/birds@0.5.0",
|
||||
"checksums": {
|
||||
"sha256": "3f19ab9fcee2f44f93a75a09e531db278c6d2cd25206836c8c2c4071cd7d3118"
|
||||
}
|
||||
},
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.0.5",
|
||||
"checksums": {
|
||||
"sha256": "b4ea243de781feeab7921227591e6584db5d0673340f30fab2ffe8ad5c9f75f5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(tempDir.resolve("project2/PklProject.deps.json"))
|
||||
.hasContent(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
"package://localhost:12110/fruit@1": {
|
||||
"type": "remote",
|
||||
"uri": "projectpackage://localhost:12110/fruit@1.1.0",
|
||||
"checksums": {
|
||||
"sha256": "98ad9fc407a79dc3fd5595e7a29c3803ade0a6957c18ec94b8a1624360b24f01"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
208
pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt
Normal file
208
pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt
Normal file
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import com.github.ajalt.clikt.core.MissingArgument
|
||||
import com.github.ajalt.clikt.core.subcommands
|
||||
import java.io.StringWriter
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.cli.commands.EvalCommand
|
||||
import org.pkl.cli.commands.RootCommand
|
||||
import org.pkl.commons.cli.CliBaseOptions
|
||||
import org.pkl.commons.cli.CliException
|
||||
import org.pkl.commons.cli.CliTestOptions
|
||||
import org.pkl.commons.readString
|
||||
import org.pkl.commons.toUri
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.Release
|
||||
|
||||
class CliTestRunnerTest {
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner succeed test`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["succeed"] {
|
||||
8 == 8
|
||||
3 == 3
|
||||
}
|
||||
}
|
||||
"""
|
||||
.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)
|
||||
runner.run()
|
||||
|
||||
assertThat(out.toString().stripFileAndLines(tempDir))
|
||||
.isEqualTo(
|
||||
"""
|
||||
module test
|
||||
succeed ✅
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner fail test`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["fail"] {
|
||||
4 == 9
|
||||
"foo" == "bar"
|
||||
}
|
||||
}
|
||||
"""
|
||||
.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 ❌
|
||||
4 == 9 ❌
|
||||
"foo" == "bar" ❌
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(err.toString()).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner JUnit reports`(@TempDir tempDir: Path) {
|
||||
val code =
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["foo"] {
|
||||
9 == trace(9)
|
||||
"foo" == "foo"
|
||||
}
|
||||
["fail"] {
|
||||
5 == 9
|
||||
}
|
||||
}
|
||||
"""
|
||||
.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="1">
|
||||
<testcase classname="test" name="foo"></testcase>
|
||||
<testcase classname="test" name="fail">
|
||||
<failure message="Fact Failure">5 == 9 ❌</failure>
|
||||
</testcase>
|
||||
<system-err><![CDATA[9 = 9
|
||||
]]></system-err>
|
||||
</testsuite>
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CliTestRunner duplicated JUnit reports`(@TempDir tempDir: Path) {
|
||||
val foo =
|
||||
"""
|
||||
module foo
|
||||
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["foo"] {
|
||||
1 == 1
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
val bar =
|
||||
"""
|
||||
module foo
|
||||
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
["foo"] {
|
||||
1 == 1
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val input = tempDir.resolve("test.pkl").writeString(foo).toString()
|
||||
val input2 = tempDir.resolve("test.pkl").writeString(bar).toString()
|
||||
val opts =
|
||||
CliBaseOptions(
|
||||
sourceModules = listOf(input.toUri(), input2.toUri()),
|
||||
settings = URI("pkl:settings")
|
||||
)
|
||||
val testOpts = CliTestOptions(junitDir = tempDir)
|
||||
val runner = CliTestRunner(opts, testOpts)
|
||||
assertThatCode { runner.run() }.hasMessageContaining("failed")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no source modules specified has same message as pkl eval`() {
|
||||
val e1 = assertThrows<CliException> { CliTestRunner(CliBaseOptions(), CliTestOptions()).run() }
|
||||
val e2 =
|
||||
assertThrows<MissingArgument> {
|
||||
val rootCommand =
|
||||
RootCommand("pkl", Release.current().versionInfo(), "").subcommands(EvalCommand(""))
|
||||
rootCommand.parse(listOf("eval"))
|
||||
}
|
||||
assertThat(e1).hasMessageContaining("Missing argument \"<modules>\"")
|
||||
assertThat(e1.message!!.replace("test", "eval")).isEqualTo(e2.helpMessage())
|
||||
}
|
||||
|
||||
private fun String.stripFileAndLines(tmpDir: Path) =
|
||||
replace(tmpDir.toUri().toString(), "/tempDir/").replace(Regex(""" \(.*, line \d+\)"""), "")
|
||||
}
|
||||
64
pkl-cli/src/test/kotlin/org/pkl/cli/repl/ReplMessagesTest.kt
Normal file
64
pkl-cli/src/test/kotlin/org/pkl/cli/repl/ReplMessagesTest.kt
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli.repl
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.core.Loggers
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.StackFrameTransformers
|
||||
import org.pkl.core.module.ModuleKeyFactories
|
||||
import org.pkl.core.repl.ReplRequest
|
||||
import org.pkl.core.repl.ReplResponse
|
||||
import org.pkl.core.repl.ReplServer
|
||||
|
||||
class ReplMessagesTest {
|
||||
private val server =
|
||||
ReplServer(
|
||||
SecurityManagers.defaultManager,
|
||||
Loggers.stdErr(),
|
||||
listOf(ModuleKeyFactories.standardLibrary),
|
||||
listOf(),
|
||||
mapOf(),
|
||||
mapOf(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"/".toPath(),
|
||||
StackFrameTransformers.defaultTransformer
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `run examples`() {
|
||||
val examples = ReplMessages.examples
|
||||
var startIndex = examples.indexOf("```")
|
||||
while (startIndex != -1) {
|
||||
val endIndex = examples.indexOf("```", startIndex + 3)
|
||||
assertThat(endIndex).isNotEqualTo(-1)
|
||||
val text =
|
||||
examples
|
||||
.substring(startIndex + 3, endIndex)
|
||||
.lines()
|
||||
.filterNot { it.contains(":force") }
|
||||
.joinToString("\n")
|
||||
val responses = server.handleRequest(ReplRequest.Eval("1", text, true, true))
|
||||
assertThat(responses.size).isBetween(1, 9)
|
||||
assertThat(responses).hasOnlyElementsOfType(ReplResponse.EvalSuccess::class.java)
|
||||
startIndex = examples.indexOf("```", endIndex + 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
30
pkl-cli/src/test/kotlin/org/pkl/cli/testExtensions.kt
Normal file
30
pkl-cli/src/test/kotlin/org/pkl/cli/testExtensions.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Path
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.writeString
|
||||
|
||||
fun Path.writeFile(fileName: String, contents: String): Path {
|
||||
return resolve(fileName).apply {
|
||||
createParentDirectories()
|
||||
writeString(contents, StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
||||
fun Path.writeEmptyFile(fileName: String): Path = writeFile(fileName, "")
|
||||
Reference in New Issue
Block a user