mirror of
https://github.com/apple/pkl.git
synced 2026-05-25 08:09:17 +02:00
Introduce "minimal" test reporter (#1563)
This commit is contained in:
@@ -546,6 +546,15 @@ When enabled, test failures will show intermediate values in the assertion expre
|
||||
Use `--no-power-assertions` to disable this feature if you prefer simpler output.
|
||||
====
|
||||
|
||||
[[test-reporter]]
|
||||
.--test-reporter
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `spec` +
|
||||
Example: `--test-reporter minimal` +
|
||||
Which test reporter to use for CLI output. Possible values are `spec` and `minimal`.
|
||||
====
|
||||
|
||||
This command also takes <<common-options, common options>>.
|
||||
|
||||
[[command-run]]
|
||||
@@ -667,6 +676,14 @@ Force generation of expected examples. +
|
||||
The old expected files will be deleted if present.
|
||||
====
|
||||
|
||||
.--test-reporter
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `spec` +
|
||||
Example: `--test-reporter minimal` +
|
||||
Which test reporter to use for CLI output. Possible values are `spec` and `minimal`.
|
||||
====
|
||||
|
||||
This command also takes <<common-options,common options>>.
|
||||
|
||||
[[command-project-resolve]]
|
||||
|
||||
@@ -322,6 +322,15 @@ Default: `false` +
|
||||
Whether to ignore expected example files and generate them again.
|
||||
====
|
||||
|
||||
[[test-reporter]]
|
||||
.test-reporter: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `"spec"` +
|
||||
Example: `reporter = "minimal"` +
|
||||
Which test reporter to use for CLI output. Possible values are `"spec"` and `"minimal"`.
|
||||
====
|
||||
|
||||
[[power-assertions-test]]
|
||||
.powerAssertions: Property<Boolean>
|
||||
[%collapsible]
|
||||
@@ -677,6 +686,14 @@ Default: `false` +
|
||||
Whether to ignore expected example files and generate them again.
|
||||
====
|
||||
|
||||
.test-reporter: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `"spec"` +
|
||||
Example: `reporter = "minimal"` +
|
||||
Which test reporter to use for CLI output. Possible values are `"spec"` and `"minimal"`.
|
||||
====
|
||||
|
||||
Common properties:
|
||||
|
||||
include::../partials/gradle-common-properties.adoc[]
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.io.StringWriter
|
||||
import java.io.Writer
|
||||
import org.pkl.commons.cli.*
|
||||
import org.pkl.core.Closeables
|
||||
@@ -22,8 +23,9 @@ import org.pkl.core.EvaluatorBuilder
|
||||
import org.pkl.core.ModuleSource.uri
|
||||
import org.pkl.core.PklException
|
||||
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.stdlib.test.report.JUnitReporter
|
||||
import org.pkl.core.stdlib.test.report.MinimalReporter
|
||||
import org.pkl.core.stdlib.test.report.SpecReporter
|
||||
import org.pkl.core.util.ErrorMessages
|
||||
|
||||
class CliTestRunner
|
||||
@@ -64,13 +66,15 @@ constructor(
|
||||
var failed = false
|
||||
var isExampleWrittenFailure = true
|
||||
val moduleNames = mutableSetOf<String>()
|
||||
val reporter = SimpleReport(useColor)
|
||||
val reporter =
|
||||
when (testOptions.reporter) {
|
||||
TestReporter.SPEC -> SpecReporter(useColor)
|
||||
TestReporter.MINIMAL -> MinimalReporter(useColor)
|
||||
}
|
||||
val allTestResults = mutableListOf<TestResults>()
|
||||
|
||||
val junitDir = testOptions.junitDir
|
||||
if (junitDir != null) {
|
||||
junitDir.toFile().mkdirs()
|
||||
}
|
||||
junitDir?.toFile()?.mkdirs()
|
||||
|
||||
for ((idx, moduleUri) in sources.withIndex()) {
|
||||
try {
|
||||
@@ -80,8 +84,11 @@ constructor(
|
||||
failed = results.failed()
|
||||
isExampleWrittenFailure = results.isExampleWrittenFailure.and(isExampleWrittenFailure)
|
||||
}
|
||||
reporter.report(results, consoleWriter)
|
||||
if (sources.size > 1 && idx != sources.size - 1) {
|
||||
val tmpWriter = StringWriter()
|
||||
reporter.report(results, tmpWriter)
|
||||
val report = tmpWriter.toString()
|
||||
consoleWriter.write(report)
|
||||
if (report.isNotEmpty() && sources.size > 1 && idx != sources.size - 1) {
|
||||
consoleWriter.append('\n')
|
||||
}
|
||||
consoleWriter.flush()
|
||||
@@ -101,7 +108,7 @@ constructor(
|
||||
moduleNames += moduleName
|
||||
|
||||
if (!testOptions.junitAggregateReports) {
|
||||
JUnitReport().reportToPath(results, junitDir.resolve(moduleName))
|
||||
JUnitReporter().reportToPath(results, junitDir.resolve(moduleName))
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
@@ -119,7 +126,7 @@ constructor(
|
||||
}
|
||||
if (testOptions.junitAggregateReports && junitDir != null) {
|
||||
val fileName = "${testOptions.junitAggregateSuiteName}.xml"
|
||||
JUnitReport(testOptions.junitAggregateSuiteName)
|
||||
JUnitReporter(testOptions.junitAggregateSuiteName)
|
||||
.summarizeToPath(allTestResults, junitDir.resolve(fileName))
|
||||
}
|
||||
consoleWriter.append('\n')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 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.
|
||||
@@ -22,4 +22,5 @@ class CliTestOptions(
|
||||
val overwrite: Boolean = false,
|
||||
val junitAggregateReports: Boolean = false,
|
||||
val junitAggregateSuiteName: String = "pkl-tests",
|
||||
val reporter: TestReporter = TestReporter.SPEC,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright © 2026 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.commons.cli
|
||||
|
||||
enum class TestReporter {
|
||||
SPEC,
|
||||
MINIMAL,
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 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.
|
||||
@@ -19,9 +19,11 @@ import com.github.ajalt.clikt.parameters.groups.OptionGroup
|
||||
import com.github.ajalt.clikt.parameters.options.default
|
||||
import com.github.ajalt.clikt.parameters.options.flag
|
||||
import com.github.ajalt.clikt.parameters.options.option
|
||||
import com.github.ajalt.clikt.parameters.types.enum
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import java.nio.file.Path
|
||||
import org.pkl.commons.cli.CliTestOptions
|
||||
import org.pkl.commons.cli.TestReporter
|
||||
|
||||
class TestOptions : OptionGroup() {
|
||||
private val junitReportDir: Path? by
|
||||
@@ -51,7 +53,19 @@ class TestOptions : OptionGroup() {
|
||||
private val overwrite: Boolean by
|
||||
option(names = arrayOf("--overwrite"), help = "Force generation of expected examples.").flag()
|
||||
|
||||
private val reporter: TestReporter by
|
||||
option(names = arrayOf("--test-reporter"), help = "Which test reporter to use for CLI output.")
|
||||
.enum<TestReporter> { it.name.lowercase() }
|
||||
.single()
|
||||
.default(TestReporter.SPEC)
|
||||
|
||||
val cliTestOptions: CliTestOptions by lazy {
|
||||
CliTestOptions(junitReportDir, overwrite, junitAggregateReports, junitAggregateSuiteName)
|
||||
CliTestOptions(
|
||||
junitReportDir,
|
||||
overwrite,
|
||||
junitAggregateReports,
|
||||
junitAggregateSuiteName,
|
||||
reporter,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-37
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2026 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.
|
||||
@@ -24,41 +24,21 @@ import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import org.pkl.core.TestResults;
|
||||
import org.pkl.core.TestResults.TestResult;
|
||||
import org.pkl.core.TestResults.TestSectionResults;
|
||||
import org.pkl.core.util.AnsiStringBuilder;
|
||||
import org.pkl.core.util.AnsiStringBuilder.AnsiCode;
|
||||
import org.pkl.core.util.AnsiTheme;
|
||||
import org.pkl.core.util.StringUtils;
|
||||
|
||||
public final class SimpleReport implements TestReport {
|
||||
public abstract class BaseReporter implements TestReporter {
|
||||
protected static final String passingMark = "✔ ";
|
||||
protected static final String failingMark = "✘ ";
|
||||
|
||||
private static final String passingMark = "✔ ";
|
||||
private static final String failingMark = "✘ ";
|
||||
protected final boolean useColor;
|
||||
|
||||
private final boolean useColor;
|
||||
|
||||
public SimpleReport(boolean useColor) {
|
||||
public BaseReporter(boolean useColor) {
|
||||
this.useColor = useColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(TestResults results, Writer writer) throws IOException {
|
||||
var builder = new AnsiStringBuilder(useColor);
|
||||
|
||||
builder.append("module ").append(results.moduleName()).append('\n');
|
||||
|
||||
if (results.error() != null) {
|
||||
var rendered = results.error().exception().getMessage();
|
||||
appendPadded(builder, rendered, " ");
|
||||
builder.append('\n');
|
||||
} else {
|
||||
reportResults(results.facts(), builder);
|
||||
reportResults(results.examples(), builder);
|
||||
}
|
||||
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void summarize(List<TestResults> allTestResults, Writer writer) throws IOException {
|
||||
var totalTests = 0;
|
||||
@@ -91,16 +71,7 @@ public final class SimpleReport implements TestReport {
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
|
||||
private void reportResults(TestSectionResults section, AnsiStringBuilder builder) {
|
||||
if (!section.results().isEmpty()) {
|
||||
builder.append(" ").append(section.name()).append('\n');
|
||||
StringUtils.joinToStringBuilder(
|
||||
builder, section.results(), "\n", res -> reportResult(res, builder));
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void reportResult(TestResult result, AnsiStringBuilder builder) {
|
||||
protected void reportResult(TestResult result, AnsiStringBuilder builder) {
|
||||
builder.append(" ");
|
||||
|
||||
if (result.isExampleWritten()) {
|
||||
@@ -129,7 +100,7 @@ public final class SimpleReport implements TestReport {
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendPadded(AnsiStringBuilder builder, String lines, String padding) {
|
||||
protected static void appendPadded(AnsiStringBuilder builder, String lines, String padding) {
|
||||
StringUtils.joinToStringBuilder(
|
||||
builder,
|
||||
lines.lines().collect(Collectors.toList()),
|
||||
+3
-3
@@ -37,15 +37,15 @@ import org.pkl.core.stdlib.PklConverter;
|
||||
import org.pkl.core.stdlib.xml.RendererNodes.Renderer;
|
||||
import org.pkl.core.util.EconomicMaps;
|
||||
|
||||
public final class JUnitReport implements TestReport {
|
||||
public final class JUnitReporter implements TestReporter {
|
||||
|
||||
private final String aggregateSuiteName;
|
||||
|
||||
public JUnitReport(String aggregateSuiteName) {
|
||||
public JUnitReporter(String aggregateSuiteName) {
|
||||
this.aggregateSuiteName = aggregateSuiteName;
|
||||
}
|
||||
|
||||
public JUnitReport() {
|
||||
public JUnitReporter() {
|
||||
this("");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright © 2026 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.test.report;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import org.pkl.core.TestResults;
|
||||
import org.pkl.core.TestResults.TestResult;
|
||||
import org.pkl.core.TestResults.TestSectionResults;
|
||||
import org.pkl.core.util.AnsiStringBuilder;
|
||||
import org.pkl.core.util.StringUtils;
|
||||
|
||||
/** Minimal reporter. Only reports failures and errors. */
|
||||
public final class MinimalReporter extends BaseReporter {
|
||||
|
||||
public MinimalReporter(boolean useColor) {
|
||||
super(useColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(TestResults results, Writer writer) throws IOException {
|
||||
var builder = new AnsiStringBuilder(useColor);
|
||||
|
||||
if (results.error() != null) {
|
||||
builder.append("module ").append(results.moduleName()).append('\n');
|
||||
|
||||
var rendered = results.error().exception().getMessage();
|
||||
appendPadded(builder, rendered, " ");
|
||||
builder.append('\n');
|
||||
} else {
|
||||
var factFailures = results.facts().results().stream().filter(TestResult::isFailure).toList();
|
||||
var exampleFailures =
|
||||
results.examples().results().stream().filter(TestResult::isFailure).toList();
|
||||
if (!factFailures.isEmpty() || !exampleFailures.isEmpty()) {
|
||||
builder.append("module ").append(results.moduleName()).append('\n');
|
||||
|
||||
reportResults(results.facts(), factFailures, builder);
|
||||
reportResults(results.examples(), exampleFailures, builder);
|
||||
}
|
||||
}
|
||||
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
|
||||
private void reportResults(
|
||||
TestSectionResults section, List<TestResults.TestResult> results, AnsiStringBuilder builder) {
|
||||
if (!results.isEmpty()) {
|
||||
builder.append(" ").append(section.name()).append('\n');
|
||||
StringUtils.joinToStringBuilder(builder, results, "\n", res -> reportResult(res, builder));
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright © 2024-2026 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.test.report;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import org.pkl.core.TestResults;
|
||||
import org.pkl.core.TestResults.TestSectionResults;
|
||||
import org.pkl.core.util.AnsiStringBuilder;
|
||||
import org.pkl.core.util.StringUtils;
|
||||
|
||||
public final class SpecReporter extends BaseReporter {
|
||||
|
||||
public SpecReporter(boolean useColor) {
|
||||
super(useColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(TestResults results, Writer writer) throws IOException {
|
||||
var builder = new AnsiStringBuilder(useColor);
|
||||
|
||||
builder.append("module ").append(results.moduleName()).append('\n');
|
||||
|
||||
if (results.error() != null) {
|
||||
var rendered = results.error().exception().getMessage();
|
||||
appendPadded(builder, rendered, " ");
|
||||
builder.append('\n');
|
||||
} else {
|
||||
reportResults(results.facts(), builder);
|
||||
reportResults(results.examples(), builder);
|
||||
}
|
||||
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
|
||||
private void reportResults(TestSectionResults section, AnsiStringBuilder builder) {
|
||||
if (!section.results().isEmpty()) {
|
||||
builder.append(" ").append(section.name()).append('\n');
|
||||
StringUtils.joinToStringBuilder(
|
||||
builder, section.results(), "\n", res -> reportResult(res, builder));
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 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.
|
||||
@@ -25,7 +25,7 @@ import org.pkl.core.PklBugException;
|
||||
import org.pkl.core.TestResults;
|
||||
import org.pkl.core.util.StringBuilderWriter;
|
||||
|
||||
public interface TestReport {
|
||||
public interface TestReporter {
|
||||
|
||||
void report(TestResults results, Writer writer) throws IOException;
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright © 2026 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 java.io.StringWriter
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.TestResults
|
||||
import org.pkl.core.TestResults.TestResult
|
||||
import org.pkl.core.TestResults.TestSectionResults
|
||||
import org.pkl.core.stdlib.test.report.MinimalReporter
|
||||
|
||||
class MinimalReportTest {
|
||||
|
||||
@Test
|
||||
fun `report with only passing tests does not show module or test names`() {
|
||||
val resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
resultsBuilder.setFactsSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.FACTS,
|
||||
listOf(TestResult("passing fact", 1, emptyList(), emptyList(), false)),
|
||||
)
|
||||
)
|
||||
resultsBuilder.setExamplesSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.EXAMPLES,
|
||||
listOf(TestResult("passing example", 1, emptyList(), emptyList(), false)),
|
||||
)
|
||||
)
|
||||
val testResults = resultsBuilder.build()
|
||||
|
||||
val writer = StringWriter()
|
||||
val minimalReport = MinimalReporter(false)
|
||||
minimalReport.report(testResults, writer)
|
||||
|
||||
assertThat(writer.toString()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `report with failures shows module name and only failed tests`() {
|
||||
val resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
resultsBuilder.setFactsSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.FACTS,
|
||||
listOf(
|
||||
TestResult("passing fact", 1, emptyList(), emptyList(), false),
|
||||
TestResult(
|
||||
"failing fact",
|
||||
1,
|
||||
listOf(TestResults.Failure("Fact Failure", "failed")),
|
||||
emptyList(),
|
||||
false,
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
resultsBuilder.setExamplesSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.EXAMPLES,
|
||||
listOf(TestResult("passing example", 1, emptyList(), emptyList(), false)),
|
||||
)
|
||||
)
|
||||
val testResults = resultsBuilder.build()
|
||||
|
||||
val writer = StringWriter()
|
||||
val minimalReport = MinimalReporter(false)
|
||||
minimalReport.report(testResults, writer)
|
||||
|
||||
val output = writer.toString()
|
||||
assertThat(output).contains("module module1")
|
||||
assertThat(output).contains("failing fact")
|
||||
assertThat(output).doesNotContain("passing fact")
|
||||
assertThat(output).doesNotContain("passing example")
|
||||
assertThat(output).doesNotContain("examples")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `summarize includes stats even when all tests pass`() {
|
||||
val resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
resultsBuilder.setFactsSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.FACTS,
|
||||
listOf(TestResult("passing fact", 1, emptyList(), emptyList(), false)),
|
||||
)
|
||||
)
|
||||
resultsBuilder.setExamplesSection(
|
||||
TestSectionResults(TestResults.TestSectionName.EXAMPLES, emptyList())
|
||||
)
|
||||
val testResults = listOf(resultsBuilder.build())
|
||||
|
||||
val writer = StringWriter()
|
||||
val minimalReport = MinimalReporter(false)
|
||||
minimalReport.summarize(testResults, writer)
|
||||
|
||||
val output = writer.toString()
|
||||
assertThat(output).contains("100.0% tests pass")
|
||||
assertThat(output).contains("1 passed")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `summarize method should generate correct output for failures`() {
|
||||
val resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
resultsBuilder.setFactsSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.FACTS,
|
||||
listOf(
|
||||
TestResult(
|
||||
"example1",
|
||||
321919,
|
||||
listOf(TestResults.Failure("Fact Failure", "failed")),
|
||||
emptyList(),
|
||||
false,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
resultsBuilder.setExamplesSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.EXAMPLES,
|
||||
listOf(
|
||||
TestResult(
|
||||
"example1",
|
||||
432525,
|
||||
listOf(TestResults.Failure("Output Mismatch", "does not match")),
|
||||
emptyList(),
|
||||
false,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
val testResults = listOf(resultsBuilder.build())
|
||||
|
||||
val writer = StringWriter()
|
||||
val minimalReport = MinimalReporter(false)
|
||||
minimalReport.summarize(testResults, writer)
|
||||
|
||||
val expectedOutput =
|
||||
"""
|
||||
0.0% tests pass [2/2 failed], 99.9% asserts pass [2/754444 failed]
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
assertThat(writer.toString().trimIndent()).isEqualTo(expectedOutput)
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,18 @@
|
||||
package org.pkl.core.stdlib
|
||||
|
||||
import java.io.StringWriter
|
||||
import java.util.*
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.TestResults
|
||||
import org.pkl.core.TestResults.TestResult
|
||||
import org.pkl.core.TestResults.TestSectionResults
|
||||
import org.pkl.core.stdlib.test.report.SimpleReport
|
||||
import org.pkl.core.stdlib.test.report.SpecReporter
|
||||
|
||||
class SimpleReportTest {
|
||||
|
||||
@Test
|
||||
fun `summarize method should generate correct output`() {
|
||||
var resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
val resultsBuilder = TestResults.Builder("module1", "module1")
|
||||
resultsBuilder.setFactsSection(
|
||||
TestSectionResults(
|
||||
TestResults.TestSectionName.FACTS,
|
||||
@@ -60,7 +59,7 @@ class SimpleReportTest {
|
||||
val testResults = listOf(resultsBuilder.build())
|
||||
|
||||
val writer = StringWriter()
|
||||
val simpleReport = SimpleReport(false)
|
||||
val simpleReport = SpecReporter(false)
|
||||
simpleReport.summarize(testResults, writer)
|
||||
|
||||
val expectedOutput =
|
||||
|
||||
@@ -100,6 +100,7 @@ public class PklPlugin implements Plugin<Project> {
|
||||
spec.getOutputPath()
|
||||
.convention(project.getLayout().getBuildDirectory().dir("generated/pkl/packages"));
|
||||
spec.getOverwrite().convention(false);
|
||||
spec.getReporter().convention("spec");
|
||||
var packageTask = createTask(project, ProjectPackageTask.class, spec);
|
||||
packageTask.configure(
|
||||
task -> {
|
||||
@@ -108,6 +109,7 @@ public class PklPlugin implements Plugin<Project> {
|
||||
task.getSkipPublishCheck().set(spec.getSkipPublishCheck());
|
||||
task.getJunitReportsDir().set(spec.getJunitReportsDir());
|
||||
task.getOverwrite().set(spec.getOverwrite());
|
||||
task.getTestReporter().set(spec.getReporter());
|
||||
});
|
||||
project
|
||||
.getPluginManager()
|
||||
@@ -278,12 +280,14 @@ public class PklPlugin implements Plugin<Project> {
|
||||
configureBaseSpec(project, spec);
|
||||
|
||||
spec.getOverwrite().convention(false);
|
||||
spec.getTestReporter().convention("spec");
|
||||
|
||||
var testTask = createModulesTask(project, TestTask.class, spec);
|
||||
testTask.configure(
|
||||
task -> {
|
||||
task.getJunitReportsDir().set(spec.getJunitReportsDir());
|
||||
task.getOverwrite().set(spec.getOverwrite());
|
||||
task.getTestReporter().set(spec.getTestReporter());
|
||||
});
|
||||
|
||||
project
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 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.
|
||||
@@ -29,4 +29,6 @@ public interface ProjectPackageSpec extends BasePklSpec {
|
||||
Property<Boolean> getOverwrite();
|
||||
|
||||
Property<Boolean> getSkipPublishCheck();
|
||||
|
||||
Property<String> getReporter();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 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.
|
||||
@@ -22,4 +22,6 @@ public interface TestSpec extends ModulesSpec {
|
||||
DirectoryProperty getJunitReportsDir();
|
||||
|
||||
Property<Boolean> getOverwrite();
|
||||
|
||||
Property<String> getTestReporter();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.gradle.api.tasks.PathSensitivity;
|
||||
import org.gradle.api.tasks.UntrackedTask;
|
||||
import org.pkl.cli.CliProjectPackager;
|
||||
import org.pkl.commons.cli.CliTestOptions;
|
||||
import org.pkl.commons.cli.TestReporter;
|
||||
|
||||
@UntrackedTask(because = "Output names are known only after execution")
|
||||
public abstract class ProjectPackageTask extends BasePklTask {
|
||||
@@ -62,6 +63,10 @@ public abstract class ProjectPackageTask extends BasePklTask {
|
||||
@Optional
|
||||
public abstract Property<Boolean> getSkipPublishCheck();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getTestReporter();
|
||||
|
||||
public ProjectPackageTask() {
|
||||
this.getJunitAggregateSuiteName().convention("pkl-tests");
|
||||
}
|
||||
@@ -75,6 +80,18 @@ public abstract class ProjectPackageTask extends BasePklTask {
|
||||
if (projectDirectories.isEmpty()) {
|
||||
throw new InvalidUserDataException("No project directories specified.");
|
||||
}
|
||||
TestReporter testReporter;
|
||||
try {
|
||||
testReporter = TestReporter.valueOf(getTestReporter().getOrElse("SPEC").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidUserDataException(
|
||||
"Invalid reporter: '%s'. Valid reporter options: %s"
|
||||
.formatted(
|
||||
getTestReporter().get(),
|
||||
TestReporter.getEntries().stream()
|
||||
.map(it -> it.name().toLowerCase())
|
||||
.collect(Collectors.joining(", "))));
|
||||
}
|
||||
|
||||
new CliProjectPackager(
|
||||
getCliBaseOptions(),
|
||||
@@ -83,7 +100,8 @@ public abstract class ProjectPackageTask extends BasePklTask {
|
||||
mapAndGetOrNull(getJunitReportsDir(), it -> it.getAsFile().toPath()),
|
||||
getOverwrite().get(),
|
||||
getJunitAggregateReports().getOrElse(false),
|
||||
getJunitAggregateSuiteName().get()),
|
||||
getJunitAggregateSuiteName().get(),
|
||||
testReporter),
|
||||
getOutputPath().get().getAsFile().getAbsolutePath(),
|
||||
getSkipPublishCheck().getOrElse(false),
|
||||
new PrintWriter(System.out),
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.pkl.gradle.task;
|
||||
import static org.pkl.gradle.utils.PluginUtils.mapAndGetOrNull;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.stream.Collectors;
|
||||
import org.gradle.api.InvalidUserDataException;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.CacheableTask;
|
||||
@@ -26,6 +28,7 @@ import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.pkl.cli.CliTestRunner;
|
||||
import org.pkl.commons.cli.CliTestOptions;
|
||||
import org.pkl.commons.cli.TestReporter;
|
||||
|
||||
@CacheableTask
|
||||
public abstract class TestTask extends ModulesTask {
|
||||
@@ -43,6 +46,10 @@ public abstract class TestTask extends ModulesTask {
|
||||
@Input
|
||||
public abstract Property<Boolean> getOverwrite();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getTestReporter();
|
||||
|
||||
public TestTask() {
|
||||
this.getJunitAggregateSuiteName().convention("pkl-tests");
|
||||
this.getPowerAssertions().convention(true);
|
||||
@@ -50,13 +57,26 @@ public abstract class TestTask extends ModulesTask {
|
||||
|
||||
@Override
|
||||
protected void doRunTask() {
|
||||
TestReporter testReporter;
|
||||
try {
|
||||
testReporter = TestReporter.valueOf(getTestReporter().getOrElse("SPEC").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidUserDataException(
|
||||
"Invalid reporter: '%s'. Valid reporter options: %s"
|
||||
.formatted(
|
||||
getTestReporter().get(),
|
||||
TestReporter.getEntries().stream()
|
||||
.map(it -> it.name().toLowerCase())
|
||||
.collect(Collectors.joining(", "))));
|
||||
}
|
||||
new CliTestRunner(
|
||||
getCliBaseOptions(),
|
||||
new CliTestOptions(
|
||||
mapAndGetOrNull(getJunitReportsDir(), it -> it.getAsFile().toPath()),
|
||||
getOverwrite().get(),
|
||||
getJunitAggregateReports().getOrElse(false),
|
||||
getJunitAggregateSuiteName().get()),
|
||||
getJunitAggregateSuiteName().get(),
|
||||
testReporter),
|
||||
new PrintWriter(System.out),
|
||||
new PrintWriter(System.err))
|
||||
.run();
|
||||
|
||||
Reference in New Issue
Block a user