mirror of
https://github.com/apple/pkl.git
synced 2026-04-22 00:08:33 +02:00
Run spotless apply
This commit is contained in:
@@ -1,26 +1,41 @@
|
||||
/**
|
||||
* 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.core.generator
|
||||
|
||||
import com.oracle.truffle.api.dsl.GeneratedBy
|
||||
import com.squareup.javapoet.ClassName
|
||||
import javax.lang.model.SourceVersion
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import com.squareup.javapoet.MethodSpec
|
||||
import com.squareup.javapoet.JavaFile
|
||||
import com.squareup.javapoet.MethodSpec
|
||||
import com.squareup.javapoet.TypeSpec
|
||||
import javax.annotation.processing.AbstractProcessor
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.SourceVersion
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
/**
|
||||
* Generates a subclass of `org.pkl.core.stdlib.registry.ExternalMemberRegistry`
|
||||
* for each stdlib module and a factory to instantiate them.
|
||||
* Generated classes are written to `generated/truffle/org/pkl/core/stdlib/registry`.
|
||||
*
|
||||
* Generates a subclass of `org.pkl.core.stdlib.registry.ExternalMemberRegistry` for each stdlib
|
||||
* module and a factory to instantiate them. Generated classes are written to
|
||||
* `generated/truffle/org/pkl/core/stdlib/registry`.
|
||||
*
|
||||
* Inputs:
|
||||
* - Generated Truffle node classes for stdlib members.
|
||||
* These classes are located in subpackages of `org.pkl.core.stdlib`
|
||||
* and identified via their `@GeneratedBy` annotations.
|
||||
* - `@PklName` annotations on handwritten node classes from which Truffle node classes are generated.
|
||||
* - Generated Truffle node classes for stdlib members. These classes are located in subpackages of
|
||||
* `org.pkl.core.stdlib` and identified via their `@GeneratedBy` annotations.
|
||||
* - `@PklName` annotations on handwritten node classes from which Truffle node classes are
|
||||
* generated.
|
||||
*/
|
||||
class MemberRegistryGenerator : AbstractProcessor() {
|
||||
private val truffleNodeClassSuffix = "NodeGen"
|
||||
@@ -35,10 +50,8 @@ class MemberRegistryGenerator : AbstractProcessor() {
|
||||
ClassName.get(registryPackageName, "EmptyMemberRegistry")
|
||||
private val memberRegistryFactoryClassName: ClassName =
|
||||
ClassName.get(registryPackageName, "MemberRegistryFactory")
|
||||
private val moduleKeyClassName: ClassName =
|
||||
ClassName.get(modulePackageName, "ModuleKey")
|
||||
private val moduleKeysClassName: ClassName =
|
||||
ClassName.get(modulePackageName, "ModuleKeys")
|
||||
private val moduleKeyClassName: ClassName = ClassName.get(modulePackageName, "ModuleKey")
|
||||
private val moduleKeysClassName: ClassName = ClassName.get(modulePackageName, "ModuleKeys")
|
||||
|
||||
override fun getSupportedAnnotationTypes(): Set<String> = setOf(GeneratedBy::class.java.name)
|
||||
|
||||
@@ -54,19 +67,27 @@ class MemberRegistryGenerator : AbstractProcessor() {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun collectNodeClasses(roundEnv: RoundEnvironment) = roundEnv
|
||||
.getElementsAnnotatedWith(GeneratedBy::class.java)
|
||||
.asSequence()
|
||||
.filterIsInstance<TypeElement>()
|
||||
.filter { it.qualifiedName.toString().startsWith(stdLibPackageName) }
|
||||
.filter { it.simpleName.toString().endsWith(truffleNodeClassSuffix) }
|
||||
.sortedWith(compareBy(
|
||||
{ if (it.enclosingElement.kind == ElementKind.PACKAGE) "" else it.enclosingElement.simpleName.toString() },
|
||||
{ it.simpleName.toString() }
|
||||
))
|
||||
.groupBy { processingEnv.elementUtils.getPackageOf(it) }
|
||||
private fun collectNodeClasses(roundEnv: RoundEnvironment) =
|
||||
roundEnv
|
||||
.getElementsAnnotatedWith(GeneratedBy::class.java)
|
||||
.asSequence()
|
||||
.filterIsInstance<TypeElement>()
|
||||
.filter { it.qualifiedName.toString().startsWith(stdLibPackageName) }
|
||||
.filter { it.simpleName.toString().endsWith(truffleNodeClassSuffix) }
|
||||
.sortedWith(
|
||||
compareBy(
|
||||
{
|
||||
if (it.enclosingElement.kind == ElementKind.PACKAGE) ""
|
||||
else it.enclosingElement.simpleName.toString()
|
||||
},
|
||||
{ it.simpleName.toString() }
|
||||
)
|
||||
)
|
||||
.groupBy { processingEnv.elementUtils.getPackageOf(it) }
|
||||
|
||||
private fun generateRegistryClasses(nodeClassesByPackage: Map<PackageElement, List<TypeElement>>) {
|
||||
private fun generateRegistryClasses(
|
||||
nodeClassesByPackage: Map<PackageElement, List<TypeElement>>
|
||||
) {
|
||||
for ((pkg, nodeClasses) in nodeClassesByPackage) {
|
||||
generateRegistryClass(pkg, nodeClasses)
|
||||
}
|
||||
@@ -75,32 +96,38 @@ class MemberRegistryGenerator : AbstractProcessor() {
|
||||
private fun generateRegistryClass(pkg: PackageElement, nodeClasses: List<TypeElement>) {
|
||||
val pklModuleName = getAnnotatedPklName(pkg) ?: pkg.simpleName.toString()
|
||||
val pklModuleNameCapitalized = pklModuleName.capitalize()
|
||||
val registryClassName = ClassName.get(registryPackageName, "${pklModuleNameCapitalized}MemberRegistry")
|
||||
val registryClassName =
|
||||
ClassName.get(registryPackageName, "${pklModuleNameCapitalized}MemberRegistry")
|
||||
|
||||
val registryClass = TypeSpec.classBuilder(registryClassName)
|
||||
.addJavadoc("Generated by {@link ${this::class.qualifiedName}}.")
|
||||
.addModifiers(Modifier.FINAL)
|
||||
.superclass(externalMemberRegistryClassName)
|
||||
val registryClass =
|
||||
TypeSpec.classBuilder(registryClassName)
|
||||
.addJavadoc("Generated by {@link ${this::class.qualifiedName}}.")
|
||||
.addModifiers(Modifier.FINAL)
|
||||
.superclass(externalMemberRegistryClassName)
|
||||
val registryClassConstructor = MethodSpec.constructorBuilder()
|
||||
|
||||
for (nodeClass in nodeClasses) {
|
||||
val enclosingClass = nodeClass.enclosingElement
|
||||
val pklClassName = getAnnotatedPklName(enclosingClass)
|
||||
?: enclosingClass.simpleName.toString().removeSuffix(truffleNodeFactorySuffix)
|
||||
val pklMemberName = getAnnotatedPklName(nodeClass)
|
||||
?: nodeClass.simpleName.toString().removeSuffix(truffleNodeClassSuffix)
|
||||
val pklMemberNameQualified = when (pklClassName) {
|
||||
// By convention, the top-level class containing node classes
|
||||
// for *module* members is named `<SimpleModuleName>Nodes`.
|
||||
// Example: `BaseNodes` for pkl.base
|
||||
pklModuleNameCapitalized ->
|
||||
"pkl.$pklModuleName#$pklMemberName"
|
||||
else ->
|
||||
"pkl.$pklModuleName#$pklClassName.$pklMemberName"
|
||||
}
|
||||
val pklClassName =
|
||||
getAnnotatedPklName(enclosingClass)
|
||||
?: enclosingClass.simpleName.toString().removeSuffix(truffleNodeFactorySuffix)
|
||||
val pklMemberName =
|
||||
getAnnotatedPklName(nodeClass)
|
||||
?: nodeClass.simpleName.toString().removeSuffix(truffleNodeClassSuffix)
|
||||
val pklMemberNameQualified =
|
||||
when (pklClassName) {
|
||||
// By convention, the top-level class containing node classes
|
||||
// for *module* members is named `<SimpleModuleName>Nodes`.
|
||||
// Example: `BaseNodes` for pkl.base
|
||||
pklModuleNameCapitalized -> "pkl.$pklModuleName#$pklMemberName"
|
||||
else -> "pkl.$pklModuleName#$pklClassName.$pklMemberName"
|
||||
}
|
||||
registryClass.addOriginatingElement(nodeClass)
|
||||
registryClassConstructor
|
||||
.addStatement("register(\$S, \$T::create)", pklMemberNameQualified, nodeClass)
|
||||
registryClassConstructor.addStatement(
|
||||
"register(\$S, \$T::create)",
|
||||
pklMemberNameQualified,
|
||||
nodeClass
|
||||
)
|
||||
}
|
||||
|
||||
registryClass.addMethod(registryClassConstructor.build())
|
||||
@@ -109,25 +136,27 @@ class MemberRegistryGenerator : AbstractProcessor() {
|
||||
}
|
||||
|
||||
private fun generateRegistryFactoryClass(packages: Collection<PackageElement>) {
|
||||
val registryFactoryClass = TypeSpec.classBuilder(memberRegistryFactoryClassName)
|
||||
.addJavadoc("Generated by {@link ${this::class.qualifiedName}}.")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
val registryFactoryConstructor = MethodSpec.constructorBuilder()
|
||||
.addModifiers(Modifier.PRIVATE)
|
||||
val registryFactoryClass =
|
||||
TypeSpec.classBuilder(memberRegistryFactoryClassName)
|
||||
.addJavadoc("Generated by {@link ${this::class.qualifiedName}}.")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
val registryFactoryConstructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE)
|
||||
registryFactoryClass.addMethod(registryFactoryConstructor.build())
|
||||
val registryFactoryGetMethod = MethodSpec.methodBuilder("get")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.addParameter(moduleKeyClassName, "moduleKey")
|
||||
.returns(externalMemberRegistryClassName)
|
||||
.beginControlFlow("if (!\$T.isStdLibModule(moduleKey))", moduleKeysClassName)
|
||||
.addStatement("return \$T.INSTANCE", emptyMemberRegistryClassName)
|
||||
.endControlFlow()
|
||||
.beginControlFlow("switch (moduleKey.getUri().getSchemeSpecificPart())")
|
||||
val registryFactoryGetMethod =
|
||||
MethodSpec.methodBuilder("get")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.addParameter(moduleKeyClassName, "moduleKey")
|
||||
.returns(externalMemberRegistryClassName)
|
||||
.beginControlFlow("if (!\$T.isStdLibModule(moduleKey))", moduleKeysClassName)
|
||||
.addStatement("return \$T.INSTANCE", emptyMemberRegistryClassName)
|
||||
.endControlFlow()
|
||||
.beginControlFlow("switch (moduleKey.getUri().getSchemeSpecificPart())")
|
||||
|
||||
for (pkg in packages) {
|
||||
val pklModuleName = getAnnotatedPklName(pkg) ?: pkg.simpleName.toString()
|
||||
val pklModuleNameCapitalized = pklModuleName.capitalize()
|
||||
val registryClassName = ClassName.get(registryPackageName, "${pklModuleNameCapitalized}MemberRegistry")
|
||||
val registryClassName =
|
||||
ClassName.get(registryPackageName, "${pklModuleNameCapitalized}MemberRegistry")
|
||||
|
||||
// declare dependency on package-info.java (for `@PklName`)
|
||||
registryFactoryClass.addOriginatingElement(pkg)
|
||||
@@ -148,8 +177,7 @@ class MemberRegistryGenerator : AbstractProcessor() {
|
||||
private fun getAnnotatedPklName(element: Element): String? {
|
||||
for (annotation in element.annotationMirrors) {
|
||||
when (annotation.annotationType.asElement().simpleName.toString()) {
|
||||
"PklName" ->
|
||||
return annotation.elementValues.values.iterator().next().value.toString()
|
||||
"PklName" -> return annotation.elementValues.values.iterator().next().value.toString()
|
||||
"GeneratedBy" -> {
|
||||
val annotationValue = annotation.elementValues.values.first().value as TypeMirror
|
||||
return getAnnotatedPklName(processingEnv.typeUtils.asElement(annotationValue))
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -8,9 +23,10 @@ class ClassInheritanceTest {
|
||||
|
||||
@Test
|
||||
fun `property override without type annotation is considered an object property definition`() {
|
||||
val module = evaluator.evaluateSchema(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluateSchema(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
class Thing
|
||||
open class Base {
|
||||
hidden thing: Thing
|
||||
@@ -18,9 +34,10 @@ class ClassInheritanceTest {
|
||||
class Derived extends Base {
|
||||
thing {}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val derivedClass = module.classes["Derived"]!!
|
||||
assertThat(derivedClass.properties["thing"]).isNull()
|
||||
@@ -33,9 +50,10 @@ class ClassInheritanceTest {
|
||||
|
||||
@Test
|
||||
fun `property override with type annotation is considered a class property definition`() {
|
||||
val module = evaluator.evaluateSchema(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluateSchema(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
class Thing
|
||||
open class Base {
|
||||
hidden thing: Thing
|
||||
@@ -43,9 +61,10 @@ class ClassInheritanceTest {
|
||||
class Derived extends Base {
|
||||
thing: Thing = new {}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val derivedClass = module.classes["Derived"]!!
|
||||
val thingProperty = derivedClass.properties["thing"]
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import kotlin.math.nextDown
|
||||
@@ -68,10 +83,9 @@ class DurationTest {
|
||||
assertThat(duration1.convertTo(MILLIS)).isEqualTo(duration2)
|
||||
assertThat(duration2.convertTo(SECONDS)).isEqualTo(duration1)
|
||||
|
||||
assertThat(duration4.convertTo(NANOS))
|
||||
.isEqualTo(Duration(0.0, NANOS))
|
||||
assertThat(duration4.convertTo(NANOS)).isEqualTo(Duration(0.0, NANOS))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun toIsoString() {
|
||||
assertThat(duration1.toIsoString()).isEqualTo("PT0.3S")
|
||||
@@ -79,8 +93,10 @@ class DurationTest {
|
||||
assertThat(duration3.toIsoString()).isEqualTo("PT0.3001S")
|
||||
assertThat(duration4.toIsoString()).isEqualTo("PT0S")
|
||||
assertThat(Duration(1.0, NANOS).toIsoString()).isEqualTo("PT0.000000001S")
|
||||
// Although ISO8601 allows for durations (P) denoted in days, months and years, it is not recommended.
|
||||
// The day notation can express an hour more or less, depending on whether it crosses a daylight savings transition,
|
||||
// Although ISO8601 allows for durations (P) denoted in days, months and years, it is not
|
||||
// recommended.
|
||||
// The day notation can express an hour more or less, depending on whether it crosses a daylight
|
||||
// savings transition,
|
||||
// when added to "now" (at the time of evaluation).
|
||||
assertThat(Duration(100.0, DAYS).toIsoString()).isEqualTo("PT2400H")
|
||||
}
|
||||
@@ -96,165 +112,132 @@ class DurationTest {
|
||||
@Test
|
||||
fun `toJavaDuration() - positive`() {
|
||||
assertThat(Duration(999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(999))
|
||||
assertThat(Duration(999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(999999))
|
||||
assertThat(Duration(999999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(999999999))
|
||||
assertThat(Duration(999999999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
999999999999999.0,
|
||||
NANOS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofNanos(999999999999999))
|
||||
assertThat(Duration(9999999999999999.0, NANOS).toJavaDuration()).isNotEqualTo(
|
||||
java.time.Duration.ofNanos(
|
||||
9999999999999999
|
||||
)
|
||||
)
|
||||
assertThat(Duration(999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(999999))
|
||||
assertThat(Duration(999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(999999999))
|
||||
assertThat(Duration(999999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(999999999999))
|
||||
assertThat(Duration(999999999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(999999999999999))
|
||||
assertThat(Duration(9999999999999999.0, NANOS).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofNanos(9999999999999999))
|
||||
|
||||
assertThat(Duration(999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(999))
|
||||
assertThat(Duration(999999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(999999))
|
||||
assertThat(Duration(999999999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(999999999))
|
||||
assertThat(Duration(999999999999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(999999999999))
|
||||
assertThat(Duration(999999999999999.0, SECONDS).toJavaDuration()).isEqualTo(
|
||||
java.time.Duration.ofSeconds(
|
||||
999999999999999
|
||||
)
|
||||
)
|
||||
assertThat(Duration(9999999999999999.0, SECONDS).toJavaDuration()).isNotEqualTo(
|
||||
java.time.Duration.ofSeconds(
|
||||
9999999999999999
|
||||
)
|
||||
)
|
||||
assertThat(Duration(999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(999))
|
||||
assertThat(Duration(999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(999999))
|
||||
assertThat(Duration(999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(999999999))
|
||||
assertThat(Duration(999999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(999999999999))
|
||||
assertThat(Duration(999999999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(999999999999999))
|
||||
assertThat(Duration(9999999999999999.0, SECONDS).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofSeconds(9999999999999999))
|
||||
|
||||
assertThat(Duration(999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(999))
|
||||
assertThat(Duration(999999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(999999))
|
||||
assertThat(Duration(999999999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(999999999))
|
||||
assertThat(Duration(999999999999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(999999999999))
|
||||
assertThat(Duration(999999999999999.0, MINUTES).toJavaDuration()).isEqualTo(
|
||||
java.time.Duration.ofMinutes(
|
||||
999999999999999
|
||||
)
|
||||
)
|
||||
assertThat(Duration(9999999999999999.0, MINUTES).toJavaDuration()).isNotEqualTo(
|
||||
java.time.Duration.ofMinutes(
|
||||
9999999999999999
|
||||
)
|
||||
)
|
||||
assertThat(Duration(999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(999))
|
||||
assertThat(Duration(999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(999999))
|
||||
assertThat(Duration(999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(999999999))
|
||||
assertThat(Duration(999999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(999999999999))
|
||||
assertThat(Duration(999999999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(999999999999999))
|
||||
assertThat(Duration(9999999999999999.0, MINUTES).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofMinutes(9999999999999999))
|
||||
|
||||
assertThat(Duration(999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(999))
|
||||
assertThat(Duration(999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(999999))
|
||||
assertThat(Duration(999999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(999999999))
|
||||
assertThat(Duration(999999999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
999999999999999.0,
|
||||
HOURS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofHours(999999999999999))
|
||||
assertThat(Duration(999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(999999))
|
||||
assertThat(Duration(999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(999999999))
|
||||
assertThat(Duration(999999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(999999999999))
|
||||
assertThat(Duration(999999999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(999999999999999))
|
||||
assertThrows<ArithmeticException> { Duration(9999999999999999.0, HOURS).toJavaDuration() }
|
||||
|
||||
assertThat(Duration(999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(999))
|
||||
assertThat(Duration(999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(999999))
|
||||
assertThat(Duration(999999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(999999999))
|
||||
assertThat(Duration(999999999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(999999999999))
|
||||
assertThat(Duration(999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(999999))
|
||||
assertThat(Duration(999999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(999999999))
|
||||
assertThat(Duration(999999999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(999999999999))
|
||||
assertThrows<ArithmeticException> { Duration(999999999999999.0, DAYS).toJavaDuration() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toJavaDuration() - negative`() {
|
||||
assertThat(Duration(-999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(-999))
|
||||
assertThat(Duration(-999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(-999999))
|
||||
assertThat(Duration(-999999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(-999999999))
|
||||
assertThat(Duration(-999999999999.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(-999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999999.0,
|
||||
NANOS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofNanos(-999999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-9999999999999999.0,
|
||||
NANOS
|
||||
).toJavaDuration()
|
||||
).isNotEqualTo(java.time.Duration.ofNanos(-9999999999999999))
|
||||
assertThat(Duration(-999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(-999999))
|
||||
assertThat(Duration(-999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(-999999999))
|
||||
assertThat(Duration(-999999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(-999999999999))
|
||||
assertThat(Duration(-999999999999999.0, NANOS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofNanos(-999999999999999))
|
||||
assertThat(Duration(-9999999999999999.0, NANOS).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofNanos(-9999999999999999))
|
||||
|
||||
assertThat(Duration(-999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(-999))
|
||||
assertThat(Duration(-999999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(-999999))
|
||||
assertThat(Duration(-999999999.0, SECONDS).toJavaDuration()).isEqualTo(java.time.Duration.ofSeconds(-999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999.0,
|
||||
SECONDS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofSeconds(-999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999999.0,
|
||||
SECONDS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofSeconds(-999999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-9999999999999999.0,
|
||||
SECONDS
|
||||
).toJavaDuration()
|
||||
).isNotEqualTo(java.time.Duration.ofSeconds(-9999999999999999))
|
||||
assertThat(Duration(-999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(-999))
|
||||
assertThat(Duration(-999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(-999999))
|
||||
assertThat(Duration(-999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(-999999999))
|
||||
assertThat(Duration(-999999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(-999999999999))
|
||||
assertThat(Duration(-999999999999999.0, SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(-999999999999999))
|
||||
assertThat(Duration(-9999999999999999.0, SECONDS).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofSeconds(-9999999999999999))
|
||||
|
||||
assertThat(Duration(-999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(-999))
|
||||
assertThat(Duration(-999999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(-999999))
|
||||
assertThat(Duration(-999999999.0, MINUTES).toJavaDuration()).isEqualTo(java.time.Duration.ofMinutes(-999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999.0,
|
||||
MINUTES
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofMinutes(-999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999999.0,
|
||||
MINUTES
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofMinutes(-999999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-9999999999999999.0,
|
||||
MINUTES
|
||||
).toJavaDuration()
|
||||
).isNotEqualTo(java.time.Duration.ofMinutes(-9999999999999999))
|
||||
assertThat(Duration(-999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(-999))
|
||||
assertThat(Duration(-999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(-999999))
|
||||
assertThat(Duration(-999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(-999999999))
|
||||
assertThat(Duration(-999999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(-999999999999))
|
||||
assertThat(Duration(-999999999999999.0, MINUTES).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofMinutes(-999999999999999))
|
||||
assertThat(Duration(-9999999999999999.0, MINUTES).toJavaDuration())
|
||||
.isNotEqualTo(java.time.Duration.ofMinutes(-9999999999999999))
|
||||
|
||||
assertThat(Duration(-999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(-999))
|
||||
assertThat(Duration(-999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(-999999))
|
||||
assertThat(Duration(-999999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(-999999999))
|
||||
assertThat(Duration(-999999999999.0, HOURS).toJavaDuration()).isEqualTo(java.time.Duration.ofHours(-999999999999))
|
||||
assertThat(
|
||||
Duration(
|
||||
-999999999999999.0,
|
||||
HOURS
|
||||
).toJavaDuration()
|
||||
).isEqualTo(java.time.Duration.ofHours(-999999999999999))
|
||||
assertThat(Duration(-999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(-999999))
|
||||
assertThat(Duration(-999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(-999999999))
|
||||
assertThat(Duration(-999999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(-999999999999))
|
||||
assertThat(Duration(-999999999999999.0, HOURS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofHours(-999999999999999))
|
||||
assertThrows<ArithmeticException> { Duration(-9999999999999999.0, HOURS).toJavaDuration() }
|
||||
|
||||
assertThat(Duration(-999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(-999))
|
||||
assertThat(Duration(-999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(-999999))
|
||||
assertThat(Duration(-999999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(-999999999))
|
||||
assertThat(Duration(-999999999999.0, DAYS).toJavaDuration()).isEqualTo(java.time.Duration.ofDays(-999999999999))
|
||||
assertThat(Duration(-999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(-999999))
|
||||
assertThat(Duration(-999999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(-999999999))
|
||||
assertThat(Duration(-999999999999.0, DAYS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofDays(-999999999999))
|
||||
assertThrows<ArithmeticException> { Duration(-999999999999999.0, DAYS).toJavaDuration() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toJavaDuration() - edge cases`() {
|
||||
assertThat(Duration(0.0, NANOS).toJavaDuration()).isEqualTo(java.time.Duration.ofNanos(0))
|
||||
assertThat(Duration(Long.MAX_VALUE.toDouble(), SECONDS).toJavaDuration()).isEqualTo(
|
||||
java.time.Duration.ofSeconds(
|
||||
Long.MAX_VALUE
|
||||
)
|
||||
)
|
||||
assertThat(Duration(Long.MIN_VALUE.toDouble(), SECONDS).toJavaDuration()).isEqualTo(
|
||||
java.time.Duration.ofSeconds(
|
||||
Long.MIN_VALUE
|
||||
)
|
||||
)
|
||||
assertThat(Duration(Long.MAX_VALUE.toDouble(), SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(Long.MAX_VALUE))
|
||||
assertThat(Duration(Long.MIN_VALUE.toDouble(), SECONDS).toJavaDuration())
|
||||
.isEqualTo(java.time.Duration.ofSeconds(Long.MIN_VALUE))
|
||||
|
||||
val justTooLarge = Duration(Long.MAX_VALUE.toDouble().nextUp(), SECONDS)
|
||||
assertThrows<ArithmeticException> { justTooLarge.toJavaDuration() }
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.time.temporal.ChronoUnit
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -5,19 +20,21 @@ import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
|
||||
class DynamicTest {
|
||||
private fun brokenInput(value: String): String = """
|
||||
private fun brokenInput(value: String): String =
|
||||
"""
|
||||
class Person { name: String; age: Int }
|
||||
|
||||
person: Person = new { name = 42; age = "Pigeon" } // oops
|
||||
|
||||
output { value = $value }
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
@Test
|
||||
fun `property access respects type`() {
|
||||
// Does not involve Dynamic, but is a baseline for the other cases.
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
assertThrows<PklException> {
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluateOutputText(ModuleSource.text(brokenInput("person.name")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -18,33 +33,41 @@ class ErrorColoringTest {
|
||||
private fun evaluate(program: String, expression: String): Any {
|
||||
return evaluator.evaluateExpression(ModuleSource.text(program), expression)
|
||||
}
|
||||
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
// Enable colouring before each test
|
||||
Ansi.setEnabled(true)
|
||||
}
|
||||
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
// Disable colouring after each test
|
||||
Ansi.setEnabled(false)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `simple error`() {
|
||||
val error = assertThrows<PklException> { evaluate("bar = 2", "bar = 15") }
|
||||
|
||||
assertThat(error).message()
|
||||
assertThat(error)
|
||||
.message()
|
||||
.contains("\u001B[31m–– Pkl Error ––\u001B[m")
|
||||
.contains("\u001B[94m1 | \u001B[m")
|
||||
.contains("\u001B[0;31m^")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `repeated error`() {
|
||||
val error = assertThrows<PklException> { evaluate("""self: String = "Strings; if they were lazy, you could tie the knot on \(self.take(7))"""", "self") }
|
||||
assertThat(error).message()
|
||||
val error =
|
||||
assertThrows<PklException> {
|
||||
evaluate(
|
||||
"""self: String = "Strings; if they were lazy, you could tie the knot on \(self.take(7))"""",
|
||||
"self"
|
||||
)
|
||||
}
|
||||
assertThat(error)
|
||||
.message()
|
||||
.contains("[91mA stack overflow occurred.[m")
|
||||
.contains("[93m┌─ [0;1;35m")
|
||||
.contains("[m repetitions of:")
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -22,13 +37,15 @@ class EvaluateExpressionTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate expression`() {
|
||||
val program = """
|
||||
val program =
|
||||
"""
|
||||
res1 = 1
|
||||
res2 {
|
||||
res3 = 3
|
||||
res4 = 4
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
assertThat(evaluate(program, "res1")).isEqualTo(1L)
|
||||
val res2 = evaluate(program, "res2")
|
||||
assertThat(res2).isInstanceOf(PObject::class.java)
|
||||
@@ -39,18 +56,25 @@ class EvaluateExpressionTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate subpath`() {
|
||||
val resp = evaluate("""
|
||||
val resp =
|
||||
evaluate(
|
||||
"""
|
||||
foo {
|
||||
bar = 2
|
||||
}
|
||||
""".trimIndent(), "foo.bar")
|
||||
"""
|
||||
.trimIndent(),
|
||||
"foo.bar"
|
||||
)
|
||||
|
||||
assertThat(resp).isEqualTo(2L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluate output text`() {
|
||||
val result = evaluate("""
|
||||
val result =
|
||||
evaluate(
|
||||
"""
|
||||
foo {
|
||||
bar = 2
|
||||
}
|
||||
@@ -58,13 +82,20 @@ class EvaluateExpressionTest {
|
||||
output {
|
||||
renderer = new YamlRenderer {}
|
||||
}
|
||||
""".trimIndent(), "output.text")
|
||||
"""
|
||||
.trimIndent(),
|
||||
"output.text"
|
||||
)
|
||||
|
||||
assertThat(result).isEqualTo("""
|
||||
assertThat(result)
|
||||
.isEqualTo(
|
||||
"""
|
||||
foo:
|
||||
bar: 2
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,10 +107,7 @@ class EvaluateExpressionTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate import expression`() {
|
||||
val result = evaluate(
|
||||
"",
|
||||
"""import("pkl:release").current.documentation.homepage"""
|
||||
)
|
||||
val result = evaluate("", """import("pkl:release").current.documentation.homepage""")
|
||||
|
||||
assertThat(result as String).startsWith("https://pkl-lang.org/")
|
||||
}
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.pkl.core.ModuleSource.text
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.core.ModuleSource.text
|
||||
|
||||
class EvaluateMultipleFileOutputTest {
|
||||
|
||||
@@ -11,7 +26,8 @@ class EvaluateMultipleFileOutputTest {
|
||||
|
||||
@Test
|
||||
fun `output files`() {
|
||||
val program = """
|
||||
val program =
|
||||
"""
|
||||
output {
|
||||
files {
|
||||
["foo.yml"] {
|
||||
@@ -28,14 +44,10 @@ class EvaluateMultipleFileOutputTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
val output = evaluator.evaluateOutputFiles(text(program))
|
||||
assertThat(output.keys).isEqualTo(setOf(
|
||||
"foo.yml",
|
||||
"bar.yml",
|
||||
"bar/biz.yml",
|
||||
"bar/../bark.yml"
|
||||
))
|
||||
assertThat(output.keys).isEqualTo(setOf("foo.yml", "bar.yml", "bar/biz.yml", "bar/../bark.yml"))
|
||||
assertThat(output["foo.yml"]?.text).isEqualTo("foo: foo text")
|
||||
assertThat(output["bar.yml"]?.text).isEqualTo("bar: bar text")
|
||||
assertThat(output["bar/biz.yml"]?.text).isEqualTo("biz: bar biz")
|
||||
@@ -45,7 +57,8 @@ class EvaluateMultipleFileOutputTest {
|
||||
@Test
|
||||
fun `using a renderer`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val program = """
|
||||
val program =
|
||||
"""
|
||||
output {
|
||||
files {
|
||||
["foo.json"] {
|
||||
@@ -57,21 +70,27 @@ class EvaluateMultipleFileOutputTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
val output = evaluator.evaluateOutputFiles(text(program))
|
||||
assertThat(output["foo.json"]?.text).isEqualTo("""
|
||||
assertThat(output["foo.json"]?.text)
|
||||
.isEqualTo(
|
||||
"""
|
||||
{
|
||||
"foo": "fooey",
|
||||
"bar": "barrey"
|
||||
}
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reading files after the evaluator is closed`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val program = """
|
||||
val program =
|
||||
"""
|
||||
output {
|
||||
files {
|
||||
["foo.json"] {
|
||||
@@ -83,7 +102,8 @@ class EvaluateMultipleFileOutputTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
val output = evaluator.evaluateOutputFiles(text(program))
|
||||
evaluator.close()
|
||||
assertThrows<PklException> { output["foo.json"]!!.text }
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.pkl.core.util.IoUtils
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.util.IoUtils
|
||||
|
||||
// tests language-internal renderers
|
||||
// uses same input/output files as Pcf/Json/Yaml/PListRendererTest
|
||||
@@ -28,13 +43,10 @@ class EvaluateOutputTextTest {
|
||||
}
|
||||
|
||||
private fun checkRenderedOutput(format: OutputFormat) {
|
||||
val evaluator = EvaluatorBuilder.preconfigured()
|
||||
.setOutputFormat(format)
|
||||
.build()
|
||||
val evaluator = EvaluatorBuilder.preconfigured().setOutputFormat(format).build()
|
||||
|
||||
val output = evaluator.evaluateOutputText(
|
||||
ModuleSource.modulePath("org/pkl/core/rendererTest.pkl")
|
||||
)
|
||||
val output =
|
||||
evaluator.evaluateOutputText(ModuleSource.modulePath("org/pkl/core/rendererTest.pkl"))
|
||||
val expected = IoUtils.readClassPathResourceAsString(javaClass, "rendererTest.$format")
|
||||
|
||||
assertThat(output.trim()).isEqualTo(expected.trim())
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.pkl.core.ModuleSource.*
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.ModuleSource.*
|
||||
import org.pkl.core.runtime.BaseModule
|
||||
|
||||
class EvaluateSchemaTest {
|
||||
@@ -17,9 +32,7 @@ class EvaluateSchemaTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate test schema`() {
|
||||
val module = evaluator.evaluateSchema(
|
||||
modulePath("org/pkl/core/EvaluateSchemaTest.pkl")
|
||||
)
|
||||
val module = evaluator.evaluateSchema(modulePath("org/pkl/core/EvaluateSchemaTest.pkl"))
|
||||
|
||||
checkModuleMetadata(module)
|
||||
|
||||
@@ -35,28 +48,27 @@ class EvaluateSchemaTest {
|
||||
@Test
|
||||
fun `evaluate pkl_base schema`() {
|
||||
val module = evaluator.evaluateSchema(uri(URI("pkl:base")))
|
||||
assertThat(module.moduleClass.superclass)
|
||||
.isEqualTo(BaseModule.getModuleClass().export())
|
||||
assertThat(module.moduleClass.superclass).isEqualTo(BaseModule.getModuleClass().export())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `does not export local classes`() {
|
||||
val module = evaluator.evaluateSchema(
|
||||
text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluateSchema(
|
||||
text(
|
||||
"""
|
||||
class Foo {}
|
||||
local class Baz {}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(module.classes.keys)
|
||||
.containsExactly("Foo")
|
||||
assertThat(module.classes.keys).containsExactly("Foo")
|
||||
}
|
||||
|
||||
private fun checkModuleMetadata(module: ModuleSchema) {
|
||||
assertThat(module.moduleUri)
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/EvaluateSchemaTest.pkl"))
|
||||
assertThat(module.moduleUri).isEqualTo(URI("modulepath:/org/pkl/core/EvaluateSchemaTest.pkl"))
|
||||
|
||||
assertThat(module.moduleName).isEqualTo("test")
|
||||
|
||||
@@ -79,9 +91,8 @@ class EvaluateSchemaTest {
|
||||
val paramType = propertyb2.type
|
||||
assertThat(paramType).isInstanceOf(PType.Class::class.java)
|
||||
paramType as PType.Class
|
||||
assertThat(paramType.pClass)
|
||||
.isEqualTo(BaseModule.getIntClass().export())
|
||||
|
||||
assertThat(paramType.pClass).isEqualTo(BaseModule.getIntClass().export())
|
||||
|
||||
val propertyb3 = properties.getValue("propertyb3")
|
||||
assertThat(propertyb3.sourceLocation.startLine).isEqualTo(24)
|
||||
assertThat(propertyb3.sourceLocation.endLine).isEqualTo(24)
|
||||
@@ -106,10 +117,8 @@ class EvaluateSchemaTest {
|
||||
val paramBaseType = paramType.baseType
|
||||
assertThat(paramBaseType).isInstanceOf(PType.Class::class.java)
|
||||
paramBaseType as PType.Class
|
||||
assertThat(paramBaseType.pClass)
|
||||
.isEqualTo(BaseModule.getStringClass().export())
|
||||
assertThat(paramType.constraints)
|
||||
.isEqualTo(listOf("!isEmpty", "startsWith(\"a\")"))
|
||||
assertThat(paramBaseType.pClass).isEqualTo(BaseModule.getStringClass().export())
|
||||
assertThat(paramType.constraints).isEqualTo(listOf("!isEmpty", "startsWith(\"a\")"))
|
||||
|
||||
val returnType = methodb2.returnType
|
||||
assertThat(returnType).isInstanceOf(PType.Constrained::class.java)
|
||||
@@ -119,7 +128,7 @@ class EvaluateSchemaTest {
|
||||
returnBaseType as PType.Class
|
||||
assertThat(returnBaseType.pClass).isEqualTo(BaseModule.getIntClass().export())
|
||||
assertThat(returnType.constraints).isEqualTo(listOf("isPositive"))
|
||||
|
||||
|
||||
val methodb3 = methods.getValue("methodb3")
|
||||
assertThat(methodb3.sourceLocation.startLine).isEqualTo(26)
|
||||
assertThat(methodb3.sourceLocation.endLine).isEqualTo(26)
|
||||
@@ -141,10 +150,8 @@ class EvaluateSchemaTest {
|
||||
assertThat(supermodule).isNotNull
|
||||
assertThat(supermodule!!.supermodule).isNull()
|
||||
|
||||
assertThat(module.moduleClass.superclass)
|
||||
.isEqualTo(supermodule.moduleClass)
|
||||
assertThat(supermodule.moduleClass.superclass)
|
||||
.isEqualTo(BaseModule.getModuleClass().export())
|
||||
assertThat(module.moduleClass.superclass).isEqualTo(supermodule.moduleClass)
|
||||
assertThat(supermodule.moduleClass.superclass).isEqualTo(BaseModule.getModuleClass().export())
|
||||
|
||||
assertThat(supermodule.moduleUri)
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/EvaluateSchemaTestBaseModule.pkl"))
|
||||
|
||||
@@ -1,15 +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.core
|
||||
|
||||
import org.pkl.commons.createTempFile
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.createTempFile
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.ModuleSource.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
|
||||
class EvaluateTestsTest {
|
||||
|
||||
@@ -17,7 +32,10 @@ class EvaluateTestsTest {
|
||||
|
||||
@Test
|
||||
fun `test successful module`() {
|
||||
val results = evaluator.evaluateTest(text("""
|
||||
val results =
|
||||
evaluator.evaluateTest(
|
||||
text(
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
@@ -26,7 +44,11 @@ class EvaluateTestsTest {
|
||||
"foo" == "foo"
|
||||
}
|
||||
}
|
||||
""".trimIndent()), true)
|
||||
"""
|
||||
.trimIndent()
|
||||
),
|
||||
true
|
||||
)
|
||||
|
||||
assertThat(results.moduleName).isEqualTo("text")
|
||||
assertThat(results.displayUri).isEqualTo("repl:text")
|
||||
@@ -38,9 +60,10 @@ class EvaluateTestsTest {
|
||||
|
||||
@Test
|
||||
fun `test module failure`() {
|
||||
val results = evaluator.evaluateTest(
|
||||
text(
|
||||
"""
|
||||
val results =
|
||||
evaluator.evaluateTest(
|
||||
text(
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
@@ -49,19 +72,20 @@ class EvaluateTestsTest {
|
||||
"foo" == "bar"
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
),
|
||||
true
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
),
|
||||
true
|
||||
)
|
||||
|
||||
assertThat(results.totalTests()).isEqualTo(1)
|
||||
assertThat(results.totalFailures()).isEqualTo(2)
|
||||
assertThat(results.failed()).isTrue
|
||||
|
||||
|
||||
val res = results.results[0]
|
||||
assertThat(res.name).isEqualTo("should fail")
|
||||
assertThat(res.errors).isEmpty()
|
||||
|
||||
|
||||
val fail1 = res.failures[0]
|
||||
assertThat(fail1.rendered).isEqualTo("1 == 2 ❌ (repl:text)")
|
||||
|
||||
@@ -71,9 +95,10 @@ class EvaluateTestsTest {
|
||||
|
||||
@Test
|
||||
fun `test module error`() {
|
||||
val results = evaluator.evaluateTest(
|
||||
text(
|
||||
"""
|
||||
val results =
|
||||
evaluator.evaluateTest(
|
||||
text(
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
facts {
|
||||
@@ -82,10 +107,11 @@ class EvaluateTestsTest {
|
||||
throw("got an error")
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
),
|
||||
true
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
),
|
||||
true
|
||||
)
|
||||
|
||||
assertThat(results.totalTests()).isEqualTo(1)
|
||||
assertThat(results.totalFailures()).isEqualTo(0)
|
||||
@@ -95,10 +121,12 @@ class EvaluateTestsTest {
|
||||
assertThat(res.name).isEqualTo("text")
|
||||
assertThat(res.failures).isEmpty()
|
||||
assertThat(res.errors.size).isEqualTo(1)
|
||||
|
||||
|
||||
val error = res.errors[0]
|
||||
assertThat(error.message).isEqualTo("got an error")
|
||||
assertThat(error.exception.message).isEqualTo("""
|
||||
assertThat(error.exception.message)
|
||||
.isEqualTo(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
got an error
|
||||
|
||||
@@ -110,13 +138,17 @@ class EvaluateTestsTest {
|
||||
^^^^^^^
|
||||
at text#facts (repl:text)
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `test successful example`(@TempDir tempDir: Path) {
|
||||
val file = tempDir.createTempFile(prefix = "example", suffix = ".pkl")
|
||||
Files.writeString(file, """
|
||||
Files.writeString(
|
||||
file,
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
@@ -127,9 +159,13 @@ class EvaluateTestsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
|
||||
Files.writeString(createExpected(file), """
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
Files.writeString(
|
||||
createExpected(file),
|
||||
"""
|
||||
examples {
|
||||
["user"] {
|
||||
new {
|
||||
@@ -138,7 +174,9 @@ class EvaluateTestsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val results = evaluator.evaluateTest(path(file), false)
|
||||
assertThat(results.moduleName).startsWith("example")
|
||||
@@ -151,7 +189,9 @@ class EvaluateTestsTest {
|
||||
@Test
|
||||
fun `test example failure`(@TempDir tempDir: Path) {
|
||||
val file = tempDir.createTempFile(prefix = "example", suffix = ".pkl")
|
||||
Files.writeString(file, """
|
||||
Files.writeString(
|
||||
file,
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
@@ -162,9 +202,13 @@ class EvaluateTestsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
Files.writeString(createExpected(file), """
|
||||
Files.writeString(
|
||||
createExpected(file),
|
||||
"""
|
||||
examples {
|
||||
["user"] {
|
||||
new {
|
||||
@@ -173,7 +217,9 @@ class EvaluateTestsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val results = evaluator.evaluateTest(path(file), false)
|
||||
assertThat(results.moduleName).startsWith("example")
|
||||
@@ -187,7 +233,9 @@ class EvaluateTestsTest {
|
||||
assertThat(res.errors.isEmpty()).isTrue
|
||||
|
||||
val fail1 = res.failures[0]
|
||||
assertThat(fail1.rendered.stripFileAndLines(tempDir)).isEqualTo("""
|
||||
assertThat(fail1.rendered.stripFileAndLines(tempDir))
|
||||
.isEqualTo(
|
||||
"""
|
||||
(/tempDir/example.pkl)
|
||||
Expected: (/tempDir/example.pkl-expected.pcf)
|
||||
new {
|
||||
@@ -199,13 +247,17 @@ class EvaluateTestsTest {
|
||||
name = "Bob"
|
||||
age = 33
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `written examples use custom string delimiters`(@TempDir tempDir: Path) {
|
||||
val file = tempDir.createTempFile(prefix = "example", suffix = ".pkl")
|
||||
Files.writeString(file, """
|
||||
Files.writeString(
|
||||
file,
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
@@ -213,25 +265,33 @@ class EvaluateTestsTest {
|
||||
"my \"string\""
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
evaluator.evaluateTest(path(file), false)
|
||||
val expectedFile = file.parent.resolve(file.fileName.toString() + "-expected.pcf")
|
||||
assertThat(expectedFile).exists()
|
||||
assertThat(expectedFile).hasContent("""
|
||||
assertThat(expectedFile)
|
||||
.hasContent(
|
||||
"""
|
||||
examples {
|
||||
["myStr"] {
|
||||
#"my "string""#
|
||||
}
|
||||
}
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
// test for backwards compatibility
|
||||
@Test
|
||||
fun `examples that don't use custom string delimiters still pass`(@TempDir tempDir: Path) {
|
||||
val file = tempDir.createTempFile(prefix = "example", suffix = ".pkl")
|
||||
Files.writeString(file, """
|
||||
Files.writeString(
|
||||
file,
|
||||
"""
|
||||
amends "pkl:test"
|
||||
|
||||
examples {
|
||||
@@ -239,25 +299,28 @@ class EvaluateTestsTest {
|
||||
"my \"string\""
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
createExpected(file).writeString("""
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
createExpected(file)
|
||||
.writeString(
|
||||
"""
|
||||
examples {
|
||||
["myStr"] {
|
||||
"my \"string\""
|
||||
}
|
||||
}
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val result = evaluator.evaluateTest(path(file), false)
|
||||
assertFalse(result.failed())
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun createExpected(path: Path): Path {
|
||||
return path
|
||||
.parent
|
||||
.resolve(path.fileName.toString() + "-expected.pcf")
|
||||
.createFile()
|
||||
return path.parent.resolve(path.fileName.toString() + "-expected.pcf").createFile()
|
||||
}
|
||||
|
||||
private fun String.stripFileAndLines(tmpDir: Path) =
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.nio.file.Path
|
||||
import java.time.Duration
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.core.project.Project
|
||||
import java.nio.file.Path
|
||||
import java.time.Duration
|
||||
|
||||
class EvaluatorBuilderTest {
|
||||
@Test
|
||||
@@ -34,40 +49,32 @@ class EvaluatorBuilderTest {
|
||||
|
||||
@Test
|
||||
fun `enforces that security manager is set`() {
|
||||
val e1 = assertThrows<IllegalStateException> {
|
||||
EvaluatorBuilder.unconfigured()
|
||||
.setStackFrameTransformer(StackFrameTransformers.empty)
|
||||
.build()
|
||||
}
|
||||
val e1 =
|
||||
assertThrows<IllegalStateException> {
|
||||
EvaluatorBuilder.unconfigured()
|
||||
.setStackFrameTransformer(StackFrameTransformers.empty)
|
||||
.build()
|
||||
}
|
||||
assertThat(e1).hasMessage("No security manager set.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `enforces that stack frame transformer is set`() {
|
||||
val e1 = assertThrows<IllegalStateException> {
|
||||
EvaluatorBuilder.unconfigured()
|
||||
.setSecurityManager(SecurityManagers.defaultManager)
|
||||
.build()
|
||||
}
|
||||
val e1 =
|
||||
assertThrows<IllegalStateException> {
|
||||
EvaluatorBuilder.unconfigured().setSecurityManager(SecurityManagers.defaultManager).build()
|
||||
}
|
||||
assertThat(e1).hasMessage("No stack frame transformer set.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sets evaluator settings from project`() {
|
||||
val projectPath = Path.of(javaClass.getResource("project/project1/PklProject")!!.toURI())
|
||||
val project = Project.loadFromPath(
|
||||
projectPath,
|
||||
SecurityManagers.defaultManager,
|
||||
null
|
||||
)
|
||||
val project = Project.loadFromPath(projectPath, SecurityManagers.defaultManager, null)
|
||||
val projectDir = Path.of(javaClass.getResource("project/project1/PklProject")!!.toURI()).parent
|
||||
val builder = EvaluatorBuilder
|
||||
.unconfigured()
|
||||
.applyFromProject(project)
|
||||
assertThat(builder.allowedResources.map { it.pattern() })
|
||||
.isEqualTo(listOf("foo:", "bar:"))
|
||||
assertThat(builder.allowedModules.map { it.pattern() })
|
||||
.isEqualTo(listOf("baz:", "biz:"))
|
||||
val builder = EvaluatorBuilder.unconfigured().applyFromProject(project)
|
||||
assertThat(builder.allowedResources.map { it.pattern() }).isEqualTo(listOf("foo:", "bar:"))
|
||||
assertThat(builder.allowedModules.map { it.pattern() }).isEqualTo(listOf("baz:", "biz:"))
|
||||
assertThat(builder.externalProperties).isEqualTo(mapOf("one" to "1"))
|
||||
assertThat(builder.environmentVariables).isEqualTo(mapOf("two" to "2"))
|
||||
assertThat(builder.moduleCacheDir).isEqualTo(projectDir.resolve("my-cache-dir/"))
|
||||
|
||||
@@ -1,32 +1,47 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.io.path.writeText
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.createTempFile
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.ModuleSource.*
|
||||
import org.pkl.core.util.IoUtils
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.core.module.ModuleKey
|
||||
import org.pkl.core.module.ModuleKeyFactories
|
||||
import org.pkl.core.module.ModuleKeyFactory
|
||||
import org.pkl.core.module.ResolvedModuleKey
|
||||
import org.pkl.core.project.Project
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.FileSystems
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.io.path.writeText
|
||||
import org.pkl.core.util.IoUtils
|
||||
|
||||
class EvaluatorTest {
|
||||
companion object {
|
||||
@@ -50,8 +65,10 @@ class EvaluatorTest {
|
||||
|
||||
override fun getUri(): URI = uri
|
||||
|
||||
override fun loadSource(): String = javaClass.classLoader.getResourceAsStream(uri.path.drop(1))!!.use { it.readAllBytes().toString(
|
||||
StandardCharsets.UTF_8) }
|
||||
override fun loadSource(): String =
|
||||
javaClass.classLoader.getResourceAsStream(uri.path.drop(1))!!.use {
|
||||
it.readAllBytes().toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
override fun resolve(securityManager: SecurityManager): ResolvedModuleKey = this
|
||||
}
|
||||
@@ -71,28 +88,20 @@ class EvaluatorTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate text with relative import`() {
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(text("import \"foo.bar\""))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Module `repl:text` cannot have a relative import URI.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(text("import \"foo.bar\"")) }
|
||||
assertThat(e).hasMessageContaining("Module `repl:text` cannot have a relative import URI.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluate named module`() {
|
||||
val module = evaluator.evaluate(
|
||||
modulePath("org/pkl/core/EvaluatorTest.pkl")
|
||||
)
|
||||
val module = evaluator.evaluate(modulePath("org/pkl/core/EvaluatorTest.pkl"))
|
||||
checkModule(module)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluate non-existing named module`() {
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("non/existing.pkl"))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `modulepath:/non/existing.pkl`.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(modulePath("non/existing.pkl")) }
|
||||
assertThat(e).hasMessageContaining("Cannot find module `modulepath:/non/existing.pkl`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,11 +116,8 @@ class EvaluatorTest {
|
||||
@Test
|
||||
fun `evaluate non-existing file`() {
|
||||
val file = File("/non/existing")
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(file(file))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `${file.toPath().toUri()}`.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(file(file)) }
|
||||
assertThat(e).hasMessageContaining("Cannot find module `${file.toPath().toUri()}`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,11 +132,8 @@ class EvaluatorTest {
|
||||
@Test
|
||||
fun `evaluate non-existing path`() {
|
||||
val path = "/non/existing".toPath()
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(path(path))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `${path.toUri()}`.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(path(path)) }
|
||||
assertThat(e).hasMessageContaining("Cannot find module `${path.toUri()}`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -150,9 +153,7 @@ class EvaluatorTest {
|
||||
// cast required to compile on JDK 14+ (which adds new overload)
|
||||
FileSystems.newFileSystem(zipFile, null as ClassLoader?).use { zipFs ->
|
||||
val file = zipFs.getPath("non/existing")
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(path(file))
|
||||
}
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(path(file)) }
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `jar:file:")
|
||||
.hasMessageContaining("non/existing")
|
||||
@@ -170,11 +171,9 @@ class EvaluatorTest {
|
||||
|
||||
@Test
|
||||
fun `evaluate non-existing URI`() {
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(uri(URI("https://localhost/non/existing")))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("I/O error loading module `https://localhost/non/existing`.")
|
||||
val e =
|
||||
assertThrows<PklException> { evaluator.evaluate(uri(URI("https://localhost/non/existing"))) }
|
||||
assertThat(e).hasMessageContaining("I/O error loading module `https://localhost/non/existing`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -187,112 +186,117 @@ class EvaluatorTest {
|
||||
@Test
|
||||
fun `evaluate jar URI with non-existing archive`() {
|
||||
val moduleUri = URI("jar:file:///non/existing!/bar.pkl")
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(uri(moduleUri))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `$moduleUri`.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(uri(moduleUri)) }
|
||||
assertThat(e).hasMessageContaining("Cannot find module `$moduleUri`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluate jar URI with non-existing archive path`(@TempDir tempDir: Path) {
|
||||
val zipFile = createModulesZip(tempDir)
|
||||
val moduleUri = URI("jar:${zipFile.toUri()}!/non/existing")
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(uri(moduleUri))
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot find module `$moduleUri`.")
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(uri(moduleUri)) }
|
||||
assertThat(e).hasMessageContaining("Cannot find module `$moduleUri`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluate module with relative URI`() {
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(create(URI("foo.bar"), ""))
|
||||
}
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(create(URI("foo.bar"), "")) }
|
||||
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Cannot evaluate relative module URI `foo.bar`.")
|
||||
assertThat(e).hasMessageContaining("Cannot evaluate relative module URI `foo.bar`.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluating a broken module multiple times results in the same error every time`() {
|
||||
val e1 = assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule1.pkl"))
|
||||
}
|
||||
val e2 = assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule1.pkl"))
|
||||
}
|
||||
val e1 =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule1.pkl"))
|
||||
}
|
||||
val e2 =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule1.pkl"))
|
||||
}
|
||||
assertThat(e2.message).isEqualTo(e1.message)
|
||||
|
||||
val e3 = assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule2.pkl"))
|
||||
}
|
||||
val e4 = assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule2.pkl"))
|
||||
}
|
||||
val e3 =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule2.pkl"))
|
||||
}
|
||||
val e4 =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(modulePath("org/pkl/core/brokenModule2.pkl"))
|
||||
}
|
||||
assertThat(e4.message).isEqualTo(e3.message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `evaluation timeout`() {
|
||||
val evaluator = EvaluatorBuilder.preconfigured()
|
||||
.setTimeout(java.time.Duration.ofMillis(100))
|
||||
.build()
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(text(
|
||||
"""
|
||||
val evaluator =
|
||||
EvaluatorBuilder.preconfigured().setTimeout(java.time.Duration.ofMillis(100)).build()
|
||||
val e =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
function fib(n) = if (n < 2) 0 else fib(n - 1) + fib(n - 2)
|
||||
x = fib(100)
|
||||
""".trimIndent()
|
||||
))
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}
|
||||
assertThat(e.message).contains("timed out")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `stack overflow`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(text("""
|
||||
val e =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
a = b
|
||||
b = c
|
||||
c = a
|
||||
""".trimIndent()))
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}
|
||||
assertThat(e.message).contains("A stack overflow occurred.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot import module located outside root dir`(@TempDir tempDir: Path) {
|
||||
val evaluator = EvaluatorBuilder.preconfigured()
|
||||
.setSecurityManager(
|
||||
SecurityManagers.standard(
|
||||
SecurityManagers.defaultAllowedModules,
|
||||
SecurityManagers.defaultAllowedResources,
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
tempDir
|
||||
val evaluator =
|
||||
EvaluatorBuilder.preconfigured()
|
||||
.setSecurityManager(
|
||||
SecurityManagers.standard(
|
||||
SecurityManagers.defaultAllowedModules,
|
||||
SecurityManagers.defaultAllowedResources,
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
tempDir
|
||||
)
|
||||
)
|
||||
)
|
||||
.build()
|
||||
.build()
|
||||
|
||||
val module = tempDir.resolve("test.pkl")
|
||||
module.writeString(
|
||||
"""
|
||||
amends "/non/existing.pkl"
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val e = assertThrows<PklException> {
|
||||
evaluator.evaluate(path(module))
|
||||
}
|
||||
val e = assertThrows<PklException> { evaluator.evaluate(path(module)) }
|
||||
assertThat(e.message).contains("Refusing to load module `file:///non/existing.pkl`")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiple-file output`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val program = """
|
||||
val program =
|
||||
"""
|
||||
output {
|
||||
files {
|
||||
["foo.yml"] {
|
||||
@@ -309,14 +313,10 @@ class EvaluatorTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
val output = evaluator.evaluateOutputFiles(ModuleSource.text(program))
|
||||
assertThat(output.keys).isEqualTo(setOf(
|
||||
"foo.yml",
|
||||
"bar.yml",
|
||||
"bar/biz.yml",
|
||||
"bar/../bark.yml"
|
||||
))
|
||||
assertThat(output.keys).isEqualTo(setOf("foo.yml", "bar.yml", "bar/biz.yml", "bar/../bark.yml"))
|
||||
assertThat(output["foo.yml"]?.text).isEqualTo("foo: foo text")
|
||||
assertThat(output["bar.yml"]?.text).isEqualTo("bar: bar text")
|
||||
assertThat(output["bar/biz.yml"]?.text).isEqualTo("biz: bar biz")
|
||||
@@ -328,10 +328,13 @@ class EvaluatorTest {
|
||||
PackageServer.populateCacheDir(cacheDir)
|
||||
val evaluatorBuilder = EvaluatorBuilder.preconfigured().setModuleCacheDir(cacheDir)
|
||||
val project = Project.load(modulePath("/org/pkl/core/project/project5/PklProject"))
|
||||
val result = evaluatorBuilder.setProjectDependencies(project.dependencies).build().use { evaluator ->
|
||||
evaluator.evaluateOutputText(modulePath("/org/pkl/core/project/project5/main.pkl"))
|
||||
}
|
||||
assertThat(result).isEqualTo("""
|
||||
val result =
|
||||
evaluatorBuilder.setProjectDependencies(project.dependencies).build().use { evaluator ->
|
||||
evaluator.evaluateOutputText(modulePath("/org/pkl/core/project/project5/main.pkl"))
|
||||
}
|
||||
assertThat(result)
|
||||
.isEqualTo(
|
||||
"""
|
||||
prop1 {
|
||||
name = "Apple"
|
||||
}
|
||||
@@ -339,30 +342,37 @@ class EvaluatorTest {
|
||||
res = 1
|
||||
}
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `project set from custom ModuleKeyFactory`(@TempDir cacheDir: Path) {
|
||||
PackageServer.populateCacheDir(cacheDir)
|
||||
val evaluatorBuilder = with(EvaluatorBuilder.preconfigured()) {
|
||||
setAllowedModules(SecurityManagers.defaultAllowedModules + Pattern.compile("custom:"))
|
||||
setAllowedResources(SecurityManagers.defaultAllowedResources + Pattern.compile("custom:"))
|
||||
setModuleCacheDir(cacheDir)
|
||||
setModuleKeyFactories(
|
||||
listOf(
|
||||
CustomModuleKeyFactory,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.projectpackage,
|
||||
ModuleKeyFactories.file
|
||||
val evaluatorBuilder =
|
||||
with(EvaluatorBuilder.preconfigured()) {
|
||||
setAllowedModules(SecurityManagers.defaultAllowedModules + Pattern.compile("custom:"))
|
||||
setAllowedResources(SecurityManagers.defaultAllowedResources + Pattern.compile("custom:"))
|
||||
setModuleCacheDir(cacheDir)
|
||||
setModuleKeyFactories(
|
||||
listOf(
|
||||
CustomModuleKeyFactory,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.projectpackage,
|
||||
ModuleKeyFactories.file
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
val project = evaluatorBuilder.build().use { Project.load(it, uri("custom:/org/pkl/core/project/project5/PklProject")) }
|
||||
}
|
||||
val project =
|
||||
evaluatorBuilder.build().use {
|
||||
Project.load(it, uri("custom:/org/pkl/core/project/project5/PklProject"))
|
||||
}
|
||||
|
||||
val evaluator = evaluatorBuilder.setProjectDependencies(project.dependencies).build()
|
||||
val output = evaluator.use { it.evaluateOutputText(uri("custom:/org/pkl/core/project/project5/main.pkl")) }
|
||||
val output =
|
||||
evaluator.use { it.evaluateOutputText(uri("custom:/org/pkl/core/project/project5/main.pkl")) }
|
||||
assertThat(output)
|
||||
.isEqualTo(
|
||||
"""
|
||||
@@ -382,45 +392,55 @@ class EvaluatorTest {
|
||||
fun `project base path set to non-hierarchical scheme`() {
|
||||
class FooBarModuleKey(val moduleUri: URI) : ModuleKey, ResolvedModuleKey {
|
||||
override fun hasHierarchicalUris(): Boolean = false
|
||||
|
||||
override fun isGlobbable(): Boolean = false
|
||||
|
||||
override fun getOriginal(): ModuleKey = this
|
||||
|
||||
override fun getUri(): URI = moduleUri
|
||||
|
||||
override fun loadSource(): String =
|
||||
if (uri.schemeSpecificPart.endsWith("PklProject")) {
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
""".trimIndent()
|
||||
} else """
|
||||
"""
|
||||
.trimIndent()
|
||||
} else
|
||||
"""
|
||||
birds = import("@birds/catalog/Ostritch.pkl")
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
override fun resolve(securityManager: SecurityManager): ResolvedModuleKey {
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
val fooBayModuleKeyFactory = ModuleKeyFactory { uri ->
|
||||
if (uri.scheme == "foobar") Optional.of(FooBarModuleKey(uri))
|
||||
else Optional.empty()
|
||||
if (uri.scheme == "foobar") Optional.of(FooBarModuleKey(uri)) else Optional.empty()
|
||||
}
|
||||
|
||||
val evaluatorBuilder = with(EvaluatorBuilder.preconfigured()) {
|
||||
setAllowedModules(SecurityManagers.defaultAllowedModules + Pattern.compile("foobar:"))
|
||||
setAllowedResources(SecurityManagers.defaultAllowedResources + Pattern.compile("foobar:"))
|
||||
setModuleKeyFactories(
|
||||
listOf(
|
||||
fooBayModuleKeyFactory,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.projectpackage,
|
||||
ModuleKeyFactories.file
|
||||
val evaluatorBuilder =
|
||||
with(EvaluatorBuilder.preconfigured()) {
|
||||
setAllowedModules(SecurityManagers.defaultAllowedModules + Pattern.compile("foobar:"))
|
||||
setAllowedResources(SecurityManagers.defaultAllowedResources + Pattern.compile("foobar:"))
|
||||
setModuleKeyFactories(
|
||||
listOf(
|
||||
fooBayModuleKeyFactory,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.projectpackage,
|
||||
ModuleKeyFactories.file
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val project = evaluatorBuilder.build().use { Project.load(it, uri("foobar:foo/PklProject")) }
|
||||
val evaluator = evaluatorBuilder.setProjectDependencies(project.dependencies).build()
|
||||
assertThatCode { evaluator.use { it.evaluateOutputText(uri("foobar:baz")) } }
|
||||
.hasMessageContaining("Cannot import dependency because project URI `foobar:foo/PklProject` does not have a hierarchical path.")
|
||||
.hasMessageContaining(
|
||||
"Cannot import dependency because project URI `foobar:foo/PklProject` does not have a hierarchical path."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -430,22 +450,34 @@ class EvaluatorTest {
|
||||
val project = Project.load(modulePath("/org/pkl/core/project/project6/PklProject"))
|
||||
evaluatorBuilder.setProjectDependencies(project.dependencies).build().use { evaluator ->
|
||||
assertThatCode {
|
||||
evaluator.evaluateOutputText(modulePath("/org/pkl/core/project/project6/globWithinDependency.pkl"))
|
||||
}.hasMessageContaining("""
|
||||
evaluator.evaluateOutputText(
|
||||
modulePath("/org/pkl/core/project/project6/globWithinDependency.pkl")
|
||||
)
|
||||
}
|
||||
.hasMessageContaining(
|
||||
"""
|
||||
Cannot resolve import in local dependency because scheme `modulepath` is not globbable.
|
||||
|
||||
1 | res = import*("*.pkl")
|
||||
^^^^^^^^^^^^^^^^
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThatCode {
|
||||
evaluator.evaluateOutputText(modulePath("/org/pkl/core/project/project6/globIntoDependency.pkl"))
|
||||
}.hasMessageContaining("""
|
||||
evaluator.evaluateOutputText(
|
||||
modulePath("/org/pkl/core/project/project6/globIntoDependency.pkl")
|
||||
)
|
||||
}
|
||||
.hasMessageContaining(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Cannot resolve import in local dependency because scheme `modulepath` is not globbable.
|
||||
|
||||
1 | import* "@project7/*.pkl" as proj7Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,13 +492,16 @@ class EvaluatorTest {
|
||||
val module1 = modulesDir.resolve("foo/bar/module1.pkl").createParentDirectories()
|
||||
val module2 = modulesDir.resolve("foo/baz/module2.pkl").createParentDirectories()
|
||||
|
||||
module1.writeText("""
|
||||
module1.writeText(
|
||||
"""
|
||||
// verify that relative import is resolved correctly
|
||||
import "../baz/module2.pkl"
|
||||
|
||||
name = module2.name
|
||||
age = module2.age
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
module2.writeText(sourceText)
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.StringWriter
|
||||
@@ -12,9 +27,7 @@ class JsonRendererTest {
|
||||
@Test
|
||||
fun `render document`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.modulePath("org/pkl/core/rendererTest.pkl")
|
||||
)
|
||||
val module = evaluator.evaluate(ModuleSource.modulePath("org/pkl/core/rendererTest.pkl"))
|
||||
val writer = StringWriter()
|
||||
val renderer = ValueRenderers.json(writer, " ", true)
|
||||
|
||||
@@ -23,14 +36,13 @@ class JsonRendererTest {
|
||||
val expected = IoUtils.readClassPathResourceAsString(javaClass, "rendererTest.json")
|
||||
|
||||
assertThat(output).isEqualTo(expected)
|
||||
assertThatCode { JsonParser(object : JsonHandler<Any, Any>() {}).parse(output) }.doesNotThrowAnyException()
|
||||
assertThatCode { JsonParser(object : JsonHandler<Any, Any>() {}).parse(output) }
|
||||
.doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rendered document ends in newline`() {
|
||||
val module: PModule = Evaluator
|
||||
.preconfigured()
|
||||
.evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
val module: PModule = Evaluator.preconfigured().evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
|
||||
for (omitNullProperties in listOf(false, true)) {
|
||||
val writer = StringWriter()
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.junit.platform.commons.annotation.Testable
|
||||
|
||||
@Testable
|
||||
class LanguageSnippetTests
|
||||
@Testable class LanguageSnippetTests
|
||||
|
||||
@Testable
|
||||
class MacLanguageSnippetTests
|
||||
@Testable class MacLanguageSnippetTests
|
||||
|
||||
@Testable
|
||||
class LinuxLanguageSnippetTests
|
||||
@Testable class LinuxLanguageSnippetTests
|
||||
|
||||
@Testable
|
||||
class AlpineLanguageSnippetTests
|
||||
@Testable class AlpineLanguageSnippetTests
|
||||
|
||||
@Testable
|
||||
class WindowsLanguageSnippetTests
|
||||
@Testable class WindowsLanguageSnippetTests
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.isRegularFile
|
||||
import kotlin.reflect.KClass
|
||||
import org.junit.platform.engine.EngineDiscoveryRequest
|
||||
import org.junit.platform.engine.TestDescriptor
|
||||
import org.junit.platform.engine.UniqueId
|
||||
@@ -11,13 +33,6 @@ import org.pkl.commons.test.PklExecutablePaths
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.project.Project
|
||||
import org.pkl.core.util.IoUtils
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.isRegularFile
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class AbstractLanguageSnippetTestsEngine : InputOutputTestEngine() {
|
||||
private val lineNumberRegex = Regex("(?m)^(( ║ )*)(\\d+) \\|")
|
||||
@@ -31,17 +46,17 @@ abstract class AbstractLanguageSnippetTestsEngine : InputOutputTestEngine() {
|
||||
private val expectedOutputDir: Path = snippetsDir.resolve("output")
|
||||
|
||||
/**
|
||||
* Convenience for development; this selects which snippet test(s) to run.
|
||||
* There is a (non-language-snippet) test to make sure this is `""` before commit.
|
||||
* Convenience for development; this selects which snippet test(s) to run. There is a
|
||||
* (non-language-snippet) test to make sure this is `""` before commit.
|
||||
*/
|
||||
//language=regexp
|
||||
// language=regexp
|
||||
internal val selection: String = ""
|
||||
|
||||
protected val packageServer: PackageServer = PackageServer()
|
||||
|
||||
override val includedTests: List<Regex> = listOf(Regex(".*$selection\\.pkl"))
|
||||
|
||||
override val excludedTests: List<Regex> = buildList {
|
||||
override val excludedTests: List<Regex> = buildList {
|
||||
add(Regex(".*/native/.*"))
|
||||
if (IoUtils.isWindows()) {
|
||||
addAll(windowsExcludedTests)
|
||||
@@ -53,8 +68,7 @@ abstract class AbstractLanguageSnippetTestsEngine : InputOutputTestEngine() {
|
||||
override val isInputFile: (Path) -> Boolean = { it.isRegularFile() }
|
||||
|
||||
protected tailrec fun Path.getProjectDir(): Path? =
|
||||
if (Files.exists(this.resolve("PklProject"))) this
|
||||
else parent?.getProjectDir()
|
||||
if (Files.exists(this.resolve("PklProject"))) this else parent?.getProjectDir()
|
||||
|
||||
override fun expectedOutputFileFor(inputFile: Path): Path {
|
||||
val relativePath = IoUtils.relativize(inputFile, inputDir).toString()
|
||||
@@ -75,17 +89,19 @@ abstract class AbstractLanguageSnippetTestsEngine : InputOutputTestEngine() {
|
||||
|
||||
private val replacement by lazy {
|
||||
if (snippetsDir.root.toString() != "/") "\$snippetsDir" else "/\$snippetsDir"
|
||||
}
|
||||
}
|
||||
|
||||
protected fun String.stripFilePaths(): String =
|
||||
replace(IoUtils.toNormalizedPathString(snippetsDir), replacement)
|
||||
|
||||
protected fun String.stripLineNumbers() = replace(lineNumberRegex) { result ->
|
||||
// replace line number with equivalent number of 'x' characters to keep formatting intact
|
||||
(result.groups[1]!!.value) + "x".repeat(result.groups[3]!!.value.length) + " |"
|
||||
}
|
||||
protected fun String.stripLineNumbers() =
|
||||
replace(lineNumberRegex) { result ->
|
||||
// replace line number with equivalent number of 'x' characters to keep formatting intact
|
||||
(result.groups[1]!!.value) + "x".repeat(result.groups[3]!!.value.length) + " |"
|
||||
}
|
||||
|
||||
protected fun String.stripWebsite() = replace(Release.current().documentation().homepage(), "https://\$pklWebsite/")
|
||||
protected fun String.stripWebsite() =
|
||||
replace(Release.current().documentation().homepage(), "https://\$pklWebsite/")
|
||||
|
||||
// can't think of a better solution right now
|
||||
protected fun String.stripVersionCheckErrorMessage() =
|
||||
@@ -103,8 +119,7 @@ abstract class AbstractLanguageSnippetTestsEngine : InputOutputTestEngine() {
|
||||
}
|
||||
|
||||
protected fun String.withUnixLineEndings(): String {
|
||||
return if (System.lineSeparator() == "\r\n") replace("\r\n", "\n")
|
||||
else this
|
||||
return if (System.lineSeparator() == "\r\n") replace("\r\n", "\n") else this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,16 +138,16 @@ class LanguageSnippetTestsEngine : AbstractLanguageSnippetTestsEngine() {
|
||||
"file:///foo/bar" to "file:///foo/bar"
|
||||
)
|
||||
)
|
||||
.setExternalProperties(mapOf(
|
||||
"name1" to "value1",
|
||||
"name2" to "value2",
|
||||
"/foo/bar" to "foobar"
|
||||
))
|
||||
.setExternalProperties(
|
||||
mapOf("name1" to "value1", "name2" to "value2", "/foo/bar" to "foobar")
|
||||
)
|
||||
.setModuleCacheDir(null)
|
||||
.setHttpClient(HttpClient.builder()
|
||||
.setTestPort(packageServer.port)
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
.buildLazily())
|
||||
.setHttpClient(
|
||||
HttpClient.builder()
|
||||
.setTestPort(packageServer.port)
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
.buildLazily()
|
||||
)
|
||||
}
|
||||
|
||||
override val testClass: KClass<*> = LanguageSnippetTests::class
|
||||
@@ -140,60 +155,65 @@ class LanguageSnippetTestsEngine : AbstractLanguageSnippetTestsEngine() {
|
||||
override fun generateOutputFor(inputFile: Path): kotlin.Pair<Boolean, String> {
|
||||
val logWriter = StringWriter()
|
||||
|
||||
val (success, output) = try {
|
||||
val evaluator = evaluatorBuilder()
|
||||
.setLogger(Loggers.writer(PrintWriter(logWriter)))
|
||||
.apply {
|
||||
if (inputFile.startsWith(projectsDir)) {
|
||||
val projectDir = inputFile.getProjectDir() ?: return@apply
|
||||
val project = Project.loadFromPath(
|
||||
projectDir.resolve("PklProject"),
|
||||
SecurityManagers.defaultManager,
|
||||
null,
|
||||
StackFrameTransformers.empty,
|
||||
mapOf()
|
||||
)
|
||||
securityManager = null
|
||||
applyFromProject(project)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
evaluator.use { true to it.evaluateOutputText(ModuleSource.path(inputFile)) }
|
||||
} catch (e: PklBugException) {
|
||||
false to e.stackTraceToString()
|
||||
} catch (e: PklException) {
|
||||
false to e.message!!
|
||||
.stripLineNumbers()
|
||||
.stripVersionCheckErrorMessage()
|
||||
}
|
||||
val (success, output) =
|
||||
try {
|
||||
val evaluator =
|
||||
evaluatorBuilder()
|
||||
.setLogger(Loggers.writer(PrintWriter(logWriter)))
|
||||
.apply {
|
||||
if (inputFile.startsWith(projectsDir)) {
|
||||
val projectDir = inputFile.getProjectDir() ?: return@apply
|
||||
val project =
|
||||
Project.loadFromPath(
|
||||
projectDir.resolve("PklProject"),
|
||||
SecurityManagers.defaultManager,
|
||||
null,
|
||||
StackFrameTransformers.empty,
|
||||
mapOf()
|
||||
)
|
||||
securityManager = null
|
||||
applyFromProject(project)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
evaluator.use { true to it.evaluateOutputText(ModuleSource.path(inputFile)) }
|
||||
} catch (e: PklBugException) {
|
||||
false to e.stackTraceToString()
|
||||
} catch (e: PklException) {
|
||||
false to e.message!!.stripLineNumbers().stripVersionCheckErrorMessage()
|
||||
}
|
||||
|
||||
val stderr = logWriter.toString().withUnixLineEndings()
|
||||
|
||||
return (success && stderr.isBlank()) to (output + stderr).stripFilePaths().stripWebsite().stripStdlibLocationSha()
|
||||
return (success && stderr.isBlank()) to
|
||||
(output + stderr).stripFilePaths().stripWebsite().stripStdlibLocationSha()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractNativeLanguageSnippetTestsEngine : AbstractLanguageSnippetTestsEngine() {
|
||||
abstract val pklExecutablePath: Path
|
||||
|
||||
override val excludedTests: List<Regex> = listOf(
|
||||
// exclude test that loads module from class path (there is no class path when using native executable)
|
||||
// on the other hand, don't exclude /native/
|
||||
Regex(".*/import1b\\.pkl"),
|
||||
)
|
||||
override val excludedTests: List<Regex> =
|
||||
listOf(
|
||||
// exclude test that loads module from class path (there is no class path when using native
|
||||
// executable)
|
||||
// on the other hand, don't exclude /native/
|
||||
Regex(".*/import1b\\.pkl"),
|
||||
)
|
||||
|
||||
/**
|
||||
* Avoid running tests for native binaries when those native binaries have not been built.
|
||||
*/
|
||||
override fun discover(discoveryRequest: EngineDiscoveryRequest, uniqueId: UniqueId): TestDescriptor {
|
||||
/** Avoid running tests for native binaries when those native binaries have not been built. */
|
||||
override fun discover(
|
||||
discoveryRequest: EngineDiscoveryRequest,
|
||||
uniqueId: UniqueId
|
||||
): TestDescriptor {
|
||||
if (!pklExecutablePath.exists()) {
|
||||
// return empty descriptor w/o children
|
||||
return EngineDescriptor(uniqueId, javaClass.simpleName)
|
||||
}
|
||||
|
||||
|
||||
return super.discover(discoveryRequest, uniqueId)
|
||||
}
|
||||
|
||||
|
||||
override fun generateOutputFor(inputFile: Path): kotlin.Pair<Boolean, String> {
|
||||
val args = buildList {
|
||||
add(pklExecutablePath.toString())
|
||||
@@ -234,20 +254,22 @@ abstract class AbstractNativeLanguageSnippetTestsEngine : AbstractLanguageSnippe
|
||||
add(inputFile.toString())
|
||||
}
|
||||
|
||||
val builder = ProcessBuilder()
|
||||
.command(args)
|
||||
val builder = ProcessBuilder().command(args)
|
||||
|
||||
val process = builder.start()
|
||||
return try {
|
||||
val (out, err) = listOf(process.inputStream, process.errorStream)
|
||||
.map { it.reader().readText().withUnixLineEndings() }
|
||||
val (out, err) =
|
||||
listOf(process.inputStream, process.errorStream).map {
|
||||
it.reader().readText().withUnixLineEndings()
|
||||
}
|
||||
val success = process.waitFor() == 0 && err.isBlank()
|
||||
success to (out + err)
|
||||
.stripFilePaths()
|
||||
.stripLineNumbers()
|
||||
.stripWebsite()
|
||||
.stripVersionCheckErrorMessage()
|
||||
.stripStdlibLocationSha()
|
||||
success to
|
||||
(out + err)
|
||||
.stripFilePaths()
|
||||
.stripLineNumbers()
|
||||
.stripWebsite()
|
||||
.stripVersionCheckErrorMessage()
|
||||
.stripStdlibLocationSha()
|
||||
} finally {
|
||||
process.destroy()
|
||||
}
|
||||
@@ -280,11 +302,12 @@ class AlpineLanguageSnippetTestsEngine : AbstractNativeLanguageSnippetTestsEngin
|
||||
}
|
||||
|
||||
// error message contains different file path on Windows
|
||||
private val windowsExcludedTests get() = listOf(Regex(".*missingProjectDeps/bug\\.pkl"))
|
||||
private val windowsExcludedTests
|
||||
get() = listOf(Regex(".*missingProjectDeps/bug\\.pkl"))
|
||||
|
||||
class WindowsLanguageSnippetTestsEngine : AbstractNativeLanguageSnippetTestsEngine() {
|
||||
override val pklExecutablePath: Path = PklExecutablePaths.windowsAmd64
|
||||
override val testClass: KClass<*> = WindowsLanguageSnippetTests::class
|
||||
override val excludedTests: List<Regex>
|
||||
override val excludedTests: List<Regex>
|
||||
get() = super.excludedTests + windowsExcludedTests
|
||||
}
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
|
||||
class PClassInfoTest {
|
||||
@Test
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.StringWriter
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.util.IoUtils
|
||||
import org.xml.sax.ErrorHandler
|
||||
import org.xml.sax.InputSource
|
||||
import org.xml.sax.SAXParseException
|
||||
import org.pkl.core.util.IoUtils
|
||||
|
||||
class PListRendererTest {
|
||||
@Test
|
||||
@@ -28,8 +43,7 @@ class PListRendererTest {
|
||||
|
||||
@Test
|
||||
fun `rendered document ends in newline`() {
|
||||
val module = Evaluator.preconfigured()
|
||||
.evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
val module = Evaluator.preconfigured().evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
|
||||
val writer = StringWriter()
|
||||
ValueRenderers.plist(writer, " ").renderDocument(module)
|
||||
@@ -37,28 +51,29 @@ class PListRendererTest {
|
||||
}
|
||||
|
||||
private fun parseAndValidateRenderedDocument(output: String) {
|
||||
val builderFactory = DocumentBuilderFactory.newInstance().apply {
|
||||
isValidating = true
|
||||
}
|
||||
val builderFactory = DocumentBuilderFactory.newInstance().apply { isValidating = true }
|
||||
|
||||
val builder = builderFactory.newDocumentBuilder().apply {
|
||||
setEntityResolver { _, _ ->
|
||||
InputSource(PListRendererTest::class.java.getResourceAsStream("PropertyList-1.0.dtd"))
|
||||
val builder =
|
||||
builderFactory.newDocumentBuilder().apply {
|
||||
setEntityResolver { _, _ ->
|
||||
InputSource(PListRendererTest::class.java.getResourceAsStream("PropertyList-1.0.dtd"))
|
||||
}
|
||||
setErrorHandler(
|
||||
object : ErrorHandler {
|
||||
override fun warning(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override fun error(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override fun fatalError(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
setErrorHandler(object : ErrorHandler {
|
||||
override fun warning(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override fun error(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override fun fatalError(exception: SAXParseException) {
|
||||
throw exception
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
builder.parse(output.byteInputStream())
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.net.URI
|
||||
@@ -25,14 +40,12 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `get unknown property`() {
|
||||
val e = assertThrows<NoSuchPropertyException> {
|
||||
pigeon.getProperty("other")
|
||||
}
|
||||
val e = assertThrows<NoSuchPropertyException> { pigeon.getProperty("other") }
|
||||
|
||||
assertThat(e)
|
||||
.hasMessage(
|
||||
"Module `test.module` does not have a property " +
|
||||
"named `other`. Available properties: [name, age]"
|
||||
"named `other`. Available properties: [name, age]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -48,15 +61,16 @@ class PModuleTest {
|
||||
var objectVisited = false
|
||||
var moduleVisited = false
|
||||
|
||||
val visitor = object : ValueVisitor {
|
||||
override fun visitObject(value: PObject) {
|
||||
objectVisited = true
|
||||
}
|
||||
val visitor =
|
||||
object : ValueVisitor {
|
||||
override fun visitObject(value: PObject) {
|
||||
objectVisited = true
|
||||
}
|
||||
|
||||
override fun visitModule(value: PModule) {
|
||||
moduleVisited = true
|
||||
override fun visitModule(value: PModule) {
|
||||
moduleVisited = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pigeon.accept(visitor)
|
||||
|
||||
@@ -69,12 +83,7 @@ class PModuleTest {
|
||||
assertThat(pigeon).isEqualTo(pigeon)
|
||||
assertThat(pigeon.hashCode()).isEqualTo(pigeon.hashCode())
|
||||
|
||||
val pigeon2 = PModule(
|
||||
moduleUri,
|
||||
moduleName,
|
||||
classInfo,
|
||||
HashMap(properties)
|
||||
)
|
||||
val pigeon2 = PModule(moduleUri, moduleName, classInfo, HashMap(properties))
|
||||
|
||||
assertThat(pigeon2).isEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isEqualTo(pigeon.hashCode())
|
||||
@@ -82,12 +91,7 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - different module uri`() {
|
||||
val pigeon2 = PModule(
|
||||
URI("other/module"),
|
||||
moduleName,
|
||||
classInfo,
|
||||
properties
|
||||
)
|
||||
val pigeon2 = PModule(URI("other/module"), moduleName, classInfo, properties)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -95,12 +99,7 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - different module name`() {
|
||||
val pigeon2 = PModule(
|
||||
moduleUri,
|
||||
"other.module",
|
||||
classInfo,
|
||||
properties
|
||||
)
|
||||
val pigeon2 = PModule(moduleUri, "other.module", classInfo, properties)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -108,12 +107,7 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - different property value`() {
|
||||
val pigeon2 = PModule(
|
||||
moduleUri,
|
||||
moduleName,
|
||||
classInfo,
|
||||
mapOf("name" to "Pigeon", "age" to 21)
|
||||
)
|
||||
val pigeon2 = PModule(moduleUri, moduleName, classInfo, mapOf("name" to "Pigeon", "age" to 21))
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -121,12 +115,7 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - missing property`() {
|
||||
val pigeon2 = PModule(
|
||||
moduleUri,
|
||||
moduleName,
|
||||
classInfo,
|
||||
mapOf("name" to "Pigeon")
|
||||
)
|
||||
val pigeon2 = PModule(moduleUri, moduleName, classInfo, mapOf("name" to "Pigeon"))
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -134,12 +123,13 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - extra property`() {
|
||||
val pigeon2 = PModule(
|
||||
moduleUri,
|
||||
moduleName,
|
||||
classInfo,
|
||||
mapOf("name" to "Pigeon", "age" to 42, "other" to true)
|
||||
)
|
||||
val pigeon2 =
|
||||
PModule(
|
||||
moduleUri,
|
||||
moduleName,
|
||||
classInfo,
|
||||
mapOf("name" to "Pigeon", "age" to 42, "other" to true)
|
||||
)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -147,7 +137,6 @@ class PModuleTest {
|
||||
|
||||
@Test
|
||||
fun `toString()`() {
|
||||
assertThat(pigeon.toString())
|
||||
.isEqualTo("test.module { name = Pigeon; age = 42 }")
|
||||
assertThat(pigeon.toString()).isEqualTo("test.module { name = Pigeon; age = 42 }")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.net.URI
|
||||
|
||||
class PObjectTest {
|
||||
private val testUri = URI("repl:test")
|
||||
@@ -29,14 +44,12 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `get unknown property`() {
|
||||
val e = assertThrows<NoSuchPropertyException> {
|
||||
pigeon.getProperty("other")
|
||||
}
|
||||
val e = assertThrows<NoSuchPropertyException> { pigeon.getProperty("other") }
|
||||
|
||||
assertThat(e)
|
||||
.hasMessage(
|
||||
"Object of type `test#Person` does not have a property " +
|
||||
"named `other`. Available properties: [name, age]"
|
||||
"named `other`. Available properties: [name, age]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,15 +65,16 @@ class PObjectTest {
|
||||
var objectVisited = false
|
||||
var moduleVisited = false
|
||||
|
||||
val visitor = object : ValueVisitor {
|
||||
override fun visitObject(value: PObject) {
|
||||
objectVisited = true
|
||||
}
|
||||
val visitor =
|
||||
object : ValueVisitor {
|
||||
override fun visitObject(value: PObject) {
|
||||
objectVisited = true
|
||||
}
|
||||
|
||||
override fun visitModule(value: PModule) {
|
||||
moduleVisited = true
|
||||
override fun visitModule(value: PModule) {
|
||||
moduleVisited = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pigeon.accept(visitor)
|
||||
|
||||
@@ -73,10 +87,7 @@ class PObjectTest {
|
||||
assertThat(pigeon).isEqualTo(pigeon)
|
||||
assertThat(pigeon.hashCode()).isEqualTo(pigeon.hashCode())
|
||||
|
||||
val pigeon2 = PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
HashMap(properties)
|
||||
)
|
||||
val pigeon2 = PObject(PClassInfo.get("test", "Person", URI("repl:test")), HashMap(properties))
|
||||
|
||||
assertThat(pigeon2).isEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isEqualTo(pigeon.hashCode())
|
||||
@@ -84,10 +95,7 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - different type`() {
|
||||
val pigeon2 = PObject(
|
||||
PClassInfo.get("test", "Other", URI("repl:Other")),
|
||||
properties
|
||||
)
|
||||
val pigeon2 = PObject(PClassInfo.get("test", "Other", URI("repl:Other")), properties)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -95,10 +103,11 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - different property value`() {
|
||||
val pigeon2 = PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
mapOf("name" to "Pigeon", "age" to 21)
|
||||
)
|
||||
val pigeon2 =
|
||||
PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
mapOf("name" to "Pigeon", "age" to 21)
|
||||
)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -106,10 +115,8 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - missing property`() {
|
||||
val pigeon2 = PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
mapOf("name" to "Pigeon")
|
||||
)
|
||||
val pigeon2 =
|
||||
PObject(PClassInfo.get("test", "Person", URI("repl:test")), mapOf("name" to "Pigeon"))
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -117,10 +124,11 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `non-equal - extra property`() {
|
||||
val pigeon2 = PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
mapOf("name" to "Pigeon", "age" to 42, "other" to true)
|
||||
)
|
||||
val pigeon2 =
|
||||
PObject(
|
||||
PClassInfo.get("test", "Person", URI("repl:test")),
|
||||
mapOf("name" to "Pigeon", "age" to 42, "other" to true)
|
||||
)
|
||||
|
||||
assertThat(pigeon2).isNotEqualTo(pigeon)
|
||||
assertThat(pigeon2.hashCode()).isNotEqualTo(pigeon.hashCode())
|
||||
@@ -128,7 +136,6 @@ class PObjectTest {
|
||||
|
||||
@Test
|
||||
fun `toString()`() {
|
||||
assertThat(pigeon.toString())
|
||||
.isEqualTo("test#Person { name = Pigeon; age = 42 }")
|
||||
assertThat(pigeon.toString()).isEqualTo("test#Person { name = Pigeon; age = 42 }")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.StringWriter
|
||||
@@ -21,14 +36,13 @@ class PcfRendererTest {
|
||||
assertThat(output.trim()).isEqualTo(expected.trim())
|
||||
|
||||
// TODO: make pcf a pkl subset again
|
||||
//assertThatCode { evaluator.evaluateText(output) }.doesNotThrowAnyException()
|
||||
// assertThatCode { evaluator.evaluateText(output) }.doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rendered document ends in newline`() {
|
||||
val module = EvaluatorBuilder.preconfigured()
|
||||
.build()
|
||||
.evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
val module =
|
||||
EvaluatorBuilder.preconfigured().build().evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
|
||||
val writer = StringWriter()
|
||||
ValueRenderers.pcf(writer, " ", false, false).renderDocument(module)
|
||||
@@ -37,16 +51,19 @@ class PcfRendererTest {
|
||||
|
||||
@Test
|
||||
fun `rendering with and without null properties`() {
|
||||
val cases = listOf(
|
||||
true to """
|
||||
val cases =
|
||||
listOf(
|
||||
true to
|
||||
"""
|
||||
baz {
|
||||
qux = 42
|
||||
corge = List(null, 1337, null, "Hello World")
|
||||
grault = Map("garply", null, "waldo", 42, "pigeon", null)
|
||||
}
|
||||
""".trimIndent(),
|
||||
|
||||
false to """
|
||||
"""
|
||||
.trimIndent(),
|
||||
false to
|
||||
"""
|
||||
foo = null
|
||||
bar = null
|
||||
baz {
|
||||
@@ -55,12 +72,15 @@ class PcfRendererTest {
|
||||
corge = List(null, 1337, null, "Hello World")
|
||||
grault = Map("garply", null, "waldo", 42, "pigeon", null)
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val module = Evaluator.preconfigured().evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val module =
|
||||
Evaluator.preconfigured()
|
||||
.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
foo = null
|
||||
bar = null
|
||||
baz {
|
||||
@@ -78,9 +98,10 @@ class PcfRendererTest {
|
||||
["pigeon"] = null
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
for ((omitNullProperties, expected) in cases) {
|
||||
val writer = StringWriter()
|
||||
ValueRenderers.pcf(writer, " ", omitNullProperties, false).renderDocument(module)
|
||||
@@ -90,7 +111,7 @@ class PcfRendererTest {
|
||||
|
||||
// TODO: ada
|
||||
// can happen in REPL or when rendering manually constructed container
|
||||
/* @Test
|
||||
/* @Test
|
||||
fun `render container with unevaluated element`() {
|
||||
renderer.renderValue(PObject(PClassInfo.Mapping, mapOf("one" to 1L, "two" to null)))
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.*
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.*
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.StringWriter
|
||||
@@ -10,23 +25,31 @@ class PropertiesRendererTest {
|
||||
@Test
|
||||
fun `render document`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module = evaluator.evaluate(ModuleSource.modulePath("org/pkl/core/propertiesRendererTest.pkl"))
|
||||
val module =
|
||||
evaluator.evaluate(ModuleSource.modulePath("org/pkl/core/propertiesRendererTest.pkl"))
|
||||
val writer = StringWriter()
|
||||
val renderer = ValueRenderers.properties(writer, true, false)
|
||||
|
||||
renderer.renderDocument(module)
|
||||
val output = writer.toString()
|
||||
val expected = IoUtils.readClassPathResourceAsString(javaClass, "propertiesRendererTest.properties")
|
||||
val expected =
|
||||
IoUtils.readClassPathResourceAsString(javaClass, "propertiesRendererTest.properties")
|
||||
|
||||
assertThat(output).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `render unsupported document values`() {
|
||||
val unsupportedValues = listOf(
|
||||
"List()", "new Listing {}", "Map()", "new Mapping {}", "Set()",
|
||||
"new PropertiesRenderer {}", "new Dynamic {}"
|
||||
)
|
||||
val unsupportedValues =
|
||||
listOf(
|
||||
"List()",
|
||||
"new Listing {}",
|
||||
"Map()",
|
||||
"new Mapping {}",
|
||||
"Set()",
|
||||
"new PropertiesRenderer {}",
|
||||
"new Dynamic {}"
|
||||
)
|
||||
|
||||
unsupportedValues.forEach {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
@@ -39,13 +62,13 @@ class PropertiesRendererTest {
|
||||
|
||||
@Test
|
||||
fun `rendered document ends in newline`() {
|
||||
val module = Evaluator.preconfigured()
|
||||
.evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
val module = Evaluator.preconfigured().evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
|
||||
for (omitNullProperties in listOf(false, true)) {
|
||||
for (restrictCharSet in listOf(false, true)) {
|
||||
val writer = StringWriter()
|
||||
ValueRenderers.properties(writer, omitNullProperties, restrictCharSet).renderDocument(module)
|
||||
ValueRenderers.properties(writer, omitNullProperties, restrictCharSet)
|
||||
.renderDocument(module)
|
||||
assertThat(writer.toString()).endsWith("\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.*
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -11,36 +26,30 @@ import org.pkl.core.repl.ReplServer
|
||||
import org.pkl.core.resource.ResourceReaders
|
||||
|
||||
class ReplServerTest {
|
||||
private val server = ReplServer(
|
||||
SecurityManagers.defaultManager,
|
||||
HttpClient.dummyClient(),
|
||||
Loggers.stdErr(),
|
||||
listOf(
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.classPath(this::class.java.classLoader),
|
||||
ModuleKeyFactories.file
|
||||
),
|
||||
listOf(
|
||||
ResourceReaders.environmentVariable(),
|
||||
ResourceReaders.externalProperty()
|
||||
),
|
||||
mapOf("NAME1" to "value1", "NAME2" to "value2"),
|
||||
mapOf("name1" to "value1", "name2" to "value2"),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"/".toPath(),
|
||||
StackFrameTransformers.defaultTransformer
|
||||
)
|
||||
private val server =
|
||||
ReplServer(
|
||||
SecurityManagers.defaultManager,
|
||||
HttpClient.dummyClient(),
|
||||
Loggers.stdErr(),
|
||||
listOf(
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.classPath(this::class.java.classLoader),
|
||||
ModuleKeyFactories.file
|
||||
),
|
||||
listOf(ResourceReaders.environmentVariable(), ResourceReaders.externalProperty()),
|
||||
mapOf("NAME1" to "value1", "NAME2" to "value2"),
|
||||
mapOf("name1" to "value1", "name2" to "value2"),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"/".toPath(),
|
||||
StackFrameTransformers.defaultTransformer
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `complete members of local property`() {
|
||||
server.handleRequest(
|
||||
ReplRequest.Eval("id", "local foo = new { bar = 10 }", false, false)
|
||||
)
|
||||
val responses = server.handleRequest(
|
||||
ReplRequest.Completion("id", "foo")
|
||||
)
|
||||
server.handleRequest(ReplRequest.Eval("id", "local foo = new { bar = 10 }", false, false))
|
||||
val responses = server.handleRequest(ReplRequest.Completion("id", "foo"))
|
||||
|
||||
assertThat(responses.size).isEqualTo(1)
|
||||
|
||||
@@ -51,9 +60,18 @@ class ReplServerTest {
|
||||
assertThat(completionResponse.members.toSortedSet())
|
||||
.isEqualTo(
|
||||
sortedSetOf(
|
||||
"default", "bar", "toList()", "toMap()", "getProperty(",
|
||||
"getPropertyOrNull(", "hasProperty(", "ifNonNull(",
|
||||
"length()", "getClass()", "toString()", "toTyped("
|
||||
"default",
|
||||
"bar",
|
||||
"toList()",
|
||||
"toMap()",
|
||||
"getProperty(",
|
||||
"getPropertyOrNull(",
|
||||
"hasProperty(",
|
||||
"ifNonNull(",
|
||||
"length()",
|
||||
"getClass()",
|
||||
"toString()",
|
||||
"toTyped("
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -61,9 +79,7 @@ class ReplServerTest {
|
||||
@Test
|
||||
fun `complete members of module import`() {
|
||||
server.handleRequest(ReplRequest.Eval("id", "import \"pkl:test\"", false, false))
|
||||
val responses = server.handleRequest(
|
||||
ReplRequest.Completion("id", "test")
|
||||
)
|
||||
val responses = server.handleRequest(ReplRequest.Completion("id", "test"))
|
||||
|
||||
assertThat(responses.size).isEqualTo(1)
|
||||
|
||||
@@ -79,14 +95,11 @@ class ReplServerTest {
|
||||
|
||||
@Test
|
||||
fun `complete members of 'this' expression`() {
|
||||
val responses1 = server.handleRequest(
|
||||
ReplRequest.Eval("id", "x = 1; function f() = 3", false, false)
|
||||
)
|
||||
val responses1 =
|
||||
server.handleRequest(ReplRequest.Eval("id", "x = 1; function f() = 3", false, false))
|
||||
assertThat(responses1.size).isEqualTo(0)
|
||||
|
||||
val responses2 = server.handleRequest(
|
||||
ReplRequest.Completion("id", "this")
|
||||
)
|
||||
val responses2 = server.handleRequest(ReplRequest.Completion("id", "this"))
|
||||
assertThat(responses2.size).isEqualTo(1)
|
||||
|
||||
val response = responses2[0]
|
||||
@@ -96,8 +109,18 @@ class ReplServerTest {
|
||||
assertThat(completionResponse.members.toSortedSet())
|
||||
.isEqualTo(
|
||||
sortedSetOf(
|
||||
"output", "toDynamic()", "toMap()", "f()", "x", "ifNonNull(", "getClass()",
|
||||
"getProperty(", "getPropertyOrNull(", "hasProperty(", "relativePathTo(", "toString()"
|
||||
"output",
|
||||
"toDynamic()",
|
||||
"toMap()",
|
||||
"f()",
|
||||
"x",
|
||||
"ifNonNull(",
|
||||
"getClass()",
|
||||
"getProperty(",
|
||||
"getPropertyOrNull(",
|
||||
"hasProperty(",
|
||||
"relativePathTo(",
|
||||
"toString()"
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -156,7 +179,10 @@ class ReplServerTest {
|
||||
val result2 = makeEvalRequest("""greet(42)""")
|
||||
assertThat(result2).isEqualTo("\"Hello, 42!\"")
|
||||
|
||||
val result3 = makeEvalRequest("function greet(name: String): String = \"Hello, \\(name)!\"; greet(\"Pigeon\") ")
|
||||
val result3 =
|
||||
makeEvalRequest(
|
||||
"function greet(name: String): String = \"Hello, \\(name)!\"; greet(\"Pigeon\") "
|
||||
)
|
||||
assertThat(result3).isEqualTo("\"Hello, Pigeon!\"")
|
||||
|
||||
val result4 = makeFailingEvalRequest("""greet(44)""")
|
||||
@@ -164,8 +190,7 @@ class ReplServerTest {
|
||||
}
|
||||
|
||||
private fun makeEvalRequest(text: String): String {
|
||||
val responses =
|
||||
server.handleRequest(ReplRequest.Eval("id", text, false, false))
|
||||
val responses = server.handleRequest(ReplRequest.Eval("id", text, false, false))
|
||||
|
||||
assertThat(responses).hasSize(1)
|
||||
val response = responses[0]
|
||||
@@ -176,8 +201,7 @@ class ReplServerTest {
|
||||
}
|
||||
|
||||
private fun makeFailingEvalRequest(text: String): String {
|
||||
val responses =
|
||||
server.handleRequest(ReplRequest.Eval("id", text, false, false))
|
||||
val responses = server.handleRequest(ReplRequest.Eval("id", text, false, false))
|
||||
|
||||
assertThat(responses).hasSize(1)
|
||||
val response = responses[0]
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.walk
|
||||
import java.nio.file.Path
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.isRegularFile
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.walk
|
||||
|
||||
/**
|
||||
* These tests don't assert Pkl's implementation correctness, but rather that no debugging settings
|
||||
@@ -22,18 +37,24 @@ class RepositoryHygiene {
|
||||
@Test
|
||||
fun `no output files exists for language snippets without an input`() {
|
||||
val input = snippetsFolder.resolve("input")
|
||||
val inputs = input.walk().filter {
|
||||
it.extension == "pkl"
|
||||
}.map {
|
||||
val path = input.relativize(it).toString()
|
||||
inputRegex.replace(path, "$1$2")
|
||||
}.collect(Collectors.toSet())
|
||||
val inputs =
|
||||
input
|
||||
.walk()
|
||||
.filter { it.extension == "pkl" }
|
||||
.map {
|
||||
val path = input.relativize(it).toString()
|
||||
inputRegex.replace(path, "$1$2")
|
||||
}
|
||||
.collect(Collectors.toSet())
|
||||
|
||||
val output = snippetsFolder.resolve("output")
|
||||
output.walk().filter { it.isRegularFile() }.forEach {
|
||||
val out = output.relativize(it).toString()
|
||||
checkOutputHasInput(inputs, out)
|
||||
}
|
||||
output
|
||||
.walk()
|
||||
.filter { it.isRegularFile() }
|
||||
.forEach {
|
||||
val out = output.relativize(it).toString()
|
||||
checkOutputHasInput(inputs, out)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkOutputHasInput(inputs: Set<String>, output: String) {
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.net.URI
|
||||
@@ -12,116 +27,84 @@ import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.toPath
|
||||
|
||||
class SecurityManagersTest {
|
||||
private val manager = SecurityManagers.standard(
|
||||
listOf(Pattern.compile("test:foo/bar")),
|
||||
listOf(Pattern.compile("env:FOO_BAR")),
|
||||
{ uri -> if (uri.scheme == "one") 1 else if (uri.scheme == "two") 2 else 0 },
|
||||
null
|
||||
)
|
||||
private val manager =
|
||||
SecurityManagers.standard(
|
||||
listOf(Pattern.compile("test:foo/bar")),
|
||||
listOf(Pattern.compile("env:FOO_BAR")),
|
||||
{ uri -> if (uri.scheme == "one") 1 else if (uri.scheme == "two") 2 else 0 },
|
||||
null
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `checkResolveModule() - complete match`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkResolveModule(URI("test:foo/bar"))
|
||||
}
|
||||
val e = catchThrowable { manager.checkResolveModule(URI("test:foo/bar")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkResolveModule() - partial match from start`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkResolveModule(URI("test:foo/bar/baz"))
|
||||
}
|
||||
val e = catchThrowable { manager.checkResolveModule(URI("test:foo/bar/baz")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkResolveModule() - partial match not from start`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(URI("other:test:foo/bar"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkResolveModule(URI("other:test:foo/bar")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkResolveModule() - no match`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(URI("other:uri"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkResolveModule(URI("other:uri")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkResolveModule() - no match #2`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(URI("test:foo/baz"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkResolveModule(URI("test:foo/baz")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkReadResource() - complete match`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkReadResource(URI("env:FOO_BAR"))
|
||||
}
|
||||
val e = catchThrowable { manager.checkReadResource(URI("env:FOO_BAR")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkReadResource() - partial match from start`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkReadResource(URI("env:FOO_BAR_BAZ"))
|
||||
}
|
||||
val e = catchThrowable { manager.checkReadResource(URI("env:FOO_BAR_BAZ")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkReadResource() - partial match not from start`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkReadResource(URI("other:env:FOO_BAR"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkReadResource(URI("other:env:FOO_BAR")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkReadResource() - no match`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkReadResource(URI("other:uri"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkReadResource(URI("other:uri")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkReadResource() - no match #2`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkReadResource(URI("env:FOO_BAZ"))
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkReadResource(URI("env:FOO_BAZ")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkImportModule() - same trust level`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkImportModule(
|
||||
URI("one:foo"),
|
||||
URI("one:bar")
|
||||
)
|
||||
}
|
||||
val e = catchThrowable { manager.checkImportModule(URI("one:foo"), URI("one:bar")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkImportModule() - higher trust level`() {
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkImportModule(
|
||||
URI("one:foo"),
|
||||
URI("two:bar")
|
||||
)
|
||||
manager.checkImportModule(URI("one:foo"), URI("two:bar"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkImportModule() - lower trust level`() {
|
||||
val e = catchThrowable {
|
||||
manager.checkImportModule(
|
||||
URI("two:foo"),
|
||||
URI("one:bar")
|
||||
)
|
||||
}
|
||||
val e = catchThrowable { manager.checkImportModule(URI("two:foo"), URI("one:bar")) }
|
||||
assertThat(e).doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@@ -154,12 +137,13 @@ class SecurityManagersTest {
|
||||
val rootDir = tempDir.resolve("root")
|
||||
Files.createDirectory(rootDir)
|
||||
|
||||
val manager = SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
val manager =
|
||||
SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
|
||||
val path = rootDir.resolve("baz.pkl")
|
||||
Files.createFile(path)
|
||||
@@ -174,12 +158,13 @@ class SecurityManagersTest {
|
||||
fun `can resolve modules and resources under root dir - files don't exist`() {
|
||||
val rootDir = "/foo/bar".toPath()
|
||||
|
||||
val manager = SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
val manager =
|
||||
SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
|
||||
manager.checkResolveModule(Path.of("/foo/bar/baz.pkl").toUri())
|
||||
manager.checkReadResource(Path.of("/foo/bar/baz.pkl").toUri())
|
||||
@@ -189,48 +174,44 @@ class SecurityManagersTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot resolve modules and resources outside root dir - files do exist`(@TempDir tempDir: Path) {
|
||||
fun `cannot resolve modules and resources outside root dir - files do exist`(
|
||||
@TempDir tempDir: Path
|
||||
) {
|
||||
val rootDir = tempDir.resolve("root")
|
||||
Files.createDirectory(rootDir)
|
||||
|
||||
val manager = SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
val manager =
|
||||
SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
|
||||
val path = rootDir.resolve("../baz.pkl")
|
||||
Files.createFile(path)
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(path.toUri())
|
||||
}
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkReadResource(path.toUri())
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkResolveModule(path.toUri()) }
|
||||
assertThrows<SecurityManagerException> { manager.checkReadResource(path.toUri()) }
|
||||
|
||||
val symlink = rootDir.resolve("qux")
|
||||
Files.createSymbolicLink(symlink, tempDir)
|
||||
val path2 = symlink.resolve("baz2.pkl")
|
||||
Files.createFile(path2)
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(path2.toUri())
|
||||
}
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkReadResource(path2.toUri())
|
||||
}
|
||||
assertThrows<SecurityManagerException> { manager.checkResolveModule(path2.toUri()) }
|
||||
assertThrows<SecurityManagerException> { manager.checkReadResource(path2.toUri()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot resolve modules and resources outside root dir - files don't exist`() {
|
||||
val rootDir = "/foo/bar".toPath()
|
||||
|
||||
val manager = SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
val manager =
|
||||
SecurityManagers.standard(
|
||||
listOf(Pattern.compile("file")),
|
||||
listOf(Pattern.compile("file")),
|
||||
SecurityManagers.defaultTrustLevels,
|
||||
rootDir
|
||||
)
|
||||
|
||||
assertThrows<SecurityManagerException> {
|
||||
manager.checkResolveModule(Path.of("/foo/baz.pkl").toUri())
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.core.http.HttpClient
|
||||
|
||||
class StackFrameTransformersTest {
|
||||
@@ -13,21 +28,13 @@ class StackFrameTransformersTest {
|
||||
fun replacePackageUriWithSourceCodeUrl() {
|
||||
PackageServer().use { server ->
|
||||
val httpClient = HttpClient.builder().setTestPort(server.port).build()
|
||||
EvaluatorBuilder.preconfigured()
|
||||
.setHttpClient(httpClient)
|
||||
.build().use {
|
||||
val frame = StackFrame(
|
||||
"package://localhost:0/birds@0.5.0#/Bird.pkl",
|
||||
null,
|
||||
listOf(),
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2)
|
||||
val transformed =
|
||||
StackFrameTransformers.replacePackageUriWithSourceCodeUrl.apply(frame)
|
||||
assertThat(transformed.moduleUri).isEqualTo("https://example.com/birds/v0.5.0/blob/Bird.pkl#L1-L2")
|
||||
}
|
||||
EvaluatorBuilder.preconfigured().setHttpClient(httpClient).build().use {
|
||||
val frame =
|
||||
StackFrame("package://localhost:0/birds@0.5.0#/Bird.pkl", null, listOf(), 1, 1, 2, 2)
|
||||
val transformed = StackFrameTransformers.replacePackageUriWithSourceCodeUrl.apply(frame)
|
||||
assertThat(transformed.moduleUri)
|
||||
.isEqualTo("https://example.com/birds/v0.5.0/blob/Bird.pkl#L1-L2")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -37,23 +52,16 @@ class VersionTest {
|
||||
|
||||
@Test
|
||||
fun `parse invalid version`() {
|
||||
assertThat(Version.parseOrNull("not a version number"))
|
||||
.isNull()
|
||||
assertThat(Version.parseOrNull("not a version number")).isNull()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
Version.parse("not a version number")
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { Version.parse("not a version number") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse too large version`() {
|
||||
assertThrows<IllegalArgumentException> {
|
||||
Version.parse("not a version number")
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { Version.parse("not a version number") }
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
Version.parse("999999999999999.0.0")
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { Version.parse("999999999999999.0.0") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -66,137 +74,80 @@ class VersionTest {
|
||||
|
||||
@Test
|
||||
fun withMethods() {
|
||||
val version = Version.parse("0.0.0")
|
||||
.withMajor(1)
|
||||
.withMinor(2)
|
||||
.withPatch(3)
|
||||
.withPreRelease("rc.1")
|
||||
.withBuild("456.789")
|
||||
val version =
|
||||
Version.parse("0.0.0")
|
||||
.withMajor(1)
|
||||
.withMinor(2)
|
||||
.withPatch(3)
|
||||
.withPreRelease("rc.1")
|
||||
.withBuild("456.789")
|
||||
|
||||
assertThat(version).isEqualTo(Version.parse("1.2.3-rc.1+456.789"))
|
||||
|
||||
val version2 = Version.parse("0.0.0")
|
||||
.withBuild("456.789")
|
||||
.withPreRelease("rc.1")
|
||||
.withPatch(3)
|
||||
.withMinor(2)
|
||||
.withMajor(1)
|
||||
val version2 =
|
||||
Version.parse("0.0.0")
|
||||
.withBuild("456.789")
|
||||
.withPreRelease("rc.1")
|
||||
.withPatch(3)
|
||||
.withMinor(2)
|
||||
.withMajor(1)
|
||||
|
||||
assertThat(version2).isEqualTo(version)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `compareTo()`() {
|
||||
assertThat(
|
||||
Version(1, 2, 3, null, null).compareTo(
|
||||
Version(1, 2, 3, null, null)
|
||||
)
|
||||
).isEqualTo(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "SNAPSHOT", null).compareTo(
|
||||
Version(1, 2, 3, "SNAPSHOT", null)
|
||||
)
|
||||
).isEqualTo(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "alpha", null).compareTo(
|
||||
Version(1, 2, 3, "alpha", null)
|
||||
)
|
||||
).isEqualTo(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "alpha", null).compareTo(
|
||||
Version(1, 2, 3, "alpha", "build123")
|
||||
)
|
||||
).isEqualTo(0)
|
||||
assertThat(Version(1, 2, 3, null, null).compareTo(Version(1, 2, 3, null, null))).isEqualTo(0)
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null).compareTo(Version(1, 2, 3, "SNAPSHOT", null)))
|
||||
.isEqualTo(0)
|
||||
assertThat(Version(1, 2, 3, "alpha", null).compareTo(Version(1, 2, 3, "alpha", null)))
|
||||
.isEqualTo(0)
|
||||
assertThat(Version(1, 2, 3, "alpha", null).compareTo(Version(1, 2, 3, "alpha", "build123")))
|
||||
.isEqualTo(0)
|
||||
|
||||
assertThat(
|
||||
Version(1, 2, 3, null, null).compareTo(
|
||||
Version(2, 2, 3, null, null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, null, null).compareTo(
|
||||
Version(1, 3, 3, null, null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, null, null).compareTo(
|
||||
Version(1, 2, 4, null, null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, null, null).compareTo(Version(2, 2, 3, null, null))).isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, null, null).compareTo(Version(1, 3, 3, null, null))).isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, null, null).compareTo(Version(1, 2, 4, null, null))).isLessThan(0)
|
||||
|
||||
assertThat(
|
||||
Version(2, 2, 3, null, null).compareTo(
|
||||
Version(1, 2, 3, null, null)
|
||||
)
|
||||
).isGreaterThan(0)
|
||||
assertThat(
|
||||
Version(1, 3, 3, null, null).compareTo(
|
||||
Version(1, 2, 3, null, null)
|
||||
)
|
||||
).isGreaterThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 4, null, null).compareTo(
|
||||
Version(1, 2, 3, null, null)
|
||||
)
|
||||
).isGreaterThan(0)
|
||||
assertThat(Version(2, 2, 3, null, null).compareTo(Version(1, 2, 3, null, null)))
|
||||
.isGreaterThan(0)
|
||||
assertThat(Version(1, 3, 3, null, null).compareTo(Version(1, 2, 3, null, null)))
|
||||
.isGreaterThan(0)
|
||||
assertThat(Version(1, 2, 4, null, null).compareTo(Version(1, 2, 3, null, null)))
|
||||
.isGreaterThan(0)
|
||||
|
||||
assertThat(
|
||||
Version(1, 2, 3, "SNAPSHOT", null).compareTo(
|
||||
Version(1, 2, 3, null, null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "alpha", null).compareTo(
|
||||
Version(1, 2, 3, "beta", null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "alpha", "build123").compareTo(
|
||||
Version(1, 2, 3, "beta", null)
|
||||
)
|
||||
).isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null).compareTo(Version(1, 2, 3, null, null)))
|
||||
.isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, "alpha", null).compareTo(Version(1, 2, 3, "beta", null)))
|
||||
.isLessThan(0)
|
||||
assertThat(Version(1, 2, 3, "alpha", "build123").compareTo(Version(1, 2, 3, "beta", null)))
|
||||
.isLessThan(0)
|
||||
|
||||
assertThat(
|
||||
Version(1, 2, 3, null, null).compareTo(
|
||||
Version(1, 2, 3, "SNAPSHOT", null)
|
||||
)
|
||||
).isGreaterThan(0)
|
||||
assertThat(
|
||||
Version(1, 2, 3, "beta", null).compareTo(
|
||||
Version(1, 2, 3, "alpha", "build123")
|
||||
)
|
||||
).isGreaterThan(0)
|
||||
assertThat(Version(1, 2, 3, null, null).compareTo(Version(1, 2, 3, "SNAPSHOT", null)))
|
||||
.isGreaterThan(0)
|
||||
assertThat(Version(1, 2, 3, "beta", null).compareTo(Version(1, 2, 3, "alpha", "build123")))
|
||||
.isGreaterThan(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `compare version with too large numeric pre-release identifier`() {
|
||||
// error is deferred until compareTo(), but should be good enough
|
||||
assertThrows<IllegalArgumentException> {
|
||||
Version(1, 2, 3, "999", null).compareTo(
|
||||
Version(1, 2, 3, "9999999999999999999", null)
|
||||
)
|
||||
Version(1, 2, 3, "999", null).compareTo(Version(1, 2, 3, "9999999999999999999", null))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `equals()`() {
|
||||
assertThat(Version(1, 2, 3, null, null))
|
||||
.isEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null))
|
||||
.isEqualTo(Version(1, 2, 3, "SNAPSHOT", null))
|
||||
assertThat(Version(1, 2, 3, "alpha", null))
|
||||
.isEqualTo(Version(1, 2, 3, "alpha", null))
|
||||
assertThat(Version(1, 2, 3, "beta", "build123"))
|
||||
.isEqualTo(Version(1, 2, 3, "beta", "build456"))
|
||||
assertThat(Version(1, 2, 3, null, null)).isEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null)).isEqualTo(Version(1, 2, 3, "SNAPSHOT", null))
|
||||
assertThat(Version(1, 2, 3, "alpha", null)).isEqualTo(Version(1, 2, 3, "alpha", null))
|
||||
assertThat(Version(1, 2, 3, "beta", "build123")).isEqualTo(Version(1, 2, 3, "beta", "build456"))
|
||||
|
||||
assertThat(Version(1, 3, 3, null, null))
|
||||
.isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 4, null, null))
|
||||
.isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null))
|
||||
.isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "beta", null))
|
||||
.isNotEqualTo(Version(1, 2, 3, "alpha", null))
|
||||
assertThat(Version(1, 3, 3, null, null)).isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 4, null, null)).isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "SNAPSHOT", null)).isNotEqualTo(Version(1, 2, 3, null, null))
|
||||
assertThat(Version(1, 2, 3, "beta", null)).isNotEqualTo(Version(1, 2, 3, "alpha", null))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/**
|
||||
* 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.core
|
||||
|
||||
import java.io.StringWriter
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.util.IoUtils
|
||||
import org.snakeyaml.engine.v2.api.Load
|
||||
import org.snakeyaml.engine.v2.api.LoadSettings
|
||||
import org.pkl.core.util.IoUtils
|
||||
|
||||
class YamlRendererTest {
|
||||
@Test
|
||||
@@ -21,15 +36,17 @@ class YamlRendererTest {
|
||||
val expected = IoUtils.readClassPathResourceAsString(javaClass, "rendererTest.yaml")
|
||||
|
||||
assertThat(output.trim()).isEqualTo(expected.trim())
|
||||
assertThatCode { Load(LoadSettings.builder().build()).loadFromString(output) }.doesNotThrowAnyException()
|
||||
assertThatCode { Load(LoadSettings.builder().build()).loadFromString(output) }
|
||||
.doesNotThrowAnyException()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `render YAML stream`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
stream = new Listing {
|
||||
new Dynamic {
|
||||
name = "Pigeon"
|
||||
@@ -48,9 +65,10 @@ class YamlRendererTest {
|
||||
"Blue Rock Ltd."
|
||||
12345
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val writer = StringWriter()
|
||||
val renderer = ValueRenderers.yaml(writer, 2, true, true)
|
||||
@@ -58,8 +76,9 @@ class YamlRendererTest {
|
||||
renderer.renderDocument(module.getProperty("stream"))
|
||||
val output = writer.toString()
|
||||
|
||||
assertThat(output.trim()).isEqualTo(
|
||||
"""
|
||||
assertThat(output.trim())
|
||||
.isEqualTo(
|
||||
"""
|
||||
name: Pigeon
|
||||
age: 42
|
||||
---
|
||||
@@ -72,14 +91,14 @@ class YamlRendererTest {
|
||||
three: 3
|
||||
--- Blue Rock Ltd.
|
||||
--- 12345
|
||||
""".trimIndent()
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rendered document ends in newline`() {
|
||||
val module = Evaluator.preconfigured()
|
||||
.evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
val module = Evaluator.preconfigured().evaluate(ModuleSource.text("foo { bar = 0 }"))
|
||||
|
||||
for (omitNullProperties in listOf(false, true)) {
|
||||
for (isStream in listOf(false, true)) {
|
||||
@@ -93,18 +112,20 @@ class YamlRendererTest {
|
||||
@Test
|
||||
fun `render truthy strings, octals and number-like strings`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
num1 = "50"
|
||||
num2 = "50.123"
|
||||
`60.123` = "60.123"
|
||||
yes = "yes"
|
||||
truth = "true"
|
||||
octalNumber = "0777"
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val writer = StringWriter()
|
||||
val renderer = ValueRenderers.yaml(writer, 2, true, false)
|
||||
@@ -112,15 +133,17 @@ class YamlRendererTest {
|
||||
renderer.renderDocument(module)
|
||||
val output = writer.toString()
|
||||
|
||||
assertThat(output.trim()).isEqualTo(
|
||||
"""
|
||||
assertThat(output.trim())
|
||||
.isEqualTo(
|
||||
"""
|
||||
num1: '50'
|
||||
num2: '50.123'
|
||||
'60.123': '60.123'
|
||||
'yes': 'yes'
|
||||
truth: 'true'
|
||||
octalNumber: '0777'
|
||||
""".trimIndent()
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
/**
|
||||
* 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.core.ast.builder
|
||||
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.module.ModuleKeys
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.module.ModuleKeys
|
||||
|
||||
class ImportsAndReadsParserTest {
|
||||
@Test
|
||||
fun parse() {
|
||||
val moduleText = """
|
||||
val moduleText =
|
||||
"""
|
||||
amends "foo.pkl"
|
||||
|
||||
import "bar.pkl"
|
||||
@@ -27,18 +43,23 @@ class ImportsAndReadsParserTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
val moduleKey = ModuleKeys.synthetic(URI("repl:text"), moduleText)
|
||||
val imports = ImportsAndReadsParser.parse(moduleKey, moduleKey.resolve(SecurityManagers.defaultManager))
|
||||
assertThat(imports?.map { it.first }).hasSameElementsAs(listOf(
|
||||
"foo.pkl",
|
||||
"bar.pkl",
|
||||
"bazzy/buz.pkl",
|
||||
"qux.pkl",
|
||||
"qux/*.pkl",
|
||||
"/some/dir/chown.txt",
|
||||
"/some/dir/chowner.txt",
|
||||
"/some/dir/*.txt"
|
||||
))
|
||||
val imports =
|
||||
ImportsAndReadsParser.parse(moduleKey, moduleKey.resolve(SecurityManagers.defaultManager))
|
||||
assertThat(imports?.map { it.first })
|
||||
.hasSameElementsAs(
|
||||
listOf(
|
||||
"foo.pkl",
|
||||
"bar.pkl",
|
||||
"bazzy/buz.pkl",
|
||||
"qux.pkl",
|
||||
"qux/*.pkl",
|
||||
"/some/dir/chown.txt",
|
||||
"/some/dir/chowner.txt",
|
||||
"/some/dir/*.txt"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.net.URI
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
|
||||
class DummyHttpClientTest {
|
||||
@Test
|
||||
@@ -13,13 +28,9 @@ class DummyHttpClientTest {
|
||||
val client = HttpClient.dummyClient()
|
||||
val request = HttpRequest.newBuilder(URI("https://example.com")).build()
|
||||
|
||||
assertThrows<AssertionError> {
|
||||
client.send(request, HttpResponse.BodyHandlers.discarding())
|
||||
}
|
||||
assertThrows<AssertionError> { client.send(request, HttpResponse.BodyHandlers.discarding()) }
|
||||
|
||||
assertThrows<AssertionError> {
|
||||
client.send(request, HttpResponse.BodyHandlers.discarding())
|
||||
}
|
||||
assertThrows<AssertionError> { client.send(request, HttpResponse.BodyHandlers.discarding()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.core.Release
|
||||
import java.net.URI
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse
|
||||
@@ -14,19 +22,25 @@ import java.nio.file.Path
|
||||
import java.time.Duration
|
||||
import kotlin.io.path.createFile
|
||||
import kotlin.io.path.readBytes
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.core.Release
|
||||
|
||||
class HttpClientTest {
|
||||
@Test
|
||||
fun `can build default client`() {
|
||||
val client = assertDoesNotThrow {
|
||||
HttpClient.builder().build()
|
||||
}
|
||||
val client = assertDoesNotThrow { HttpClient.builder().build() }
|
||||
|
||||
assertThat(client).isInstanceOf(RequestRewritingClient::class.java)
|
||||
client as RequestRewritingClient
|
||||
|
||||
val release = Release.current()
|
||||
assertThat(client.userAgent).isEqualTo("Pkl/${release.version()} (${release.os()}; ${release.flavor()})")
|
||||
assertThat(client.userAgent)
|
||||
.isEqualTo("Pkl/${release.version()} (${release.os()}; ${release.flavor()})")
|
||||
assertThat(client.requestTimeout).isEqualTo(Duration.ofSeconds(60))
|
||||
|
||||
assertThat(client.delegate).isInstanceOf(JdkHttpClient::class.java)
|
||||
@@ -37,11 +51,12 @@ class HttpClientTest {
|
||||
|
||||
@Test
|
||||
fun `can build custom client`() {
|
||||
val client = HttpClient.builder()
|
||||
.setUserAgent("Agent 1")
|
||||
.setRequestTimeout(Duration.ofHours(86))
|
||||
.setConnectTimeout(Duration.ofMinutes(42))
|
||||
.build() as RequestRewritingClient
|
||||
val client =
|
||||
HttpClient.builder()
|
||||
.setUserAgent("Agent 1")
|
||||
.setRequestTimeout(Duration.ofHours(86))
|
||||
.setConnectTimeout(Duration.ofMinutes(42))
|
||||
.build() as RequestRewritingClient
|
||||
|
||||
assertThat(client.userAgent).isEqualTo("Agent 1")
|
||||
assertThat(client.requestTimeout).isEqualTo(Duration.ofHours(86))
|
||||
@@ -68,27 +83,24 @@ class HttpClientTest {
|
||||
fun `certificate file cannot be empty`(@TempDir tempDir: Path) {
|
||||
val file = tempDir.resolve("certs.pem").createFile()
|
||||
|
||||
val e = assertThrows<HttpClientInitException> {
|
||||
HttpClient.builder().addCertificates(file).build()
|
||||
}
|
||||
val e =
|
||||
assertThrows<HttpClientInitException> { HttpClient.builder().addCertificates(file).build() }
|
||||
|
||||
assertThat(e).hasMessageContaining("empty")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can load built-in certificates`() {
|
||||
assertDoesNotThrow {
|
||||
HttpClient.builder().build()
|
||||
}
|
||||
assertDoesNotThrow { HttpClient.builder().build() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be closed multiple times`() {
|
||||
val client = HttpClient.builder().build()
|
||||
|
||||
assertDoesNotThrow {
|
||||
client.close()
|
||||
client.close()
|
||||
assertDoesNotThrow {
|
||||
client.close()
|
||||
client.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,46 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import java.net.URI
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse.BodyHandlers
|
||||
import java.nio.file.Path
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.createTempFile
|
||||
import org.pkl.commons.writeString
|
||||
import java.net.URI
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse.BodyHandlers
|
||||
import java.nio.file.Path
|
||||
|
||||
class LazyHttpClientTest {
|
||||
@Test
|
||||
fun `builds underlying client on first send`(@TempDir tempDir: Path) {
|
||||
val certFile = tempDir.resolve("cert.pem").apply { writeString("broken") }
|
||||
val client = HttpClient.builder()
|
||||
.addCertificates(certFile)
|
||||
.buildLazily()
|
||||
val client = HttpClient.builder().addCertificates(certFile).buildLazily()
|
||||
val request = HttpRequest.newBuilder(URI("https://example.com")).build()
|
||||
|
||||
assertThrows<HttpClientInitException> {
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
}
|
||||
|
||||
assertThrows<HttpClientInitException> { client.send(request, BodyHandlers.discarding()) }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `does not build underlying client unnecessarily`(@TempDir tempDir: Path) {
|
||||
val certFile = tempDir.createTempFile().apply { writeString("broken") }
|
||||
val client = HttpClient.builder()
|
||||
.addCertificates(certFile)
|
||||
.buildLazily()
|
||||
|
||||
val client = HttpClient.builder().addCertificates(certFile).buildLazily()
|
||||
|
||||
assertDoesNotThrow {
|
||||
client.close()
|
||||
client.close()
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import java.net.URI
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
|
||||
@Suppress("HttpUrlsUsage")
|
||||
class NoProxyRuleTest {
|
||||
@@ -44,7 +59,7 @@ class NoProxyRuleTest {
|
||||
assertFalse(noProxyRule.matches(URI("https://ooofoo.com")))
|
||||
assertFalse(noProxyRule.matches(URI("pkl:foo.com")))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `hostname matching, with port`() {
|
||||
val noProxyRule = NoProxyRule("foo.com:5000")
|
||||
@@ -52,7 +67,7 @@ class NoProxyRuleTest {
|
||||
assertFalse(noProxyRule.matches(URI("https://foo.com")))
|
||||
assertFalse(noProxyRule.matches(URI("https://foo.com:3000")))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `ipv4 address literal matching`() {
|
||||
val noProxyRule = NoProxyRule("192.168.1.1")
|
||||
@@ -95,7 +110,7 @@ class NoProxyRuleTest {
|
||||
assertFalse(noProxyRule.matches(URI("https://[::2]")))
|
||||
assertFalse(noProxyRule.matches(URI("https://[::2]:5000")))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `ipv4 port from protocol`() {
|
||||
val noProxyRuleHttp = NoProxyRule("192.168.1.1:80")
|
||||
@@ -104,7 +119,7 @@ class NoProxyRuleTest {
|
||||
assertTrue(noProxyRuleHttp.matches(URI("https://192.168.1.1:80")))
|
||||
assertFalse(noProxyRuleHttp.matches(URI("https://192.168.1.1")))
|
||||
assertFalse(noProxyRuleHttp.matches(URI("https://192.168.1.1:5000")))
|
||||
|
||||
|
||||
val noProxyRuleHttps = NoProxyRule("192.168.1.1:443")
|
||||
assertTrue(noProxyRuleHttps.matches(URI("https://192.168.1.1")))
|
||||
assertTrue(noProxyRuleHttps.matches(URI("http://192.168.1.1:443")))
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import org.pkl.commons.test.FakeHttpResponse
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse
|
||||
import org.pkl.commons.test.FakeHttpResponse
|
||||
|
||||
class RequestCapturingClient : HttpClient {
|
||||
lateinit var request: HttpRequest
|
||||
|
||||
|
||||
override fun <T : Any> send(
|
||||
request: HttpRequest,
|
||||
responseBodyHandler: HttpResponse.BodyHandler<T>
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
/**
|
||||
* 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.core.http
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatList
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
import java.net.http.HttpClient as JdkHttpClient
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpRequest.BodyPublishers
|
||||
import java.net.http.HttpResponse.BodyHandlers
|
||||
import java.time.Duration
|
||||
import java.net.http.HttpClient as JdkHttpClient
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatList
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class RequestRewritingClientTest {
|
||||
private val captured = RequestCapturingClient()
|
||||
@@ -19,17 +34,18 @@ class RequestRewritingClientTest {
|
||||
@Test
|
||||
fun `fills in missing User-Agent header`() {
|
||||
client.send(exampleRequest, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThatList(captured.request.headers().allValues("User-Agent")).containsOnly("Pkl")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `overrides existing User-Agent headers`() {
|
||||
val request = HttpRequest.newBuilder(exampleUri)
|
||||
.header("User-Agent", "Agent 1")
|
||||
.header("User-Agent", "Agent 2")
|
||||
.build()
|
||||
|
||||
val request =
|
||||
HttpRequest.newBuilder(exampleUri)
|
||||
.header("User-Agent", "Agent 1")
|
||||
.header("User-Agent", "Agent 2")
|
||||
.build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
assertThatList(captured.request.headers().allValues("User-Agent")).containsOnly("Pkl")
|
||||
@@ -38,16 +54,14 @@ class RequestRewritingClientTest {
|
||||
@Test
|
||||
fun `fills in missing request timeout`() {
|
||||
client.send(exampleRequest, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThat(captured.request.timeout()).hasValue(Duration.ofSeconds(42))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `leaves existing request timeout intact`() {
|
||||
val request = HttpRequest.newBuilder(exampleUri)
|
||||
.timeout(Duration.ofMinutes(33))
|
||||
.build()
|
||||
|
||||
val request = HttpRequest.newBuilder(exampleUri).timeout(Duration.ofMinutes(33)).build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
assertThat(captured.request.timeout()).hasValue(Duration.ofMinutes(33))
|
||||
@@ -62,12 +76,10 @@ class RequestRewritingClientTest {
|
||||
|
||||
@Test
|
||||
fun `leaves existing HTTP version intact`() {
|
||||
val request = HttpRequest.newBuilder(exampleUri)
|
||||
.version(JdkHttpClient.Version.HTTP_1_1)
|
||||
.build()
|
||||
|
||||
val request = HttpRequest.newBuilder(exampleUri).version(JdkHttpClient.Version.HTTP_1_1).build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThat(captured.request.version()).hasValue(JdkHttpClient.Version.HTTP_1_1)
|
||||
}
|
||||
|
||||
@@ -79,30 +91,26 @@ class RequestRewritingClientTest {
|
||||
|
||||
assertThat(captured.request.method()).isEqualTo("GET")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `leaves explicit method intact`() {
|
||||
val request = HttpRequest.newBuilder(exampleUri)
|
||||
.DELETE()
|
||||
.build()
|
||||
|
||||
val request = HttpRequest.newBuilder(exampleUri).DELETE().build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThat(captured.request.method()).isEqualTo("DELETE")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `leaves body publisher intact`() {
|
||||
val publisher = BodyPublishers.ofString("body")
|
||||
val request = HttpRequest.newBuilder(exampleUri)
|
||||
.PUT(publisher)
|
||||
.build()
|
||||
|
||||
val request = HttpRequest.newBuilder(exampleUri).PUT(publisher).build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThat(captured.request.bodyPublisher().get()).isSameAs(publisher)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `rewrites port 0 if test port is set`() {
|
||||
val captured = RequestCapturingClient()
|
||||
@@ -113,15 +121,13 @@ class RequestRewritingClientTest {
|
||||
|
||||
assertThat(captured.request.uri().port).isEqualTo(5000)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `leaves port 0 intact if no test port is set`() {
|
||||
val request = HttpRequest.newBuilder(URI("https://example.com:0")).build()
|
||||
|
||||
client.send(request, BodyHandlers.discarding())
|
||||
|
||||
|
||||
assertThat(captured.request.uri().port).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.outputStream
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
@@ -7,10 +26,6 @@ import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.SecurityManagers
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.outputStream
|
||||
|
||||
class ModuleKeyFactoriesTest {
|
||||
@Test
|
||||
@@ -78,9 +93,7 @@ class ModuleKeyFactoriesTest {
|
||||
fun `module path - jar files`(@TempDir tempDir: Path) {
|
||||
val jarFile = tempDir.resolve("test.jar")
|
||||
jarFile.outputStream().use { outStream ->
|
||||
javaClass.getResourceAsStream("test.jar")!!.use { inStream ->
|
||||
inStream.copyTo(outStream)
|
||||
}
|
||||
javaClass.getResourceAsStream("test.jar")!!.use { inStream -> inStream.copyTo(outStream) }
|
||||
}
|
||||
|
||||
val factory = ModuleKeyFactories.modulePath(ModulePathResolver(listOf(jarFile)))
|
||||
|
||||
@@ -1,19 +1,34 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import java.io.FileNotFoundException
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.SecurityManagers
|
||||
|
||||
class ModuleKeysTest {
|
||||
private val securityManager = SecurityManagers.defaultManager
|
||||
@@ -46,9 +61,7 @@ class ModuleKeysTest {
|
||||
|
||||
@Test
|
||||
fun `standard library - wrong scheme`() {
|
||||
assertThrows<IllegalArgumentException> {
|
||||
ModuleKeys.standardLibrary(URI("other:base"))
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { ModuleKeys.standardLibrary(URI("other:base")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,18 +110,18 @@ class ModuleKeysTest {
|
||||
|
||||
@Test
|
||||
fun `class path - module not found`() {
|
||||
val key = ModuleKeys.classPath(URI("modulepath:/non/existing"), ModuleKeysTest::class.java.classLoader)
|
||||
val key =
|
||||
ModuleKeys.classPath(URI("modulepath:/non/existing"), ModuleKeysTest::class.java.classLoader)
|
||||
|
||||
assertThrows<FileNotFoundException> {
|
||||
key.resolve(SecurityManagers.defaultManager)
|
||||
}
|
||||
assertThrows<FileNotFoundException> { key.resolve(SecurityManagers.defaultManager) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `class path - missing leading slash`() {
|
||||
val e = assertThrows<IllegalArgumentException> {
|
||||
ModuleKeys.classPath(URI("modulepath:foo/bar.pkl"), ModuleKeysTest::class.java.classLoader)
|
||||
}
|
||||
val e =
|
||||
assertThrows<IllegalArgumentException> {
|
||||
ModuleKeys.classPath(URI("modulepath:foo/bar.pkl"), ModuleKeysTest::class.java.classLoader)
|
||||
}
|
||||
assertThat(e).hasMessageContaining("`/`")
|
||||
}
|
||||
|
||||
@@ -127,10 +140,8 @@ class ModuleKeysTest {
|
||||
|
||||
val resolvedKey = key.resolve(securityManager)
|
||||
|
||||
assertThat(resolvedKey.uri.scheme)
|
||||
.isEqualTo("file")
|
||||
assertThat(resolvedKey.loadSource())
|
||||
.isEqualTo("age = 40")
|
||||
assertThat(resolvedKey.uri.scheme).isEqualTo("file")
|
||||
assertThat(resolvedKey.loadSource()).isEqualTo("age = 40")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,61 +155,55 @@ class ModuleKeysTest {
|
||||
fun `module path - module not found`() {
|
||||
val key = ModuleKeys.modulePath(URI("modulepath:/non/existing"), ModulePathResolver(listOf()))
|
||||
|
||||
assertThrows<FileNotFoundException> {
|
||||
key.resolve(SecurityManagers.defaultManager)
|
||||
}
|
||||
assertThrows<FileNotFoundException> { key.resolve(SecurityManagers.defaultManager) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `module path - missing leading slash`() {
|
||||
val e = assertThrows<IllegalArgumentException> {
|
||||
ModuleKeys.modulePath(URI("modulepath:foo/bar.pkl"), ModulePathResolver(listOf()))
|
||||
}
|
||||
val e =
|
||||
assertThrows<IllegalArgumentException> {
|
||||
ModuleKeys.modulePath(URI("modulepath:foo/bar.pkl"), ModulePathResolver(listOf()))
|
||||
}
|
||||
assertThat(e).hasMessageContaining("`/`")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `package - no version`() {
|
||||
val e = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package://localhost:0/birds#/Bird.pkl"))
|
||||
}
|
||||
val e =
|
||||
assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package://localhost:0/birds#/Bird.pkl"))
|
||||
}
|
||||
assertThat(e).hasMessageContaining("A package URI must have its path suffixed by its version")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `package - invalid semver`() {
|
||||
val e = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package://localhost:0/birds@notAVersion#/Bird.pkl"))
|
||||
}
|
||||
val e =
|
||||
assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package://localhost:0/birds@notAVersion#/Bird.pkl"))
|
||||
}
|
||||
assertThat(e).hasMessageContaining("`notAVersion` could not be parsed")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `package - missing leading slash`() {
|
||||
val e = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package:invalid"))
|
||||
}
|
||||
assertThat(e).hasMessageContaining("Module URI `package:invalid` is missing a `/` after `package:`")
|
||||
val e = assertThrows<URISyntaxException> { ModuleKeys.pkg(URI("package:invalid")) }
|
||||
assertThat(e)
|
||||
.hasMessageContaining("Module URI `package:invalid` is missing a `/` after `package:`")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `package - missing authority`() {
|
||||
val e = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package:/not/a/valid/path"))
|
||||
}
|
||||
val e = assertThrows<URISyntaxException> { ModuleKeys.pkg(URI("package:/not/a/valid/path")) }
|
||||
assertThat(e).hasMessageContaining("Package URIs must have an authority component")
|
||||
|
||||
val e2 = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package:///not/a/valid/path"))
|
||||
}
|
||||
val e2 = assertThrows<URISyntaxException> { ModuleKeys.pkg(URI("package:///not/a/valid/path")) }
|
||||
assertThat(e2).hasMessageContaining("Package URIs must have an authority component")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `package - missing path`() {
|
||||
val e = assertThrows<URISyntaxException> {
|
||||
ModuleKeys.pkg(URI("package://example.com"))
|
||||
}
|
||||
val e = assertThrows<URISyntaxException> { ModuleKeys.pkg(URI("package://example.com")) }
|
||||
assertThat(e).hasMessageContaining("Package URIs must have a path component")
|
||||
}
|
||||
|
||||
@@ -234,11 +239,8 @@ class ModuleKeysTest {
|
||||
val uri = URI("repl:foo")
|
||||
val key = ModuleKeys.genericUrl(uri)
|
||||
|
||||
val e = assertThrows<MalformedURLException> {
|
||||
key.resolve(securityManager)
|
||||
}
|
||||
val e = assertThrows<MalformedURLException> { key.resolve(securityManager) }
|
||||
|
||||
assertThat(e)
|
||||
.hasMessage("unknown protocol: repl")
|
||||
assertThat(e).hasMessage("unknown protocol: repl")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import java.net.URI
|
||||
@@ -26,9 +41,7 @@ class ResolvedModuleKeysTest {
|
||||
fun `url()`(@TempDir tempDir: Path) {
|
||||
val path = tempDir.createTempFile().writeString("x = 1")
|
||||
val resolvedUri = URI("test:resolved.uri")
|
||||
val resolved = ResolvedModuleKeys.url(
|
||||
module, resolvedUri, path.toUri().toURL()
|
||||
)
|
||||
val resolved = ResolvedModuleKeys.url(module, resolvedUri, path.toUri().toURL())
|
||||
|
||||
assertThat(resolved.original).isSameAs(module)
|
||||
assertThat(resolved.uri).isEqualTo(resolvedUri)
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
import org.pkl.core.PClassInfo
|
||||
import org.pkl.core.PModule
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
|
||||
class ServiceProviderTest {
|
||||
@Test
|
||||
fun `load module through service provider`() {
|
||||
val module = Evaluator
|
||||
.preconfigured()
|
||||
.evaluate(ModuleSource.uri(URI("test:foo")))
|
||||
val module = Evaluator.preconfigured().evaluate(ModuleSource.uri(URI("test:foo")))
|
||||
|
||||
val uri = URI("modulepath:/org/pkl/core/module/testFactoryTest.pkl")
|
||||
Assertions.assertThat(module).isEqualTo(
|
||||
PModule(
|
||||
uri,
|
||||
"testFactoryTest",
|
||||
PClassInfo.forModuleClass("testFactoryTest", uri),
|
||||
mapOf("name" to "Pigeon", "age" to 40L)
|
||||
Assertions.assertThat(module)
|
||||
.isEqualTo(
|
||||
PModule(
|
||||
uri,
|
||||
"testFactoryTest",
|
||||
PClassInfo.forModuleClass("testFactoryTest", uri),
|
||||
mapOf("name" to "Pigeon", "age" to 40L)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.module
|
||||
|
||||
import java.net.URI
|
||||
|
||||
@@ -1,33 +1,54 @@
|
||||
package org.pkl.core.packages;
|
||||
/**
|
||||
* 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.core.packages
|
||||
|
||||
import org.pkl.core.Version
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.net.URI
|
||||
import java.nio.charset.StandardCharsets
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Version
|
||||
|
||||
class DependencyMetadataTest {
|
||||
private val dependencyMetadata = DependencyMetadata(
|
||||
"my-proj-name",
|
||||
PackageUri("package://example.com/my-proj-name@0.10.0"),
|
||||
Version.parse("0.10.0"),
|
||||
URI("https://example.com/foo/bar@0.5.3.zip"),
|
||||
Checksums("abc123"),
|
||||
mapOf(
|
||||
"foo" to Dependency.RemoteDependency(PackageUri("package://example.com/foo@0.5.3"), Checksums("abc123")),
|
||||
),
|
||||
"https://example.com/my/source/0.5.3/blob%{path}#L%{line}-L%{endLine}",
|
||||
URI("https://example.com/my/source"),
|
||||
URI("https://example.com/my/docs"),
|
||||
"MIT",
|
||||
"The MIT License, you know it",
|
||||
listOf("birdy@bird.com"),
|
||||
URI("https://example.com/issues"),
|
||||
"Some package description"
|
||||
)
|
||||
private val dependencyMetadata =
|
||||
DependencyMetadata(
|
||||
"my-proj-name",
|
||||
PackageUri("package://example.com/my-proj-name@0.10.0"),
|
||||
Version.parse("0.10.0"),
|
||||
URI("https://example.com/foo/bar@0.5.3.zip"),
|
||||
Checksums("abc123"),
|
||||
mapOf(
|
||||
"foo" to
|
||||
Dependency.RemoteDependency(
|
||||
PackageUri("package://example.com/foo@0.5.3"),
|
||||
Checksums("abc123")
|
||||
),
|
||||
),
|
||||
"https://example.com/my/source/0.5.3/blob%{path}#L%{line}-L%{endLine}",
|
||||
URI("https://example.com/my/source"),
|
||||
URI("https://example.com/my/docs"),
|
||||
"MIT",
|
||||
"The MIT License, you know it",
|
||||
listOf("birdy@bird.com"),
|
||||
URI("https://example.com/issues"),
|
||||
"Some package description"
|
||||
)
|
||||
|
||||
private val dependencyMetadataStr = """
|
||||
private val dependencyMetadataStr =
|
||||
"""
|
||||
{
|
||||
"name": "my-proj-name",
|
||||
"packageUri": "package://example.com/my-proj-name@0.10.0",
|
||||
@@ -55,7 +76,8 @@ class DependencyMetadataTest {
|
||||
"issueTracker": "https://example.com/issues",
|
||||
"description": "Some package description"
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
@Test
|
||||
fun parse() {
|
||||
@@ -64,10 +86,11 @@ class DependencyMetadataTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeTo(){
|
||||
val str = ByteArrayOutputStream()
|
||||
.apply { dependencyMetadata.writeTo(this) }
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
fun writeTo() {
|
||||
val str =
|
||||
ByteArrayOutputStream()
|
||||
.apply { dependencyMetadata.writeTo(this) }
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
assertThat(str).isEqualTo(dependencyMetadataStr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
/**
|
||||
* 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.core.packages
|
||||
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.readBytes
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
@@ -11,31 +31,27 @@ import org.pkl.commons.readString
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.test.listFilesRecursively
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.module.PathElement
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.readBytes
|
||||
|
||||
class PackageResolversTest {
|
||||
abstract class AbstractPackageResolverTest {
|
||||
|
||||
abstract val resolver: PackageResolver
|
||||
|
||||
private val packageRoot = FileTestUtils.rootProjectDir.resolve("pkl-commons-test/src/main/files/packages")
|
||||
private val packageRoot =
|
||||
FileTestUtils.rootProjectDir.resolve("pkl-commons-test/src/main/files/packages")
|
||||
|
||||
companion object {
|
||||
private val packageServer = PackageServer()
|
||||
|
||||
|
||||
@JvmStatic
|
||||
@AfterAll
|
||||
fun afterAll() {
|
||||
packageServer.close()
|
||||
}
|
||||
|
||||
|
||||
val httpClient: HttpClient by lazy {
|
||||
HttpClient.builder()
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
@@ -46,105 +62,107 @@ class PackageResolversTest {
|
||||
|
||||
@Test
|
||||
fun `get module bytes`() {
|
||||
val expectedBirdModule = packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readString(StandardCharsets.UTF_8)
|
||||
val expectedBirdModule =
|
||||
packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readString(StandardCharsets.UTF_8)
|
||||
val assetUri = PackageAssetUri("package://localhost:0/birds@0.5.0#/Bird.pkl")
|
||||
val birdModule = resolver
|
||||
.getBytes(assetUri, false, null)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
val birdModule = resolver.getBytes(assetUri, false, null).toString(StandardCharsets.UTF_8)
|
||||
assertThat(birdModule).isEqualTo(expectedBirdModule)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get directory`() {
|
||||
val assetUri = PackageAssetUri("package://localhost:0/birds@0.5.0#/")
|
||||
val err = assertThrows<IOException> {
|
||||
resolver
|
||||
.getBytes(assetUri, false, null)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
val err =
|
||||
assertThrows<IOException> {
|
||||
resolver.getBytes(assetUri, false, null).toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
assertThat(err).hasMessage("Is a directory")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get directory, allowing directory reads`() {
|
||||
val assetUri = PackageAssetUri("package://localhost:0/birds@0.5.0#/")
|
||||
val bytes = resolver
|
||||
.getBytes(assetUri, true, null)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
assertThat(bytes).isEqualTo("""
|
||||
val bytes = resolver.getBytes(assetUri, true, null).toString(StandardCharsets.UTF_8)
|
||||
assertThat(bytes)
|
||||
.isEqualTo(
|
||||
"""
|
||||
Bird.pkl
|
||||
allFruit.pkl
|
||||
catalog
|
||||
catalog.pkl
|
||||
some
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get module bytes resolving path`() {
|
||||
val expectedBirdModule = packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readString(StandardCharsets.UTF_8)
|
||||
val expectedBirdModule =
|
||||
packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readString(StandardCharsets.UTF_8)
|
||||
val assetUri = PackageAssetUri("package://localhost:0/birds@0.5.0#/foo/../Bird.pkl")
|
||||
val birdModule = resolver
|
||||
.getBytes(assetUri, false, null)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
val birdModule = resolver.getBytes(assetUri, false, null).toString(StandardCharsets.UTF_8)
|
||||
assertThat(birdModule).isEqualTo(expectedBirdModule)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list path elements at root`() {
|
||||
// cast to set to avoid sort issues
|
||||
val elements = resolver
|
||||
.listElements(PackageAssetUri("package://localhost:0/birds@0.5.0#/"), null)
|
||||
.toSet()
|
||||
assertThat(elements).isEqualTo(
|
||||
setOf(
|
||||
PathElement("some", true),
|
||||
PathElement("catalog", true),
|
||||
PathElement("Bird.pkl", false),
|
||||
PathElement("allFruit.pkl", false),
|
||||
PathElement("catalog.pkl", false)
|
||||
val elements =
|
||||
resolver.listElements(PackageAssetUri("package://localhost:0/birds@0.5.0#/"), null).toSet()
|
||||
assertThat(elements)
|
||||
.isEqualTo(
|
||||
setOf(
|
||||
PathElement("some", true),
|
||||
PathElement("catalog", true),
|
||||
PathElement("Bird.pkl", false),
|
||||
PathElement("allFruit.pkl", false),
|
||||
PathElement("catalog.pkl", false)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get multiple assets`() {
|
||||
val bird = resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/birds@0.5.0#/Bird.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
val swallow = resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/birds@0.5.0#/catalog/Swallow.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
val bird =
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/birds@0.5.0#/Bird.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
val swallow =
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/birds@0.5.0#/catalog/Swallow.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
assertThat(bird).isEqualTo(packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readBytes())
|
||||
assertThat(swallow).isEqualTo(packageRoot.resolve("birds@0.5.0/package/catalog/Swallow.pkl").readBytes())
|
||||
assertThat(swallow)
|
||||
.isEqualTo(packageRoot.resolve("birds@0.5.0/package/catalog/Swallow.pkl").readBytes())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list path elements in nested directory`() {
|
||||
// cast to set to avoid sort issues
|
||||
val elements = resolver.listElements(PackageAssetUri("package://localhost:0/birds@0.5.0#/catalog/"), null).toSet()
|
||||
assertThat(elements).isEqualTo(
|
||||
setOf(
|
||||
PathElement("Ostritch.pkl", false),
|
||||
PathElement("Swallow.pkl", false),
|
||||
val elements =
|
||||
resolver
|
||||
.listElements(PackageAssetUri("package://localhost:0/birds@0.5.0#/catalog/"), null)
|
||||
.toSet()
|
||||
assertThat(elements)
|
||||
.isEqualTo(
|
||||
setOf(
|
||||
PathElement("Ostritch.pkl", false),
|
||||
PathElement("Swallow.pkl", false),
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getBytes() throws FileNotFound if package exists but path does not`() {
|
||||
assertThrows<FileNotFoundException> {
|
||||
resolver
|
||||
.getBytes(
|
||||
PackageAssetUri("package://localhost:0/birds@0.5.0#/Horse.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
.getBytes(PackageAssetUri("package://localhost:0/birds@0.5.0#/Horse.pkl"), false, null)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
@@ -156,7 +174,8 @@ class PackageResolversTest {
|
||||
.getBytes(
|
||||
PackageAssetUri("package://localhost:0/not-a-package@0.5.0#/Horse.pkl"),
|
||||
false,
|
||||
null)
|
||||
null
|
||||
)
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
@@ -164,26 +183,35 @@ class PackageResolversTest {
|
||||
@Test
|
||||
fun `requires package zip to be an HTTPS URI`() {
|
||||
assertThatCode {
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/badPackageZipUrl@1.0.0#/Bug.pkl"),
|
||||
false,
|
||||
null)
|
||||
}
|
||||
.hasMessage("Expected the zip asset for package `package://localhost:0/badPackageZipUrl@1.0.0` to be an HTTPS URI, but got `ftp://wait/a/minute`.")
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/badPackageZipUrl@1.0.0#/Bug.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
}
|
||||
.hasMessage(
|
||||
"Expected the zip asset for package `package://localhost:0/badPackageZipUrl@1.0.0` to be an HTTPS URI, but got `ftp://wait/a/minute`."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `throws if package checksum is invalid`() {
|
||||
val error = assertThrows<PackageLoadError> {
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/badChecksum@1.0.0#/Bug.pkl"),
|
||||
false,
|
||||
null)
|
||||
}
|
||||
assertThat(error).hasMessageContaining("""
|
||||
val error =
|
||||
assertThrows<PackageLoadError> {
|
||||
resolver.getBytes(
|
||||
PackageAssetUri("package://localhost:0/badChecksum@1.0.0#/Bug.pkl"),
|
||||
false,
|
||||
null
|
||||
)
|
||||
}
|
||||
assertThat(error)
|
||||
.hasMessageContaining(
|
||||
"""
|
||||
Computed checksum: "a6bf858cdd1c09da475c2abe50525902580910ee5cc1ff624999170591bf8f69"
|
||||
Expected checksum: "intentionally bogus checksum"
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,12 +233,16 @@ class PackageResolversTest {
|
||||
}
|
||||
}
|
||||
|
||||
override val resolver: PackageResolver = PackageResolvers.DiskCachedPackageResolver(
|
||||
SecurityManagers.defaultManager, httpClient, cacheDir)
|
||||
override val resolver: PackageResolver =
|
||||
PackageResolvers.DiskCachedPackageResolver(
|
||||
SecurityManagers.defaultManager,
|
||||
httpClient,
|
||||
cacheDir
|
||||
)
|
||||
}
|
||||
|
||||
class InMemoryPackageResolverTest : AbstractPackageResolverTest() {
|
||||
override val resolver: PackageResolver = PackageResolvers.InMemoryPackageResolver(
|
||||
SecurityManagers.defaultManager, httpClient)
|
||||
override val resolver: PackageResolver =
|
||||
PackageResolvers.InMemoryPackageResolver(SecurityManagers.defaultManager, httpClient)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.parser
|
||||
|
||||
import org.antlr.v4.runtime.CommonToken
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
/**
|
||||
* 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.core.parser
|
||||
|
||||
import org.pkl.core.Evaluator
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
// tests whitespace handling in multi-line string literals that cannot be reliably tested via snippets
|
||||
// tests whitespace handling in multi-line string literals that cannot be reliably tested via
|
||||
// snippets
|
||||
// (e.g. due to editors not displaying and/or automatically removing whitespace)
|
||||
class MultiLineStringLiteralTest {
|
||||
private val evaluator = Evaluator.preconfigured()
|
||||
|
||||
@Test
|
||||
fun `multi-line strings have unix newlines`() {
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"x = \"\"\"\none\rtwo\nthree\r\nfour\n\"\"\""
|
||||
)
|
||||
)
|
||||
val module =
|
||||
evaluator.evaluate(ModuleSource.text("x = \"\"\"\none\rtwo\nthree\r\nfour\n\"\"\""))
|
||||
assertThat(module.properties["x"]).isEqualTo("one\ntwo\nthree\nfour")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `raw multi-line strings have unix newlines`() {
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text("x = #\"\"\"\none\rtwo\nthree\r\nfour\n\"\"\"#")
|
||||
)
|
||||
val module =
|
||||
evaluator.evaluate(ModuleSource.text("x = #\"\"\"\none\rtwo\nthree\r\nfour\n\"\"\"#"))
|
||||
assertThat(module.properties["x"]).isEqualTo("one\ntwo\nthree\nfour")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
/**
|
||||
* 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.core.parser
|
||||
|
||||
import org.pkl.core.Evaluator
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
class ShebangTest {
|
||||
@@ -10,15 +25,17 @@ class ShebangTest {
|
||||
|
||||
@Test
|
||||
fun `shebang is ignored`() {
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
#!/usr/local/bin/pkl
|
||||
x = 1
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat (module.properties["x"]).isEqualTo(1L)
|
||||
assertThat(module.properties["x"]).isEqualTo(1L)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
/**
|
||||
* 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.core.project
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.charset.StandardCharsets
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -7,23 +24,21 @@ import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.toPath
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.PklException
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.packages.PackageResolver
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
class ProjectDependenciesResolverTest {
|
||||
companion object {
|
||||
private val packageServer = PackageServer()
|
||||
|
||||
|
||||
@JvmStatic
|
||||
@AfterAll
|
||||
fun afterAll() {
|
||||
packageServer.close()
|
||||
}
|
||||
|
||||
|
||||
val httpClient: HttpClient by lazy {
|
||||
HttpClient.builder()
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
@@ -36,13 +51,17 @@ class ProjectDependenciesResolverTest {
|
||||
fun resolveDependencies() {
|
||||
val project2Path = javaClass.getResource("project2/PklProject")!!.toURI().toPath()
|
||||
val project = Project.loadFromPath(project2Path)
|
||||
val packageResolver = PackageResolver.getInstance(SecurityManagers.defaultManager, httpClient, null)
|
||||
val packageResolver =
|
||||
PackageResolver.getInstance(SecurityManagers.defaultManager, httpClient, null)
|
||||
val deps = ProjectDependenciesResolver(project, packageResolver, System.out.writer()).resolve()
|
||||
val strDeps = ByteArrayOutputStream()
|
||||
.apply { deps.writeTo(this) }
|
||||
.toByteArray()
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
assertThat(strDeps).isEqualTo("""
|
||||
val strDeps =
|
||||
ByteArrayOutputStream()
|
||||
.apply { deps.writeTo(this) }
|
||||
.toByteArray()
|
||||
.toString(StandardCharsets.UTF_8)
|
||||
assertThat(strDeps)
|
||||
.isEqualTo(
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
@@ -67,22 +86,30 @@ class ProjectDependenciesResolverTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `fails if project declares a package with an incorrect checksum`() {
|
||||
val projectPath = javaClass.getResource("badProjectChecksum/PklProject")!!.toURI().toPath()
|
||||
val project = Project.loadFromPath(projectPath)
|
||||
val packageResolver = PackageResolver.getInstance(SecurityManagers.defaultManager, httpClient, null)
|
||||
val e = assertThrows<PklException> {
|
||||
ProjectDependenciesResolver(project, packageResolver, System.err.writer()).resolve()
|
||||
}
|
||||
assertThat(e).hasMessage("""
|
||||
val packageResolver =
|
||||
PackageResolver.getInstance(SecurityManagers.defaultManager, httpClient, null)
|
||||
val e =
|
||||
assertThrows<PklException> {
|
||||
ProjectDependenciesResolver(project, packageResolver, System.err.writer()).resolve()
|
||||
}
|
||||
assertThat(e)
|
||||
.hasMessage(
|
||||
"""
|
||||
Computed checksum did not match declared checksum for dependency `package://localhost:0/birds@0.5.0`.
|
||||
|
||||
Computed: "${PackageServer.BIRDS_SHA}"
|
||||
Declared: "intentionally bogus value"
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
/**
|
||||
* 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.core.project
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.file.Path
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.packages.Checksums
|
||||
import org.pkl.core.packages.Dependency
|
||||
import org.pkl.core.packages.PackageUri
|
||||
import org.pkl.core.util.EconomicMaps
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.file.Path
|
||||
|
||||
class ProjectDepsTest {
|
||||
private val projectDepsStr = """
|
||||
private val projectDepsStr =
|
||||
"""
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"resolvedDependencies": {
|
||||
@@ -28,27 +44,29 @@ class ProjectDepsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
private val projectDeps = let {
|
||||
val projectDepsMap = EconomicMaps.of<CanonicalPackageUri, Dependency>(
|
||||
CanonicalPackageUri.of("package://localhost:0/birds@0"), Dependency.RemoteDependency(
|
||||
PackageUri.create("package://localhost:0/birds@0.5.0"),
|
||||
Checksums("abc123")
|
||||
),
|
||||
CanonicalPackageUri.of("package://localhost:0/fruit@1"), Dependency.LocalDependency(
|
||||
PackageUri.create("package://localhost:0/fruit@1.1.0"),
|
||||
Path.of("../fruit")
|
||||
val projectDepsMap =
|
||||
EconomicMaps.of<CanonicalPackageUri, Dependency>(
|
||||
CanonicalPackageUri.of("package://localhost:0/birds@0"),
|
||||
Dependency.RemoteDependency(
|
||||
PackageUri.create("package://localhost:0/birds@0.5.0"),
|
||||
Checksums("abc123")
|
||||
),
|
||||
CanonicalPackageUri.of("package://localhost:0/fruit@1"),
|
||||
Dependency.LocalDependency(
|
||||
PackageUri.create("package://localhost:0/fruit@1.1.0"),
|
||||
Path.of("../fruit")
|
||||
)
|
||||
)
|
||||
)
|
||||
ProjectDeps(projectDepsMap)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeTo() {
|
||||
val str = ByteArrayOutputStream()
|
||||
.apply { projectDeps.writeTo(this) }
|
||||
.toString(Charsets.UTF_8)
|
||||
val str = ByteArrayOutputStream().apply { projectDeps.writeTo(this) }.toString(Charsets.UTF_8)
|
||||
assertThat(str).isEqualTo(projectDepsStr)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
/**
|
||||
* 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.core.project
|
||||
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import java.util.regex.Pattern
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatCode
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -8,54 +26,52 @@ import org.pkl.commons.test.FileTestUtils
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.*
|
||||
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.core.packages.PackageUri
|
||||
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class ProjectTest {
|
||||
@Test
|
||||
fun loadFromPath(@TempDir path: Path) {
|
||||
val projectPath = path.resolve("PklProject")
|
||||
val expectedPackage = Package(
|
||||
"hawk",
|
||||
PackageUri("package://example.com/hawk@0.5.0"),
|
||||
Version.parse("0.5.0"),
|
||||
URI("https://example.com/hawk/0.5.0/hawk-0.5.0.zip"),
|
||||
"Some project about hawks",
|
||||
listOf("Birdy Bird <birdy@bird.com>"),
|
||||
URI("https://example.com/my/website"),
|
||||
URI("https://example.com/my/docs"),
|
||||
URI("https://example.com/my/repo"),
|
||||
"https://example.com/my/repo/0.5.0%{path}",
|
||||
"MIT",
|
||||
"""
|
||||
val expectedPackage =
|
||||
Package(
|
||||
"hawk",
|
||||
PackageUri("package://example.com/hawk@0.5.0"),
|
||||
Version.parse("0.5.0"),
|
||||
URI("https://example.com/hawk/0.5.0/hawk-0.5.0.zip"),
|
||||
"Some project about hawks",
|
||||
listOf("Birdy Bird <birdy@bird.com>"),
|
||||
URI("https://example.com/my/website"),
|
||||
URI("https://example.com/my/docs"),
|
||||
URI("https://example.com/my/repo"),
|
||||
"https://example.com/my/repo/0.5.0%{path}",
|
||||
"MIT",
|
||||
"""
|
||||
# Some License text
|
||||
|
||||
This is my license text
|
||||
""".trimIndent(),
|
||||
URI("https://example.com/my/issues"),
|
||||
listOf(Path.of("apiTest1.pkl"), Path.of("apiTest2.pkl")),
|
||||
listOf("PklProject", "PklProject.deps.json", ".**", "*.exe")
|
||||
)
|
||||
val expectedSettings = PklEvaluatorSettings(
|
||||
mapOf("two" to "2"),
|
||||
mapOf("one" to "1"),
|
||||
listOf("foo:", "bar:").map(Pattern::compile),
|
||||
listOf("baz:", "biz:").map(Pattern::compile),
|
||||
false,
|
||||
path.resolve("cache/"),
|
||||
listOf(
|
||||
path.resolve("modulepath1/"),
|
||||
path.resolve("modulepath2/")
|
||||
),
|
||||
Duration.ofMinutes(5.0),
|
||||
path,
|
||||
null
|
||||
)
|
||||
projectPath.writeString("""
|
||||
"""
|
||||
.trimIndent(),
|
||||
URI("https://example.com/my/issues"),
|
||||
listOf(Path.of("apiTest1.pkl"), Path.of("apiTest2.pkl")),
|
||||
listOf("PklProject", "PklProject.deps.json", ".**", "*.exe")
|
||||
)
|
||||
val expectedSettings =
|
||||
PklEvaluatorSettings(
|
||||
mapOf("two" to "2"),
|
||||
mapOf("one" to "1"),
|
||||
listOf("foo:", "bar:").map(Pattern::compile),
|
||||
listOf("baz:", "biz:").map(Pattern::compile),
|
||||
false,
|
||||
path.resolve("cache/"),
|
||||
listOf(path.resolve("modulepath1/"), path.resolve("modulepath2/")),
|
||||
Duration.ofMinutes(5.0),
|
||||
path,
|
||||
null
|
||||
)
|
||||
projectPath.writeString(
|
||||
"""
|
||||
amends "pkl:Project"
|
||||
|
||||
evaluatorSettings {
|
||||
@@ -114,24 +130,28 @@ class ProjectTest {
|
||||
"test1.pkl"
|
||||
"test2.pkl"
|
||||
}
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val project = Project.loadFromPath(projectPath)
|
||||
assertThat(project.`package`).isEqualTo(expectedPackage)
|
||||
assertThat(project.evaluatorSettings).isEqualTo(expectedSettings)
|
||||
assertThat(project.tests).isEqualTo(listOf(path.resolve("test1.pkl"), path.resolve("test2.pkl")))
|
||||
assertThat(project.tests)
|
||||
.isEqualTo(listOf(path.resolve("test1.pkl"), path.resolve("test2.pkl")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `load wrong type`(@TempDir path: Path) {
|
||||
val projectPath = path.resolve("PklProject")
|
||||
projectPath.writeString("""
|
||||
projectPath.writeString(
|
||||
"""
|
||||
module com.apple.Foo
|
||||
|
||||
foo = 1
|
||||
""".trimIndent())
|
||||
assertThatCode {
|
||||
Project.loadFromPath(projectPath, SecurityManagers.defaultManager, null)
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThatCode { Project.loadFromPath(projectPath, SecurityManagers.defaultManager, null) }
|
||||
.hasMessageContaining("be of type `pkl.Project`, but got type `com.apple.Foo`")
|
||||
}
|
||||
|
||||
@@ -140,18 +160,20 @@ class ProjectTest {
|
||||
PackageServer().use { server ->
|
||||
val projectDir = Path.of(javaClass.getResource("badProjectChecksum2/")!!.toURI())
|
||||
val project = Project.loadFromPath(projectDir.resolve("PklProject"))
|
||||
val httpClient = HttpClient.builder()
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
.setTestPort(server.port)
|
||||
.build()
|
||||
val evaluator = EvaluatorBuilder.preconfigured()
|
||||
.applyFromProject(project)
|
||||
.setModuleCacheDir(null)
|
||||
.setHttpClient(httpClient)
|
||||
.build()
|
||||
assertThatCode {
|
||||
evaluator.evaluate(ModuleSource.path(projectDir.resolve("bug.pkl")))
|
||||
}.hasMessageStartingWith("""
|
||||
val httpClient =
|
||||
HttpClient.builder()
|
||||
.addCertificates(FileTestUtils.selfSignedCertificate)
|
||||
.setTestPort(server.port)
|
||||
.build()
|
||||
val evaluator =
|
||||
EvaluatorBuilder.preconfigured()
|
||||
.applyFromProject(project)
|
||||
.setModuleCacheDir(null)
|
||||
.setHttpClient(httpClient)
|
||||
.build()
|
||||
assertThatCode { evaluator.evaluate(ModuleSource.path(projectDir.resolve("bug.pkl"))) }
|
||||
.hasMessageStartingWith(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Cannot download package `package://localhost:0/fruit@1.0.5` because the computed checksum for package metadata does not match the expected checksum.
|
||||
|
||||
@@ -161,7 +183,9 @@ class ProjectTest {
|
||||
|
||||
1 | import "@fruit/Fruit.pkl"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
/**
|
||||
* 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.core.resource
|
||||
|
||||
import org.pkl.core.Evaluator
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.outputStream
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.EvaluatorBuilder
|
||||
import org.pkl.core.ModuleSource
|
||||
import org.pkl.core.module.ModulePathResolver
|
||||
import kotlin.io.path.outputStream
|
||||
|
||||
class ResourceReadersEvaluatorTest {
|
||||
@Test
|
||||
fun `class path`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
res1 = read("modulepath:/org/pkl/core/resource/resource.txt").text
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(module.getProperty("res1")).isEqualTo("content")
|
||||
}
|
||||
@@ -38,18 +54,16 @@ class ResourceReadersEvaluatorTest {
|
||||
ModulePathResolver(listOf(jarFile)).use { resolver ->
|
||||
val reader = ResourceReaders.modulePath(resolver)
|
||||
|
||||
val evaluator = EvaluatorBuilder
|
||||
.preconfigured()
|
||||
.addResourceReader(reader)
|
||||
.build()
|
||||
val evaluator = EvaluatorBuilder.preconfigured().addResourceReader(reader).build()
|
||||
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
res1 = read("modulepath:/dir1/resource1.txt").text
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(module.getProperty("res1")).isEqualTo("content\n")
|
||||
}
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
/**
|
||||
* 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.core.resource
|
||||
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.outputStream
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.core.module.ModulePathResolver
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.outputStream
|
||||
|
||||
class ResourceReadersTest {
|
||||
@Test
|
||||
@@ -82,9 +97,7 @@ class ResourceReadersTest {
|
||||
fun `module path - missing leading slash`() {
|
||||
val reader = ResourceReaders.modulePath(ModulePathResolver(listOf()))
|
||||
|
||||
assertThrows<URISyntaxException> {
|
||||
reader.read(URI("modulepath:non/existing"))
|
||||
}
|
||||
assertThrows<URISyntaxException> { reader.read(URI("modulepath:non/existing")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.resource
|
||||
|
||||
import java.net.URI
|
||||
|
||||
@@ -1,38 +1,58 @@
|
||||
package org.pkl.core.runtime;
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.net.URI;
|
||||
//import java.net.URISyntaxException;
|
||||
//import java.nio.file.Files;
|
||||
//import java.nio.file.Path;
|
||||
//import java.util.Arrays;
|
||||
//import java.util.Collections;
|
||||
// import java.io.IOException;
|
||||
// import java.net.URI;
|
||||
// import java.net.URISyntaxException;
|
||||
// import java.nio.file.Files;
|
||||
// import java.nio.file.Path;
|
||||
// import java.util.Arrays;
|
||||
// import java.util.Collections;
|
||||
//
|
||||
//import org.pkl.core.EvalOptions;
|
||||
//import org.pkl.core.EvalException;
|
||||
//import org.pkl.core.resolve.ModuleKey;
|
||||
//import org.pkl.core.resolve.ModuleKeyFactories;
|
||||
//import org.pkl.core.resolve.ModuleKeys;
|
||||
//import com.oracle.truffle.api.source.SourceSection;
|
||||
//import org.junit.Ignore;
|
||||
//import org.junit.Test;
|
||||
// import org.pkl.core.EvalOptions;
|
||||
// import org.pkl.core.EvalException;
|
||||
// import org.pkl.core.resolve.ModuleKey;
|
||||
// import org.pkl.core.resolve.ModuleKeyFactories;
|
||||
// import org.pkl.core.resolve.ModuleKeys;
|
||||
// import com.oracle.truffle.api.source.SourceSection;
|
||||
// import org.junit.Ignore;
|
||||
// import org.junit.Test;
|
||||
//
|
||||
//import static org.junit.Assert.assertEquals;
|
||||
//import static org.junit.Assert.assertTrue;
|
||||
// import static org.junit.Assert.assertEquals;
|
||||
// import static org.junit.Assert.assertTrue;
|
||||
//
|
||||
//public class DefaultModuleResolverTest {
|
||||
// public class DefaultModuleResolverTest {
|
||||
// private final SourceSection sourceSection = VmUtils.unavailableSourceSection();
|
||||
// private final ModuleResolver resolver =
|
||||
// new ModuleResolver(ModuleKeyFactories.namedModuleOnClassPath, EvalOptions.namedModuleOnClassPath.getAllowedModules());
|
||||
// new ModuleResolver(ModuleKeyFactories.namedModuleOnClassPath,
|
||||
// EvalOptions.namedModuleOnClassPath.getAllowedModules());
|
||||
// private final ModuleKey fileUrlModule;
|
||||
// private final ModuleKey httpsUrlModule;
|
||||
// private final ModuleKey literalUrlModule;
|
||||
//
|
||||
// {
|
||||
// try {
|
||||
// fileUrlModule = ModuleKeys.genericUrl(new URI("file:///path/script.pkl"), ModuleKeys.FULL_TRUST);
|
||||
// httpsUrlModule = ModuleKeys.genericUrl(new URI("https://some.domain.com/path/script.pkl"), ModuleKeys.FULL_TRUST);
|
||||
// literalUrlModule = ModuleKeys.synthetic("myLiteralModule", "my literal source code", ModuleKeys.FULL_TRUST);
|
||||
// fileUrlModule = ModuleKeys.genericUrl(new URI("file:///path/script.pkl"),
|
||||
// ModuleKeys.FULL_TRUST);
|
||||
// httpsUrlModule = ModuleKeys.genericUrl(new URI("https://some.domain.com/path/script.pkl"),
|
||||
// ModuleKeys.FULL_TRUST);
|
||||
// literalUrlModule = ModuleKeys.synthetic("myLiteralModule", "my literal source code",
|
||||
// ModuleKeys.FULL_TRUST);
|
||||
// } catch (URISyntaxException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
@@ -61,7 +81,8 @@ package org.pkl.core.runtime;
|
||||
//
|
||||
// @Test
|
||||
// public void importHttpsUrlFromFileUrl() throws IOException {
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl", fileUrlModule, sourceSection);
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl",
|
||||
// fileUrlModule, sourceSection);
|
||||
// assertTrue(result instanceof ModuleKey.Url);
|
||||
// assertEquals("https://other.domain.com/path2/script2.pkl", result.toString());
|
||||
// }
|
||||
@@ -94,7 +115,8 @@ package org.pkl.core.runtime;
|
||||
//
|
||||
// @Test
|
||||
// public void importHttpsUrlFromHttpsUrl() throws IOException {
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl", httpsUrlModule, sourceSection);
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl",
|
||||
// httpsUrlModule, sourceSection);
|
||||
// assertTrue(result instanceof ModuleKey.Url);
|
||||
// assertEquals("https://other.domain.com/path2/script2.pkl", result.toString());
|
||||
// }
|
||||
@@ -127,14 +149,16 @@ package org.pkl.core.runtime;
|
||||
//
|
||||
// @Test
|
||||
// public void importFileUrlFromLiteral() throws IOException {
|
||||
// ModuleKey result = resolver.resolve("file:///import/file.pkl", literalUrlModule, sourceSection);
|
||||
// ModuleKey result = resolver.resolve("file:///import/file.pkl", literalUrlModule,
|
||||
// sourceSection);
|
||||
// assertTrue(result instanceof ModuleKey.Url);
|
||||
// assertEquals("file:///import/file.pkl", result.toString());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void importHttpsUrlFromLiteral() throws IOException {
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl", literalUrlModule, sourceSection);
|
||||
// ModuleKey result = resolver.resolve("https://other.domain.com/path2/script2.pkl",
|
||||
// literalUrlModule, sourceSection);
|
||||
// assertTrue(result instanceof ModuleKey.Url);
|
||||
// assertEquals("https://other.domain.com/path2/script2.pkl", result.toString());
|
||||
// }
|
||||
@@ -183,4 +207,4 @@ package org.pkl.core.runtime;
|
||||
//
|
||||
// resolver.resolve("pkl:base", fileUrlModule, sourceSection);
|
||||
// }
|
||||
//}
|
||||
// }
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
|
||||
class FileSystemManagerTest {
|
||||
private val resource =
|
||||
javaClass.getResource("/org/pkl/core/resource/resource1.jar")!!.toURI()
|
||||
private val resource = javaClass.getResource("/org/pkl/core/resource/resource1.jar")!!.toURI()
|
||||
private val resourceUri = URI("jar:$resource")
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
package org.pkl.core.runtime;
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
//
|
||||
//import java.io.File;
|
||||
//import java.io.IOException;
|
||||
//import java.net.URI;
|
||||
//import java.net.URISyntaxException;
|
||||
// import java.io.File;
|
||||
// import java.io.IOException;
|
||||
// import java.net.URI;
|
||||
// import java.net.URISyntaxException;
|
||||
//
|
||||
//import org.pkl.core.resolve.ModuleKey;
|
||||
//import org.pkl.core.resolve.ModuleKeys;
|
||||
//import org.junit.Rule;
|
||||
//import org.junit.Test;
|
||||
//import org.junit.rules.TemporaryFolder;
|
||||
// import org.pkl.core.resolve.ModuleKey;
|
||||
// import org.pkl.core.resolve.ModuleKeys;
|
||||
// import org.junit.Rule;
|
||||
// import org.junit.Test;
|
||||
// import org.junit.rules.TemporaryFolder;
|
||||
//
|
||||
//import static org.junit.Assert.assertEquals;
|
||||
//import static org.junit.Assert.assertFalse;
|
||||
//import static org.junit.Assert.assertTrue;
|
||||
// import static org.junit.Assert.assertEquals;
|
||||
// import static org.junit.Assert.assertFalse;
|
||||
// import static org.junit.Assert.assertTrue;
|
||||
//
|
||||
//// some parts of ModuleKey are tested as part of DefaultModuleResolverTest
|
||||
//public class ModuleKeyTest {
|
||||
// public class ModuleKeyTest {
|
||||
// @Rule
|
||||
// public TemporaryFolder folder = new TemporaryFolder();
|
||||
//
|
||||
@@ -73,4 +89,4 @@ package org.pkl.core.runtime;
|
||||
// assertEquals("literal:name", module.getUri());
|
||||
// assertFalse(module.isBaseModule());
|
||||
// }
|
||||
//}
|
||||
// }
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.pkl.core.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.core.*
|
||||
|
||||
class StackTraceRendererTest {
|
||||
companion object {
|
||||
@@ -20,39 +35,51 @@ class StackTraceRendererTest {
|
||||
|
||||
@Test
|
||||
fun `stringy self-reference`() {
|
||||
val message = assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val message =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
self: String = "Strings; if they were lazy, you could tie the knot on \(self.take(7))"
|
||||
""".trimIndent())
|
||||
)
|
||||
}.message!!
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}
|
||||
.message!!
|
||||
assertThat(message)
|
||||
.contains("A stack overflow occurred.")
|
||||
.containsPattern("""
|
||||
.containsPattern(
|
||||
"""
|
||||
┌─ \d* repetitions of:
|
||||
│ 1 | self: String = "Strings; if they were lazy, you could tie the knot on \\\(self.take\(7\)\)"
|
||||
│ ^^^^
|
||||
""".trim())
|
||||
"""
|
||||
.trim()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cyclic property references`() {
|
||||
val message = assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val message =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
foo: String = "FOO:" + bar
|
||||
bar: String = "BAR:" + baz
|
||||
baz: String = "BAZ:" + qux
|
||||
qux: String = "QUX:" + foo
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}.message!!
|
||||
}
|
||||
.message!!
|
||||
assertThat(message)
|
||||
.contains("A stack overflow occurred.")
|
||||
.containsPattern("""
|
||||
.containsPattern(
|
||||
"""
|
||||
┌─ \d+ repetitions of:
|
||||
│ 4 | qux: String = "QUX:" + foo
|
||||
│ ^^^
|
||||
@@ -70,13 +97,16 @@ class StackTraceRendererTest {
|
||||
│ ^^^
|
||||
│ at text#foo (repl:text)
|
||||
└─
|
||||
""".trim())
|
||||
"""
|
||||
.trim()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Suppress("RegExpRepeatedSpace")
|
||||
fun `reduce stack overflow from actual Pkl code`() {
|
||||
val pklCode = """
|
||||
val pklCode =
|
||||
"""
|
||||
function suffix(n: UInt): UInt =
|
||||
if (n == 0)
|
||||
0
|
||||
@@ -106,15 +136,15 @@ class StackTraceRendererTest {
|
||||
prefix(n - 1)
|
||||
|
||||
result = prefix(13)
|
||||
""".trimIndent()
|
||||
val message = assertThrows<PklException> {
|
||||
evaluator.evaluate(ModuleSource.text(pklCode))
|
||||
}.message!!
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
val message =
|
||||
assertThrows<PklException> { evaluator.evaluate(ModuleSource.text(pklCode)) }.message!!
|
||||
|
||||
if (message.contains("5 | suffix")) {
|
||||
assertThat(message).containsPattern("repetitions of:\n│ 5 | suffix(n - 1)")
|
||||
}
|
||||
|
||||
|
||||
assertThat(message)
|
||||
.contains("A stack overflow occurred.")
|
||||
.containsPattern("┌─ \\d+ repetitions of:\n│ \n│ 9 | loop\\(\\)")
|
||||
@@ -159,15 +189,11 @@ class StackTraceRendererTest {
|
||||
add(createFrame("foo", 3))
|
||||
}
|
||||
val loop = StackTraceRenderer.StackFrameLoop(loopFrames, 1)
|
||||
val frames = listOf(
|
||||
createFrame("bar", 1),
|
||||
createFrame("baz", 2),
|
||||
loop
|
||||
)
|
||||
val renderedFrames = buildString {
|
||||
renderer.doRender(frames, null, this, "", true)
|
||||
}
|
||||
assertThat(renderedFrames).isEqualTo("""
|
||||
val frames = listOf(createFrame("bar", 1), createFrame("baz", 2), loop)
|
||||
val renderedFrames = buildString { renderer.doRender(frames, null, this, "", true) }
|
||||
assertThat(renderedFrames)
|
||||
.isEqualTo(
|
||||
"""
|
||||
1 | foo
|
||||
^
|
||||
at <unknown> (file:bar)
|
||||
@@ -188,7 +214,9 @@ class StackTraceRendererTest {
|
||||
^
|
||||
at <unknown> (file:foo)
|
||||
|
||||
""".trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun createFrame(name: String, id: Int): StackFrame {
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -10,15 +25,12 @@ class VmSafeMathTest {
|
||||
assertThat(VmSafeMath.negate(0)).isEqualTo(0)
|
||||
assertThat(VmSafeMath.negate(1)).isEqualTo(-1)
|
||||
assertThat(VmSafeMath.negate(-1)).isEqualTo(1)
|
||||
assertThat(VmSafeMath.negate(java.lang.Long.MAX_VALUE))
|
||||
.isEqualTo(-java.lang.Long.MAX_VALUE)
|
||||
assertThat(VmSafeMath.negate(java.lang.Long.MAX_VALUE)).isEqualTo(-java.lang.Long.MAX_VALUE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `negate long - overflow`() {
|
||||
assertThrows<VmEvalException> {
|
||||
VmSafeMath.negate(java.lang.Long.MIN_VALUE)
|
||||
}
|
||||
assertThrows<VmEvalException> { VmSafeMath.negate(java.lang.Long.MIN_VALUE) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -27,10 +39,8 @@ class VmSafeMathTest {
|
||||
assertThat(VmSafeMath.negate(-1.0)).isEqualTo(1.0)
|
||||
assertThat(VmSafeMath.negate(1.0)).isEqualTo(-1.0)
|
||||
assertThat(VmSafeMath.negate(123.456)).isEqualTo(-123.456)
|
||||
assertThat(VmSafeMath.negate(-java.lang.Double.MAX_VALUE))
|
||||
.isEqualTo(java.lang.Double.MAX_VALUE)
|
||||
assertThat(VmSafeMath.negate(-java.lang.Double.MIN_VALUE))
|
||||
.isEqualTo(java.lang.Double.MIN_VALUE)
|
||||
assertThat(VmSafeMath.negate(-java.lang.Double.MAX_VALUE)).isEqualTo(java.lang.Double.MAX_VALUE)
|
||||
assertThat(VmSafeMath.negate(-java.lang.Double.MIN_VALUE)).isEqualTo(java.lang.Double.MIN_VALUE)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -38,31 +48,23 @@ class VmSafeMathTest {
|
||||
assertThat(VmSafeMath.add(0, 0)).isEqualTo(0)
|
||||
assertThat(VmSafeMath.add(1, 2)).isEqualTo(3)
|
||||
assertThat(VmSafeMath.add(1, -2)).isEqualTo(-1)
|
||||
assertThat(VmSafeMath.add(java.lang.Long.MAX_VALUE - 1, 1))
|
||||
.isEqualTo(java.lang.Long.MAX_VALUE)
|
||||
assertThat(VmSafeMath.add(java.lang.Long.MAX_VALUE - 1, 1)).isEqualTo(java.lang.Long.MAX_VALUE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add long - overflow #1`() {
|
||||
assertThrows<VmEvalException> {
|
||||
VmSafeMath.add(java.lang.Long.MAX_VALUE, 1)
|
||||
}
|
||||
assertThrows<VmEvalException> { VmSafeMath.add(java.lang.Long.MAX_VALUE, 1) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add long - overflow #2`() {
|
||||
assertThrows<VmEvalException> {
|
||||
VmSafeMath.add(java.lang.Long.MIN_VALUE, -1)
|
||||
}
|
||||
assertThrows<VmEvalException> { VmSafeMath.add(java.lang.Long.MIN_VALUE, -1) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add long - overflow #3`() {
|
||||
assertThrows<VmEvalException> {
|
||||
VmSafeMath.add(
|
||||
java.lang.Long.MAX_VALUE / 2,
|
||||
java.lang.Long.MAX_VALUE / 3 * 2
|
||||
)
|
||||
VmSafeMath.add(java.lang.Long.MAX_VALUE / 2, java.lang.Long.MAX_VALUE / 3 * 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.module.ModuleKeys
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
|
||||
class VmUtilsTest {
|
||||
@Test
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.runtime
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
/**
|
||||
* 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.core.settings
|
||||
|
||||
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.commons.createParentDirectories
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
import org.pkl.core.PObject
|
||||
import org.pkl.core.StackFrameTransformers
|
||||
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings
|
||||
import org.pkl.core.runtime.VmException
|
||||
import org.pkl.core.settings.PklSettings.Editor
|
||||
import java.net.URI
|
||||
|
||||
class PklSettingsTest {
|
||||
@Test
|
||||
@@ -26,13 +38,14 @@ class PklSettingsTest {
|
||||
"""
|
||||
amends "pkl:settings"
|
||||
editor = Sublime
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val settings = PklSettings.loadFromPklHomeDir(tempDir)
|
||||
assertThat(settings).isEqualTo(PklSettings(Editor.SUBLIME, null))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `load user settings with http`(@TempDir tempDir: Path) {
|
||||
val settingsPath = tempDir.resolve("settings.pkl")
|
||||
@@ -49,16 +62,18 @@ class PklSettingsTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val settings = PklSettings.loadFromPklHomeDir(tempDir)
|
||||
val expectedHttp = PklEvaluatorSettings.Http(
|
||||
PklEvaluatorSettings.Proxy(
|
||||
URI("http://localhost:8080"),
|
||||
listOf("example.com", "pkg.pkl-lang.org")
|
||||
val expectedHttp =
|
||||
PklEvaluatorSettings.Http(
|
||||
PklEvaluatorSettings.Proxy(
|
||||
URI("http://localhost:8080"),
|
||||
listOf("example.com", "pkg.pkl-lang.org")
|
||||
)
|
||||
)
|
||||
)
|
||||
assertThat(settings).isEqualTo(PklSettings(Editor.SYSTEM, expectedHttp))
|
||||
}
|
||||
|
||||
@@ -74,16 +89,18 @@ class PklSettingsTest {
|
||||
address = "http://localhost:8080"
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val settings = PklSettings.loadFromPklHomeDir(tempDir)
|
||||
val expectedHttp = PklEvaluatorSettings.Http(
|
||||
PklEvaluatorSettings.Proxy(
|
||||
URI("http://localhost:8080"),
|
||||
listOf(),
|
||||
val expectedHttp =
|
||||
PklEvaluatorSettings.Http(
|
||||
PklEvaluatorSettings.Proxy(
|
||||
URI("http://localhost:8080"),
|
||||
listOf(),
|
||||
)
|
||||
)
|
||||
)
|
||||
assertThat(settings).isEqualTo(PklSettings(Editor.SYSTEM, expectedHttp))
|
||||
}
|
||||
|
||||
@@ -94,7 +111,8 @@ class PklSettingsTest {
|
||||
"""
|
||||
amends "pkl:settings"
|
||||
editor = Idea
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val settings = PklSettings.load(ModuleSource.path(settingsPath))
|
||||
@@ -104,9 +122,10 @@ class PklSettingsTest {
|
||||
@Test
|
||||
fun `predefined editors`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
import "pkl:settings"
|
||||
|
||||
system = settings.System
|
||||
@@ -115,9 +134,10 @@ class PklSettingsTest {
|
||||
sublime = settings.Sublime
|
||||
atom = settings.Atom
|
||||
vsCode = settings.VsCode
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
checkEquals(Editor.SYSTEM, module.getProperty("system") as PObject)
|
||||
checkEquals(Editor.IDEA, module.getProperty("idea") as PObject)
|
||||
@@ -131,7 +151,9 @@ class PklSettingsTest {
|
||||
fun `invalid settings file`(@TempDir tempDir: Path) {
|
||||
val settingsFile = tempDir.resolve("settings.pkl").apply { writeString("foo = 1") }
|
||||
assertThatCode { PklSettings.loadFromPklHomeDir(tempDir) }
|
||||
.hasMessageContaining("Expected `output.value` of module `${settingsFile.toUri()}` to be of type `pkl.settings`, but got type `settings`.")
|
||||
.hasMessageContaining(
|
||||
"Expected `output.value` of module `${settingsFile.toUri()}` to be of type `pkl.settings`, but got type `settings`."
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkEquals(expected: Editor, actual: PObject) {
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
/**
|
||||
* 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.core.stdlib
|
||||
|
||||
import org.pkl.core.runtime.Identifier
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.runtime.Identifier
|
||||
|
||||
class PathConverterSupportTest {
|
||||
@Test
|
||||
@@ -15,14 +29,16 @@ class PathConverterSupportTest {
|
||||
|
||||
@Test
|
||||
fun `wildcard properties`() {
|
||||
val pathSpec = listOf(Identifier.get("foo"), PklConverter.WILDCARD_PROPERTY, Identifier.get("baz"))
|
||||
val pathSpec =
|
||||
listOf(Identifier.get("foo"), PklConverter.WILDCARD_PROPERTY, Identifier.get("baz"))
|
||||
val pathPartSpec = listOf(Identifier.get("foo"), Identifier.get("bar"), Identifier.get("baz"))
|
||||
assertTrue(PathConverterSupport.pathMatches(pathSpec, pathPartSpec))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `wildcard elements`() {
|
||||
val pathSpec = listOf(Identifier.get("foo"), PklConverter.WILDCARD_ELEMENT, Identifier.get("baz"))
|
||||
val pathSpec =
|
||||
listOf(Identifier.get("foo"), PklConverter.WILDCARD_ELEMENT, Identifier.get("baz"))
|
||||
val pathPartSpec = listOf(Identifier.get("foo"), 0, Identifier.get("baz"))
|
||||
assertTrue(PathConverterSupport.pathMatches(pathSpec, pathPartSpec))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.stdlib
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -12,14 +27,11 @@ class PathSpecParserTest {
|
||||
|
||||
@Test
|
||||
fun `parse valid path specs`() {
|
||||
assertThat(parser.parse(""))
|
||||
.isEqualTo(arrayOf(TOP_LEVEL_VALUE))
|
||||
assertThat(parser.parse("")).isEqualTo(arrayOf(TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("^"))
|
||||
.isEqualTo(arrayOf(TOP_LEVEL_VALUE))
|
||||
assertThat(parser.parse("^")).isEqualTo(arrayOf(TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("property"))
|
||||
.isEqualTo(arrayOf(Identifier.get("property")))
|
||||
assertThat(parser.parse("property")).isEqualTo(arrayOf(Identifier.get("property")))
|
||||
|
||||
assertThat(parser.parse("^property"))
|
||||
.isEqualTo(arrayOf(Identifier.get("property"), TOP_LEVEL_VALUE))
|
||||
@@ -28,107 +40,55 @@ class PathSpecParserTest {
|
||||
.isEqualTo(arrayOf(Identifier.get("prop3"), Identifier.get("prop2"), Identifier.get("prop1")))
|
||||
|
||||
assertThat(parser.parse("^prop1.prop2.prop3"))
|
||||
.isEqualTo(arrayOf(Identifier.get("prop3"), Identifier.get("prop2"), Identifier.get("prop1"), TOP_LEVEL_VALUE))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
Identifier.get("prop3"),
|
||||
Identifier.get("prop2"),
|
||||
Identifier.get("prop1"),
|
||||
TOP_LEVEL_VALUE
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(parser.parse("[key]"))
|
||||
.isEqualTo(arrayOf("key"))
|
||||
assertThat(parser.parse("[key]")).isEqualTo(arrayOf("key"))
|
||||
|
||||
assertThat(parser.parse("^[key]"))
|
||||
.isEqualTo(arrayOf("key", TOP_LEVEL_VALUE))
|
||||
assertThat(parser.parse("^[key]")).isEqualTo(arrayOf("key", TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("[key1][key2][key3]"))
|
||||
.isEqualTo(arrayOf("key3", "key2", "key1"))
|
||||
assertThat(parser.parse("[key1][key2][key3]")).isEqualTo(arrayOf("key3", "key2", "key1"))
|
||||
|
||||
assertThat(parser.parse("^[key1][key2][key3]"))
|
||||
.isEqualTo(arrayOf("key3", "key2", "key1", TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("*"))
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY))
|
||||
assertThat(parser.parse("*")).isEqualTo(arrayOf(WILDCARD_PROPERTY))
|
||||
|
||||
assertThat(parser.parse("^*"))
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY, TOP_LEVEL_VALUE))
|
||||
assertThat(parser.parse("^*")).isEqualTo(arrayOf(WILDCARD_PROPERTY, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("[*]"))
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT))
|
||||
assertThat(parser.parse("[*]")).isEqualTo(arrayOf(WILDCARD_ELEMENT))
|
||||
|
||||
assertThat(parser.parse("^[*]"))
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT, TOP_LEVEL_VALUE))
|
||||
assertThat(parser.parse("^[*]")).isEqualTo(arrayOf(WILDCARD_ELEMENT, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("*.*.*"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_PROPERTY
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY, WILDCARD_PROPERTY, WILDCARD_PROPERTY))
|
||||
|
||||
assertThat(parser.parse("^*.*.*"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_PROPERTY,
|
||||
TOP_LEVEL_VALUE
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY, WILDCARD_PROPERTY, WILDCARD_PROPERTY, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("[*][*][*]"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_ELEMENT
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT, WILDCARD_ELEMENT, WILDCARD_ELEMENT))
|
||||
|
||||
assertThat(parser.parse("^[*][*][*]"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_ELEMENT,
|
||||
TOP_LEVEL_VALUE
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT, WILDCARD_ELEMENT, WILDCARD_ELEMENT, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("[*].*[*]"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_ELEMENT
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT, WILDCARD_PROPERTY, WILDCARD_ELEMENT))
|
||||
|
||||
assertThat(parser.parse("^[*].*[*]"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_ELEMENT,
|
||||
TOP_LEVEL_VALUE
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_ELEMENT, WILDCARD_PROPERTY, WILDCARD_ELEMENT, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("*[*].*"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_PROPERTY
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY, WILDCARD_ELEMENT, WILDCARD_PROPERTY))
|
||||
|
||||
assertThat(parser.parse("^*[*].*"))
|
||||
.isEqualTo(
|
||||
arrayOf(
|
||||
WILDCARD_PROPERTY,
|
||||
WILDCARD_ELEMENT,
|
||||
WILDCARD_PROPERTY,
|
||||
TOP_LEVEL_VALUE
|
||||
)
|
||||
)
|
||||
.isEqualTo(arrayOf(WILDCARD_PROPERTY, WILDCARD_ELEMENT, WILDCARD_PROPERTY, TOP_LEVEL_VALUE))
|
||||
|
||||
assertThat(parser.parse("prop1[key1].*[key2].prop2[*]"))
|
||||
.isEqualTo(
|
||||
@@ -160,60 +120,32 @@ class PathSpecParserTest {
|
||||
// TODO: support quoted identifiers?
|
||||
@Test
|
||||
fun `parse invalid path specs`() {
|
||||
assertThrows<VmException> {
|
||||
parser.parse("^^")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("^^") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("property.")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("property.") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("property^")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("property^") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse(".property")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse(".property") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("prop1..prop2")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("prop1..prop2") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[key")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[key") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("key]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("key]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[[key]]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[[key]]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("property.[key]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("property.[key]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[key1].[key2]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[key1].[key2]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[key1] [key2]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[key1] [key2]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("**")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("**") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[**]")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[**]") }
|
||||
|
||||
assertThrows<VmException> {
|
||||
parser.parse("[*")
|
||||
}
|
||||
assertThrows<VmException> { parser.parse("[*") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,47 @@
|
||||
/**
|
||||
* 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.core.stdlib
|
||||
|
||||
import org.pkl.core.Evaluator
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
class ReflectModuleTest {
|
||||
private val evaluator = Evaluator.preconfigured()
|
||||
|
||||
@ValueSource(
|
||||
strings = [
|
||||
"pkl:base", "pkl:json", "pkl:jsonnet", "pkl:math", "pkl:protobuf", "pkl:reflect",
|
||||
"pkl:settings", "pkl:shell", "pkl:test", "pkl:xml", "pkl:yaml"
|
||||
]
|
||||
strings =
|
||||
[
|
||||
"pkl:base",
|
||||
"pkl:json",
|
||||
"pkl:jsonnet",
|
||||
"pkl:math",
|
||||
"pkl:protobuf",
|
||||
"pkl:reflect",
|
||||
"pkl:settings",
|
||||
"pkl:shell",
|
||||
"pkl:test",
|
||||
"pkl:xml",
|
||||
"pkl:yaml"
|
||||
]
|
||||
)
|
||||
@ParameterizedTest(name = "can reflect on {0} module")
|
||||
fun `can reflect on stdlib module`(moduleName: String) {
|
||||
//language=Pkl
|
||||
// language=Pkl
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
@@ -26,7 +51,8 @@ class ReflectModuleTest {
|
||||
output {
|
||||
text = reflect.Module(import("$moduleName")).toString()
|
||||
}
|
||||
""".trimIndent()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
/**
|
||||
* 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.core.truffle
|
||||
|
||||
import org.pkl.core.Evaluator
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
// Verifies that (long, long) specialization is chosen for (long, long) inputs
|
||||
@@ -18,84 +33,84 @@ class LongVsDoubleSpecializationTest {
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text("""
|
||||
x1 = Pair(1.0 + 2.0, 1 + 2).second
|
||||
"""
|
||||
""")
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(3L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text("""
|
||||
x1 = Pair(1.0 - 2.0, 1 - 2).second
|
||||
"""
|
||||
""")
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(-1L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text("""
|
||||
x1 = Pair(1.0 * 2.0, 1 * 2).second
|
||||
"""
|
||||
""")
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(2L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun exponentiation() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
import "pkl:math"
|
||||
|
||||
x1 = Pair(2.0 ** 2.0, 2 ** 2).second
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(4L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun math_min() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
import "pkl:math"
|
||||
|
||||
x1 = Pair(math.min(1.0, 2.0), math.min(1, 2)).second
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(1L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun math_max() {
|
||||
val result = evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
val result =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
import "pkl:math"
|
||||
|
||||
x1 = Pair(math.max(1.0, 2.0), math.max(1, 2)).second
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(result.properties["x1"]).isEqualTo(2L)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.util
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@@ -7,11 +22,12 @@ import org.junit.jupiter.api.assertThrows
|
||||
class ArrayCharEscaperTest {
|
||||
@Test
|
||||
fun `basic usage`() {
|
||||
val escaper = ArrayCharEscaper.builder()
|
||||
.withEscape('ä', "ae")
|
||||
.withEscape('ö', "oe")
|
||||
.withEscape('ü', "ue")
|
||||
.build()
|
||||
val escaper =
|
||||
ArrayCharEscaper.builder()
|
||||
.withEscape('ä', "ae")
|
||||
.withEscape('ö', "oe")
|
||||
.withEscape('ü', "ue")
|
||||
.build()
|
||||
|
||||
assertThat(escaper.escape("")).isEqualTo("")
|
||||
assertThat(escaper.escape("äää")).isEqualTo("aeaeae")
|
||||
@@ -26,10 +42,7 @@ class ArrayCharEscaperTest {
|
||||
@Test
|
||||
fun `enforces size limit`() {
|
||||
assertThrows<IllegalStateException> {
|
||||
ArrayCharEscaper.builder()
|
||||
.withEscape('a', "aa")
|
||||
.withEscape('Ɇ', "ee")
|
||||
.build()
|
||||
ArrayCharEscaper.builder().withEscape('a', "aa").withEscape('Ɇ', "ee").build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +57,7 @@ class ArrayCharEscaperTest {
|
||||
|
||||
@Test
|
||||
fun `returns original string if no escaping required`() {
|
||||
val escaper = ArrayCharEscaper.builder()
|
||||
.withEscape('ä', "ae")
|
||||
.build()
|
||||
val escaper = ArrayCharEscaper.builder().withEscape('ä', "ae").build()
|
||||
|
||||
val fox = "The quick brown fox jumps over the lazy dog."
|
||||
assertThat(escaper.escape(fox)).isSameAs(fox)
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/**
|
||||
* 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.core.util
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.IOException
|
||||
import java.lang.Error
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExceptionsTest {
|
||||
@Test
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* 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.core.util
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
@@ -26,77 +41,74 @@ class GlobResolverTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"foo.pkl",
|
||||
"bar.pkl",
|
||||
"baz.pkl",
|
||||
"buzzy...baz.pkl",
|
||||
"ted_lasso.min.pkl",
|
||||
"ted_lasso.pkl.min.pkl"
|
||||
])
|
||||
@ValueSource(
|
||||
strings =
|
||||
[
|
||||
"foo.pkl",
|
||||
"bar.pkl",
|
||||
"baz.pkl",
|
||||
"buzzy...baz.pkl",
|
||||
"ted_lasso.min.pkl",
|
||||
"ted_lasso.pkl.min.pkl"
|
||||
]
|
||||
)
|
||||
fun `glob match`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("*.pkl")
|
||||
assertTrue(pattern.matcher(input).matches())
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"bar.pcf",
|
||||
"bar.yml",
|
||||
"bar.pkl.bcl",
|
||||
"bar.pklpkl",
|
||||
"pkl",
|
||||
// crosses directory boundaries
|
||||
"/bar/baz.pkl",
|
||||
"/baz.pkl"
|
||||
])
|
||||
@ValueSource(
|
||||
strings =
|
||||
[
|
||||
"bar.pcf",
|
||||
"bar.yml",
|
||||
"bar.pkl.bcl",
|
||||
"bar.pklpkl",
|
||||
"pkl",
|
||||
// crosses directory boundaries
|
||||
"/bar/baz.pkl",
|
||||
"/baz.pkl"
|
||||
]
|
||||
)
|
||||
fun `glob non-match`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("*.pkl")
|
||||
assertFalse(pattern.matcher(input).matches())
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"/foo.pkl/bar/baz.pkl",
|
||||
"//fo///ba.pkl",
|
||||
".pkl",
|
||||
"buz.pkl",
|
||||
"pkl.pkl.pkl.pkl"
|
||||
])
|
||||
@ValueSource(
|
||||
strings = ["/foo.pkl/bar/baz.pkl", "//fo///ba.pkl", ".pkl", "buz.pkl", "pkl.pkl.pkl.pkl"]
|
||||
)
|
||||
fun `globstar match`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("**.pkl")
|
||||
assertTrue(pattern.matcher(input).matches())
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"/foo.pkl/bar/baz.pkl",
|
||||
"//fo///ba.pkl",
|
||||
".pkl",
|
||||
"buz.pkl",
|
||||
"pkl.pkl.pkl.pkl"
|
||||
])
|
||||
@ValueSource(
|
||||
strings = ["/foo.pkl/bar/baz.pkl", "//fo///ba.pkl", ".pkl", "buz.pkl", "pkl.pkl.pkl.pkl"]
|
||||
)
|
||||
fun `globstar non-match`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("**.pkl")
|
||||
assertTrue(pattern.matcher(input).matches())
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"/foo.pkl/bar/baz.pkl",
|
||||
"//fo///ba.pkl",
|
||||
])
|
||||
@ValueSource(
|
||||
strings =
|
||||
[
|
||||
"/foo.pkl/bar/baz.pkl",
|
||||
"//fo///ba.pkl",
|
||||
]
|
||||
)
|
||||
fun `globstar match 2`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("/**/*.pkl")
|
||||
assertTrue(pattern.matcher(input).matches())
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"bar.pkl",
|
||||
".pkl",
|
||||
"/foo.pkl"
|
||||
])
|
||||
@ValueSource(strings = ["bar.pkl", ".pkl", "/foo.pkl"])
|
||||
fun `globstar non-match 2`(input: String) {
|
||||
val pattern = GlobResolver.toRegexPattern("/**/*.pkl")
|
||||
assertFalse(pattern.matcher(input).matches())
|
||||
@@ -135,7 +147,9 @@ class GlobResolverTest {
|
||||
|
||||
@Test
|
||||
fun `invalid sub-patterns`() {
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("{foo{bar}}") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("{foo{bar}}")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("{foo") }
|
||||
// no leading open curly means closing curly is treated verbatim
|
||||
assertDoesNotThrow { GlobResolver.toRegexPattern("foo}") }
|
||||
@@ -164,21 +178,39 @@ class GlobResolverTest {
|
||||
@Test
|
||||
fun `invalid character classes`() {
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("thing[") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("thing[foo/bar]") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("[[=a=]]") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("[[:alnum:]]") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("[[.a-acute.]]") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("thing[foo/bar]")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("[[=a=]]")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("[[:alnum:]]")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("[[.a-acute.]]")
|
||||
}
|
||||
// no leading open square bracket means closing square bracket is verbatim
|
||||
assertDoesNotThrow { GlobResolver.toRegexPattern("]") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid extglob`() {
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("!(foo|bar)") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("+(foo|bar)") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("?(foo|bar)") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("@(foo|bar)") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> { GlobResolver.toRegexPattern("*(foo|bar)") }
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("!(foo|bar)")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("+(foo|bar)")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("?(foo|bar)")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("@(foo|bar)")
|
||||
}
|
||||
assertThrows<GlobResolver.InvalidGlobPatternException> {
|
||||
GlobResolver.toRegexPattern("*(foo|bar)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/**
|
||||
* 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.core.util
|
||||
|
||||
import java.io.IOException
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.commons.test.FakeHttpResponse
|
||||
import java.io.IOException
|
||||
import java.net.URI
|
||||
|
||||
class HttpUtilsTest {
|
||||
@Test
|
||||
@@ -21,32 +36,20 @@ class HttpUtilsTest {
|
||||
assertThat(HttpUtils.isHttpUrl(URI("HtTpS://example.com").toURL())).isTrue
|
||||
assertThat(HttpUtils.isHttpUrl(URI("file://example.com").toURL())).isFalse
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun checkHasStatusCode200() {
|
||||
val response = FakeHttpResponse.withoutBody {
|
||||
statusCode = 200
|
||||
}
|
||||
assertDoesNotThrow {
|
||||
HttpUtils.checkHasStatusCode200(response)
|
||||
}
|
||||
val response = FakeHttpResponse.withoutBody { statusCode = 200 }
|
||||
assertDoesNotThrow { HttpUtils.checkHasStatusCode200(response) }
|
||||
|
||||
val response2 = FakeHttpResponse.withoutBody {
|
||||
statusCode = 404
|
||||
}
|
||||
assertThrows<IOException> {
|
||||
HttpUtils.checkHasStatusCode200(response2)
|
||||
}
|
||||
val response2 = FakeHttpResponse.withoutBody { statusCode = 404 }
|
||||
assertThrows<IOException> { HttpUtils.checkHasStatusCode200(response2) }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun setPort() {
|
||||
assertThrows<IllegalArgumentException> {
|
||||
HttpUtils.setPort(URI("https://example.com"), -1)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
HttpUtils.setPort(URI("https://example.com"), 65536)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { HttpUtils.setPort(URI("https://example.com"), -1) }
|
||||
assertThrows<IllegalArgumentException> { HttpUtils.setPort(URI("https://example.com"), 65536) }
|
||||
assertThat(HttpUtils.setPort(URI("http://example.com"), 123))
|
||||
.isEqualTo(URI("http://example.com:123"))
|
||||
assertThat(HttpUtils.setPort(URI("http://example.com:456"), 123))
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
/**
|
||||
* 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.core.util
|
||||
|
||||
import java.io.FileNotFoundException
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -11,12 +31,6 @@ import org.pkl.core.SecurityManager
|
||||
import org.pkl.core.module.ModuleKeyFactories
|
||||
import org.pkl.core.module.ModuleKeys
|
||||
import org.pkl.core.runtime.ModuleResolver
|
||||
import java.io.FileNotFoundException
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.net.URL
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
|
||||
class IoUtilsTest {
|
||||
object FakeSecurityManager : SecurityManager {
|
||||
@@ -29,35 +43,32 @@ class IoUtilsTest {
|
||||
override fun checkResolveResource(resource: URI) {}
|
||||
}
|
||||
|
||||
private val moduleResolver = ModuleResolver(
|
||||
listOf(
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.file,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.genericUrl
|
||||
private val moduleResolver =
|
||||
ModuleResolver(
|
||||
listOf(
|
||||
ModuleKeyFactories.pkg,
|
||||
ModuleKeyFactories.file,
|
||||
ModuleKeyFactories.standardLibrary,
|
||||
ModuleKeyFactories.genericUrl
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `ensurePathEndsWithSlash() - relative URI`() {
|
||||
val uri = URI("/some/path")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri))
|
||||
.isEqualTo(URI("/some/path/"))
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri)).isEqualTo(URI("/some/path/"))
|
||||
|
||||
val uri2 = URI("/some/path/")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri2))
|
||||
.isEqualTo(URI("/some/path/"))
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri2)).isEqualTo(URI("/some/path/"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensurePathEndsWithSlash() - absolute URI`() {
|
||||
val uri = URI("https://apple.com/path")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri))
|
||||
.isEqualTo(URI("https://apple.com/path/"))
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri)).isEqualTo(URI("https://apple.com/path/"))
|
||||
|
||||
val uri2 = URI("https://apple.com/path/")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri2))
|
||||
.isEqualTo(URI("https://apple.com/path/"))
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri2)).isEqualTo(URI("https://apple.com/path/"))
|
||||
|
||||
val uri3 = URI("https://user:pwd@apple.com:8080/path?foo=bar#frag")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri3))
|
||||
@@ -71,8 +82,7 @@ class IoUtilsTest {
|
||||
@Test
|
||||
fun `ensurePathEndsWithSlash() - opaque URI`() {
|
||||
val uri = URI("foo:some.thing")
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri))
|
||||
.isEqualTo(URI("foo:some.thing"))
|
||||
assertThat(IoUtils.ensurePathEndsWithSlash(uri)).isEqualTo(URI("foo:some.thing"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,7 +96,7 @@ class IoUtilsTest {
|
||||
val resolved = IoUtils.resolve(URI("file:/foo/bar"), URI("baz"))
|
||||
assertThat(resolved).isEqualTo(URI("file:/foo/baz"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `resolving relative URI against triple-slash jar-file URI results in triple-slash jar-file URI`() {
|
||||
val resolved = IoUtils.resolve(URI("jar:file:///some/archive.zip!/foo/bar"), URI("baz"))
|
||||
@@ -98,12 +108,11 @@ class IoUtilsTest {
|
||||
val resolved = IoUtils.resolve(URI("jar:file:/some/archive.zip!/foo/bar"), URI("baz"))
|
||||
assertThat(resolved).isEqualTo(URI("jar:file:/some/archive.zip!/foo/baz"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `resolve absolute URI against jar-file URI`() {
|
||||
val uri = URI("jar:file:///some/archive.zip!/foo/bar.pkl")
|
||||
assertThat(IoUtils.resolve(uri, URI("https://apple.com")))
|
||||
.isEqualTo(URI("https://apple.com"))
|
||||
assertThat(IoUtils.resolve(uri, URI("https://apple.com"))).isEqualTo(URI("https://apple.com"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -117,150 +126,106 @@ class IoUtilsTest {
|
||||
|
||||
@Test
|
||||
fun `relativize file URLs`() {
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/bar/baz.pkl")
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/bar/baz.pkl")))
|
||||
.isEqualTo(URI("baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/bar/qux.pkl")
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/bar/qux.pkl")))
|
||||
.isEqualTo(URI("baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/bar/")
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/bar/")))
|
||||
.isEqualTo(URI("baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/bar")
|
||||
)
|
||||
).isEqualTo(URI("bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/bar")))
|
||||
.isEqualTo(URI("bar/baz.pkl"))
|
||||
|
||||
// URI.relativize() returns an absolute URI here
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/qux/")
|
||||
)
|
||||
).isEqualTo(URI("../bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/qux/")))
|
||||
.isEqualTo(URI("../bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/qux/qux2/")
|
||||
)
|
||||
).isEqualTo(URI("../../bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/qux/qux2/")))
|
||||
.isEqualTo(URI("../../bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///foo/qux/qux2")
|
||||
)
|
||||
).isEqualTo(URI("../bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///foo/qux/qux2")))
|
||||
.isEqualTo(URI("../bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("file:///qux/qux2/")
|
||||
)
|
||||
).isEqualTo(URI("../../foo/bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("file:///qux/qux2/")))
|
||||
.isEqualTo(URI("../../foo/bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("file:///foo/bar/baz.pkl"),
|
||||
URI("https:///foo/bar/baz.pkl")
|
||||
)
|
||||
).isEqualTo(URI("file:///foo/bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("file:///foo/bar/baz.pkl"), URI("https:///foo/bar/baz.pkl")))
|
||||
.isEqualTo(URI("file:///foo/bar/baz.pkl"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `relativize HTTP URLs`() {
|
||||
// perhaps URI("") would be a more precise result
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl"),
|
||||
URI("https://foo.com/bar/baz.pkl")
|
||||
IoUtils.relativize(URI("https://foo.com/bar/baz.pkl"), URI("https://foo.com/bar/baz.pkl"))
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl"))
|
||||
.isEqualTo(URI("baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
IoUtils.relativize(URI("https://foo.com/bar/baz.pkl"), URI("https://foo.com/bar/qux.pkl"))
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl"))
|
||||
.isEqualTo(URI("baz.pkl"))
|
||||
|
||||
assertThat(IoUtils.relativize(URI("https://foo.com/bar/baz.pkl"), URI("https://foo.com/qux/")))
|
||||
.isEqualTo(URI("../bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl"),
|
||||
URI("https://foo.com/qux/")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("../bar/baz.pkl"))
|
||||
.isEqualTo(URI("baz.pkl?query"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl?query"))
|
||||
.isEqualTo(URI("baz.pkl#fragment"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl#fragment"))
|
||||
.isEqualTo(URI("baz.pkl?query#fragment"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl?query2#fragment2")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl?query#fragment"))
|
||||
.isEqualTo(URI("baz.pkl?query#fragment"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com/bar/baz.pkl?query#fragment"),
|
||||
URI("https://foo.com/bar/qux.pkl?query2#fragment2")
|
||||
IoUtils.relativize(URI("https://foo.com:80/bar/baz.pkl"), URI("https://foo.com:443/bar/"))
|
||||
)
|
||||
).isEqualTo(URI("baz.pkl?query#fragment"))
|
||||
.isEqualTo(URI("https://foo.com:80/bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com:80/bar/baz.pkl"),
|
||||
URI("https://foo.com:443/bar/")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com:80/bar/baz.pkl"),
|
||||
URI("https://bar.com:80/bar/baz.pkl")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("https://foo.com:80/bar/baz.pkl"))
|
||||
.isEqualTo(URI("https://foo.com:80/bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo.com:80/bar/baz.pkl"),
|
||||
URI("https://bar.com:80/bar/baz.pkl")
|
||||
IoUtils.relativize(
|
||||
URI("https://foo:bar@foo.com:80/bar/baz.pkl"),
|
||||
URI("https://foo:baz@bar.com:80/bar/baz.pkl")
|
||||
)
|
||||
)
|
||||
).isEqualTo(URI("https://foo.com:80/bar/baz.pkl"))
|
||||
.isEqualTo(URI("https://foo:bar@foo.com:80/bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo:bar@foo.com:80/bar/baz.pkl"),
|
||||
URI("https://foo:baz@bar.com:80/bar/baz.pkl")
|
||||
)
|
||||
).isEqualTo(URI("https://foo:bar@foo.com:80/bar/baz.pkl"))
|
||||
|
||||
assertThat(
|
||||
IoUtils.relativize(
|
||||
URI("https://foo/bar/baz.pkl"),
|
||||
URI("file://foo/bar/baz.pkl")
|
||||
)
|
||||
).isEqualTo(URI("https://foo/bar/baz.pkl"))
|
||||
assertThat(IoUtils.relativize(URI("https://foo/bar/baz.pkl"), URI("file://foo/bar/baz.pkl")))
|
||||
.isEqualTo(URI("https://foo/bar/baz.pkl"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -304,20 +269,21 @@ class IoUtilsTest {
|
||||
|
||||
@Test
|
||||
fun inferModuleName() {
|
||||
val assertions = mapOf(
|
||||
"file:///foo.pkl" to "foo",
|
||||
"file:///foo/bar/baz.pkl" to "baz",
|
||||
"jar:file:///some/archive.zip!/foo.pkl" to "foo",
|
||||
"jar:file:///some/archive.zip!/foo/bar/baz.pkl" to "baz",
|
||||
"https://apple.com/foo.pkl" to "foo",
|
||||
"https://apple.com/foo/bar/baz.pkl" to "baz",
|
||||
"pkl:foo" to "foo",
|
||||
"pkl:foo.bar.baz" to "baz",
|
||||
"modulepath:/foo.pkl" to "foo",
|
||||
"modulepath:/foo/bar/baz.pkl" to "baz",
|
||||
"package://example.com/foo/bar@1.0.0#/baz.pkl" to "baz",
|
||||
"package://example.com/foo/bar@1.0.0#/baz/biz/qux.pkl" to "qux"
|
||||
)
|
||||
val assertions =
|
||||
mapOf(
|
||||
"file:///foo.pkl" to "foo",
|
||||
"file:///foo/bar/baz.pkl" to "baz",
|
||||
"jar:file:///some/archive.zip!/foo.pkl" to "foo",
|
||||
"jar:file:///some/archive.zip!/foo/bar/baz.pkl" to "baz",
|
||||
"https://apple.com/foo.pkl" to "foo",
|
||||
"https://apple.com/foo/bar/baz.pkl" to "baz",
|
||||
"pkl:foo" to "foo",
|
||||
"pkl:foo.bar.baz" to "baz",
|
||||
"modulepath:/foo.pkl" to "foo",
|
||||
"modulepath:/foo/bar/baz.pkl" to "baz",
|
||||
"package://example.com/foo/bar@1.0.0#/baz.pkl" to "baz",
|
||||
"package://example.com/foo/bar@1.0.0#/baz/biz/qux.pkl" to "qux"
|
||||
)
|
||||
for ((uriStr, name) in assertions) {
|
||||
val uri = URI(uriStr)
|
||||
val moduleKey = moduleResolver.resolve(uri)
|
||||
@@ -330,33 +296,32 @@ class IoUtilsTest {
|
||||
assertThat(IoUtils.toUri("file://foo.pkl")).isEqualTo(URI("file://foo.pkl"))
|
||||
assertThat(IoUtils.toUri("foo.pkl")).isEqualTo(URI("foo.pkl"))
|
||||
assertThat(IoUtils.toUri("foo bar.pkl").rawPath).isEqualTo("foo%20bar.pkl")
|
||||
assertThrows<URISyntaxException> {
|
||||
IoUtils.toUri("file:foo bar.pkl")
|
||||
}
|
||||
assertThrows<URISyntaxException> { IoUtils.toUri("file:foo bar.pkl") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolveUri - file hierarchy`(@TempDir tempDir: Path) {
|
||||
val file1 = tempDir.resolve("base1/base2/foo.pkl").createParentDirectories().createFile()
|
||||
val file2 = tempDir.resolve("base1/base2/dir1/dir2/foo.pkl").createParentDirectories().createFile()
|
||||
val file2 =
|
||||
tempDir.resolve("base1/base2/dir1/dir2/foo.pkl").createParentDirectories().createFile()
|
||||
val file3 = tempDir.resolve("base1/dir2/foo.pkl").createParentDirectories().createFile()
|
||||
|
||||
val uri = file2.toUri()
|
||||
val key = ModuleKeys.file(uri)
|
||||
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI("..."))).isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../foo.pkl"))).isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../base2/foo.pkl"))).isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../base1/base2/foo.pkl"))).isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../dir2/foo.pkl"))).isEqualTo(file3.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../foo.pkl")))
|
||||
.isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../base2/foo.pkl")))
|
||||
.isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../base1/base2/foo.pkl")))
|
||||
.isEqualTo(file1.toUri())
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../dir2/foo.pkl")))
|
||||
.isEqualTo(file3.toUri())
|
||||
|
||||
assertThrows<URISyntaxException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key, URI(".../"))
|
||||
}
|
||||
assertThrows<URISyntaxException> { IoUtils.resolve(FakeSecurityManager, key, URI(".../")) }
|
||||
|
||||
assertThrows<URISyntaxException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key, URI("...abc"))
|
||||
}
|
||||
assertThrows<URISyntaxException> { IoUtils.resolve(FakeSecurityManager, key, URI("...abc")) }
|
||||
|
||||
assertThrows<FileNotFoundException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key, URI(".../bar.pkl"))
|
||||
@@ -382,20 +347,32 @@ class IoUtilsTest {
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../NamedModuleResolversTest.pkl")))
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/module/NamedModuleResolversTest.pkl"))
|
||||
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../module/NamedModuleResolversTest.pkl")))
|
||||
assertThat(
|
||||
IoUtils.resolve(FakeSecurityManager, key, URI(".../module/NamedModuleResolversTest.pkl"))
|
||||
)
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/module/NamedModuleResolversTest.pkl"))
|
||||
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../core/module/NamedModuleResolversTest.pkl")))
|
||||
assertThat(
|
||||
IoUtils.resolve(
|
||||
FakeSecurityManager,
|
||||
key,
|
||||
URI(".../core/module/NamedModuleResolversTest.pkl")
|
||||
)
|
||||
)
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/module/NamedModuleResolversTest.pkl"))
|
||||
|
||||
assertThat(IoUtils.resolve(FakeSecurityManager, key, URI(".../org/pkl/core/module/NamedModuleResolversTest.pkl")))
|
||||
assertThat(
|
||||
IoUtils.resolve(
|
||||
FakeSecurityManager,
|
||||
key,
|
||||
URI(".../org/pkl/core/module/NamedModuleResolversTest.pkl")
|
||||
)
|
||||
)
|
||||
.isEqualTo(URI("modulepath:/org/pkl/core/module/NamedModuleResolversTest.pkl"))
|
||||
|
||||
val uri2 = URI("modulepath:/foo/bar/baz.pkl")
|
||||
val key2 = ModuleKeys.classPath(uri2, classLoader)
|
||||
assertThrows<FileNotFoundException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key2, URI("..."))
|
||||
}
|
||||
assertThrows<FileNotFoundException> { IoUtils.resolve(FakeSecurityManager, key2, URI("...")) }
|
||||
assertThrows<FileNotFoundException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key2, URI(".../other.pkl"))
|
||||
}
|
||||
@@ -403,22 +380,16 @@ class IoUtilsTest {
|
||||
IoUtils.resolve(FakeSecurityManager, key2, URI(".../dir1/dir2/NamedModuleResolversTest.pkl"))
|
||||
}
|
||||
|
||||
assertThrows<URISyntaxException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key2, URI(".../"))
|
||||
}
|
||||
assertThrows<URISyntaxException> { IoUtils.resolve(FakeSecurityManager, key2, URI(".../")) }
|
||||
assertThrows<URISyntaxException> {
|
||||
IoUtils.resolve(FakeSecurityManager, key2, URI("...NamedModuleResolversTest.pkl"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `readBytes(URL) does not support HTTP URLs`() {
|
||||
assertThrows<IllegalArgumentException> {
|
||||
IoUtils.readBytes(URI("https://example.com"))
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
IoUtils.readBytes(URI("http://example.com"))
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { IoUtils.readBytes(URI("https://example.com")) }
|
||||
assertThrows<IllegalArgumentException> { IoUtils.readBytes(URI("http://example.com")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -426,9 +397,7 @@ class IoUtilsTest {
|
||||
assertThrows<IllegalArgumentException> {
|
||||
IoUtils.readString(URI("https://example.com").toURL())
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
IoUtils.readString(URI("http://example.com").toURL())
|
||||
}
|
||||
assertThrows<IllegalArgumentException> { IoUtils.readString(URI("http://example.com").toURL()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user