/* * Copyright 2015-2017 the original author or authors. * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package org.junit.platform.console; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertLinesMatch; import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.platform.commons.util.ReflectionUtils.findMethods; import static org.junit.platform.commons.util.ReflectionUtils.getFullyQualifiedMethodName; import java.lang.reflect.Method; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DynamicContainer; import org.junit.jupiter.api.DynamicNode; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.TestReporter; import org.junit.jupiter.api.function.Executable; import org.junit.platform.console.options.Details; import org.junit.platform.console.options.Theme; /** * @since 1.0 */ class ConsoleDetailsTests { @DisplayName("Basic") private static class Basic { @Test void empty() { } @Test @DisplayName(".oO fancy display name Oo.") void changeDisplayName() { } } @DisplayName("Skip") private static class Skip { @Test @Disabled("single line skip reason") void skipWithSingleLineReason() { } @Test @Disabled("multi\nline\nfail\nmessage") void skipWithMultiLineMessage() { } } @DisplayName("Fail") private static class Fail { @Test void failWithSingleLineMessage() { fail("single line fail message"); } @Test void failWithMultiLineMessage() { fail("multi\nline\nfail\nmessage"); } } @DisplayName("Report") private static class Report { @Test void reportSingleEntryWithSingleMapping(TestReporter reporter) { reporter.publishEntry("foo", "bar"); } @Test void reportMultiEntriesWithSingleMapping(TestReporter reporter) { reporter.publishEntry("foo", "bar"); reporter.publishEntry("far", "boo"); } @Test void reportMultiEntriesWithMultiMappings(TestReporter reporter) { Map<String, String> values = new LinkedHashMap<>(); values.put("user name", "dk38"); values.put("award year", "1974"); reporter.publishEntry(values); reporter.publishEntry("single", "mapping"); Map<String, String> more = new LinkedHashMap<>(); more.put("user name", "st77"); more.put("award year", "1977"); more.put("last seen", "2001"); reporter.publishEntry(more); } } @TestFactory @DisplayName("Basic tests and annotations usage") List<DynamicNode> basic() { return scanContainerClassAndCreateDynamicTests(Basic.class); } @TestFactory @DisplayName("Skipped and disabled tests") List<DynamicNode> skipped() { return scanContainerClassAndCreateDynamicTests(Skip.class); } @TestFactory @DisplayName("Failed tests") List<DynamicNode> failed() { return scanContainerClassAndCreateDynamicTests(Fail.class); } @TestFactory @DisplayName("Tests publishing report entries") List<DynamicNode> reports() { return scanContainerClassAndCreateDynamicTests(Report.class); } private List<DynamicNode> scanContainerClassAndCreateDynamicTests(Class<?> containerClass) { String containerName = containerClass.getSimpleName(); List<DynamicNode> nodes = new ArrayList<>(); Map<Details, List<DynamicTest>> map = new EnumMap<>(Details.class); for (Method method : findMethods(containerClass, m -> m.isAnnotationPresent(Test.class))) { String methodName = method.getName(); Class<?>[] types = method.getParameterTypes(); for (Details details : Details.values()) { List<DynamicTest> tests = map.computeIfAbsent(details, key -> new ArrayList<>()); for (Theme theme : Theme.values()) { String caption = containerName + "-" + methodName + "-" + details + "-" + theme; String[] args = { // "--include-engine", "junit-jupiter", // "--details", details.name(), // "--details-theme", theme.name(), // "--disable-ansi-colors", "true", // "--include-classname", containerClass.getCanonicalName(), // "--select-method", getFullyQualifiedMethodName(containerClass, methodName, types) // }; String displayName = methodName + "() " + theme.name(); String dirName = "console/details/" + containerName.toLowerCase(); String outName = caption + ".out.txt"; tests.add(DynamicTest.dynamicTest(displayName, new Runner(dirName, outName, args))); } } } map.forEach((details, tests) -> nodes.add(DynamicContainer.dynamicContainer(details.name(), tests))); return nodes; } private static class Runner implements Executable { private final String dirName; private final String outName; private final String[] args; private Runner(String dirName, String outName, String... args) { this.dirName = dirName; this.outName = outName; this.args = args; } @Override public void execute() throws Throwable { ConsoleLauncherWrapper wrapper = new ConsoleLauncherWrapper(); ConsoleLauncherWrapperResult result = wrapper.execute(Optional.empty(), args); String resourceName = dirName + "/" + outName; Optional<URL> optionalUrl = Optional.ofNullable(getClass().getClassLoader().getResource(resourceName)); if (!optionalUrl.isPresent()) { if (Boolean.getBoolean("org.junit.platform.console.ConsoleDetailsTests.writeResultOut")) { // do not use Files.createTempDirectory(prefix) as we want one folder for one container Path temp = Paths.get(System.getProperty("java.io.tmpdir"), dirName.replace('/', '-')); Files.createDirectories(temp); Path path = Files.write(temp.resolve(outName), result.out.getBytes(UTF_8)); assumeTrue(false, format("resource `%s` not found\nwrote console stdout to: %s", resourceName, path)); } fail("could not load resource named `" + resourceName + "`"); } URL url = optionalUrl.orElseThrow(AssertionError::new); Path path = Paths.get(url.toURI()); assumeTrue(path.toFile().exists(), "path does not exist: " + path); assumeTrue(path.toFile().canRead(), "can not read: " + path); List<String> expectedLines = Files.readAllLines(path, UTF_8); List<String> actualLines = asList(result.out.split("\\R")); assertLinesMatch(expectedLines, actualLines); } } }