All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pkl.cli.CliTestRunner.kt Maven / Gradle / Ivy

Go to download

Fat Jar containing pkl-cli, pkl-codegen-java, pkl-codegen-kotlin, pkl-config-java, pkl-core, pkl-doc, and their shaded third-party dependencies.

There is a newer version: 0.27.1
Show newest version
/*
 * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.pkl.cli

import java.io.Writer
import org.pkl.commons.cli.*
import org.pkl.core.Closeables
import org.pkl.core.EvaluatorBuilder
import org.pkl.core.ModuleSource.uri
import org.pkl.core.TestResults
import org.pkl.core.stdlib.test.report.JUnitReport
import org.pkl.core.stdlib.test.report.SimpleReport
import org.pkl.core.util.ErrorMessages

class CliTestRunner
@JvmOverloads
constructor(
  private val options: CliBaseOptions,
  private val testOptions: CliTestOptions,
  private val consoleWriter: Writer = System.out.writer(),
  private val errWriter: Writer = System.err.writer()
) : CliCommand(options) {

  override fun doRun() {
    val builder = evaluatorBuilder()
    try {
      evalTest(builder)
    } finally {
      Closeables.closeQuietly(builder.moduleKeyFactories)
      Closeables.closeQuietly(builder.resourceReaders)
    }
  }

  private fun evalTest(builder: EvaluatorBuilder) {
    val sources =
      options.normalizedSourceModules.ifEmpty { project?.tests?.map { it.toUri() } }
        ?:
        // keep in sync with error message thrown by clikt
        throw CliException(
          """
          Usage: pkl test [OPTIONS] ...
          
          Error: Missing argument ""
        """
            .trimIndent()
        )

    val evaluator = builder.build()
    evaluator.use {
      var failed = false
      var isExampleWrittenFailure = true
      val moduleNames = mutableSetOf()
      val reporter = SimpleReport(useColor)
      val allTestResults = mutableListOf()
      for ((idx, moduleUri) in sources.withIndex()) {
        try {
          val results = evaluator.evaluateTest(uri(moduleUri), testOptions.overwrite)
          allTestResults.add(results)
          if (!failed) {
            failed = results.failed()
            isExampleWrittenFailure = results.isExampleWrittenFailure.and(isExampleWrittenFailure)
          }
          reporter.report(results, consoleWriter)
          if (sources.size > 1 && idx != sources.size - 1) {
            consoleWriter.append('\n')
          }
          consoleWriter.flush()
          val junitDir = testOptions.junitDir
          if (junitDir != null) {
            junitDir.toFile().mkdirs()
            val moduleName = "${results.moduleName}.xml"
            if (moduleName in moduleNames) {
              throw RuntimeException(
                """
                  Cannot generate JUnit report for $moduleUri.
                  A report with the same name was already generated.
                  
                  To fix, provide a different name for this module by adding a module header.
                """
                  .trimIndent()
              )
            }
            moduleNames += moduleName
            JUnitReport().reportToPath(results, junitDir.resolve(moduleName))
          }
        } catch (ex: Exception) {
          errWriter.appendLine("Error evaluating module ${moduleUri.path}:")
          errWriter.write(ex.message ?: "")
          if (moduleUri != sources.last()) {
            errWriter.appendLine()
          }
          errWriter.flush()
          failed = true
        }
      }
      consoleWriter.append('\n')
      reporter.summarize(allTestResults, consoleWriter)
      consoleWriter.flush()
      if (failed) {
        val exitCode = if (isExampleWrittenFailure) 10 else 1
        throw CliTestException(ErrorMessages.create("testsFailed"), exitCode)
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy