Skip to content

Commit

Permalink
feat: add versions description command for ios and android (#988)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamfilipow92 authored Aug 14, 2020
1 parent f6007e5 commit 654421f
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 6 deletions.
2 changes: 1 addition & 1 deletion release_notes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## next (unreleased)
- [#987](https://github.com/Flank/flank/pull/987) Flank Error Monitoring readme addition ([sloox](https://github.com/Sloox))
- [#990](https://github.com/Flank/flank/pull/990) Fix: exclusion of @Suppress test. ([piotradamczyk5](https://github.com/piotradamczyk5))
-
- [#988](https://github.com/Flank/flank/pull/988) Add versions description command for ios and android. ([adamfilipow92](https://github.com/adamfilipow92))
-

## v20.08.1
Expand Down
7 changes: 6 additions & 1 deletion test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ftl.android
import com.google.api.services.testing.model.AndroidDevice
import com.google.api.services.testing.model.AndroidDeviceCatalog
import ftl.environment.android.asPrintableTable
import ftl.environment.android.getDescription
import ftl.environment.asPrintableTable
import ftl.environment.common.asPrintableTable
import ftl.gc.GcTesting
Expand All @@ -27,7 +28,11 @@ object AndroidCatalog {

fun devicesCatalogAsTable(projectId: String) = deviceCatalog(projectId).models.asPrintableTable()

fun supportedVersionsAsTable(projectId: String) = deviceCatalog(projectId).versions.asPrintableTable()
fun supportedVersionsAsTable(projectId: String) = getVersionsList(projectId).asPrintableTable()

fun describeSoftwareVersion(projectId: String, versionId: String) = getVersionsList(projectId).getDescription(versionId)

private fun getVersionsList(projectId: String) = deviceCatalog(projectId).versions

fun supportedOrientationsAsTable(projectId: String) = deviceCatalog(projectId).runtimeConfiguration.orientations.asPrintableTable()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import picocli.CommandLine
optionListHeading = "%n@|bold,underline Options:|@%n",
header = ["Information about available software versions"],
description = ["Information about available software versions. For example prints list of available software versions"],
subcommands = [AndroidVersionsListCommand::class],
subcommands = [AndroidVersionsListCommand::class, AndroidVersionsDescribeCommand::class],
usageHelpAutoWidth = true
)
class AndroidVersionsCommand : Runnable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ftl.cli.firebase.test.android.versions

import ftl.android.AndroidCatalog
import ftl.args.AndroidArgs
import ftl.config.FtlConstants
import ftl.util.FlankConfigurationError
import picocli.CommandLine
import java.nio.file.Paths

@CommandLine.Command(
name = "describe",
headerHeading = "",
synopsisHeading = "%n",
descriptionHeading = "%n@|bold,underline Description:|@%n%n",
parameterListHeading = "%n@|bold,underline Parameters:|@%n",
optionListHeading = "%n@|bold,underline Options:|@%n",
header = ["List of OS versions available to test against"],
description = ["Print current list of android versions available to test against"],
usageHelpAutoWidth = true
)
class AndroidVersionsDescribeCommand : Runnable {
override fun run() {
if (versionId.isBlank()) throw FlankConfigurationError("Argument VERSION_ID must be specified.")
println(AndroidCatalog.describeSoftwareVersion(AndroidArgs.loadOrDefault(Paths.get(configPath)).project, versionId))
}

@CommandLine.Option(names = ["-c", "--config"], description = ["YAML config file path"])
var configPath: String = FtlConstants.defaultAndroidConfig

@CommandLine.Parameters(
index = "0",
arity = "1",
paramLabel = "VERSION_ID",
defaultValue = "",
description = ["The version to describe, found" +
" using \$ gcloud firebase test android versions list."]
)
var versionId: String = ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import picocli.CommandLine

@CommandLine.Command(
name = "versions",
subcommands = [IosVersionsListCommand::class],
subcommands = [IosVersionsListCommand::class, IosVersionsDescribeCommand::class],
headerHeading = "",
synopsisHeading = "%n",
descriptionHeading = "%n@|bold,underline Description:|@%n%n",
parameterListHeading = "%n@|bold,underline Parameters:|@%n",
optionListHeading = "%n@|bold,underline Options:|@%n",
header = ["Information about available software versions"],
header = ["Describe software versions"],
description = ["Information about available software versions. For example prints list of available software versions"],
usageHelpAutoWidth = true
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ftl.cli.firebase.test.ios.versions

import ftl.args.IosArgs
import ftl.config.FtlConstants
import ftl.ios.IosCatalog
import ftl.util.FlankConfigurationError
import picocli.CommandLine
import java.nio.file.Paths

@CommandLine.Command(
name = "describe",
headerHeading = "",
synopsisHeading = "%n",
descriptionHeading = "%n@|bold,underline Description:|@%n%n",
parameterListHeading = "%n@|bold,underline Parameters:|@%n",
optionListHeading = "%n@|bold,underline Options:|@%n",
header = ["List of OS versions available to test against"],
description = ["Print current list of iOS versions available to test against"],
usageHelpAutoWidth = true
)
class IosVersionsDescribeCommand : Runnable {
override fun run() {
if (versionId.isBlank()) throw FlankConfigurationError("Argument VERSION_ID must be specified.")
println(IosCatalog.describeSoftwareVersion(IosArgs.loadOrDefault(Paths.get(configPath)).project, versionId))
}

@CommandLine.Option(names = ["-c", "--config"], description = ["YAML config file path"])
var configPath: String = FtlConstants.defaultIosConfig

@CommandLine.Parameters(
index = "0",
arity = "1",
paramLabel = "VERSION_ID",
defaultValue = "",
description = ["The version to describe, found" +
" using \$ gcloud firebase test ios versions list."]
)
var versionId: String = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ftl.environment.android

import com.google.api.services.testing.model.AndroidVersion
import ftl.util.FlankGeneralError

fun List<AndroidVersion>.getDescription(versionId: String) = findVersion(versionId)?.prepareDescription().orErrorMessage(versionId)

private fun List<AndroidVersion>.findVersion(versionId: String) = firstOrNull { it.id == versionId }

private fun AndroidVersion.prepareDescription() = """
apiLevel: $apiLevel
codeName: $codeName
id: '$id'
releaseDate:
day: ${releaseDate.day}
month: ${releaseDate.month}
year: ${releaseDate.year}
""".trimIndent().addDataIfExists(tags).addVersion(versionString).trim()

private fun String.addVersion(versionString: String) = StringBuilder(this).appendln("\nversionString: $versionString").toString()

private fun String.addDataIfExists(data: List<String?>?) =
if (!data.isNullOrEmpty()) StringBuilder(this).appendln("\n$TAGS_HEADER:").appendDataToList(data)
else this

private fun StringBuilder.appendDataToList(data: List<String?>) = apply {
data.filterNotNull().forEach { item -> appendln("- $item") }
}.toString().trim()

private fun String?.orErrorMessage(versionId: String) = this ?: throw FlankGeneralError("ERROR: '$versionId' is not a valid OS version")

private const val TAGS_HEADER = "tags"
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ftl.environment.ios

import com.google.api.services.testing.model.IosVersion
import ftl.util.FlankGeneralError

fun List<IosVersion>.getDescription(versionId: String) = findVersion(versionId)?.prepareDescription().orErrorMessage(versionId)

private fun List<IosVersion>.findVersion(versionId: String) = firstOrNull { it.id == versionId }

private fun IosVersion.prepareDescription() = """
id: '$id'
majorVersion: $majorVersion
minorVersion: $minorVersion
""".trimIndent().addDataIfExists(SUPPORTED_VERSIONS_HEADER, supportedXcodeVersionIds).addDataIfExists(TAGS_HEADER, tags)

private fun String.addDataIfExists(header: String, data: List<String?>?) =
if (!data.isNullOrEmpty()) StringBuilder(this).appendln("\n$header:").appendDataToList(data)
else this

private fun StringBuilder.appendDataToList(data: List<String?>) = apply {
data.filterNotNull().forEach { item -> appendln("- $item") }
}.toString().trim()

private fun String?.orErrorMessage(versionId: String) = this ?: throw FlankGeneralError("ERROR: '$versionId' is not a valid OS version")

private const val TAGS_HEADER = "tags"
private const val SUPPORTED_VERSIONS_HEADER = "supportedXcodeVersionIds"
7 changes: 6 additions & 1 deletion test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ftl.environment.android.asPrintableTable
import ftl.environment.asPrintableTable
import ftl.environment.common.asPrintableTable
import ftl.environment.ios.asPrintableTable
import ftl.environment.ios.getDescription
import ftl.gc.GcTesting
import ftl.http.executeWithRetry

Expand All @@ -19,7 +20,11 @@ object IosCatalog {

fun devicesCatalogAsTable(projectId: String) = iosDeviceCatalog(projectId).models.asPrintableTable()

fun softwareVersionsAsTable(projectId: String) = iosDeviceCatalog(projectId).versions.asPrintableTable()
fun softwareVersionsAsTable(projectId: String) = getVersionsList(projectId).asPrintableTable()

fun describeSoftwareVersion(projectId: String, versionId: String) = getVersionsList(projectId).getDescription(versionId)

private fun getVersionsList(projectId: String) = iosDeviceCatalog(projectId).versions

fun localesAsTable(projectId: String) = iosDeviceCatalog(projectId).runtimeConfiguration.locales.asPrintableTable()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ftl.cli.firebase.test.android.versions

import ftl.android.AndroidCatalog
import ftl.cli.firebase.test.ios.versions.IosVersionsDescribeCommand
import ftl.test.util.TestHelper
import ftl.util.FlankConfigurationError
import io.mockk.mockkObject
import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Test
import picocli.CommandLine

class AndroidVersionsDescribeCommandTest {

@Test
fun `should execute AndroidCatalog describeSoftwareVersion when run AndroidVersionsDescribeCommand`() {
mockkObject(AndroidCatalog) {
CommandLine(AndroidVersionsDescribeCommand()).execute("21")
verify { AndroidCatalog.describeSoftwareVersion(any(), any()) }
}
}

@Test(expected = FlankConfigurationError::class)
fun `should throw if version not specified`() {
CommandLine(AndroidVersionsDescribeCommand()).execute()
}

@Test
fun `should return error message if version not exists`() {
val exception = TestHelper.getThrowable { CommandLine(IosVersionsDescribeCommand()).execute("test") }
assertEquals("ERROR: 'test' is not a valid OS version", exception.message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ftl.cli.firebase.test.ios.versions

import ftl.ios.IosCatalog
import ftl.test.util.TestHelper.getThrowable
import ftl.util.FlankConfigurationError
import io.mockk.mockkObject
import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.contrib.java.lang.system.SystemOutRule
import picocli.CommandLine

class IosVersionsDescribeCommandTest {
@get:Rule
val systemOutRule: SystemOutRule = SystemOutRule().enableLog().muteForSuccessfulTests()

@Test
fun `should execute IosCatalog describeSoftwareVersion when run IosVersionsDescribeCommand`() {
mockkObject(IosCatalog) {
CommandLine(IosVersionsDescribeCommand()).execute("10.3")
verify { IosCatalog.describeSoftwareVersion(any(), any()) }
}
}

@Test(expected = FlankConfigurationError::class)
fun `should throw if version not specified`() {
CommandLine(IosVersionsDescribeCommand()).execute()
}

@Test
fun `should return error message if version not exists`() {
val exception = getThrowable { CommandLine(IosVersionsDescribeCommand()).execute("test") }
assertEquals("ERROR: 'test' is not a valid OS version", exception.message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ftl.environment.android

import com.google.api.services.testing.model.AndroidVersion
import com.google.api.services.testing.model.Date
import ftl.test.util.TestHelper.getThrowable
import org.junit.Assert
import org.junit.Test

class AndroidSoftwareVersionDescriptionTest {
@Test
fun `should return software version with tag if any tag exists`() {
val versions = listOf(AndroidVersion().apply {
id = "26"
apiLevel = 26
codeName = "Oreo"
versionString = "8.0.x"
releaseDate = Date().apply {
day = 21
month = 8
year = 2017
}
tags = listOf("default")
})

val localesDescription = versions.getDescription("26")
val expected = """
apiLevel: 26
codeName: Oreo
id: '26'
releaseDate:
day: 21
month: 8
year: 2017
tags:
- default
versionString: 8.0.x
""".trimIndent()
Assert.assertEquals(expected, localesDescription)
}

@Test
fun `should return software version without tag if no tags`() {
val versions = listOf(AndroidVersion().apply {
id = "23"
apiLevel = 23
codeName = "Marshmallow"
versionString = "6.0.x"
releaseDate = Date().apply {
day = 5
month = 10
year = 2015
}
})

val localesDescription = versions.getDescription("23")
val expected = """
apiLevel: 23
codeName: Marshmallow
id: '23'
releaseDate:
day: 5
month: 10
year: 2015
versionString: 6.0.x
""".trimIndent()
Assert.assertEquals(expected, localesDescription)
}

@Test
fun `should return error message if version not found`() {
val versions = listOf<AndroidVersion>()
val versionName = "test"
val localesDescription = getThrowable { versions.getDescription(versionName) }
val expected = "ERROR: '$versionName' is not a valid OS version"
Assert.assertEquals(expected, localesDescription.message)
}
}
Loading

0 comments on commit 654421f

Please sign in to comment.