From b68ec2805066d21ef79141d4547fa472ce6052a6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 21 Mar 2017 16:32:20 -0700 Subject: [PATCH] Colors. --- kobalt/src/Build.kt | 3 +- .../main/kotlin/com/beust/kobalt/AsciiArt.kt | 28 ++-- .../com/beust/kobalt/internal/TestNgRunner.kt | 128 +++++++++++++++++- 3 files changed, 143 insertions(+), 16 deletions(-) diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index 7f46d9d2..261f5b6e 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -110,7 +110,8 @@ val kobaltPluginApi = project { "org.eclipse.jgit:org.eclipse.jgit:4.5.0.201609210915-r", "org.slf4j:slf4j-simple:${Versions.slf4j}", *mavenResolver("api", "spi", "util", "impl", "connector-basic", "transport-http", "transport-file"), - "org.apache.maven:maven-aether-provider:3.3.9" + "org.apache.maven:maven-aether-provider:3.3.9", + "org.testng.testng-remote:testng-remote:1.3.0" ) exclude(*aether("impl", "spi", "util", "api")) } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/AsciiArt.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/AsciiArt.kt index 6247caeb..e138fabc 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/AsciiArt.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/AsciiArt.kt @@ -17,16 +17,16 @@ class AsciiArt { companion object { private val BANNERS = arrayOf( " __ __ __ __ __ \n" + - " / //_/ ____ / /_ ____ _ / / / /_\n" + - " / ,< / __ \\ / __ \\ / __ `/ / / / __/\n" + - " / /| | / /_/ / / /_/ // /_/ / / / / /_ \n" + - " /_/ |_| \\____/ /_.___/ \\__,_/ /_/ \\__/ ", + " / //_/ ____ / /_ ____ _ / / / /_\n" + + " / ,< / __ \\ / __ \\ / __ `/ / / / __/\n" + + " / /| | / /_/ / / /_/ // /_/ / / / / /_ \n" + + " /_/ |_| \\____/ /_.___/ \\__,_/ /_/ \\__/ ", " _ __ _ _ _ \n" + - " | |/ / ___ | |__ __ _ | | | |_ \n" + - " | ' / / _ \\ | '_ \\ / _` | | | | __|\n" + - " | . \\ | (_) | | |_) | | (_| | | | | |_ \n" + - " |_|\\_\\ \\___/ |_.__/ \\__,_| |_| \\__| " + " | |/ / ___ | |__ __ _ | | | |_ \n" + + " | ' / / _ \\ | '_ \\ / _` | | | | __|\n" + + " | . \\ | (_) | | |_) | | (_| | | | | |_ \n" + + " |_|\\_\\ \\___/ |_.__/ \\__,_| |_| \\__| " ) val banner : String get() = BANNERS[Random().nextInt(BANNERS.size)] @@ -85,7 +85,7 @@ class AsciiArt { } fun logBox(s: String, bl: String = bottomLeft, br: String = bottomRight, indent: Int = 0) - = logBox(listOf(s), bl, br, indent) + = logBox(listOf(s), bl, br, indent) fun fill(n: Int) = buildString { repeat(n, { append(" ")})}.toString() @@ -105,7 +105,7 @@ class AsciiArt { const val CYAN = "\u001B[36m" const val WHITE = "\u001B[37m" - private fun wrap(s: CharSequence, color: String) = color + s + RESET + fun wrap(s: CharSequence, color: String) = color + s + RESET private fun blue(s: CharSequence) = wrap(s, BLUE) private fun red(s: CharSequence) = wrap(s, RED) private fun yellow(s: CharSequence) = wrap(s, YELLOW) @@ -141,10 +141,10 @@ class AsciiTable { fun build() : String { val formattedHeaders = - headers.mapIndexed { index, s -> - val s2 = col(widths[index], s) - s2 - }.joinToString(vb) + headers.mapIndexed { index, s -> + val s2 = col(widths[index], s) + s2 + }.joinToString(vb) val result = StringBuffer().apply { append(AsciiArt.logBox(formattedHeaders, AsciiArt.bottomLeft2, AsciiArt.bottomRight2)) append("\n") diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt index f43be88c..5f288204 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt @@ -1,12 +1,22 @@ package com.beust.kobalt.internal +import com.beust.kobalt.AsciiArt import com.beust.kobalt.TestConfig import com.beust.kobalt.api.IClasspathDependency import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Project +import com.beust.kobalt.maven.aether.AetherDependency import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.Versions +import com.beust.kobalt.misc.runCommand import com.beust.kobalt.misc.warn +import org.testng.remote.RemoteArgs +import org.testng.remote.strprotocol.JsonMessageSender +import org.testng.remote.strprotocol.MessageHelper +import org.testng.remote.strprotocol.MessageHub +import org.testng.remote.strprotocol.TestResultMessage import java.io.File +import java.io.IOException class TestNgRunner : GenericTestRunner() { @@ -39,7 +49,7 @@ class TestNgRunner : GenericTestRunner() { add("-testclass") add(testClasses.joinToString(",")) } else { - if (! testConfig.isDefault) warn("Couldn't find any test classes for ${project.name}") + if (!testConfig.isDefault) warn("Couldn't find any test classes for ${project.name}") // else do nothing: since the user didn't specify an explicit test{} directive, not finding // any test sources is not a problem } @@ -48,4 +58,120 @@ class TestNgRunner : GenericTestRunner() { addAll(testConfig.testArgs) } } + + val VERSION_6_10 = 600100000L + + override fun runTests(project: Project, context: KobaltContext, classpath: List, + configName: String): Boolean { + + val testngDependency = (project.testDependencies.filter { it.id.contains("testng") } + .firstOrNull() as AetherDependency).version + val testngDependencyVersion = Versions.toLongVersion(testngDependency) + val result = + if (testngDependencyVersion >= VERSION_6_10) { + displayPrettyColors(project, context, classpath) + } else { + super.runTests(project, context, classpath, configName) + } + return result + } + + fun displayPrettyColors(project: Project, context: KobaltContext, classpath: List) + : Boolean { + val port = 2345 + + val jf = context.dependencyManager.create("org.testng.testng-remote:testng-remote:1.3.0") + val tr = context.dependencyManager.create("org.testng.testng-remote:testng-remote6_10:1.3.0") + val testng = context.dependencyManager.create("org.testng:testng:6.10") + val dep1 = context.dependencyManager.transitiveClosure(listOf(jf, tr, testng)) + + val v = Versions.toLongVersion("6.10") + val cp = (classpath + dep1).map { it.jarFile.get() } + .joinToString(File.pathSeparator) + val passedArgs = listOf( + "-classpath", + cp, + "org.testng.remote.RemoteTestNG", + "-serport", port.toString(), + "-version", "6.10", + "-dontexit", + RemoteArgs.PROTOCOL, + "json", + "src/test/resources/testng.xml") + + Thread { + val exitCode = runCommand { + command = "java" + directory = File(project.directory) + args = passedArgs + } + }.start() + + // Thread { + // val args2 = arrayOf("-serport", port.toString(), "-dontexit", RemoteArgs.PROTOCOL, "json", + // "-version", "6.10", + // "src/test/resources/testng.xml") + // RemoteTestNG.main(args2) + // }.start() + + val mh = MessageHub(JsonMessageSender("localhost", port, true)) + mh.setDebug(true) + mh.initReceiver() + val passed = arrayListOf() + + data class FailedTest(val method: String, val cls: String, val stackTrace: String) + + val failed = arrayListOf() + var skipped = arrayListOf() + + fun d(n: Int, color: String) + = AsciiArt.wrap(String.format("%4d", n), color) + + fun red(s: String) = AsciiArt.wrap(s, AsciiArt.RED) + fun green(s: String) = AsciiArt.wrap(s, AsciiArt.GREEN) + fun yellow(s: String) = AsciiArt.wrap(s, AsciiArt.YELLOW) + + try { + var message = mh.receiveMessage() + println("") + println(green("PASSED") + " | " + red("FAILED") + " | " + yellow("SKIPPED")) + while (message != null) { + message = mh.receiveMessage() + if (message is TestResultMessage) { + when (message.result) { + MessageHelper.PASSED_TEST -> passed.add(message.name) + MessageHelper.FAILED_TEST -> failed.add(FailedTest(message.testClass, + message.method, message.stackTrace)) + MessageHelper.SKIPPED_TEST -> skipped.add(message.name) + } + } + print("\r " + d(passed.size, AsciiArt.GREEN) + + " | " + d(failed.size, AsciiArt.RED) + + " | " + d(skipped.size, AsciiArt.YELLOW)) + // Thread.sleep(500) + // print("\r" + String.format("%4d / %4d / %4d", passed.size, failed.size, skipped.size)) + // Thread.sleep(200) + } + } catch(ex: IOException) { + println("Exception: ${ex.message}") + } + println("\nPassed: " + passed.size + ", Failed: " + failed.size + ", Skipped: " + skipped.size) + failed.forEach { + val top = it.stackTrace.substring(0, it.stackTrace.indexOf("\n")) + println(" " + it.cls + "." + it.method + "\n " + top) + } + return failed.isEmpty() && skipped.isEmpty() + } +} + +fun main(args: Array) { + fun d(n: Int, color: String) + = AsciiArt.wrap(String.format("%4d", n), color) + + println("PASSED | FAILED | SKIPPED") + repeat(20) { i -> + print("\r " + d(i, AsciiArt.GREEN) + " | " + d(i * 2, AsciiArt.RED) + " | " + d(i, AsciiArt.YELLOW)) + Thread.sleep(500) + } + println("") }