From d6e0fd2f0de659e5f645505334c00c2ef7fe7795 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 1 Apr 2017 17:13:28 -0400 Subject: [PATCH 1/6] Sort the import alphabetically in Defaults --- main/src/main/scala/sbt/Defaults.scala | 70 ++++++++++++-------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 910f1d6ea..8d6ab9ef2 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -3,51 +3,43 @@ */ package sbt -import scala.concurrent.duration.FiniteDuration -import sbt.internal._ -import sbt.internal.util.Attributed.data -import Scope.{ fillTaskAxis, GlobalScope, ThisScope } -import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } -import Project.{ inConfig, inScope, inTask, richInitialize, richInitializeTask, richTaskSessionVar } import Def.{ Initialize, ScopedKey, Setting, SettingsDefinition } -import sbt.internal.librarymanagement.{ CustomPomParser, DependencyFilter } -import sbt.librarymanagement.Artifact.{ DocClassifier, SourceClassifier } -import sbt.librarymanagement.{ Configuration, Configurations, ConflictManager, CrossVersion, MavenRepository, Resolver, ScalaArtifacts, UpdateOptions } -import sbt.librarymanagement.Configurations.{ Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test } -import sbt.librarymanagement.CrossVersion.{ binarySbtVersion, binaryScalaVersion, partialVersion } -import sbt.internal.util.complete._ -import std.TaskExtra._ -import testing.{ Framework, Runner, AnnotatedFingerprint, SubclassFingerprint } - -import sjsonnew.{ IsoLList, JsonFormat, LList, LNil }, LList.:*: -import sbt.internal.util.CacheImplicits._ -import sbt.librarymanagement.{ `package` => _, _ } -import sbt.internal.librarymanagement._ -import sbt.internal.librarymanagement.syntax._ -import sbt.internal.util._ -import sbt.util.{ Level, Logger, ShowLines } -import scala.xml.NodeSeq -import scala.util.control.NonFatal - -import org.apache.ivy.core.module.{ descriptor, id } -import descriptor.ModuleDescriptor, id.ModuleRevisionId import java.io.{ File, PrintWriter } import java.net.{ URI, URL } import java.util.concurrent.{ TimeUnit, Callable } -import sbt.internal.CommandStrings.ExportStream - -import xsbti.{ CrossValue, Maybe } -import sbt.util.InterfaceUtil.{ f1, o2m } - -import sbt.internal.util.Types._ - -import sbt.internal.io.WatchState -import sbt.io.{ AllPassFilter, FileFilter, GlobFilter, HiddenFileFilter, IO, NameFilter, NothingFilter, Path, PathFinder, SimpleFileFilter, DirectoryFilter, Hash } - -import Path._ -import sbt.io.syntax._ import Keys._ +import org.apache.ivy.core.module.{ descriptor, id }, descriptor.ModuleDescriptor, id.ModuleRevisionId +import Project.{ inConfig, inScope, inTask, richInitialize, richInitializeTask, richTaskSessionVar } +import sbt.internal._ +import sbt.internal.CommandStrings.ExportStream +import sbt.internal.io.WatchState +import sbt.internal.librarymanagement._ +import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } +import sbt.internal.librarymanagement.syntax._ +import sbt.internal.librarymanagement.{ CustomPomParser, DependencyFilter } +import sbt.internal.util._ +import sbt.internal.util.Attributed.data +import sbt.internal.util.CacheImplicits._ +import sbt.internal.util.complete._ +import sbt.internal.util.Types._ +import sbt.io.syntax._ +import sbt.io.{ AllPassFilter, FileFilter, GlobFilter, HiddenFileFilter, IO, NameFilter, NothingFilter, Path, PathFinder, SimpleFileFilter, DirectoryFilter, Hash }, Path._ +import sbt.librarymanagement.Artifact.{ DocClassifier, SourceClassifier } +import sbt.librarymanagement.Configurations.{ Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test } +import sbt.librarymanagement.CrossVersion.{ binarySbtVersion, binaryScalaVersion, partialVersion } +import sbt.librarymanagement.{ `package` => _, _ } +import sbt.librarymanagement.{ Configuration, Configurations, ConflictManager, CrossVersion, MavenRepository, Resolver, ScalaArtifacts, UpdateOptions } +import sbt.util.InterfaceUtil.{ f1, o2m } +import sbt.util.{ Level, Logger, ShowLines } +import scala.concurrent.duration.FiniteDuration +import scala.util.control.NonFatal +import scala.xml.NodeSeq +import Scope.{ fillTaskAxis, GlobalScope, ThisScope } +import sjsonnew.{ IsoLList, JsonFormat, LList, LNil }, LList.:*: +import std.TaskExtra._ +import testing.{ Framework, Runner, AnnotatedFingerprint, SubclassFingerprint } import xsbti.compile.IncToolOptionsUtil +import xsbti.{ CrossValue, Maybe } // incremental compiler import xsbt.api.Discovery From 093fc061ccf72ea44d288df13515b79112fde6f1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 1 Apr 2017 17:19:45 -0400 Subject: [PATCH 2/6] Send testing events to logger --- build.sbt | 5 +- .../src/main/scala/sbt/ForkTests.scala | 1 + .../src/main/scala/sbt/TestResultLogger.scala | 3 +- main-actions/src/main/scala/sbt/Tests.scala | 22 ++-- main/src/main/scala/sbt/Defaults.scala | 1 + project/ContrabandConfig.scala | 1 + .../testing/EndTestGroupErrorEvent.scala | 37 +++++++ .../protocol/testing/EndTestGroupEvent.scala | 37 +++++++ .../testing/StartTestGroupEvent.scala | 33 ++++++ .../protocol/testing/TestCompleteEvent.scala | 33 ++++++ .../sbt/protocol/testing/TestInitEvent.scala | 30 ++++++ .../sbt/protocol/testing/TestItemDetail.scala | 54 ++++++++++ .../sbt/protocol/testing/TestItemEvent.scala | 41 +++++++ .../sbt/protocol/testing/TestMessage.scala | 26 +++++ .../sbt/protocol/testing/TestResult.scala | 15 +++ .../protocol/testing/TestStringEvent.scala | 32 ++++++ .../codec/EndTestGroupErrorEventFormats.scala | 29 +++++ .../codec/EndTestGroupEventFormats.scala | 29 +++++ .../protocol/testing/codec/JsonProtocol.scala | 19 ++++ .../codec/StartTestGroupEventFormats.scala | 27 +++++ .../codec/TestCompleteEventFormats.scala | 27 +++++ .../testing/codec/TestInitEventFormats.scala | 27 +++++ .../testing/codec/TestItemDetailFormats.scala | 31 ++++++ .../testing/codec/TestItemEventFormats.scala | 29 +++++ .../testing/codec/TestMessageFormats.scala | 10 ++ .../testing/codec/TestResultFormats.scala | 31 ++++++ .../codec/TestStringEventFormats.scala | 27 +++++ testing/src/main/contraband/testing.contra | 65 +++++++++++ .../scala/sbt/JUnitXmlTestsListener.scala | 5 +- .../src/main/scala/sbt/TestFramework.scala | 23 ++-- .../main/scala/sbt/TestReportListener.scala | 74 ++----------- .../main/scala/sbt/TestStatusReporter.scala | 5 +- .../sbt/internal/testing/StatusFormats.scala | 38 +++++++ .../sbt/internal/testing/TestLogger.scala | 101 ++++++++++++++++++ 34 files changed, 878 insertions(+), 90 deletions(-) create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupErrorEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/StartTestGroupEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestCompleteEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestInitEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestItemDetail.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestItemEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestMessage.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestResult.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/TestStringEvent.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupErrorEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/JsonProtocol.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/StartTestGroupEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestCompleteEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestInitEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemDetailFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestResultFormats.scala create mode 100644 testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestStringEventFormats.scala create mode 100644 testing/src/main/contraband/testing.contra create mode 100644 testing/src/main/scala/sbt/internal/testing/StatusFormats.scala create mode 100644 testing/src/main/scala/sbt/internal/testing/TestLogger.scala diff --git a/build.sbt b/build.sbt index d4fc0cbab..0ff74cdd6 100644 --- a/build.sbt +++ b/build.sbt @@ -101,11 +101,14 @@ lazy val bundledLauncherProj = // Runner for uniform test interface lazy val testingProj = (project in file("testing")). + enablePlugins(ContrabandPlugin, JsonCodecPlugin). dependsOn(testAgentProj). settings( baseSettings, name := "Testing", - libraryDependencies ++= Seq(testInterface,launcherInterface) + libraryDependencies ++= Seq(testInterface,launcherInterface, sjsonNewScalaJson), + sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", + contrabandFormatsForType in generateContrabands in Compile := ContrabandConfig.getFormats ). configure(addSbtIO, addSbtCompilerClasspath, addSbtUtilLogging) diff --git a/main-actions/src/main/scala/sbt/ForkTests.scala b/main-actions/src/main/scala/sbt/ForkTests.scala index fce5e445f..bcf395193 100755 --- a/main-actions/src/main/scala/sbt/ForkTests.scala +++ b/main-actions/src/main/scala/sbt/ForkTests.scala @@ -12,6 +12,7 @@ import Tests.{ Output => TestOutput, _ } import sbt.io.IO import sbt.util.Logger import sbt.ConcurrentRestrictions.Tag +import sbt.protocol.testing._ private[sbt] object ForkTests { def apply(runners: Map[TestFramework, Runner], tests: List[TestDefinition], config: Execution, classpath: Seq[File], fork: ForkOptions, log: Logger, tag: Tag): Task[TestOutput] = { diff --git a/main-actions/src/main/scala/sbt/TestResultLogger.scala b/main-actions/src/main/scala/sbt/TestResultLogger.scala index c0a9cc4c9..9715c42c5 100644 --- a/main-actions/src/main/scala/sbt/TestResultLogger.scala +++ b/main-actions/src/main/scala/sbt/TestResultLogger.scala @@ -2,6 +2,7 @@ package sbt import sbt.Tests.{ Output, Summary } import sbt.util.{ Level, Logger } +import sbt.protocol.testing.TestResult /** * Logs information about tests after they finish. @@ -138,7 +139,7 @@ object TestResultLogger { }) val printFailures = TestResultLogger((log, results, _) => { - def select(resultTpe: TestResult.Value) = results.events collect { + def select(resultTpe: TestResult) = results.events collect { case (name, tpe) if tpe.result == resultTpe => scala.reflect.NameTransformer.decode(name) } diff --git a/main-actions/src/main/scala/sbt/Tests.scala b/main-actions/src/main/scala/sbt/Tests.scala index bdcd79308..5911726f0 100644 --- a/main-actions/src/main/scala/sbt/Tests.scala +++ b/main-actions/src/main/scala/sbt/Tests.scala @@ -15,7 +15,9 @@ import ConcurrentRestrictions.Tag import testing.{ AnnotatedFingerprint, Fingerprint, Framework, SubclassFingerprint, Runner, TaskDef, SuiteSelector, Task => TestTask } import scala.annotation.tailrec +import sbt.internal.util.ManagedLogger import sbt.util.Logger +import sbt.protocol.testing.TestResult sealed trait TestOption object Tests { @@ -26,7 +28,7 @@ object Tests { * @param events The result of each test group (suite) executed during this test run. * @param summaries Explicit summaries directly provided by test frameworks. This may be empty, in which case a default summary will be generated. */ - final case class Output(overall: TestResult.Value, events: Map[String, SuiteResult], summaries: Iterable[Summary]) + final case class Output(overall: TestResult, events: Map[String, SuiteResult], summaries: Iterable[Summary]) /** * Summarizes a test run. @@ -162,7 +164,7 @@ object Tests { in.filter(t => seen.add(f(t))) } - def apply(frameworks: Map[TestFramework, Framework], testLoader: ClassLoader, runners: Map[TestFramework, Runner], discovered: Seq[TestDefinition], config: Execution, log: Logger): Task[Output] = + def apply(frameworks: Map[TestFramework, Framework], testLoader: ClassLoader, runners: Map[TestFramework, Runner], discovered: Seq[TestDefinition], config: Execution, log: ManagedLogger): Task[Output] = { val o = processOptions(config, discovered, log) testTask(testLoader, frameworks, runners, o.tests, o.setup, o.cleanup, log, o.testListeners, config) @@ -170,7 +172,7 @@ object Tests { def testTask(loader: ClassLoader, frameworks: Map[TestFramework, Framework], runners: Map[TestFramework, Runner], tests: Seq[TestDefinition], userSetup: Iterable[ClassLoader => Unit], userCleanup: Iterable[ClassLoader => Unit], - log: Logger, testListeners: Seq[TestReportListener], config: Execution): Task[Output] = + log: ManagedLogger, testListeners: Seq[TestReportListener], config: Execution): Task[Output] = { def fj(actions: Iterable[() => Unit]): Task[Unit] = nop.dependsOn(actions.toSeq.fork(_()): _*) def partApp(actions: Iterable[ClassLoader => Unit]) = actions.toSeq map { a => () => a(loader) } @@ -249,12 +251,20 @@ object Tests { def processResults(results: Iterable[(String, SuiteResult)]): Output = Output(overall(results.map(_._2.result)), results.toMap, Iterable.empty) + + private def severity(r: TestResult): Int = + r match { + case TestResult.Passed => 0 + case TestResult.Failed => 1 + case TestResult.Error => 2 + } + def foldTasks(results: Seq[Task[Output]], parallel: Boolean): Task[Output] = if (results.isEmpty) task { Output(TestResult.Passed, Map.empty, Nil) } else if (parallel) reduced(results.toIndexedSeq, { - case (Output(v1, m1, _), Output(v2, m2, _)) => Output(if (v1.id < v2.id) v2 else v1, m1 ++ m2, Iterable.empty) + case (Output(v1, m1, _), Output(v2, m2, _)) => Output(if (severity(v1) < severity(v2)) v2 else v1, m1 ++ m2, Iterable.empty) }) else { def sequence(tasks: List[Task[Output]], acc: List[Output]): Task[List[Output]] = tasks match { @@ -266,8 +276,8 @@ object Tests { Output(overall(rs), ms reduce (_ ++ _), Iterable.empty) } } - def overall(results: Iterable[TestResult.Value]): TestResult.Value = - (TestResult.Passed /: results) { (acc, result) => if (acc.id < result.id) result else acc } + def overall(results: Iterable[TestResult]): TestResult = + ((TestResult.Passed: TestResult) /: results) { (acc, result) => if (severity(acc) < severity(result)) result else acc } def discover(frameworks: Seq[Framework], analysis: CompileAnalysis, log: Logger): (Seq[TestDefinition], Set[String]) = discover(frameworks flatMap TestFramework.getFingerprints, allDefs(analysis), log) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 8d6ab9ef2..50beb5a50 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -17,6 +17,7 @@ import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } import sbt.internal.librarymanagement.syntax._ import sbt.internal.librarymanagement.{ CustomPomParser, DependencyFilter } +import sbt.internal.testing.TestLogger import sbt.internal.util._ import sbt.internal.util.Attributed.data import sbt.internal.util.CacheImplicits._ diff --git a/project/ContrabandConfig.scala b/project/ContrabandConfig.scala index 7fb8a2b8e..f1bbd9d42 100644 --- a/project/ContrabandConfig.scala +++ b/project/ContrabandConfig.scala @@ -22,6 +22,7 @@ object ContrabandConfig { case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) } case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) } case "Int" | "Long" => { _ => Nil } + case "sbt.testing.Status" => { _ => "sbt.internal.testing.StatusFormats" :: Nil } case "scala.json.ast.unsafe.JValue" => { _ => "sbt.internal.JValueFormat" :: Nil } } diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupErrorEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupErrorEvent.scala new file mode 100644 index 000000000..905567dfd --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupErrorEvent.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called if test completed with an error. */ +final class EndTestGroupErrorEvent private ( + val name: String, + val error: String) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: EndTestGroupErrorEvent => (this.name == x.name) && (this.error == x.error) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + name.##) + error.##) + } + override def toString: String = { + "EndTestGroupErrorEvent(" + name + ", " + error + ")" + } + protected[this] def copy(name: String = name, error: String = error): EndTestGroupErrorEvent = { + new EndTestGroupErrorEvent(name, error) + } + def withName(name: String): EndTestGroupErrorEvent = { + copy(name = name) + } + def withError(error: String): EndTestGroupErrorEvent = { + copy(error = error) + } +} +object EndTestGroupErrorEvent { + + def apply(name: String, error: String): EndTestGroupErrorEvent = new EndTestGroupErrorEvent(name, error) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupEvent.scala new file mode 100644 index 000000000..c42958747 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/EndTestGroupEvent.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called if test completed. */ +final class EndTestGroupEvent private ( + val name: String, + val result: sbt.protocol.testing.TestResult) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: EndTestGroupEvent => (this.name == x.name) && (this.result == x.result) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + name.##) + result.##) + } + override def toString: String = { + "EndTestGroupEvent(" + name + ", " + result + ")" + } + protected[this] def copy(name: String = name, result: sbt.protocol.testing.TestResult = result): EndTestGroupEvent = { + new EndTestGroupEvent(name, result) + } + def withName(name: String): EndTestGroupEvent = { + copy(name = name) + } + def withResult(result: sbt.protocol.testing.TestResult): EndTestGroupEvent = { + copy(result = result) + } +} +object EndTestGroupEvent { + + def apply(name: String, result: sbt.protocol.testing.TestResult): EndTestGroupEvent = new EndTestGroupEvent(name, result) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/StartTestGroupEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/StartTestGroupEvent.scala new file mode 100644 index 000000000..c8326429d --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/StartTestGroupEvent.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called for each class or equivalent grouping. */ +final class StartTestGroupEvent private ( + val name: String) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: StartTestGroupEvent => (this.name == x.name) + case _ => false + } + override def hashCode: Int = { + 37 * (17 + name.##) + } + override def toString: String = { + "StartTestGroupEvent(" + name + ")" + } + protected[this] def copy(name: String = name): StartTestGroupEvent = { + new StartTestGroupEvent(name) + } + def withName(name: String): StartTestGroupEvent = { + copy(name = name) + } +} +object StartTestGroupEvent { + + def apply(name: String): StartTestGroupEvent = new StartTestGroupEvent(name) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestCompleteEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestCompleteEvent.scala new file mode 100644 index 000000000..c2afaceac --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestCompleteEvent.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called once, at end of the testing. */ +final class TestCompleteEvent private ( + val result: sbt.protocol.testing.TestResult) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TestCompleteEvent => (this.result == x.result) + case _ => false + } + override def hashCode: Int = { + 37 * (17 + result.##) + } + override def toString: String = { + "TestCompleteEvent(" + result + ")" + } + protected[this] def copy(result: sbt.protocol.testing.TestResult = result): TestCompleteEvent = { + new TestCompleteEvent(result) + } + def withResult(result: sbt.protocol.testing.TestResult): TestCompleteEvent = { + copy(result = result) + } +} +object TestCompleteEvent { + + def apply(result: sbt.protocol.testing.TestResult): TestCompleteEvent = new TestCompleteEvent(result) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestInitEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestInitEvent.scala new file mode 100644 index 000000000..e1bbe4425 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestInitEvent.scala @@ -0,0 +1,30 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called once, at beginning of the testing. */ +final class TestInitEvent private () extends sbt.protocol.testing.TestMessage() with Serializable { + + + +override def equals(o: Any): Boolean = o match { + case x: TestInitEvent => true + case _ => false +} +override def hashCode: Int = { + 17 +} +override def toString: String = { + "TestInitEvent()" +} +protected[this] def copy(): TestInitEvent = { + new TestInitEvent() +} + +} +object TestInitEvent { + + def apply(): TestInitEvent = new TestInitEvent() +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemDetail.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemDetail.scala new file mode 100644 index 000000000..105378904 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemDetail.scala @@ -0,0 +1,54 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Mini version of sbt.testing.Event */ +final class TestItemDetail private ( + /** + * The fully qualified name of a class that can rerun the suite or test + * about which an event was fired. + */ + val fullyQualifiedName: String, + /** Indicates whether the event represents a test success, failure, error, skipped, ignored, canceled, pending. */ + val status: sbt.testing.Status, + /** + * An amount of time, in milliseconds, that was required to complete the action reported by this event. + * None, if no duration was available. + */ + val duration: Option[Long]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TestItemDetail => (this.fullyQualifiedName == x.fullyQualifiedName) && (this.status == x.status) && (this.duration == x.duration) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + fullyQualifiedName.##) + status.##) + duration.##) + } + override def toString: String = { + "TestItemDetail(" + fullyQualifiedName + ", " + status + ", " + duration + ")" + } + protected[this] def copy(fullyQualifiedName: String = fullyQualifiedName, status: sbt.testing.Status = status, duration: Option[Long] = duration): TestItemDetail = { + new TestItemDetail(fullyQualifiedName, status, duration) + } + def withFullyQualifiedName(fullyQualifiedName: String): TestItemDetail = { + copy(fullyQualifiedName = fullyQualifiedName) + } + def withStatus(status: sbt.testing.Status): TestItemDetail = { + copy(status = status) + } + def withDuration(duration: Option[Long]): TestItemDetail = { + copy(duration = duration) + } + def withDuration(duration: Long): TestItemDetail = { + copy(duration = Option(duration)) + } +} +object TestItemDetail { + + def apply(fullyQualifiedName: String, status: sbt.testing.Status, duration: Option[Long]): TestItemDetail = new TestItemDetail(fullyQualifiedName, status, duration) + def apply(fullyQualifiedName: String, status: sbt.testing.Status, duration: Long): TestItemDetail = new TestItemDetail(fullyQualifiedName, status, Option(duration)) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemEvent.scala new file mode 100644 index 000000000..27139b070 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestItemEvent.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Called for each test method or equivalent. */ +final class TestItemEvent private ( + val result: Option[sbt.protocol.testing.TestResult], + val detail: Vector[sbt.protocol.testing.TestItemDetail]) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TestItemEvent => (this.result == x.result) && (this.detail == x.detail) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + result.##) + detail.##) + } + override def toString: String = { + "TestItemEvent(" + result + ", " + detail + ")" + } + protected[this] def copy(result: Option[sbt.protocol.testing.TestResult] = result, detail: Vector[sbt.protocol.testing.TestItemDetail] = detail): TestItemEvent = { + new TestItemEvent(result, detail) + } + def withResult(result: Option[sbt.protocol.testing.TestResult]): TestItemEvent = { + copy(result = result) + } + def withResult(result: sbt.protocol.testing.TestResult): TestItemEvent = { + copy(result = Option(result)) + } + def withDetail(detail: Vector[sbt.protocol.testing.TestItemDetail]): TestItemEvent = { + copy(detail = detail) + } +} +object TestItemEvent { + + def apply(result: Option[sbt.protocol.testing.TestResult], detail: Vector[sbt.protocol.testing.TestItemDetail]): TestItemEvent = new TestItemEvent(result, detail) + def apply(result: sbt.protocol.testing.TestResult, detail: Vector[sbt.protocol.testing.TestItemDetail]): TestItemEvent = new TestItemEvent(Option(result), detail) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestMessage.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestMessage.scala new file mode 100644 index 000000000..0a7360717 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestMessage.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Events for testing */ +abstract class TestMessage() extends Serializable { + + + + +override def equals(o: Any): Boolean = o match { + case x: TestMessage => true + case _ => false +} +override def hashCode: Int = { + 17 +} +override def toString: String = { + "TestMessage()" +} +} +object TestMessage { + +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestResult.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestResult.scala new file mode 100644 index 000000000..d421e29ba --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestResult.scala @@ -0,0 +1,15 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +/** Testing result */ +sealed abstract class TestResult extends Serializable +object TestResult { + + + case object Passed extends TestResult + case object Failed extends TestResult + case object Error extends TestResult +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/TestStringEvent.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/TestStringEvent.scala new file mode 100644 index 000000000..ea1267c2f --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/TestStringEvent.scala @@ -0,0 +1,32 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing +final class TestStringEvent private ( + val value: String) extends sbt.protocol.testing.TestMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TestStringEvent => (this.value == x.value) + case _ => false + } + override def hashCode: Int = { + 37 * (17 + value.##) + } + override def toString: String = { + value + } + protected[this] def copy(value: String = value): TestStringEvent = { + new TestStringEvent(value) + } + def withValue(value: String): TestStringEvent = { + copy(value = value) + } +} +object TestStringEvent { + + def apply(value: String): TestStringEvent = new TestStringEvent(value) +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupErrorEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupErrorEventFormats.scala new file mode 100644 index 000000000..e978f6e39 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupErrorEventFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait EndTestGroupErrorEventFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val EndTestGroupErrorEventFormat: JsonFormat[sbt.protocol.testing.EndTestGroupErrorEvent] = new JsonFormat[sbt.protocol.testing.EndTestGroupErrorEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.EndTestGroupErrorEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val error = unbuilder.readField[String]("error") + unbuilder.endObject() + sbt.protocol.testing.EndTestGroupErrorEvent(name, error) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.EndTestGroupErrorEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("error", obj.error) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupEventFormats.scala new file mode 100644 index 000000000..14767f783 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/EndTestGroupEventFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait EndTestGroupEventFormats { self: sbt.protocol.testing.codec.TestResultFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val EndTestGroupEventFormat: JsonFormat[sbt.protocol.testing.EndTestGroupEvent] = new JsonFormat[sbt.protocol.testing.EndTestGroupEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.EndTestGroupEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val result = unbuilder.readField[sbt.protocol.testing.TestResult]("result") + unbuilder.endObject() + sbt.protocol.testing.EndTestGroupEvent(name, result) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.EndTestGroupEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("result", obj.result) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/JsonProtocol.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/JsonProtocol.scala new file mode 100644 index 000000000..a9cdccd8d --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/JsonProtocol.scala @@ -0,0 +1,19 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +trait JsonProtocol extends sjsonnew.BasicJsonProtocol + with sbt.protocol.testing.codec.TestStringEventFormats + with sbt.protocol.testing.codec.TestInitEventFormats + with sbt.protocol.testing.codec.TestResultFormats + with sbt.protocol.testing.codec.TestCompleteEventFormats + with sbt.protocol.testing.codec.StartTestGroupEventFormats + with sbt.protocol.testing.codec.EndTestGroupEventFormats + with sbt.protocol.testing.codec.EndTestGroupErrorEventFormats + with sbt.internal.testing.StatusFormats + with sbt.protocol.testing.codec.TestItemDetailFormats + with sbt.protocol.testing.codec.TestItemEventFormats + with sbt.protocol.testing.codec.TestMessageFormats +object JsonProtocol extends JsonProtocol \ No newline at end of file diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/StartTestGroupEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/StartTestGroupEventFormats.scala new file mode 100644 index 000000000..2dc65ebd9 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/StartTestGroupEventFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait StartTestGroupEventFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val StartTestGroupEventFormat: JsonFormat[sbt.protocol.testing.StartTestGroupEvent] = new JsonFormat[sbt.protocol.testing.StartTestGroupEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.StartTestGroupEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + unbuilder.endObject() + sbt.protocol.testing.StartTestGroupEvent(name) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.StartTestGroupEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestCompleteEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestCompleteEventFormats.scala new file mode 100644 index 000000000..df6654faa --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestCompleteEventFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestCompleteEventFormats { self: sbt.protocol.testing.codec.TestResultFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val TestCompleteEventFormat: JsonFormat[sbt.protocol.testing.TestCompleteEvent] = new JsonFormat[sbt.protocol.testing.TestCompleteEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestCompleteEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val result = unbuilder.readField[sbt.protocol.testing.TestResult]("result") + unbuilder.endObject() + sbt.protocol.testing.TestCompleteEvent(result) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestCompleteEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("result", obj.result) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestInitEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestInitEventFormats.scala new file mode 100644 index 000000000..e721cdaba --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestInitEventFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestInitEventFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val TestInitEventFormat: JsonFormat[sbt.protocol.testing.TestInitEvent] = new JsonFormat[sbt.protocol.testing.TestInitEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestInitEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.protocol.testing.TestInitEvent() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestInitEvent, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemDetailFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemDetailFormats.scala new file mode 100644 index 000000000..9c0a73eb8 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemDetailFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestItemDetailFormats { self: sbt.internal.testing.StatusFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val TestItemDetailFormat: JsonFormat[sbt.protocol.testing.TestItemDetail] = new JsonFormat[sbt.protocol.testing.TestItemDetail] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestItemDetail = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val fullyQualifiedName = unbuilder.readField[String]("fullyQualifiedName") + val status = unbuilder.readField[sbt.testing.Status]("status") + val duration = unbuilder.readField[Option[Long]]("duration") + unbuilder.endObject() + sbt.protocol.testing.TestItemDetail(fullyQualifiedName, status, duration) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestItemDetail, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("fullyQualifiedName", obj.fullyQualifiedName) + builder.addField("status", obj.status) + builder.addField("duration", obj.duration) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala new file mode 100644 index 000000000..c93fc1ee7 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestItemEventFormats { self: sbt.protocol.testing.codec.TestResultFormats with sbt.protocol.testing.codec.TestItemDetailFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val TestItemEventFormat: JsonFormat[sbt.protocol.testing.TestItemEvent] = new JsonFormat[sbt.protocol.testing.TestItemEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestItemEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val result = unbuilder.readField[Option[sbt.protocol.testing.TestResult]]("result") + val detail = unbuilder.readField[Vector[sbt.protocol.testing.TestItemDetail]]("detail") + unbuilder.endObject() + sbt.protocol.testing.TestItemEvent(result, detail) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestItemEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("result", obj.result) + builder.addField("detail", obj.detail) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala new file mode 100644 index 000000000..4b0c95d20 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala @@ -0,0 +1,10 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.testing.codec.TestStringEventFormats with sbt.protocol.testing.codec.TestInitEventFormats with sbt.protocol.testing.codec.TestResultFormats with sbt.protocol.testing.codec.TestCompleteEventFormats with sbt.protocol.testing.codec.StartTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupErrorEventFormats with sbt.protocol.testing.codec.TestItemDetailFormats with sbt.protocol.testing.codec.TestItemEventFormats => +implicit lazy val TestMessageFormat: JsonFormat[sbt.protocol.testing.TestMessage] = flatUnionFormat7[sbt.protocol.testing.TestMessage, sbt.protocol.testing.TestStringEvent, sbt.protocol.testing.TestInitEvent, sbt.protocol.testing.TestCompleteEvent, sbt.protocol.testing.StartTestGroupEvent, sbt.protocol.testing.EndTestGroupEvent, sbt.protocol.testing.EndTestGroupErrorEvent, sbt.protocol.testing.TestItemEvent]("type") +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestResultFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestResultFormats.scala new file mode 100644 index 000000000..dce5ec118 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestResultFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestResultFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val TestResultFormat: JsonFormat[sbt.protocol.testing.TestResult] = new JsonFormat[sbt.protocol.testing.TestResult] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestResult = { + jsOpt match { + case Some(js) => + unbuilder.readString(js) match { + case "Passed" => sbt.protocol.testing.TestResult.Passed + case "Failed" => sbt.protocol.testing.TestResult.Failed + case "Error" => sbt.protocol.testing.TestResult.Error + } + case None => + deserializationError("Expected JsString but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestResult, builder: Builder[J]): Unit = { + val str = obj match { + case sbt.protocol.testing.TestResult.Passed => "Passed" + case sbt.protocol.testing.TestResult.Failed => "Failed" + case sbt.protocol.testing.TestResult.Error => "Error" + } + builder.writeString(str) + } +} +} diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestStringEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestStringEventFormats.scala new file mode 100644 index 000000000..fe33f9825 --- /dev/null +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestStringEventFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.testing.codec +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait TestStringEventFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val TestStringEventFormat: JsonFormat[sbt.protocol.testing.TestStringEvent] = new JsonFormat[sbt.protocol.testing.TestStringEvent] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestStringEvent = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val value = unbuilder.readField[String]("value") + unbuilder.endObject() + sbt.protocol.testing.TestStringEvent(value) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.testing.TestStringEvent, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("value", obj.value) + builder.endObject() + } +} +} diff --git a/testing/src/main/contraband/testing.contra b/testing/src/main/contraband/testing.contra new file mode 100644 index 000000000..94cb92425 --- /dev/null +++ b/testing/src/main/contraband/testing.contra @@ -0,0 +1,65 @@ +package sbt.protocol.testing +@target(Scala) +@codecPackage("sbt.protocol.testing.codec") +@fullCodec("JsonProtocol") + +## Events for testing +interface TestMessage { +} + +type TestStringEvent implements TestMessage { + value: String! + #xtostring value +} + +## Called once, at beginning of the testing. +type TestInitEvent implements TestMessage {} + +## Called once, at end of the testing. +type TestCompleteEvent implements TestMessage { + result: sbt.protocol.testing.TestResult! +} + +## Called for each class or equivalent grouping. +type StartTestGroupEvent implements TestMessage { + name: String! +} + +## Called if test completed. +type EndTestGroupEvent implements TestMessage { + name: String! + result: sbt.protocol.testing.TestResult! +} + +## Called if test completed with an error. +type EndTestGroupErrorEvent implements TestMessage { + name: String! + error: String! +} + +## Called for each test method or equivalent. +type TestItemEvent implements TestMessage { + result: sbt.protocol.testing.TestResult + detail: [sbt.protocol.testing.TestItemDetail] +} + +## Mini version of sbt.testing.Event +type TestItemDetail { + ## The fully qualified name of a class that can rerun the suite or test + ## about which an event was fired. + fullyQualifiedName: String! + + ## Indicates whether the event represents a test success, failure, error, skipped, ignored, canceled, pending. + status: sbt.testing.Status! + + ## An amount of time, in milliseconds, that was required to complete the action reported by this event. + ## None, if no duration was available. + duration: Long +} + +## Testing result +enum TestResult { + Passed + Failed + Error +} diff --git a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala index ca0898ce7..0215c2fa9 100644 --- a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala +++ b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala @@ -8,6 +8,7 @@ import scala.collection.mutable.ListBuffer import scala.util.DynamicVariable import scala.xml.{ Elem, Node => XNode, XML } import testing.{ Event => TEvent, Status => TStatus, OptionalThrowable, TestSelector } +import sbt.protocol.testing.TestResult /** * A tests listener that outputs the results it receives in junit xml @@ -161,7 +162,7 @@ class JUnitXmlTestsListener(val outputDir: String) extends TestsListener { * Ends the current suite, wraps up the result and writes it to an XML file * in the output folder that is named after the suite. */ - override def endGroup(name: String, result: TestResult.Value) = { + override def endGroup(name: String, result: TestResult) = { writeSuite() } @@ -177,7 +178,7 @@ class JUnitXmlTestsListener(val outputDir: String) extends TestsListener { } /**Does nothing, as we write each file after a suite is done.*/ - override def doComplete(finalResult: TestResult.Value): Unit = {} + override def doComplete(finalResult: TestResult): Unit = {} /**Returns None*/ override def contentLogger(test: TestDefinition): Option[ContentLogger] = None diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index 9199f4188..ea2cd9ff1 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -10,12 +10,9 @@ import org.scalatools.testing.{ Framework => OldFramework } import sbt.internal.inc.classpath.{ ClasspathUtilities, DualLoader } import sbt.internal.inc.ScalaInstance import scala.annotation.tailrec -import sbt.util.Logger +import sbt.internal.util.ManagedLogger import sbt.io.IO - -object TestResult extends Enumeration { - val Passed, Failed, Error = Value -} +import sbt.protocol.testing.TestResult object TestFrameworks { val ScalaCheck = new TestFramework("org.scalacheck.ScalaCheckFramework") @@ -27,7 +24,7 @@ object TestFrameworks { case class TestFramework(implClassNames: String*) { @tailrec - private def createFramework(loader: ClassLoader, log: Logger, frameworkClassNames: List[String]): Option[Framework] = { + private def createFramework(loader: ClassLoader, log: ManagedLogger, frameworkClassNames: List[String]): Option[Framework] = { frameworkClassNames match { case head :: tail => try { @@ -45,7 +42,7 @@ case class TestFramework(implClassNames: String*) { } } - def create(loader: ClassLoader, log: Logger): Option[Framework] = + def create(loader: ClassLoader, log: ManagedLogger): Option[Framework] = createFramework(loader, log, implClassNames.toList) } final class TestDefinition(val name: String, val fingerprint: Fingerprint, val explicitlySpecified: Boolean, val selectors: Array[Selector]) { @@ -58,7 +55,7 @@ final class TestDefinition(val name: String, val fingerprint: Fingerprint, val e override def hashCode: Int = (name.hashCode, TestFramework.hashCode(fingerprint)).hashCode } -final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log: Logger) { +final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log: ManagedLogger) { final def tasks(testDefs: Set[TestDefinition]): Array[TestTask] = delegate.tasks(testDefs.map(df => new TaskDef(df.name, df.fingerprint, df.explicitlySpecified, df.selectors)).toArray) @@ -106,7 +103,7 @@ object TestFramework { case _ => sys.error("Could not call 'fingerprints' on framework " + framework) } - private[sbt] def safeForeach[T](it: Iterable[T], log: Logger)(f: T => Unit): Unit = + private[sbt] def safeForeach[T](it: Iterable[T], log: ManagedLogger)(f: T => Unit): Unit = it.foreach(i => try f(i) catch { case NonFatal(e) => log.trace(e); log.error(e.toString) }) private[sbt] def hashCode(f: Fingerprint): Int = f match { @@ -132,9 +129,9 @@ object TestFramework { runners: Map[TestFramework, Runner], testLoader: ClassLoader, tests: Seq[TestDefinition], - log: Logger, + log: ManagedLogger, listeners: Seq[TestReportListener] - ): (() => Unit, Seq[(String, TestFunction)], TestResult.Value => () => Unit) = + ): (() => Unit, Seq[(String, TestFunction)], TestResult => () => Unit) = { val mappedTests = testMap(frameworks.values.toSeq, tests) if (mappedTests.isEmpty) @@ -160,7 +157,7 @@ object TestFramework { map.toMap.mapValues(_.toSet) } - private def createTestTasks(loader: ClassLoader, runners: Map[Framework, TestRunner], tests: Map[Framework, Set[TestDefinition]], ordered: Seq[TestDefinition], log: Logger, listeners: Seq[TestReportListener]) = + private def createTestTasks(loader: ClassLoader, runners: Map[Framework, TestRunner], tests: Map[Framework, Set[TestDefinition]], ordered: Seq[TestDefinition], log: ManagedLogger, listeners: Seq[TestReportListener]) = { val testsListeners = listeners collect { case tl: TestsListener => tl } @@ -178,7 +175,7 @@ object TestFramework { } } - val endTask = (result: TestResult.Value) => foreachListenerSafe(_.doComplete(result)) + val endTask = (result: TestResult) => foreachListenerSafe(_.doComplete(result)) (startTask, order(testTasks, ordered), endTask) } private[this] def withContextLoader[T](loader: ClassLoader)(eval: => T): T = diff --git a/testing/src/main/scala/sbt/TestReportListener.scala b/testing/src/main/scala/sbt/TestReportListener.scala index 878d9c765..9d4fcfe35 100644 --- a/testing/src/main/scala/sbt/TestReportListener.scala +++ b/testing/src/main/scala/sbt/TestReportListener.scala @@ -5,8 +5,7 @@ package sbt import testing.{ Logger => TLogger, Event => TEvent, Status => TStatus } -import sbt.internal.util.{ BufferedLogger, FullLogger } -import sbt.util.Level +import sbt.protocol.testing._ trait TestReportListener { /** called for each class or equivalent grouping */ @@ -19,23 +18,25 @@ trait TestReportListener { def endGroup(name: String, t: Throwable): Unit /** called if test completed */ - def endGroup(name: String, result: TestResult.Value): Unit + def endGroup(name: String, result: TestResult): Unit /** Used by the test framework for logging test results*/ def contentLogger(test: TestDefinition): Option[ContentLogger] = None } +final class ContentLogger(val log: TLogger, val flush: () => Unit) + trait TestsListener extends TestReportListener { /** called once, at beginning. */ def doInit(): Unit /** called once, at end. */ - def doComplete(finalResult: TestResult.Value): Unit + def doComplete(finalResult: TestResult): Unit } /** Provides the overall `result` of a group of tests (a suite) and test counts for each result type. */ final class SuiteResult( - val result: TestResult.Value, + val result: TestResult, val passedCount: Int, val failureCount: Int, val errorCount: Int, val skippedCount: Int, val ignoredCount: Int, val canceledCount: Int, val pendingCount: Int ) { @@ -65,7 +66,7 @@ object SuiteResult { } abstract class TestEvent { - def result: Option[TestResult.Value] + def result: Option[TestResult] def detail: Seq[TEvent] = Nil } object TestEvent { @@ -75,8 +76,8 @@ object TestEvent { override val detail = events } - private[sbt] def overallResult(events: Seq[TEvent]): TestResult.Value = - (TestResult.Passed /: events) { (sum, event) => + private[sbt] def overallResult(events: Seq[TEvent]): TestResult = + ((TestResult.Passed: TestResult) /: events) { (sum, event) => (sum, event.status) match { case (TestResult.Error, _) => TestResult.Error case (_, TStatus.Error) => TestResult.Error @@ -86,60 +87,3 @@ object TestEvent { } } } - -object TestLogger { - @deprecated("Doesn't provide for underlying resources to be released.", "0.13.1") - def apply(logger: sbt.util.Logger, logTest: TestDefinition => sbt.util.Logger, buffered: Boolean): TestLogger = - new TestLogger(new TestLogging(wrap(logger), tdef => contentLogger(logTest(tdef), buffered))) - - @deprecated("Doesn't provide for underlying resources to be released.", "0.13.1") - def contentLogger(log: sbt.util.Logger, buffered: Boolean): ContentLogger = - { - val blog = new BufferedLogger(FullLogger(log)) - if (buffered) blog.record() - new ContentLogger(wrap(blog), () => blog.stopQuietly()) - } - - final class PerTest private[sbt] (val log: sbt.util.Logger, val flush: () => Unit, val buffered: Boolean) - - def make(global: sbt.util.Logger, perTest: TestDefinition => PerTest): TestLogger = - { - def makePerTest(tdef: TestDefinition): ContentLogger = - { - val per = perTest(tdef) - val blog = new BufferedLogger(FullLogger(per.log)) - if (per.buffered) blog.record() - new ContentLogger(wrap(blog), () => { blog.stopQuietly(); per.flush() }) - } - val config = new TestLogging(wrap(global), makePerTest) - new TestLogger(config) - } - - def wrap(logger: sbt.util.Logger): TLogger = - new TLogger { - def error(s: String) = log(Level.Error, s) - def warn(s: String) = log(Level.Warn, s) - def info(s: String) = log(Level.Info, s) - def debug(s: String) = log(Level.Debug, s) - def trace(t: Throwable) = logger.trace(t) - private def log(level: Level.Value, s: String) = logger.log(level, s) - def ansiCodesSupported() = logger.ansiCodesSupported - } -} -final class TestLogging(val global: TLogger, val logTest: TestDefinition => ContentLogger) -final class ContentLogger(val log: TLogger, val flush: () => Unit) -class TestLogger(val logging: TestLogging) extends TestsListener { - import logging.{ global => log, logTest } - - def startGroup(name: String): Unit = () - def testEvent(event: TestEvent): Unit = () - def endGroup(name: String, t: Throwable): Unit = { - log.trace(t) - log.error("Could not run test " + name + ": " + t.toString) - } - def endGroup(name: String, result: TestResult.Value): Unit = () - def doInit: Unit = () - /** called once, at end of test group. */ - def doComplete(finalResult: TestResult.Value): Unit = () - override def contentLogger(test: TestDefinition): Option[ContentLogger] = Some(logTest(test)) -} diff --git a/testing/src/main/scala/sbt/TestStatusReporter.scala b/testing/src/main/scala/sbt/TestStatusReporter.scala index 738b6c6cf..90a1a40f5 100644 --- a/testing/src/main/scala/sbt/TestStatusReporter.scala +++ b/testing/src/main/scala/sbt/TestStatusReporter.scala @@ -7,6 +7,7 @@ import java.io.File import sbt.io.IO import scala.collection.mutable.Map +import sbt.protocol.testing.TestResult // Assumes exclusive ownership of the file. private[sbt] class TestStatusReporter(f: File) extends TestsListener { @@ -16,11 +17,11 @@ private[sbt] class TestStatusReporter(f: File) extends TestsListener { def startGroup(name: String): Unit = { succeeded remove name } def testEvent(event: TestEvent): Unit = () def endGroup(name: String, t: Throwable): Unit = () - def endGroup(name: String, result: TestResult.Value): Unit = { + def endGroup(name: String, result: TestResult): Unit = { if (result == TestResult.Passed) succeeded(name) = System.currentTimeMillis } - def doComplete(finalResult: TestResult.Value): Unit = { + def doComplete(finalResult: TestResult): Unit = { TestStatus.write(succeeded, "Successful Tests", f) } } diff --git a/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala b/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala new file mode 100644 index 000000000..862204488 --- /dev/null +++ b/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala @@ -0,0 +1,38 @@ +package sbt.internal.testing + +import sbt.testing.Status + +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } + +trait StatusFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val StatusFormat: JsonFormat[Status] = new JsonFormat[Status] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): Status = { + jsOpt match { + case Some(js) => + unbuilder.readString(js) match { + case "Success" => Status.Success + case "Error" => Status.Error + case "Failure" => Status.Failure + case "Skipped" => Status.Skipped + case "Ignored" => Status.Ignored + case "Canceled" => Status.Canceled + case "Pending" => Status.Pending + } + case None => + deserializationError("Expected JsString but found None") + } + } + override def write[J](obj: Status, builder: Builder[J]): Unit = { + val str = obj match { + case Status.Success => "Success" + case Status.Error => "Error" + case Status.Failure => "Failure" + case Status.Skipped => "Skipped" + case Status.Ignored => "Ignored" + case Status.Canceled => "Canceled" + case Status.Pending => "Pending" + } + builder.writeString(str) + } + } +} diff --git a/testing/src/main/scala/sbt/internal/testing/TestLogger.scala b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala new file mode 100644 index 000000000..3bd75c728 --- /dev/null +++ b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala @@ -0,0 +1,101 @@ +package sbt +package internal.testing + +import testing.{ Logger => TLogger } +import sbt.internal.util.{ ManagedLogger, BufferedAppender } +import sbt.util.{ Level, LogExchange } +import sbt.protocol.testing._ +import java.util.concurrent.atomic.AtomicInteger +import scala.collection.JavaConverters._ + +object TestLogger { + import sbt.protocol.testing.codec.JsonProtocol._ + + private def generateName: String = + "test-" + generateId.incrementAndGet + private val generateId: AtomicInteger = new AtomicInteger + private def generateBufferName: String = + "testbuffer-" + generateBufferId.incrementAndGet + private val generateBufferId: AtomicInteger = new AtomicInteger + + final class PerTest private[sbt] (val log: ManagedLogger, val flush: () => Unit, val buffered: Boolean) + + def make(global: ManagedLogger, perTest: TestDefinition => PerTest): TestLogger = + { + def makePerTest(tdef: TestDefinition): ContentLogger = + { + val per = perTest(tdef) + val l0 = per.log + val config = LogExchange.loggerConfig(l0.name) + val as = config.getAppenders.asScala + val buffs: List[BufferedAppender] = (as map { + case (k, v) => BufferedAppender(generateBufferName, v) + }).toList + val newLog = LogExchange.logger(generateName, l0.channelName, l0.execId) + LogExchange.bindLoggerAppenders(newLog.name, buffs map { x => (x, Level.Debug) }) + if (per.buffered) { + buffs foreach { _.record() } + } + new ContentLogger(wrap(newLog), () => { + buffs foreach { _.stopQuietly() } + per.flush() + }) + } + val config = new TestLogging(wrap(global), global, makePerTest) + new TestLogger(config) + } + + def wrap(logger: ManagedLogger): TLogger = + new TLogger { + def error(s: String) = log(Level.Error, TestStringEvent(s)) + def warn(s: String) = log(Level.Warn, TestStringEvent(s)) + def info(s: String) = log(Level.Info, TestStringEvent(s)) + def debug(s: String) = log(Level.Debug, TestStringEvent(s)) + def trace(t: Throwable) = logger.trace(t) + private def log(level: Level.Value, event: TestStringEvent) = logger.logEvent(level, event) + def ansiCodesSupported() = logger.ansiCodesSupported + } + + private[sbt] def toTestItemEvent(event: TestEvent): TestItemEvent = + TestItemEvent(event.result, event.detail.toVector map { d => + TestItemDetail( + d.fullyQualifiedName, + d.status, + d.duration match { + case -1 => None + case x => Some(x) + } + ) + }) +} +final class TestLogging( + val global: TLogger, + val managed: ManagedLogger, + val logTest: TestDefinition => ContentLogger +) + +class TestLogger(val logging: TestLogging) extends TestsListener { + import TestLogger._ + import logging.{ global => log, logTest, managed } + import sbt.protocol.testing.codec.JsonProtocol._ + + def startGroup(name: String): Unit = + managed.logEvent(Level.Debug, StartTestGroupEvent(name)) + def testEvent(event: TestEvent): Unit = + managed.logEvent(Level.Debug, toTestItemEvent(event)) + def endGroup(name: String, t: Throwable): Unit = { + log.trace(t) + log.error("Could not run test " + name + ": " + t.toString) + managed.logEvent(Level.Debug, EndTestGroupErrorEvent( + name, + t.getMessage + "\n" + t.getStackTrace.toList.mkString("\n") + )) + } + def endGroup(name: String, result: TestResult): Unit = + managed.logEvent(Level.Debug, EndTestGroupEvent(name, result)) + def doInit: Unit = managed.logEvent(Level.Debug, TestInitEvent()) + /** called once, at end of test group. */ + def doComplete(finalResult: TestResult): Unit = + managed.logEvent(Level.Debug, TestCompleteEvent(finalResult)) + override def contentLogger(test: TestDefinition): Option[ContentLogger] = Some(logTest(test)) +} From 304d167813b96d319eaed8c02d7b10978a14accc Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 3 Apr 2017 03:17:57 -0400 Subject: [PATCH 3/6] Send ObjectEvent as JSON --- .../scala/sbt/internal/RelayAppender.scala | 26 ++++++++++++++++--- .../sbt/internal/testing/TestLogger.scala | 12 ++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/main/src/main/scala/sbt/internal/RelayAppender.scala b/main/src/main/scala/sbt/internal/RelayAppender.scala index 792ab626d..fc2fc66be 100644 --- a/main/src/main/scala/sbt/internal/RelayAppender.scala +++ b/main/src/main/scala/sbt/internal/RelayAppender.scala @@ -10,9 +10,12 @@ import sbt.util.Level import sbt.internal.util._ import sbt.protocol.LogEvent import sbt.internal.util.codec._ +import scala.json.ast.unsafe._ class RelayAppender(name: String) extends AbstractAppender(name, null, PatternLayout.createDefaultLayout(), true) { - import JsonProtocol._ + lazy val exchange = StandardMain.exchange + lazy val jsonFormat = new sjsonnew.BasicJsonProtocol + with JValueFormats {} def append(event: XLogEvent): Unit = { @@ -26,10 +29,27 @@ class RelayAppender(name: String) extends AbstractAppender(name, null, PatternLa } } def appendLog(level: Level.Value, message: => String): Unit = { - StandardMain.exchange.publishEventMessage(LogEvent(level.toString, message)) + exchange.publishEventMessage(LogEvent(level.toString, message)) } def appendEvent(level: Level.Value, event: AnyRef): Unit = event match { - case x: StringEvent => StandardMain.exchange.publishEvent(x: AbstractEntry) + case x: StringEvent => + { + import JsonProtocol._ + exchange.publishEvent(x: AbstractEntry) + } + case x: ObjectEvent[_] => + { + import jsonFormat._ + val json = JObject(JField("type", JString(x.contentType)), ( + Vector(JField("message", x.json), + JField("level", JString(x.level.toString))) ++ + (x.channelName.toVector map { channelName => JField("channelName", JString(channelName)) }) ++ + (x.execId.toVector map { execId => JField("execId", JString(execId)) })): _*) + exchange.publishEvent(json: JValue) + } + case _ => + println(s"appendEvent: ${event.getClass}") + () } } diff --git a/testing/src/main/scala/sbt/internal/testing/TestLogger.scala b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala index 3bd75c728..0f08603cf 100644 --- a/testing/src/main/scala/sbt/internal/testing/TestLogger.scala +++ b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala @@ -80,22 +80,22 @@ class TestLogger(val logging: TestLogging) extends TestsListener { import sbt.protocol.testing.codec.JsonProtocol._ def startGroup(name: String): Unit = - managed.logEvent(Level.Debug, StartTestGroupEvent(name)) + managed.logEvent(Level.Info, StartTestGroupEvent(name)) def testEvent(event: TestEvent): Unit = - managed.logEvent(Level.Debug, toTestItemEvent(event)) + managed.logEvent(Level.Info, toTestItemEvent(event)) def endGroup(name: String, t: Throwable): Unit = { log.trace(t) log.error("Could not run test " + name + ": " + t.toString) - managed.logEvent(Level.Debug, EndTestGroupErrorEvent( + managed.logEvent(Level.Info, EndTestGroupErrorEvent( name, t.getMessage + "\n" + t.getStackTrace.toList.mkString("\n") )) } def endGroup(name: String, result: TestResult): Unit = - managed.logEvent(Level.Debug, EndTestGroupEvent(name, result)) - def doInit: Unit = managed.logEvent(Level.Debug, TestInitEvent()) + managed.logEvent(Level.Info, EndTestGroupEvent(name, result)) + def doInit: Unit = managed.logEvent(Level.Info, TestInitEvent()) /** called once, at end of test group. */ def doComplete(finalResult: TestResult): Unit = - managed.logEvent(Level.Debug, TestCompleteEvent(finalResult)) + managed.logEvent(Level.Info, TestCompleteEvent(finalResult)) override def contentLogger(test: TestDefinition): Option[ContentLogger] = Some(logTest(test)) } From 622ebfd000751bb8cb154be578b0382d266ed471 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 3 Apr 2017 03:41:45 -0400 Subject: [PATCH 4/6] Switch to using util's JValueFormats --- project/ContrabandConfig.scala | 2 +- .../protocol/codec/EventMessageFormats.scala | 2 +- .../sbt/protocol/codec/JsonProtocol.scala | 2 +- .../codec/SettingQueryResponseFormats.scala | 2 +- .../codec/SettingQuerySuccessFormats.scala | 2 +- .../scala/sbt/internal/JValueFormat.scala | 45 ------------------- 6 files changed, 5 insertions(+), 50 deletions(-) delete mode 100644 protocol/src/main/scala/sbt/internal/JValueFormat.scala diff --git a/project/ContrabandConfig.scala b/project/ContrabandConfig.scala index f1bbd9d42..d9955fe0d 100644 --- a/project/ContrabandConfig.scala +++ b/project/ContrabandConfig.scala @@ -23,7 +23,7 @@ object ContrabandConfig { case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) } case "Int" | "Long" => { _ => Nil } case "sbt.testing.Status" => { _ => "sbt.internal.testing.StatusFormats" :: Nil } - case "scala.json.ast.unsafe.JValue" => { _ => "sbt.internal.JValueFormat" :: Nil } + case "scala.json.ast.unsafe.JValue" => { _ => "sbt.internal.util.codec.JValueFormats" :: Nil } } /** Returns the list of formats required to encode the given `TpeRef`. */ diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/EventMessageFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/EventMessageFormats.scala index 0727e822c..8ca31e712 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/EventMessageFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/EventMessageFormats.scala @@ -5,6 +5,6 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } -trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.internal.JValueFormat with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats => +trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.internal.util.codec.JValueFormats with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats => implicit lazy val EventMessageFormat: JsonFormat[sbt.protocol.EventMessage] = flatUnionFormat5[sbt.protocol.EventMessage, sbt.protocol.ChannelAcceptedEvent, sbt.protocol.LogEvent, sbt.protocol.ExecStatusEvent, sbt.protocol.SettingQuerySuccess, sbt.protocol.SettingQueryFailure]("type") } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala index f755ceb8c..3b92fc46c 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala @@ -11,7 +11,7 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats - with sbt.internal.JValueFormat + with sbt.internal.util.codec.JValueFormats with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats with sbt.protocol.codec.EventMessageFormats diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQueryResponseFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQueryResponseFormats.scala index 9e0aebed9..73991945f 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQueryResponseFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQueryResponseFormats.scala @@ -5,6 +5,6 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } -trait SettingQueryResponseFormats { self: sbt.internal.JValueFormat with sjsonnew.BasicJsonProtocol with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats => +trait SettingQueryResponseFormats { self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats => implicit lazy val SettingQueryResponseFormat: JsonFormat[sbt.protocol.SettingQueryResponse] = flatUnionFormat2[sbt.protocol.SettingQueryResponse, sbt.protocol.SettingQuerySuccess, sbt.protocol.SettingQueryFailure]("type") } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQuerySuccessFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQuerySuccessFormats.scala index 431a23d71..d8966c84e 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQuerySuccessFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/SettingQuerySuccessFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } -trait SettingQuerySuccessFormats { self: sbt.internal.JValueFormat with sjsonnew.BasicJsonProtocol => +trait SettingQuerySuccessFormats { self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SettingQuerySuccessFormat: JsonFormat[sbt.protocol.SettingQuerySuccess] = new JsonFormat[sbt.protocol.SettingQuerySuccess] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.SettingQuerySuccess = { jsOpt match { diff --git a/protocol/src/main/scala/sbt/internal/JValueFormat.scala b/protocol/src/main/scala/sbt/internal/JValueFormat.scala deleted file mode 100644 index d6f2a6dc9..000000000 --- a/protocol/src/main/scala/sbt/internal/JValueFormat.scala +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 Lightbend Inc. - */ -package sbt -package internal - -import sjsonnew.{ JsonWriter => JW, JsonReader => JR, JsonFormat => JF, _ } -import scala.json.ast.unsafe._ - -trait JValueFormat { self: sjsonnew.BasicJsonProtocol => - implicit val JNullJF: JF[JNull.type] = new JF[JNull.type] { - def write[J](x: JNull.type, b: Builder[J]) = b.writeNull() - def read[J](j: Option[J], u: Unbuilder[J]) = JNull - } - - implicit val JBooleanJF: JF[JBoolean] = project(_.get, JBoolean(_)) - implicit val JStringJF: JF[JString] = project(_.value, JString(_)) - implicit val JNumberJF: JF[JNumber] = project(x => BigDecimal(x.value), (x: BigDecimal) => JNumber(x.toString)) - implicit val JArrayJF: JF[JArray] = project[JArray, Array[JValue]](_.value, JArray(_)) - - implicit lazy val JObjectJW: JW[JObject] = new JW[JObject] { - def write[J](x: JObject, b: Builder[J]) = { - b.beginObject() - x.value foreach (jsonField => JValueJW.addField(jsonField.field, jsonField.value, b)) - b.endObject() - } - } - - implicit lazy val JValueJW: JW[JValue] = new JW[JValue] { - def write[J](x: JValue, b: Builder[J]) = x match { - case x: JNull.type => JNullJF.write(x, b) - case x: JBoolean => JBooleanJF.write(x, b) - case x: JString => JStringJF.write(x, b) - case x: JNumber => JNumberJF.write(x, b) - case x: JArray => JArrayJF.write(x, b) - case x: JObject => JObjectJW.write(x, b) - } - } - - implicit lazy val JValueJR: JR[JValue] = new JR[JValue] { - def read[J](j: Option[J], u: Unbuilder[J]) = ??? // Is this even possible? with no Manifest[J]? - } - - implicit lazy val JValueJF: JF[JValue] = jsonFormat[JValue](JValueJR, JValueJW) -} From 596dc62d7e62cee0fb9f465aa64c9cbde7337a4e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 4 Apr 2017 02:39:33 -0400 Subject: [PATCH 5/6] util 1.0.0-M21 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index c58be9818..36a961ec7 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,7 +12,7 @@ object Dependencies { // sbt modules private val ioVersion = "1.0.0-M9" - private val utilVersion = "1.0.0-M20" + private val utilVersion = "1.0.0-M21" private val lmVersion = "1.0.0-X7" private val zincVersion = "1.0.0-X11" From 2a1d8fb9e729af2f706e875f8cd5d43cd0002b36 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 4 Apr 2017 05:22:23 -0400 Subject: [PATCH 6/6] Expose TestResult --- MIGRATION.md | 1 + sbt/src/main/scala/Import.scala | 4 ++++ sbt/src/sbt-test/tests/t543/build.sbt | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 55c6f2d7c..b573d491b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -14,4 +14,5 @@ Migration notes - Log options `-error`, `-warn`, `-info`, `-debug` are added as shorthand for `"early(error)"` etc. - `sbt.Process` and `sbt.ProcessExtra` are gone. Use `scala.sys.process` instead. - `incOptions.value.withNameHashing(...)` option is removed. +- `TestResult.Value` is now `TestResult`. - the scripted plugin is cross-versioned now, so you must use %% when depending on it diff --git a/sbt/src/main/scala/Import.scala b/sbt/src/main/scala/Import.scala index ef3a6f84f..cb2880053 100644 --- a/sbt/src/main/scala/Import.scala +++ b/sbt/src/main/scala/Import.scala @@ -8,6 +8,10 @@ trait Import { type URI = java.net.URI type URL = java.net.URL + // sbt.testing + type TestResult = sbt.protocol.testing.TestResult + val TestResult = sbt.protocol.testing.TestResult + // sbt.io val AllPassFilter = sbt.io.AllPassFilter val DirectoryFilter = sbt.io.DirectoryFilter diff --git a/sbt/src/sbt-test/tests/t543/build.sbt b/sbt/src/sbt-test/tests/t543/build.sbt index 9d48c0433..fa93b01ee 100644 --- a/sbt/src/sbt-test/tests/t543/build.sbt +++ b/sbt/src/sbt-test/tests/t543/build.sbt @@ -26,7 +26,7 @@ lazy val root = (project in file(".")). } def startGroup(name: String): Unit = () def endGroup(name: String, t: Throwable): Unit = () - def endGroup(name: String, result: TestResult.Value): Unit = () + def endGroup(name: String, result: TestResult): Unit = () }, check := { val exists = marker.exists