From e708770f38ed46179753d11a6bba9b9564151f3e Mon Sep 17 00:00:00 2001 From: Trevor Jones Date: Tue, 2 Jul 2019 21:47:12 -0600 Subject: [PATCH] update gradle to 5.5 update publishing configuration to use latest POM dsl group/id/version from project to aim for composite build compat less indirection on gradle files, small project, not strictly necessary remove gradle version plugin, small project, not strictly necessary update bintray plugin to 1.8.4 update rxjava to v2 update spek to v2 --- build.gradle | 34 +++---- composer/build.gradle | 90 +++++++----------- .../main/kotlin/com/gojuno/composer/Apk.kt | 10 +- .../main/kotlin/com/gojuno/composer/Files.kt | 25 ++--- .../com/gojuno/composer/Instrumentation.kt | 4 +- .../kotlin/com/gojuno/composer/JUnitReport.kt | 8 +- .../main/kotlin/com/gojuno/composer/Main.kt | 19 ++-- .../kotlin/com/gojuno/composer/TestRun.kt | 66 ++++++------- .../com/gojuno/composer/html/HtmlReport.kt | 2 +- .../kotlin/com/gojuno/composer/ApkSpec.kt | 7 +- .../kotlin/com/gojuno/composer/ArgsSpec.kt | 49 +++++----- .../gojuno/composer/InstrumentationSpec.kt | 81 ++++++++-------- .../com/gojuno/composer/JUnitReportSpec.kt | 14 +-- .../com/gojuno/composer/LogLineParserSpec.kt | 11 +-- .../gojuno/composer/html/HtmlDeviceSpec.kt | 7 +- .../gojuno/composer/html/HtmlFullSuiteSpec.kt | 7 +- .../gojuno/composer/html/HtmlFullTestSpec.kt | 7 +- .../gojuno/composer/html/HtmlReportSpec.kt | 19 ++-- .../composer/html/HtmlShortSuiteSpec.kt | 7 +- .../gojuno/composer/html/HtmlShortTestSpec.kt | 7 +- .../test/kotlin/com/gojuno/composer/test.kt | 6 +- dependencies.gradle | 37 ------- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 6 +- 26 files changed, 229 insertions(+), 299 deletions(-) delete mode 100644 dependencies.gradle create mode 100644 gradle.properties diff --git a/build.gradle b/build.gradle index 2734601..86ee167 100644 --- a/build.gradle +++ b/build.gradle @@ -1,19 +1,13 @@ -apply from: 'dependencies.gradle' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { - // Gradle will not find vars defined in an external file when referring to them - // in the buildscript block, unless you link it from the buildscript block, too. - apply from: 'dependencies.gradle' - repositories { jcenter() } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" - classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0' - classpath "org.junit.platform:junit-platform-gradle-plugin:$versions.junitPlatform" - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.40" + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' } } @@ -21,8 +15,11 @@ allprojects { repositories { jcenter() } - - apply plugin: 'com.github.ben-manes.versions' + tasks.withType(KotlinCompile).all { + kotlinOptions { + freeCompilerArgs += '-XXLanguage:+NewInference' + } + } } def gitTag() { @@ -35,9 +32,7 @@ def gitTag() { return tag } -def projectVersion() { - def tag = gitTag() - +def projectVersion(tag) { if (tag.startsWith('v')) { return tag.substring(1) } else if (tag.isEmpty()) { @@ -48,11 +43,18 @@ def projectVersion() { } def validateTagAndVersion() { - if (gitTag().isEmpty()) { + def gitTag = gitTag() + def tagVersion = projectVersion(gitTag) + + if (gitTag.isEmpty()) { throw new IllegalStateException('Publishing is not allowed because current commit has no tag') } - if (projectVersion().isEmpty()) { + if (tagVersion.isEmpty()) { throw new IllegalStateException('Publishing is not allowed because current projectVersion is empty') } + + if (tagVersion != project.version) { + throw new IllegalStateException('Publishing not allowed because current tag version does not match version declared in gradle.properties') + } } diff --git a/composer/build.gradle b/composer/build.gradle index d03471f..f7c2d95 100644 --- a/composer/build.gradle +++ b/composer/build.gradle @@ -1,29 +1,23 @@ apply plugin: 'kotlin' apply plugin: 'application' -apply plugin: 'org.junit.platform.gradle.plugin' -apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'com.jfrog.bintray' mainClassName = 'com.gojuno.composer.MainKt' dependencies { - compile libraries.kotlinStd - compile libraries.rxJava - compile libraries.jCommander - compile libraries.commanderOs - compile libraries.commanderAndroid - compile libraries.apacheCommonsIo - compile libraries.apacheCommonsLang - compile libraries.gson - compile libraries.dexParser -} - -dependencies { - testCompile libraries.spek - testCompile libraries.junitPlatformRunner - testCompile libraries.spekJunitPlatformEngine - testCompile libraries.assertJ + api "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + api "com.gojuno.commander:android:0.2.0" + api "com.beust:jcommander:1.71" + api "commons-io:commons-io:2.6" + api "org.apache.commons:commons-text:1.6" + api "com.google.code.gson:gson:2.8.5" + api "com.linkedin.dextestparser:parser:1.1.0" + + testImplementation "org.assertj:assertj-core:3.11.1" + testImplementation "org.spekframework.spek2:spek-dsl-jvm:2.0.5" + testRuntimeOnly "org.spekframework.spek2:spek-runner-junit5:2.0.5" + testRuntimeOnly "org.jetbrains.kotlin:kotlin-reflect" } jar { @@ -39,23 +33,19 @@ jar { } } -junitPlatform { - platformVersion = versions.junitPlatform - - filters { - engines { - include 'spek' - } +test { + useJUnitPlatform { + includeEngines 'spek2' } } task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' + archiveClassifier = 'sources' from sourceSets.main.allSource } task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -67,23 +57,6 @@ task validatePublishing { bintrayUpload.dependsOn validatePublishing -def pomConfig = { - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'gojuno' - name 'Juno Inc.' - email 'opensource@gojuno.com' - } - } -} - publishing { publications { ComposerPublication(MavenPublication) { @@ -92,16 +65,23 @@ publishing { artifact sourcesJar artifact javadocJar - groupId 'com.gojuno.composer' - artifactId 'composer' - version projectVersion() - - pom.withXml { - def root = asNode() - root.appendNode('description', 'Reactive Android Instrumentation Test Runner.') - root.appendNode('name', 'Composer') - root.appendNode('url', 'https://github.com/gojuno/composer') - root.children().last() + pomConfig + pom { + description ='Reactive Android Instrumentation Test Runner.' + url ='https://github.com/gojuno/composer' + licenses { + license { + name = 'The Apache Software License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution = 'repo' + } + } + developers { + developer { + id = 'gojuno' + name = 'Juno Inc.' + email = 'opensource@gojuno.com' + } + } } } } @@ -121,7 +101,7 @@ bintray { publications = ['ComposerPublication'] version { - name = projectVersion() + name = project.version vcsTag = gitTag() gpg { diff --git a/composer/src/main/kotlin/com/gojuno/composer/Apk.kt b/composer/src/main/kotlin/com/gojuno/composer/Apk.kt index 664cb8b..2b3481e 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/Apk.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/Apk.kt @@ -36,9 +36,8 @@ fun parseTestPackage(testApkPath: String): TestPackage = ?.let(TestPackage::Valid) ?: TestPackage.ParseError("Cannot parse test package from `aapt dump badging \$APK` output.") } - .toSingle() - .toBlocking() - .value() + .singleOrError() + .blockingGet() fun parseTestRunner(testApkPath: String): TestRunner = process( @@ -60,9 +59,8 @@ fun parseTestRunner(testApkPath: String): TestRunner = ?.let(TestRunner::Valid) ?: TestRunner.ParseError("Cannot parse test runner from `aapt dump xmltree \$TEST_APK AndroidManifest.xml` output.") } - .toSingle() - .toBlocking() - .value() + .singleOrError() + .blockingGet() fun parseTests(testApkPath: String): List = DexParser.findTestMethods(testApkPath).map { TestMethod(it.testName, it.annotationNames) } diff --git a/composer/src/main/kotlin/com/gojuno/composer/Files.kt b/composer/src/main/kotlin/com/gojuno/composer/Files.kt index 5f5915e..416404a 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/Files.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/Files.kt @@ -1,22 +1,17 @@ package com.gojuno.composer +import io.reactivex.Observable import org.apache.commons.io.input.Tailer import org.apache.commons.io.input.TailerListener -import rx.Emitter.BackpressureMode -import rx.Observable import java.io.File import java.io.FileNotFoundException -import java.lang.Exception -fun tail(file: File): Observable = Observable.create( - { emitter -> - Tailer.create(file, object : TailerListener { - override fun init(tailer: Tailer) = emitter.setCancellation { tailer.stop() } - override fun handle(line: String) = emitter.onNext(line) - override fun handle(e: Exception) = emitter.onError(e) - override fun fileRotated() = emitter.onError(IllegalStateException("Output rotation detected $file")) - override fun fileNotFound() = emitter.onError(FileNotFoundException("$file file was not found")) - }) - }, - BackpressureMode.BUFFER -) +fun tail(file: File): Observable = Observable.create { emitter -> + Tailer.create(file, object : TailerListener { + override fun init(tailer: Tailer) = emitter.setCancellable { tailer.stop() } + override fun handle(line: String) = emitter.onNext(line) + override fun handle(e: Exception) = emitter.onError(e) + override fun fileRotated() = emitter.onError(IllegalStateException("Output rotation detected $file")) + override fun fileNotFound() = emitter.onError(FileNotFoundException("$file file was not found")) + }) +} diff --git a/composer/src/main/kotlin/com/gojuno/composer/Instrumentation.kt b/composer/src/main/kotlin/com/gojuno/composer/Instrumentation.kt index 7809806..3616f74 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/Instrumentation.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/Instrumentation.kt @@ -3,7 +3,7 @@ package com.gojuno.composer import com.gojuno.composer.InstrumentationTest.Status.Failed import com.gojuno.composer.InstrumentationTest.Status.Ignored import com.gojuno.composer.InstrumentationTest.Status.Passed -import rx.Observable +import io.reactivex.Observable import java.io.File data class InstrumentationTest( @@ -186,5 +186,5 @@ fun Observable.asTests(): Observable } } .filter { it.tests.isNotEmpty() } - .flatMap { Observable.from(it.tests) } + .flatMap { Observable.fromIterable(it.tests) } } diff --git a/composer/src/main/kotlin/com/gojuno/composer/JUnitReport.kt b/composer/src/main/kotlin/com/gojuno/composer/JUnitReport.kt index 175ee37..0ff810d 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/JUnitReport.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/JUnitReport.kt @@ -1,9 +1,9 @@ package com.gojuno.composer import com.gojuno.composer.AdbDeviceTest.Status.* -import org.apache.commons.lang3.StringEscapeUtils -import rx.Completable -import rx.Single +import io.reactivex.Completable +import io.reactivex.Single +import org.apache.commons.text.StringEscapeUtils import java.io.File import java.text.SimpleDateFormat import java.util.* @@ -73,4 +73,4 @@ fun writeJunit4Report(suite: Suite, outputFile: File): Completable = Single } } .map { xml -> outputFile.writeText(xml) } - .toCompletable() + .ignoreElement() diff --git a/composer/src/main/kotlin/com/gojuno/composer/Main.kt b/composer/src/main/kotlin/com/gojuno/composer/Main.kt index 6e97899..e73d072 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/Main.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/Main.kt @@ -6,8 +6,9 @@ import com.gojuno.commander.os.log import com.gojuno.commander.os.nanosToHumanReadableTime import com.gojuno.composer.html.writeHtmlReport import com.google.gson.Gson -import rx.Observable -import rx.schedulers.Schedulers +import io.reactivex.Observable +import io.reactivex.Single +import io.reactivex.schedulers.Schedulers import java.io.File import java.util.* import java.util.concurrent.TimeUnit @@ -105,9 +106,9 @@ private fun runAllTests(args: Args, testPackage: TestPackage.Valid, testRunner: } } } - .doOnNext { log("${it.size} connected adb device(s): $it") } + .doOnSuccess { log("${it.size} connected adb device(s): $it") } .flatMap { connectedAdbDevices -> - val runTestsOnDevices: List> = connectedAdbDevices.mapIndexed { index, device -> + val runTestsOnDevices: List> = connectedAdbDevices.mapIndexed { index, device -> val installTimeout = Pair(args.installTimeoutSeconds, TimeUnit.SECONDS) val installAppApk = device.installApk(pathToApk = args.appApkPath, timeout = installTimeout) val installTestApk = device.installApk(pathToApk = args.testApkPath, timeout = installTimeout) @@ -160,10 +161,9 @@ private fun runAllTests(args: Args, testPackage: TestPackage.Valid, testRunner: ).toSingleDefault(adbDeviceTestRun) } .subscribeOn(Schedulers.io()) - .toObservable() } } - Observable.zip(runTestsOnDevices, { results -> results.map { it as AdbDeviceTestRun } }) + Single.zip(runTestsOnDevices, { results: Array -> results.map { it as AdbDeviceTestRun } }) } .map { adbDeviceTestRuns -> when (args.shard) { @@ -199,11 +199,10 @@ private fun runAllTests(args: Args, testPackage: TestPackage.Valid, testRunner: log("Generating HTML report...") val htmlReportStartTime = System.nanoTime() writeHtmlReport(gson, suites, File(args.outputDirectory, "html-report"), Date()) - .doOnCompleted { log("HTML report generated, took ${(System.nanoTime() - htmlReportStartTime).nanosToHumanReadableTime()}.") } - .andThen(Observable.just(suites)) + .doOnComplete { log("HTML report generated, took ${(System.nanoTime() - htmlReportStartTime).nanosToHumanReadableTime()}.") } + .andThen(Single.just(suites)) } - .toBlocking() - .first() + .blockingGet() } private fun List.pairArguments(): List> = diff --git a/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt b/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt index 4648b25..f8d9bfc 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt @@ -4,9 +4,9 @@ import com.gojuno.commander.android.* import com.gojuno.commander.os.Notification import com.gojuno.commander.os.nanosToHumanReadableTime import com.gojuno.commander.os.process -import rx.Observable -import rx.Single -import rx.schedulers.Schedulers +import io.reactivex.Observable +import io.reactivex.Single +import io.reactivex.schedulers.Schedulers import java.io.File data class AdbDeviceTestRun( @@ -80,8 +80,8 @@ fun AdbDevice.runTests( adbDevice.log( "Test ${test.index}/${test.total} $status in " + - "${test.durationNanos.nanosToHumanReadableTime()}: " + - "${test.className}.${test.testName}" + "${test.durationNanos.nanosToHumanReadableTime()}: " + + "${test.className}.${test.testName}" ) } .flatMap { test -> @@ -92,12 +92,8 @@ fun AdbDevice.runTests( } .toList() - val adbDeviceTestRun = Observable - .zip( - Observable.fromCallable { System.nanoTime() }, - runningTests, - { time, tests -> time to tests } - ) + val adbDeviceTestRun = Single + .zip(Single.fromCallable { System.nanoTime() }, runningTests, { time, tests -> time to tests }) .map { (startTimeNanos, testsWithPulledFiles) -> val tests = testsWithPulledFiles.map { it.first } @@ -136,12 +132,12 @@ fun AdbDevice.runTests( // TODO: Stop when all expected tests were parsed from logcat and not when instrumentation finishes. // Logcat may be delivered with delay and that may result in missing logcat for last (n) tests (it's just a theory though). .takeUntil(testRunFinish) - .startWith(Unit) // To allow zip finish normally even if no tests were run. + .last(Unit) // Default value to allow zip finish normally even if no tests were run. - return Observable - .zip(adbDeviceTestRun, saveLogcat, testRunFinish) { suite, _, _ -> suite } + return Single + .zip(adbDeviceTestRun, saveLogcat, testRunFinish.singleOrError()) { suite, _, _ -> suite } .doOnSubscribe { adbDevice.log("Starting tests...") } - .doOnNext { testRun -> + .doOnSuccess { testRun -> adbDevice.log( "Test run finished, " + "${testRun.passedCount} passed, " + @@ -150,7 +146,6 @@ fun AdbDevice.runTests( ) } .doOnError { adbDevice.log("Error during tests run: $it") } - .toSingle() } data class PulledFiles( @@ -164,24 +159,27 @@ private fun pullTestFiles(adbDevice: AdbDevice, test: InstrumentationTest, outpu File(File(File(outputDir, "screenshots"), adbDevice.id), test.className).apply { mkdirs() } } .flatMap { screenshotsFolderOnHostMachine -> - adbDevice - .pullFolder( - // TODO: Add support for internal storage and external storage strategies. - folderOnDevice = "/storage/emulated/0/app_spoon-screenshots/${test.className}/${test.testName}", + // TODO: Add support for internal storage and external storage strategies. + val folderOnDevice = "/storage/emulated/0/app_spoon-screenshots/${test.className}/${test.testName}" + Single.concat( + adbDevice.pullFolder( + folderOnDevice = folderOnDevice, folderOnHostMachine = screenshotsFolderOnHostMachine, logErrors = verboseOutput + ), + adbDevice.deleteFolder( + folderOnDevice = folderOnDevice, + logErrors = verboseOutput ) + ) + .lastOrError() .map { File(screenshotsFolderOnHostMachine, test.testName) } } .map { screenshotsFolderOnHostMachine -> PulledFiles( files = emptyList(), // TODO: Pull test files. - screenshots = screenshotsFolderOnHostMachine.let { - when (it.exists()) { - true -> it.listFiles().toList() - else -> emptyList() - } - } + screenshots = screenshotsFolderOnHostMachine + .takeIf { it.exists() }?.listFiles()?.toList() ?: emptyList() ) } @@ -199,14 +197,18 @@ internal fun String.parseTestClassAndName(): Pair? { return null } -private fun saveLogcat(adbDevice: AdbDevice, logsDir: File): Observable> = Observable +private fun saveLogcat(adbDevice: AdbDevice, logsDir: File): Observable> = Single .just(logsDir to logcatFileForDevice(logsDir)) - .flatMap { (logsDir, fullLogcatFile) -> adbDevice.redirectLogcatToFile(fullLogcatFile).toObservable().map { logsDir to fullLogcatFile } } - .flatMap { (logsDir, fullLogcatFile) -> - data class result(val logcat: String = "", val startedTestClassAndName: Pair? = null, val finishedTestClassAndName: Pair? = null) + .flatMap { (logsDir, fullLogcatFile) -> adbDevice.redirectLogcatToFile(fullLogcatFile).map { logsDir to fullLogcatFile } } + .flatMapObservable { (logsDir, fullLogcatFile) -> + data class CaptureState( + val logcat: String = "", + val startedTestClassAndName: Pair? = null, + val finishedTestClassAndName: Pair? = null + ) tail(fullLogcatFile) - .scan(result()) { previous, newline -> + .scan(CaptureState()) { previous, newline -> val logcat = when (previous.startedTestClassAndName != null && previous.finishedTestClassAndName != null) { true -> newline false -> "${previous.logcat}\n$newline" @@ -217,7 +219,7 @@ private fun saveLogcat(adbDevice: AdbDevice, logsDir: File): Observable? = newline.parseTestClassAndName() val finishedTest: Pair? = newline.parseTestClassAndName() - result( + CaptureState( logcat = logcat, startedTestClassAndName = startedTest ?: previous.startedTestClassAndName, finishedTestClassAndName = finishedTest // Actual finished test should always overwrite previous. diff --git a/composer/src/main/kotlin/com/gojuno/composer/html/HtmlReport.kt b/composer/src/main/kotlin/com/gojuno/composer/html/HtmlReport.kt index ce69edc..5afb9ff 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/html/HtmlReport.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/html/HtmlReport.kt @@ -3,7 +3,7 @@ package com.gojuno.composer.html import com.gojuno.composer.Suite import com.google.gson.Gson import org.apache.commons.lang3.StringEscapeUtils -import rx.Completable +import io.reactivex.Completable import java.io.File import java.io.InputStream import java.text.SimpleDateFormat diff --git a/composer/src/test/kotlin/com/gojuno/composer/ApkSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/ApkSpec.kt index 9675148..1c6dff6 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/ApkSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/ApkSpec.kt @@ -1,13 +1,12 @@ package com.gojuno.composer import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe class ApkSpec : Spek({ - context("parse package from apk") { + describe("parse package from apk") { val testApkPath by memoized { fileFromJarResources("instrumentation-test.apk").absolutePath } diff --git a/composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt index f6740e1..a0ee482 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt @@ -2,9 +2,8 @@ package com.gojuno.composer import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe class ArgsSpec : Spek({ @@ -13,7 +12,7 @@ class ArgsSpec : Spek({ "--test-apk", "test_apk_path" ) - context("parse args with only required params") { + describe("parse args with only required params") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields) } @@ -37,7 +36,7 @@ class ArgsSpec : Spek({ } } - context("parse args with test runner specified") { + describe("parse args with test runner specified") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--test-runner", "test_runner")) @@ -48,7 +47,7 @@ class ArgsSpec : Spek({ } } - context("parse args with instrumentation arguments") { + describe("parse args with instrumentation arguments") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--instrumentation-arguments", "key1", "value1", "key2", "value2")) @@ -59,7 +58,7 @@ class ArgsSpec : Spek({ } } - context("parse args with instrumentation arguments with values with commas") { + describe("parse args with instrumentation arguments with values with commas") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--instrumentation-arguments", "key1", "value1,value2", "key2", "value3,value4")) @@ -70,7 +69,7 @@ class ArgsSpec : Spek({ } } - context("parse args with explicitly passed --shard") { + describe("parse args with explicitly passed --shard") { listOf(true, false).forEach { shard -> @@ -87,7 +86,7 @@ class ArgsSpec : Spek({ } } - context("parse args with explicitly passed --verbose-output") { + describe("parse args with explicitly passed --verbose-output") { listOf(true, false).forEach { verboseOutput -> @@ -104,7 +103,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --devices") { + describe("parse args with passed --devices") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--devices", "emulator-5554")) @@ -115,7 +114,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed two --devices") { + describe("parse args with passed two --devices") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--devices", "emulator-5554", "emulator-5556")) @@ -126,7 +125,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --device-pattern") { + describe("parse args with passed --device-pattern") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--device-pattern", "[abc|def]")) @@ -137,7 +136,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --devices and --device-pattern") { + describe("parse args with passed --devices and --device-pattern") { it("raises argument error") { assertThatThrownBy { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--device-pattern", "[abc|def]") + arrayOf("--devices", "emulator-5554")) } @@ -146,7 +145,7 @@ class ArgsSpec : Spek({ } } - context("parse args with --keep-output-on-exit") { + describe("parse args with --keep-output-on-exit") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + "--keep-output-on-exit") @@ -157,7 +156,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --install-timeout") { + describe("parse args with passed --install-timeout") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--install-timeout", "600")) @@ -168,7 +167,7 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --fail-if-no-tests") { + describe("parse args with passed --fail-if-no-tests") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--fail-if-no-tests", "false")) @@ -179,7 +178,7 @@ class ArgsSpec : Spek({ } } - context("parse args with explicitly passed --fail-if-no-tests") { + describe("parse args with explicitly passed --fail-if-no-tests") { listOf(true, false).forEach { failIfNoTests -> @@ -196,7 +195,7 @@ class ArgsSpec : Spek({ } } - context("parse args with --with-orchestrator") { + describe("parse args with --with-orchestrator") { val args by memoized { parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--with-orchestrator", "true")) @@ -207,15 +206,15 @@ class ArgsSpec : Spek({ } } - context("parse args with passed --extra-apks") { + describe("parse args with passed --extra-apks") { - val args by memoized { - parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--extra-apks", "apk1.apk", "apk2.apk")) - } + val args by memoized { + parseArgs(rawArgsWithOnlyRequiredFields + arrayOf("--extra-apks", "apk1.apk", "apk2.apk")) + } - it("parses correctly two extra apks") { - assertThat(args.extraApks).isEqualTo(listOf("apk1.apk", "apk2.apk")) + it("parses correctly two extra apks") { + assertThat(args.extraApks).isEqualTo(listOf("apk1.apk", "apk2.apk")) + } } - } }) diff --git a/composer/src/test/kotlin/com/gojuno/composer/InstrumentationSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/InstrumentationSpec.kt index 430cbc4..6ec491d 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/InstrumentationSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/InstrumentationSpec.kt @@ -3,19 +3,18 @@ package com.gojuno.composer import com.gojuno.composer.InstrumentationTest.Status.Failed import com.gojuno.composer.InstrumentationTest.Status.Ignored import com.gojuno.composer.InstrumentationTest.Status.Passed +import io.reactivex.observers.TestObserver import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it -import rx.observers.TestSubscriber +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.util.concurrent.TimeUnit.SECONDS class InstrumentationSpec : Spek({ - context("read output with failed test") { + describe("read output with failed test") { val entries by memoized { readInstrumentationOutput(fileFromJarResources("instrumentation-output-failed-test.txt")) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -105,7 +104,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 stream = normalizeLinefeed(stream) // We have no control over system time in tests. - assertThat(entriesSubscriber.onNextEvents.map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( + assertThat(entriesSubscriber.values().map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( InstrumentationEntry( numTests = 4, stream = "com.example.test.TestClass:", @@ -198,7 +197,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - entriesSubscriber.assertCompleted() + entriesSubscriber.assertComplete() } it("does not emit error") { @@ -207,7 +206,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 context("as tests") { - val testsSubscriber by memoized { TestSubscriber() } + val testsSubscriber by memoized { TestObserver() } perform { entries.asTests().subscribe(testsSubscriber) @@ -256,7 +255,7 @@ at android.support.test.runner.JunoAndroidRunner.onStart(JunoAndroidRunner.kt:10 at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:1932)""" stacktrace = normalizeLinefeed(stacktrace) - assertThat(testsSubscriber.onNextEvents.map { it.copy(durationNanos = 0) }).isEqualTo(listOf( + assertThat(testsSubscriber.values().map { it.copy(durationNanos = 0) }).isEqualTo(listOf( InstrumentationTest( index = 1, total = 4, @@ -293,7 +292,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - testsSubscriber.assertCompleted() + testsSubscriber.assertComplete() } it("does not emit error") { @@ -302,10 +301,10 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } } - context("read output with 0 tests") { + describe("read output with 0 tests") { val entries by memoized { readInstrumentationOutput(fileFromJarResources("instrumentation-output-0-tests.txt")) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -317,7 +316,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - entriesSubscriber.assertCompleted() + entriesSubscriber.assertComplete() } it("does not emit error") { @@ -326,7 +325,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 context("as tests") { - val testsSubscriber by memoized { TestSubscriber() } + val testsSubscriber by memoized { TestObserver() } perform { entries.asTests().subscribe(testsSubscriber) @@ -338,7 +337,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - testsSubscriber.assertCompleted() + testsSubscriber.assertComplete() } it("does not emit error") { @@ -347,10 +346,10 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } } - context("read unordered output") { + describe("read unordered output") { val entries by memoized { readInstrumentationOutput(fileFromJarResources("instrumentation-unordered-output.txt")) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -359,7 +358,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 it("emits expected entries") { // We have no control over system time in tests. - assertThat(entriesSubscriber.onNextEvents.map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( + assertThat(entriesSubscriber.values().map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( InstrumentationEntry( numTests = 3, stream = "com.example.test.TestClass:", @@ -430,7 +429,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - entriesSubscriber.assertCompleted() + entriesSubscriber.assertComplete() } it("does not emit error") { @@ -439,7 +438,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 context("as tests") { - val testsSubscriber by memoized { TestSubscriber() } + val testsSubscriber by memoized { TestObserver() } perform { entries.asTests().subscribe(testsSubscriber) @@ -447,7 +446,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("emits expected tests") { - assertThat(testsSubscriber.onNextEvents.map { it.copy(durationNanos = 0) }).isEqualTo(listOf( + assertThat(testsSubscriber.values().map { it.copy(durationNanos = 0) }).isEqualTo(listOf( InstrumentationTest( index = 1, total = 3, @@ -476,7 +475,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - testsSubscriber.assertCompleted() + testsSubscriber.assertComplete() } it("does not emit error") { @@ -485,10 +484,10 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } } - context("read output with ignored test") { + describe("read output with ignored test") { val entries by memoized { readInstrumentationOutput(fileFromJarResources("instrumentation-output-ignored-test.txt")) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -497,7 +496,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 it("emits expected entries") { // We have no control over system time in tests. - assertThat(entriesSubscriber.onNextEvents.map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( + assertThat(entriesSubscriber.values().map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( InstrumentationEntry( numTests = 2, stream = "com.example.test.TestClass:", @@ -546,7 +545,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("completes stream") { - entriesSubscriber.assertCompleted() + entriesSubscriber.assertComplete() } it("does not emit error") { @@ -555,7 +554,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 context("as tests") { - val testsSubscriber by memoized { TestSubscriber() } + val testsSubscriber by memoized { TestObserver() } perform { entries.asTests().subscribe(testsSubscriber) @@ -563,7 +562,7 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } it("emits expected tests") { - assertThat(testsSubscriber.onNextEvents.map { it.copy(durationNanos = 0) }).isEqualTo(listOf( + assertThat(testsSubscriber.values().map { it.copy(durationNanos = 0) }).isEqualTo(listOf( InstrumentationTest( index = 1, total = 2, @@ -585,10 +584,10 @@ at android.app.Instrumentation.InstrumentationThread.run(Instrumentation.java:19 } } - context("read output containing test with assumption violation") { + describe("read output containing test with assumption violation") { val entries by memoized { readInstrumentationOutput(fileFromJarResources("instrumentation-output-assumption-violation.txt")) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -629,7 +628,7 @@ at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.jav at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.java:2074)""" stacktrace = normalizeLinefeed(stacktrace) - assertThat(entriesSubscriber.onNextEvents.map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( + assertThat(entriesSubscriber.values().map { it.copy(timestampNanos = 0) }).isEqualTo(listOf( InstrumentationEntry( numTests = 1, stream = "com.example.test.TestClass:", @@ -656,7 +655,7 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja } it("completes stream") { - entriesSubscriber.assertCompleted() + entriesSubscriber.assertComplete() } it("does not emit error") { @@ -665,7 +664,7 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja context("as tests") { - val testsSubscriber by memoized { TestSubscriber() } + val testsSubscriber by memoized { TestObserver() } perform { entries.asTests().subscribe(testsSubscriber) @@ -704,7 +703,7 @@ at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:5 at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375) at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.java:2074)""" stacktrace = normalizeLinefeed(stacktrace) - assertThat(testsSubscriber.onNextEvents.map { it.copy(durationNanos = 0) }).isEqualTo(listOf( + assertThat(testsSubscriber.values().map { it.copy(durationNanos = 0) }).isEqualTo(listOf( InstrumentationTest( index = 1, total = 1, @@ -718,11 +717,11 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja } } - context("read output with unable to find instrumentation info error") { + describe("read output with unable to find instrumentation info error") { val outputFile = fileFromJarResources("instrumentation-output-unable-to-find-instrumentation-info.txt") val entries by memoized { readInstrumentationOutput(outputFile) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -730,7 +729,7 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja } it("emits exception with human readable message") { - assertThat(entriesSubscriber.onErrorEvents.first()).hasMessage( + assertThat(entriesSubscriber.errors().first()).hasMessage( "Instrumentation was unable to run tests using runner com.composer.example.ExampleAndroidJUnitRunner.\n" + "Most likely you forgot to declare test runner in AndroidManifest.xml or build.gradle.\n" + "Detailed log can be found in ${outputFile.path} or Logcat output.\n" + @@ -739,11 +738,11 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja } } - context("read output with crash") { + describe("read output with crash") { val outputFile = fileFromJarResources("instrumentation-output-app-crash.txt") val entries by memoized { readInstrumentationOutput(outputFile) } - val entriesSubscriber by memoized { TestSubscriber() } + val entriesSubscriber by memoized { TestObserver() } perform { entries.subscribe(entriesSubscriber) @@ -751,7 +750,7 @@ at android.app.Instrumentation${'$'}InstrumentationThread.run(Instrumentation.ja } it("emits exception describing issue") { - assertThat(entriesSubscriber.onErrorEvents.first()).hasMessage( + assertThat(entriesSubscriber.errors().first()).hasMessage( "Application process crashed. Check Logcat output for more details." ) } diff --git a/composer/src/test/kotlin/com/gojuno/composer/JUnitReportSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/JUnitReportSpec.kt index 824ae2f..72d92f7 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/JUnitReportSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/JUnitReportSpec.kt @@ -2,11 +2,11 @@ package com.gojuno.composer import com.gojuno.commander.android.AdbDevice import com.gojuno.composer.AdbDeviceTest.Status.* +import io.reactivex.observers.TestObserver +import io.reactivex.subscribers.TestSubscriber import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it -import rx.observers.TestSubscriber +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.util.concurrent.TimeUnit.MILLISECONDS import java.util.concurrent.TimeUnit.SECONDS @@ -14,10 +14,10 @@ class JUnitReportSpec : Spek({ val LF = System.getProperty("line.separator") - context("write test run result as junit4 report to file") { + describe("write test run result as junit4 report to file") { val adbDevice by memoized { AdbDevice(id = "testDevice", online = true) } - val subscriber by memoized { TestSubscriber() } + val subscriber by memoized { TestObserver() } val outputFile by memoized { testFile() } perform { @@ -124,7 +124,7 @@ class JUnitReportSpec : Spek({ } it("emits completion") { - subscriber.assertCompleted() + subscriber.assertComplete() } it("does not emit values") { diff --git a/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt index 575142e..ae88416 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt @@ -1,13 +1,12 @@ package com.gojuno.composer import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe class LogLineParserSpec : Spek({ - context("parse TestRunner log line with long prefix") { + describe("parse TestRunner log line with long prefix") { context("parse started log") { val args by memoized { @@ -30,7 +29,7 @@ class LogLineParserSpec : Spek({ } } - context("parse TestRunner log line with short prefix") { + describe("parse TestRunner log line with short prefix") { context("parse started log") { @@ -55,7 +54,7 @@ class LogLineParserSpec : Spek({ } } - context("parse non TestRunner started/finished logs") { + describe("parse non TestRunner started/finished logs") { it("does not parse empty log") { assertThat("".parseTestClassAndName()).isNull() diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlDeviceSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlDeviceSpec.kt index 341e9f1..80f87d9 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlDeviceSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlDeviceSpec.kt @@ -3,13 +3,12 @@ package com.gojuno.composer.html import com.gojuno.composer.Device import com.gojuno.composer.testFile import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe class HtmlDeviceSpec : Spek({ - context("Device.toHtmlDevice") { + describe("Device.toHtmlDevice") { val device = Device(id = "testDevice1", logcat = testFile(), instrumentationOutput = testFile(), model = "testModel1") diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullSuiteSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullSuiteSpec.kt index 141c724..ef6a246 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullSuiteSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullSuiteSpec.kt @@ -6,14 +6,13 @@ import com.gojuno.composer.Device import com.gojuno.composer.Suite import com.gojuno.composer.testFile import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.util.concurrent.TimeUnit.NANOSECONDS class HtmlFullSuiteSpec : Spek({ - context("Suite.toHtmlFullSuite") { + describe("Suite.toHtmlFullSuite") { val suite = Suite( testPackage = "p", devices = listOf( diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullTestSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullTestSpec.kt index 7a58c09..892da00 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullTestSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlFullTestSpec.kt @@ -4,14 +4,13 @@ import com.gojuno.commander.android.AdbDevice import com.gojuno.composer.AdbDeviceTest import com.gojuno.composer.testFile import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.util.concurrent.TimeUnit.NANOSECONDS class HtmlFullTestSpec : Spek({ - context("AdbDeviceTest.toHtmlTest") { + describe("AdbDeviceTest.toHtmlTest") { val adbDeviceTest = AdbDeviceTest( adbDevice = AdbDevice(id = "testDevice", online = true, model = "testModel"), diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlReportSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlReportSpec.kt index 3c0dc4d..d8fd3e3 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlReportSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlReportSpec.kt @@ -8,10 +8,8 @@ import com.gojuno.composer.perform import com.google.gson.Gson import org.assertj.core.api.Assertions.assertThat import org.assertj.core.util.Files -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it -import rx.observers.TestSubscriber +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.io.File import java.util.* import java.util.concurrent.TimeUnit.MILLISECONDS @@ -19,7 +17,7 @@ import java.util.concurrent.TimeUnit.SECONDS class HtmlReportSpec : Spek({ - context("writeHtmlReport") { + describe("writeHtmlReport") { val outputDir by memoized { Files.newTemporaryFolder() } @@ -71,8 +69,6 @@ class HtmlReportSpec : Spek({ ) } - val subscriber by memoized { TestSubscriber() } - fun File.deleteOnExitRecursively() { when (isDirectory) { false -> deleteOnExit() @@ -82,14 +78,17 @@ class HtmlReportSpec : Spek({ val date by memoized { Date(1496848677000) } + val subscriber by memoized { + writeHtmlReport(Gson(), suites, outputDir, date).test() + } + perform { - writeHtmlReport(Gson(), suites, outputDir, date).subscribe(subscriber) subscriber.awaitTerminalEvent(5, SECONDS) outputDir.deleteOnExitRecursively() } it("completes") { - subscriber.assertCompleted() + subscriber.assertComplete() } it("does not emit error") { @@ -202,7 +201,7 @@ class HtmlReportSpec : Spek({ } } - context("cssClassForLogcatLine") { + describe("cssClassForLogcatLine") { context("verbose") { diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortSuiteSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortSuiteSpec.kt index 0d15bec..bdacaac 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortSuiteSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortSuiteSpec.kt @@ -6,14 +6,13 @@ import com.gojuno.composer.Device import com.gojuno.composer.Suite import com.gojuno.composer.testFile import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe import java.util.concurrent.TimeUnit.NANOSECONDS class HtmlShortSuiteSpec : Spek({ - context("Suite.toHtmlShortSuite") { + describe("Suite.toHtmlShortSuite") { val suite by memoized { Suite( testPackage = "p", diff --git a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortTestSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortTestSpec.kt index 0afcf41..b68bcfd 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortTestSpec.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/html/HtmlShortTestSpec.kt @@ -1,13 +1,12 @@ package com.gojuno.composer.html import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.context -import org.jetbrains.spek.api.dsl.it +import org.spekframework.spek2.Spek +import org.spekframework.spek2.style.specification.describe class HtmlShortTestSpec : Spek({ - context("HtmlFullTest.toHtmlShortTest") { + describe("HtmlFullTest.toHtmlShortTest") { val htmlFullTest by memoized { HtmlFullTest( diff --git a/composer/src/test/kotlin/com/gojuno/composer/test.kt b/composer/src/test/kotlin/com/gojuno/composer/test.kt index 99ae482..8cfc2ee 100644 --- a/composer/src/test/kotlin/com/gojuno/composer/test.kt +++ b/composer/src/test/kotlin/com/gojuno/composer/test.kt @@ -1,15 +1,15 @@ package com.gojuno.composer -import org.jetbrains.spek.api.dsl.SpecBody +import org.spekframework.spek2.style.specification.Suite import java.io.File inline fun fileFromJarResources(name: String) = File(C::class.java.classLoader.getResource(name).file) fun testFile(): File = createTempFile().apply { deleteOnExit() } -fun SpecBody.perform(body: () -> Unit) = beforeEachTest(body) +fun Suite.perform(body: () -> Unit) = beforeEachTest(body) -fun SpecBody.cleanup(body: () -> Unit) = afterEachTest(body) +fun Suite.cleanup(body: () -> Unit) = afterEachTest(body) /** Make a Unix-formatted String compliant with current operating system's newline format */ fun normalizeLinefeed(str: String): String = str.replace("\n", System.getProperty("line.separator")); diff --git a/dependencies.gradle b/dependencies.gradle deleted file mode 100644 index 6808688..0000000 --- a/dependencies.gradle +++ /dev/null @@ -1,37 +0,0 @@ -ext.versions = [ - kotlin : '1.1.1', - - rxJava : '1.3.0', - jCommander : '1.71', - commander : '0.1.7', - apacheCommonsIo : '2.5', - apacheCommonsLang: '3.5', - gson : '2.8.0', - dexParser : '1.1.0', - - junit : '4.12', - junitPlatform : '1.0.0-M4', - spek : '1.1.2', - assertJ : '3.5.2', -] - -ext.libraries = [ - kotlinStd : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlin", - kotlinRuntime : "org.jetbrains.kotlin:kotlin-runtime:$versions.kotlin", - kotlinReflect : "org.jetbrains.kotlin:kotlin-reflect:$versions.kotlin", - - rxJava : "io.reactivex:rxjava:$versions.rxJava", - jCommander : "com.beust:jcommander:$versions.jCommander", - commanderOs : "com.gojuno.commander:os:$versions.commander", - commanderAndroid : "com.gojuno.commander:android:$versions.commander", - apacheCommonsIo : "commons-io:commons-io:$versions.apacheCommonsIo", - apacheCommonsLang : "org.apache.commons:commons-lang3:$versions.apacheCommonsLang", - gson : "com.google.code.gson:gson:$versions.gson", - dexParser : "com.linkedin.dextestparser:parser:$versions.dexParser", - - junit : "junit:junit:$versions.junit", - spek : "org.jetbrains.spek:spek-api:$versions.spek", - junitPlatformRunner : "org.junit.platform:junit-platform-launcher:$versions.junitPlatform", - spekJunitPlatformEngine: "org.jetbrains.spek:spek-junit-platform-engine:$versions.spek", - assertJ : "org.assertj:assertj-core:$versions.assertJ", -] diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..4cf9446 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +group=com.gojuno.composer +version=0.7.0 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 11d62ccd786e17f9e93b1ec59112ccf52e94ca77..91ca28c8b802289c3a438766657a5e98f20eff03 100644 GIT binary patch delta 34122 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

x&K5s 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

yM(fBN7#L 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