From 83da53ed30ff01ac6473fbf5d33810a61a6c54db Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Thu, 1 Oct 2020 17:02:54 +0200 Subject: [PATCH 01/19] XCTestRun.rewrite methods supports now multiple test-targets --- .../src/main/kotlin/ftl/args/IosArgs.kt | 33 ++++++++- .../src/main/kotlin/ftl/ios/Xctestrun.kt | 68 +++++++++++++---- .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 74 ++++++++++++++++--- 3 files changed, 147 insertions(+), 28 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index 829d5a4765..72fc55ffd0 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -2,6 +2,7 @@ package ftl.args import com.google.common.annotations.VisibleForTesting import ftl.ios.Xctestrun.findTestNames +import ftl.ios.XctestrunMethods import ftl.run.exception.FlankConfigurationError import ftl.shard.Chunk import ftl.util.FlankTestMethod @@ -69,9 +70,11 @@ IosArgs private fun IosArgs.calculateShardChunks() = if (disableSharding) emptyList() else ArgsHelper.calculateShards( - filteredTests = filterTests(findTestNames(xctestrunFile), testTargets) - .distinct() - .map { FlankTestMethod(it, ignored = false) }, + filteredTests = filterTests2(findTestNames(xctestrunFile), testTargets) + .map { it.value } + .flatMap { it } + .distinct() + .map { FlankTestMethod(it, ignored = false) }, args = this ).shardChunks @@ -95,3 +98,27 @@ internal fun filterTests(validTestMethods: List, testTargetsRgx: List): XctestrunMethods { + if (testTargetsRgx.isEmpty()) { + return validTestMethods + } + + return validTestMethods.mapValues { + it.value.filter { test -> + testTargetsRgx.filterNotNull().forEach { target -> + try { + if (test.matches(target.toRegex())) { + return@filter true + } + } catch (e: Exception) { + throw FlankConfigurationError("Invalid regex: $target", e) + } + } + + return@filter false + } + } +} + diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 31b7ec66dd..039adbc8b0 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -9,6 +9,11 @@ import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Paths +// { "TestTarget": ["method1", "method2"], +// "TestTarget2: ["method3", "method4"] +// } +typealias XctestrunMethods = Map> + object Xctestrun { private fun String.isMetadata(): Boolean { @@ -70,35 +75,51 @@ object Xctestrun { return PropertyListParser.parse(xctestrun) as NSDictionary } - fun findTestNames(xctestrun: String): List { + fun findTestNames(xctestrun: String): XctestrunMethods { return findTestNames(File(xctestrun)) } + fun findTestNames(testTarget: String, xctestrun: String): List { + return findTestNamesForTarget( + testTarget = testTarget, + xctestrun = File(xctestrun) + ) + } + // Finds tests in a xctestrun file - private fun findTestNames(xctestrun: File): List { + private fun findTestNames(xctestrun: File): XctestrunMethods { val root = parse(xctestrun) - val result = mutableListOf() - // EarlGreyExampleSwiftTests_iphoneos11.3-arm64.xctestrun => EarlGreyExampleSwiftTests - val testRoot = xctestrun.parent + "/" + val result = mutableMapOf>() - // OnlyTestIdentifiers - // Test-Class-Name[/Test-Method-Name] - // Example/testExample for (testTarget in root.allKeys()) { - val testDictionary = (root[testTarget] as NSDictionary) - - val methods = testsForTarget( - testDictionary = testDictionary, - testRoot = testRoot, - testTarget = testTarget + val methods = findTestNamesForTarget( + testTarget = testTarget, + xctestrun = xctestrun ) + result[testTarget] = methods + } + + return result + } + + // Finds tests for testTarget in xctestrun file + fun findTestNamesForTarget(testTarget: String, xctestrun: File): List { + val rootDictionary = parse(xctestrun) + val testRoot = xctestrun.parent + "/" - result += methods + if (!rootDictionary.containsKey(testTarget)) { + throw FlankGeneralError("XCTestrun does not contain $testTarget test target.") } + val testDictionary = (rootDictionary[testTarget] as NSDictionary) - return result.distinct() + return testsForTarget( + testDictionary = testDictionary, + testRoot = testRoot, + testTarget = testTarget + ).distinct() } + // TODO: AXEL REMOVE fun rewrite(root: NSDictionary, methods: Collection): ByteArray { val rootClone = root.clone() for (testTarget in rootClone.allKeys()) { @@ -110,6 +131,21 @@ object Xctestrun { return rootClone.toByteArray() } + fun rewrite(root: NSDictionary, data: XctestrunMethods): ByteArray { + val rootClone = root.clone() + + for (testTarget in rootClone.allKeys()) { + if (testTarget.isMetadata()) continue + val methods = data[testTarget] + if (methods != null) { + val testDictionary = (rootClone[testTarget] as NSDictionary) + setOnlyTestIdentifiers(testDictionary, methods) + } + } + + return rootClone.toByteArray() + } + fun NSDictionary.toByteArray(): ByteArray { val out = ByteArrayOutputStream() PropertyListParser.saveAsXML(this, out) diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 989ae54f43..f5c2dff6e7 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -1,5 +1,6 @@ package ftl.ios +import com.dd.plist.NSArray import com.dd.plist.NSDictionary import com.google.common.truth.Truth.assertThat import ftl.config.FtlConstants.isWindows @@ -16,6 +17,8 @@ import java.nio.file.Paths class XctestrunTest { private val swiftXctestrun = "$fixturesPath/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" + private val multipleTargetsSwiftXctestrun = "$fixturesPath/axel/AllTests_iphoneos13.7-arm64e.xctestrun" + private val swiftTests = listOf( "EarlGreyExampleSwiftTests/testBasicSelection", "EarlGreyExampleSwiftTests/testBasicSelectionActionAssert", @@ -64,7 +67,10 @@ class XctestrunTest { val root = Xctestrun.parse(swiftXctestrun) val methods = Xctestrun.findTestNames(swiftXctestrun) - val results = String(Xctestrun.rewrite(root, methods)) + val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods) + + val results = String(Xctestrun.rewrite(root, methodsData)) + assertThat(results.contains("OnlyTestIdentifiers")).isTrue() } @@ -73,14 +79,15 @@ class XctestrunTest { assumeFalse(isWindows) val root = Xctestrun.parse(swiftXctestrun) - val methods = Xctestrun.findTestNames(swiftXctestrun) + val methods = Xctestrun.findTestNames(testTarget = "EarlGreyExampleSwiftTests", xctestrun = swiftXctestrun) + val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods) // ensure root object isn't modified. Rewrite should return a new object. val key = "OnlyTestIdentifiers" assertThat(root.toASCIIPropertyList().contains(key)).isFalse() - Xctestrun.rewrite(root, methods) + Xctestrun.rewrite(root, methodsData) assertThat(root.toASCIIPropertyList().contains(key)).isFalse() } @@ -90,10 +97,11 @@ class XctestrunTest { val root = NSDictionary() root["EarlGreyExampleSwiftTests"] = NSDictionary() root["EarlGreyExampleTests"] = NSDictionary() - val methods = setOf("testOne", "testTwo") - Xctestrun.rewrite(root, methods) - Xctestrun.rewrite(root, methods) - val result = Xctestrun.rewrite(root, methods) + val methods = listOf("testOne", "testTwo") + val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods, "EarlGreyExampleTests" to methods) + Xctestrun.rewrite(root, methodsData) + Xctestrun.rewrite(root, methodsData) + val result = Xctestrun.rewrite(root, methodsData) val expected = """ @@ -143,7 +151,8 @@ class XctestrunTest { """.trimIndent() val root = Xctestrun.parse(inputXml.toByteArray()) - val rewrittenXml = String(Xctestrun.rewrite(root, listOf("testOne", "testTwo"))) + val tests = mapOf>("EarlGreyExampleSwiftTests" to listOf("testOne", "testTwo")) + val rewrittenXml = String(Xctestrun.rewrite(root, tests)) assertThat(inputXml).isEqualTo(rewrittenXml.normalizeLineEnding()) } @@ -192,7 +201,54 @@ class XctestrunTest { Files.write(tmpXml, inputXml.toByteArray()) tmpXml.toFile().deleteOnExit() - val actualTests = Xctestrun.findTestNames(tmpXml.toString()).sorted() + val actualTests = Xctestrun.findTestNames("EarlGreyExampleSwiftTests", tmpXml.toString()).sorted() assertThat(actualTests).isEqualTo(listOf("EarlGreyExampleSwiftTests/testBasicSelection")) } + + // New + @Test + fun findTestNamesForTestTarget() { + assumeFalse(isWindows) + val names = Xctestrun.findTestNames(testTarget = "EarlGreyExampleSwiftTests", xctestrun = swiftXctestrun).sorted() + assertThat(swiftTests).isEqualTo(names) + } + + @Test(expected = FlankGeneralError::class) + fun `findTestNames for nonexisting test target`() { + assumeFalse(isWindows) + Xctestrun.findTestNames(testTarget = "Incorrect", xctestrun = swiftXctestrun).sorted() + } +x + fun `find test names for xctestrun file containing multiple test targets`() { + assumeFalse(isWindows) + val names = Xctestrun.findTestNames(testTarget = "SwiftTests1", xctestrun = multipleTargetsSwiftXctestrun).sorted() + assertThat(names).isEqualTo(listOf("SuiteA/testA1", "SuiteA/testA2", "SuiteB/testB1", "SuiteB/testB2")) + + val names2 = Xctestrun.findTestNames(testTarget = "SwiftTests2", xctestrun = multipleTargetsSwiftXctestrun).sorted() + assertThat(names2).isEqualTo(listOf("SwiftTests2/tests2_test1", "SwiftTests2/tests2_test2")) + } + + @Test + fun `rewrite methods in multiple test targets`() { + assumeFalse(isWindows) + + val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") + val expectedMethods2 = listOf("SwiftTests2/tests2_test1") + + val root = Xctestrun.parse(multipleTargetsSwiftXctestrun) + val data = mapOf>( + "SwiftTests1" to expectedMethods1, + "SwiftTests2" to expectedMethods2, + ) + val result = Xctestrun.rewrite(root, data) + val resultXML = Xctestrun.parse(result) + + val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary + val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary + val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + + assertThat(expectedMethods1).isEqualTo(resultMethods1.array.map { it.toJavaObject() }) + assertThat(expectedMethods2).isEqualTo(resultMethods2.array.map { it.toJavaObject() }) + } } From 8475584cf21ff53ed66117dbe660da17f4137fba Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Fri, 2 Oct 2020 12:41:27 +0200 Subject: [PATCH 02/19] Usage of new `Xctestrun.rewrite` in IosRunCommand --- .../src/main/kotlin/ftl/args/IosArgs.kt | 3 +- .../src/main/kotlin/ftl/gc/GcIosTestMatrix.kt | 2 +- .../src/main/kotlin/ftl/ios/Xctestrun.kt | 26 +++---- .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 68 +++++++++++++++---- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index 72fc55ffd0..54e92cbbb2 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -71,8 +71,7 @@ private fun IosArgs.calculateShardChunks() = if (disableSharding) emptyList() else ArgsHelper.calculateShards( filteredTests = filterTests2(findTestNames(xctestrunFile), testTargets) - .map { it.value } - .flatMap { it } + .flatMap { it.value } .distinct() .map { FlankTestMethod(it, ignored = false) }, args = this diff --git a/test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt b/test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt index 59b2071d87..687856f92b 100644 --- a/test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt +++ b/test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt @@ -49,7 +49,7 @@ object GcIosTestMatrix { val generatedXctestrun = if (args.disableSharding) { xcTestParsed.toByteArray() } else { - Xctestrun.rewrite(xcTestParsed, testTargets) + Xctestrun.rewrite(args.xctestrunFile, testTargets) } // Add shard number to file name diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 039adbc8b0..f774fb7a89 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -4,6 +4,7 @@ import com.dd.plist.NSArray import com.dd.plist.NSDictionary import com.dd.plist.NSString import com.dd.plist.PropertyListParser +import com.google.common.annotations.VisibleForTesting import ftl.run.exception.FlankGeneralError import java.io.ByteArrayOutputStream import java.io.File @@ -86,7 +87,7 @@ object Xctestrun { ) } - // Finds tests in a xctestrun file + /* Finds tests in a xctestrun file */ private fun findTestNames(xctestrun: File): XctestrunMethods { val root = parse(xctestrun) val result = mutableMapOf>() @@ -102,8 +103,8 @@ object Xctestrun { return result } - // Finds tests for testTarget in xctestrun file - fun findTestNamesForTarget(testTarget: String, xctestrun: File): List { + /* Finds tests for testTarget in xctestrun file */ + private fun findTestNamesForTarget(testTarget: String, xctestrun: File): List { val rootDictionary = parse(xctestrun) val testRoot = xctestrun.parent + "/" @@ -119,26 +120,21 @@ object Xctestrun { ).distinct() } - // TODO: AXEL REMOVE - fun rewrite(root: NSDictionary, methods: Collection): ByteArray { - val rootClone = root.clone() - for (testTarget in rootClone.allKeys()) { - if (testTarget.isMetadata()) continue - val testDictionary = (rootClone[testTarget] as NSDictionary) - setOnlyTestIdentifiers(testDictionary, methods) - } - - return rootClone.toByteArray() + fun rewrite(xctestrun: String, methods: List): ByteArray { + val xctestrunFile = File(xctestrun) + val methodsToRun = findTestNames(xctestrunFile).mapValues { it.value.filter { methods.contains(it) } } + return rewrite(parse(xctestrunFile), methodsToRun) } - fun rewrite(root: NSDictionary, data: XctestrunMethods): ByteArray { + @VisibleForTesting + internal fun rewrite(root: NSDictionary, data: XctestrunMethods): ByteArray { val rootClone = root.clone() for (testTarget in rootClone.allKeys()) { if (testTarget.isMetadata()) continue val methods = data[testTarget] if (methods != null) { - val testDictionary = (rootClone[testTarget] as NSDictionary) + val testDictionary = rootClone[testTarget] as NSDictionary setOnlyTestIdentifiers(testDictionary, methods) } } diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index f5c2dff6e7..8a7e28f942 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -57,7 +57,9 @@ class XctestrunTest { fun findTestNames() { assumeFalse(isWindows) - val names = Xctestrun.findTestNames(swiftXctestrun).sorted() + val names = Xctestrun.findTestNames(swiftXctestrun) + .flatMap { it.value } + .sorted() assertThat(swiftTests).isEqualTo(names) } @@ -66,7 +68,7 @@ class XctestrunTest { assumeFalse(isWindows) val root = Xctestrun.parse(swiftXctestrun) - val methods = Xctestrun.findTestNames(swiftXctestrun) + val methods = Xctestrun.findTestNames(testTarget = "EarlGreyExampleSwiftTests", xctestrun = swiftXctestrun) val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods) val results = String(Xctestrun.rewrite(root, methodsData)) @@ -218,7 +220,7 @@ class XctestrunTest { assumeFalse(isWindows) Xctestrun.findTestNames(testTarget = "Incorrect", xctestrun = swiftXctestrun).sorted() } -x + fun `find test names for xctestrun file containing multiple test targets`() { assumeFalse(isWindows) val names = Xctestrun.findTestNames(testTarget = "SwiftTests1", xctestrun = multipleTargetsSwiftXctestrun).sorted() @@ -229,18 +231,60 @@ x } @Test - fun `rewrite methods in multiple test targets`() { + fun `rewrite methods in single test target`() { assumeFalse(isWindows) + val methods = listOf("EarlGreyExampleSwiftTests/testBasicSelectionActionAssert", "EarlGreyExampleSwiftTests/testBasicSelection") + val result = Xctestrun.rewrite(xctestrun = swiftXctestrun, methods) + val resultXML = Xctestrun.parse(result) + val testTarget = resultXML["EarlGreyExampleSwiftTests"] as NSDictionary + val resultMethods = testTarget["OnlyTestIdentifiers"] as NSArray + + assertThat(methods.toSet()).isEqualTo(resultMethods.array.map { it.toJavaObject() }.toSet()) + } + + @Test + fun `rewrite methods in multiple test targets`() { + val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") + val expectedMethods2 = listOf("SwiftTests2/tests2_test1") + + val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(expectedMethods1, expectedMethods2).flatMap { it }) + val resultXML = Xctestrun.parse(result) + + val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary + val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary + val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + + assertThat(expectedMethods1.toSet()).isEqualTo(resultMethods1.array.map { it.toJavaObject() }.toSet()) + assertThat(expectedMethods2.toSet()).isEqualTo(resultMethods2.array.map { it.toJavaObject() }.toSet()) + } + + @Test + fun `rewrite incorrect methods in multiple test targets`() { + val methods1 = listOf("incorrect1", "incorrect2") + val methods2 = listOf("incorrect3") + + val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(methods1, methods2).flatMap { it }) + val resultXML = Xctestrun.parse(result) + + val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary + val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary + val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + + assertThat(resultMethods1.array.isEmpty()).isTrue() + assertThat(resultMethods2.array.isEmpty()).isTrue() + } + + @Test + fun `rewrite mix of correct and incorrect methods in multiple test targets`() { + val methods1 = listOf("SuiteA/testA1", "SuiteA/testA2", "incorrect1") + val methods2 = listOf("SwiftTests2/tests2_test1", "incorrect2") val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") val expectedMethods2 = listOf("SwiftTests2/tests2_test1") - val root = Xctestrun.parse(multipleTargetsSwiftXctestrun) - val data = mapOf>( - "SwiftTests1" to expectedMethods1, - "SwiftTests2" to expectedMethods2, - ) - val result = Xctestrun.rewrite(root, data) + val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(expectedMethods1, expectedMethods2).flatMap { it }) val resultXML = Xctestrun.parse(result) val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary @@ -248,7 +292,7 @@ x val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray - assertThat(expectedMethods1).isEqualTo(resultMethods1.array.map { it.toJavaObject() }) - assertThat(expectedMethods2).isEqualTo(resultMethods2.array.map { it.toJavaObject() }) + assertThat(expectedMethods1.toSet()).isEqualTo(resultMethods1.array.map { it.toJavaObject() }.toSet()) + assertThat(expectedMethods2.toSet()).isEqualTo(resultMethods2.array.map { it.toJavaObject() }.toSet()) } } From b3d191bf8d8135f715df3edf277604761561928b Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Fri, 2 Oct 2020 14:54:52 +0200 Subject: [PATCH 03/19] Code formatting + Removed old implementations of IosArgs.filterTests methods --- .../src/main/kotlin/ftl/args/IosArgs.kt | 26 ++----------------- .../src/main/kotlin/ftl/ios/Xctestrun.kt | 9 ++++--- .../src/test/kotlin/ftl/args/IosArgsTest.kt | 15 +++++++---- .../test/kotlin/ftl/gc/GcIosTestMatrixTest.kt | 4 ++- .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 8 +++--- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index 54e92cbbb2..13fa224bf0 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -70,7 +70,7 @@ IosArgs private fun IosArgs.calculateShardChunks() = if (disableSharding) emptyList() else ArgsHelper.calculateShards( - filteredTests = filterTests2(findTestNames(xctestrunFile), testTargets) + filteredTests = filterTests(findTestNames(xctestrunFile), testTargets) .flatMap { it.value } .distinct() .map { FlankTestMethod(it, ignored = false) }, @@ -78,28 +78,7 @@ private fun IosArgs.calculateShardChunks() = if (disableSharding) ).shardChunks @VisibleForTesting -internal fun filterTests(validTestMethods: List, testTargetsRgx: List): List { - if (testTargetsRgx.isEmpty()) { - return validTestMethods - } - - return validTestMethods.filter { test -> - testTargetsRgx.filterNotNull().forEach { target -> - try { - if (test.matches(target.toRegex())) { - return@filter true - } - } catch (e: Exception) { - throw FlankConfigurationError("Invalid regex: $target", e) - } - } - - return@filter false - } -} - -@VisibleForTesting -internal fun filterTests2(validTestMethods: XctestrunMethods, testTargetsRgx: List): XctestrunMethods { +internal fun filterTests(validTestMethods: XctestrunMethods, testTargetsRgx: List): XctestrunMethods { if (testTargetsRgx.isEmpty()) { return validTestMethods } @@ -120,4 +99,3 @@ internal fun filterTests2(validTestMethods: XctestrunMethods, testTargetsRgx: Li } } } - diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index f774fb7a89..49452037b0 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -10,9 +10,12 @@ import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Paths -// { "TestTarget": ["method1", "method2"], -// "TestTarget2: ["method3", "method4"] -// } +/* +{ + "TestTarget": ["method1", "method2"], + "TestTarget2: ["method3", "method4"] +} +*/ typealias XctestrunMethods = Map> object Xctestrun { diff --git a/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt b/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt index 895d944807..0c0d11b543 100644 --- a/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt @@ -867,13 +867,15 @@ IosArgs @Test(expected = FlankConfigurationError::class) fun `invalid regex filter throws custom exception`() { - filterTests(listOf("test"), testTargetsRgx = listOf("*.")) + val validTestMethods = mapOf("SampleXCTest" to listOf("test")) + filterTests(validTestMethods, testTargetsRgx = listOf("*.")) } @Test fun `filterTests emptyFilter`() { val tests = getValidTestsSample() - val actual = filterTests(tests, emptyList()) + val validTestMethods = mapOf("SampleXCTest" to tests) + val actual = filterTests(validTestMethods, emptyList()).flatMap { it.value } assertThat(actual).containsExactlyElementsIn(tests) } @@ -881,8 +883,9 @@ IosArgs @Test fun `filterTests regularFilter`() { val tests = getValidTestsSample() + val validTestMethods = mapOf("SampleXCTest" to tests) val filter = listOf("ClassOneTest/testOne", "ClassFourTest/testFour") - val actual = filterTests(tests, filter) + val actual = filterTests(validTestMethods, filter).flatMap { it.value } val expected = listOf("ClassOneTest/testOne", "ClassFourTest/testFour") @@ -892,8 +895,9 @@ IosArgs @Test fun `filterTests starFilter`() { val tests = getValidTestsSample() + val validTestMethods = mapOf("SampleXCTest" to tests) val filter = listOf(".*?Test/testOne", ".*?/testFour") - val actual = filterTests(tests, filter) + val actual = filterTests(validTestMethods, filter).flatMap { it.value } val expected = listOf( "ClassOneTest/testOne", @@ -906,8 +910,9 @@ IosArgs @Test fun `filterTests starAndRegularFilter`() { val tests = getValidTestsSample() + val validTestMethods = mapOf("SampleXCTest" to tests) val filter = listOf(".*?Screenshots/testTwo", "ClassOneTest/testOne") - val actual = filterTests(tests, filter) + val actual = filterTests(validTestMethods, filter).flatMap { it.value } val expected = listOf( "ClassTwoScreenshots/testTwo", diff --git a/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt b/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt index 39d647e42b..d36eb4014d 100644 --- a/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt +++ b/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt @@ -4,8 +4,10 @@ import com.dd.plist.NSDictionary import com.google.api.services.testing.model.IosDeviceList import ftl.shard.Chunk import ftl.args.IosArgs +import ftl.mock.TestArtifact import ftl.shard.TestMethod import ftl.test.util.FlankTestRunner +import ftl.test.util.ios2ConfigYaml import ftl.util.ShardCounter import io.mockk.every import io.mockk.mockk @@ -64,7 +66,7 @@ class GcIosTestMatrixTest { every { iosArgs.testTimeout } returns "3m" every { iosArgs.resultsBucket } returns "/hi" every { iosArgs.project } returns "123" - every { iosArgs.xctestrunFile } returns "any/path/to/test/file.xctestrun" + every { iosArgs.xctestrunFile } returns "${TestArtifact.fixturesPath}/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" GcIosTestMatrix.build( iosDeviceList = IosDeviceList(), diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 8a7e28f942..09134fd5be 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -69,7 +69,7 @@ class XctestrunTest { val root = Xctestrun.parse(swiftXctestrun) val methods = Xctestrun.findTestNames(testTarget = "EarlGreyExampleSwiftTests", xctestrun = swiftXctestrun) - val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods) + val methodsData = mapOf>("EarlGreyExampleSwiftTests" to methods) val results = String(Xctestrun.rewrite(root, methodsData)) @@ -82,7 +82,7 @@ class XctestrunTest { val root = Xctestrun.parse(swiftXctestrun) val methods = Xctestrun.findTestNames(testTarget = "EarlGreyExampleSwiftTests", xctestrun = swiftXctestrun) - val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods) + val methodsData = mapOf>("EarlGreyExampleSwiftTests" to methods) // ensure root object isn't modified. Rewrite should return a new object. val key = "OnlyTestIdentifiers" @@ -100,7 +100,7 @@ class XctestrunTest { root["EarlGreyExampleSwiftTests"] = NSDictionary() root["EarlGreyExampleTests"] = NSDictionary() val methods = listOf("testOne", "testTwo") - val methodsData= mapOf>("EarlGreyExampleSwiftTests" to methods, "EarlGreyExampleTests" to methods) + val methodsData = mapOf>("EarlGreyExampleSwiftTests" to methods, "EarlGreyExampleTests" to methods) Xctestrun.rewrite(root, methodsData) Xctestrun.rewrite(root, methodsData) val result = Xctestrun.rewrite(root, methodsData) @@ -284,7 +284,7 @@ class XctestrunTest { val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") val expectedMethods2 = listOf("SwiftTests2/tests2_test1") - val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(expectedMethods1, expectedMethods2).flatMap { it }) + val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(methods1, methods2).flatMap { it }) val resultXML = Xctestrun.parse(result) val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary From 7b9cb10658358d0e5643ac9c42c018fb2eddc75b Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Tue, 13 Oct 2020 12:23:55 +0200 Subject: [PATCH 04/19] Rebase from master - updated for using new test artefacts - resolved conflicts --- test_runner/build.gradle.kts | 2 +- test_runner/src/test/kotlin/Debug.kt | 11 ++++----- .../test/kotlin/ftl/fixtures/flank2.ios.yml | 23 ++++++++++++++++++- .../test/kotlin/ftl/gc/GcIosTestMatrixTest.kt | 5 ++-- .../src/test/kotlin/ftl/ios/Constants.kt | 2 +- .../src/test/kotlin/ftl/ios/ParseTest.kt | 8 +++---- .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 6 ++--- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/test_runner/build.gradle.kts b/test_runner/build.gradle.kts index c01932edd4..0b3b8a0c3f 100644 --- a/test_runner/build.gradle.kts +++ b/test_runner/build.gradle.kts @@ -139,7 +139,7 @@ detekt { input = files("src/main/kotlin", "src/test/kotlin") config = files("../config/detekt.yml") parallel = true - failFast = true // fail build on any finding + failFast = false // fail build on any finding autoCorrect = true reports { diff --git a/test_runner/src/test/kotlin/Debug.kt b/test_runner/src/test/kotlin/Debug.kt index 608364e6bf..6bfc538043 100644 --- a/test_runner/src/test/kotlin/Debug.kt +++ b/test_runner/src/test/kotlin/Debug.kt @@ -13,23 +13,22 @@ fun main() { val projectId = System.getenv("GOOGLE_CLOUD_PROJECT") ?: "YOUR PROJECT ID" - val quantity = "multiple" - val type = "flaky" +// val quantity = "multiple" +// val type = "flaky" // Bugsnag keeps the process alive so we must call exitProcess // https://github.com/bugsnag/bugsnag-java/issues/151 withGlobalExceptionHandling { CommandLine(Main()).execute( // "--debug", - "firebase", - "test", - "android", + "firebase", "test", "ios", "run", // "--dry", // "--dump-shards", "--output-style=single", // "--full-junit-result", // "--legacy-junit-result", - "-c=src/test/kotlin/ftl/fixtures/test_app_cases/flank-$quantity-$type.yml", +// "-c=src/test/kotlin/ftl/fixtures/test_app_cases/flank-$quantity-$type.yml", + "-c=test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml", "--project=$projectId" // "--client-details=key1=value1,key2=value2" ) diff --git a/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml b/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml index 3bb4d7c18f..6cd58c2ac7 100644 --- a/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml +++ b/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml @@ -1,5 +1,5 @@ gcloud: - test: ./src/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip + test: ./zsrc/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip xctestrun-file: ./src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun results-bucket: tmp_bucket_2 record-video: true @@ -18,3 +18,24 @@ flank: - EarlGreyExampleSwiftTests/testWith.*$ test-targets-always-run: - EarlGreyExampleSwiftTests/testWithGreyAssertions + +#gcloud: +# test: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/multiple-test-targets/FlankTests.zip +# xctestrun-file: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/multiple-test-targets/FlankTests_iphoneos14.0-arm64.xctestrun +# # results-bucket: tmp_bucket_2 +# # record-video: true +# # timeout: 60m +# async: false +# device: +# - model: iphone8 +# version: 13.6 +# orientation: portrait +# locale: en_US +# +#flank: +## max-test-shards: 2 +## num-test-runs: 1 +## test-targets: +## - FlankExampleTests/test1 +## test-targets-always-run: +## - EarlGreyExampleSwiftTests/testWithGreyAssertions diff --git a/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt b/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt index d36eb4014d..5743847894 100644 --- a/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt +++ b/test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt @@ -4,10 +4,9 @@ import com.dd.plist.NSDictionary import com.google.api.services.testing.model.IosDeviceList import ftl.shard.Chunk import ftl.args.IosArgs -import ftl.mock.TestArtifact +import ftl.ios.FIXTURES_PATH import ftl.shard.TestMethod import ftl.test.util.FlankTestRunner -import ftl.test.util.ios2ConfigYaml import ftl.util.ShardCounter import io.mockk.every import io.mockk.mockk @@ -66,7 +65,7 @@ class GcIosTestMatrixTest { every { iosArgs.testTimeout } returns "3m" every { iosArgs.resultsBucket } returns "/hi" every { iosArgs.project } returns "123" - every { iosArgs.xctestrunFile } returns "${TestArtifact.fixturesPath}/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" + every { iosArgs.xctestrunFile } returns "$FIXTURES_PATH/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" GcIosTestMatrix.build( iosDeviceList = IosDeviceList(), diff --git a/test_runner/src/test/kotlin/ftl/ios/Constants.kt b/test_runner/src/test/kotlin/ftl/ios/Constants.kt index 2bf6e5a441..f85d25e180 100644 --- a/test_runner/src/test/kotlin/ftl/ios/Constants.kt +++ b/test_runner/src/test/kotlin/ftl/ios/Constants.kt @@ -1,3 +1,3 @@ package ftl.ios -const val fixturesPath = "./src/test/kotlin/ftl/fixtures/tmp" +const val FIXTURES_PATH = "./src/test/kotlin/ftl/fixtures/tmp" diff --git a/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt b/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt index e1ced6f5c7..f60288d62b 100644 --- a/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt @@ -11,8 +11,8 @@ import org.junit.runner.RunWith @RunWith(FlankTestRunner::class) class ParseTest { - private val objcBinary = "$fixturesPath/objc/EarlGreyExampleTests" - private val swiftBinary = "$fixturesPath/swift/EarlGreyExampleSwiftTests" + private val objcBinary = "$FIXTURES_PATH/objc/EarlGreyExampleTests" + private val swiftBinary = "$FIXTURES_PATH/swift/EarlGreyExampleSwiftTests" private val objcTests = listOf( "EarlGreyExampleTests/testBasicSelection", @@ -72,10 +72,10 @@ class ParseTest { fun `Parse ObjC and Swift with space in path`() { assumeFalse(isWindows) - var results = Parse.parseObjcTests("$fixturesPath/sp ace/objc/EarlGreyExampleTests").sorted() + var results = Parse.parseObjcTests("$FIXTURES_PATH/sp ace/objc/EarlGreyExampleTests").sorted() checkObjcTests(results) - results = Parse.parseSwiftTests("$fixturesPath/sp ace/swift/EarlGreyExampleSwiftTests").sorted() + results = Parse.parseSwiftTests("$FIXTURES_PATH/sp ace/swift/EarlGreyExampleSwiftTests").sorted() checkSwiftTests(results) } diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 09134fd5be..69f4d089d5 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -16,8 +16,8 @@ import java.nio.file.Paths @RunWith(FlankTestRunner::class) class XctestrunTest { - private val swiftXctestrun = "$fixturesPath/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" - private val multipleTargetsSwiftXctestrun = "$fixturesPath/axel/AllTests_iphoneos13.7-arm64e.xctestrun" + private val swiftXctestrun = "$FIXTURES_PATH/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" + private val multipleTargetsSwiftXctestrun = "$FIXTURES_PATH/axel/AllTests_iphoneos13.7-arm64e.xctestrun" private val swiftTests = listOf( "EarlGreyExampleSwiftTests/testBasicSelection", @@ -199,7 +199,7 @@ class XctestrunTest { """.trimIndent() - val tmpXml = Paths.get(fixturesPath, "skip.xctestrun") + val tmpXml = Paths.get(FIXTURES_PATH, "skip.xctestrun") Files.write(tmpXml, inputXml.toByteArray()) tmpXml.toFile().deleteOnExit() From 71f32bcbbc212878b45842af953e5698d0397da0 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Tue, 13 Oct 2020 20:29:40 +0200 Subject: [PATCH 05/19] Code cleaning - updated code signing in EarlGreyExample project - updated methods/test targets names --- .../EarlGreyExample.xcodeproj/project.pbxproj | 6 +-- .../src/main/kotlin/ftl/args/IosArgs.kt | 20 ++++------ .../src/main/kotlin/ftl/ios/Xctestrun.kt | 13 ++----- .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 38 +++++++++---------- 4 files changed, 33 insertions(+), 44 deletions(-) diff --git a/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj b/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj index 468c3051fe..03d7c54fdf 100644 --- a/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj +++ b/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj @@ -509,7 +509,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = AD2V26JBWL; + DEVELOPMENT_TEAM = L2UF9MLSM6; INFOPLIST_FILE = EarlGreyExampleSwiftTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -642,7 +642,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = AD2V26JBWL; + DEVELOPMENT_TEAM = L2UF9MLSM6; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; INFOPLIST_FILE = "$(SRCROOT)/EarlGreyExample/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -704,7 +704,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = AD2V26JBWL; + DEVELOPMENT_TEAM = L2UF9MLSM6; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; HEADER_SEARCH_PATHS = ( diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index 13fa224bf0..f406c42e61 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -78,24 +78,20 @@ private fun IosArgs.calculateShardChunks() = if (disableSharding) ).shardChunks @VisibleForTesting -internal fun filterTests(validTestMethods: XctestrunMethods, testTargetsRgx: List): XctestrunMethods { - if (testTargetsRgx.isEmpty()) { - return validTestMethods - } - - return validTestMethods.mapValues { +internal fun filterTests( + validTestMethods: XctestrunMethods, + testTargetsRgx: List +): XctestrunMethods = + if (testTargetsRgx.isEmpty()) validTestMethods + else validTestMethods.mapValues { it.value.filter { test -> testTargetsRgx.filterNotNull().forEach { target -> try { - if (test.matches(target.toRegex())) { - return@filter true - } + if (test.matches(target.toRegex())) return@filter true } catch (e: Exception) { throw FlankConfigurationError("Invalid regex: $target", e) } } - - return@filter false + false } } -} diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 49452037b0..80d0024d2d 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -91,21 +91,14 @@ object Xctestrun { } /* Finds tests in a xctestrun file */ - private fun findTestNames(xctestrun: File): XctestrunMethods { - val root = parse(xctestrun) - val result = mutableMapOf>() - - for (testTarget in root.allKeys()) { - val methods = findTestNamesForTarget( + private fun findTestNames(xctestrun: File): XctestrunMethods = + parse(xctestrun).allKeys().associate { testTarget -> + testTarget to findTestNamesForTarget( testTarget = testTarget, xctestrun = xctestrun ) - result[testTarget] = methods } - return result - } - /* Finds tests for testTarget in xctestrun file */ private fun findTestNamesForTarget(testTarget: String, xctestrun: File): List { val rootDictionary = parse(xctestrun) diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 69f4d089d5..294d886fa5 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -17,7 +17,7 @@ import java.nio.file.Paths class XctestrunTest { private val swiftXctestrun = "$FIXTURES_PATH/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" - private val multipleTargetsSwiftXctestrun = "$FIXTURES_PATH/axel/AllTests_iphoneos13.7-arm64e.xctestrun" + private val multipleTargetsSwiftXctestrun = "$FIXTURES_PATH/axel/FlankTests_iphoneos14.0-arm64.xctestrun" private val swiftTests = listOf( "EarlGreyExampleSwiftTests/testBasicSelection", @@ -244,16 +244,16 @@ class XctestrunTest { @Test fun `rewrite methods in multiple test targets`() { - val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") - val expectedMethods2 = listOf("SwiftTests2/tests2_test1") + val expectedMethods1 = listOf("FlankExampleTests/test1", "FlankExampleTests/test2") + val expectedMethods2 = listOf("FlankExampleSecondTests/test3") val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(expectedMethods1, expectedMethods2).flatMap { it }) val resultXML = Xctestrun.parse(result) - val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary - val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary - val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray - val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + val target1 = resultXML["FlankExampleTests"] as NSDictionary + val target2 = resultXML["FlankExampleSecondTests"] as NSDictionary + val resultMethods1 = target1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = target2["OnlyTestIdentifiers"] as NSArray assertThat(expectedMethods1.toSet()).isEqualTo(resultMethods1.array.map { it.toJavaObject() }.toSet()) assertThat(expectedMethods2.toSet()).isEqualTo(resultMethods2.array.map { it.toJavaObject() }.toSet()) @@ -267,10 +267,10 @@ class XctestrunTest { val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(methods1, methods2).flatMap { it }) val resultXML = Xctestrun.parse(result) - val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary - val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary - val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray - val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + val target1 = resultXML["FlankExampleTests"] as NSDictionary + val target2 = resultXML["FlankExampleSecondTests"] as NSDictionary + val resultMethods1 = target1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = target2["OnlyTestIdentifiers"] as NSArray assertThat(resultMethods1.array.isEmpty()).isTrue() assertThat(resultMethods2.array.isEmpty()).isTrue() @@ -278,19 +278,19 @@ class XctestrunTest { @Test fun `rewrite mix of correct and incorrect methods in multiple test targets`() { - val methods1 = listOf("SuiteA/testA1", "SuiteA/testA2", "incorrect1") - val methods2 = listOf("SwiftTests2/tests2_test1", "incorrect2") + val methods1 = listOf("FlankExampleTests/test1", "FlankExampleTests/test2", "incorrect1") + val methods2 = listOf("FlankExampleSecondTests/test3", "incorrect2") - val expectedMethods1 = listOf("SuiteA/testA1", "SuiteA/testA2") - val expectedMethods2 = listOf("SwiftTests2/tests2_test1") + val expectedMethods1 = listOf("FlankExampleTests/test1", "FlankExampleTests/test2") + val expectedMethods2 = listOf("FlankExampleSecondTests/test3") val result = Xctestrun.rewrite(xctestrun = multipleTargetsSwiftXctestrun, listOf(methods1, methods2).flatMap { it }) val resultXML = Xctestrun.parse(result) - val targetSwiftTests1 = resultXML["SwiftTests1"] as NSDictionary - val targetSwiftTests2 = resultXML["SwiftTests2"] as NSDictionary - val resultMethods1 = targetSwiftTests1["OnlyTestIdentifiers"] as NSArray - val resultMethods2 = targetSwiftTests2["OnlyTestIdentifiers"] as NSArray + val target1 = resultXML["FlankExampleTests"] as NSDictionary + val target2 = resultXML["FlankExampleSecondTests"] as NSDictionary + val resultMethods1 = target1["OnlyTestIdentifiers"] as NSArray + val resultMethods2 = target2["OnlyTestIdentifiers"] as NSArray assertThat(expectedMethods1.toSet()).isEqualTo(resultMethods1.array.map { it.toJavaObject() }.toSet()) assertThat(expectedMethods2.toSet()).isEqualTo(resultMethods2.array.map { it.toJavaObject() }.toSet()) From 4c8e96ca7542cfb7c0f657358e35e782e72f3547 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Tue, 13 Oct 2020 20:56:30 +0200 Subject: [PATCH 06/19] Updated XCtestrun tests --- test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 294d886fa5..7ba18f833c 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -207,7 +207,6 @@ class XctestrunTest { assertThat(actualTests).isEqualTo(listOf("EarlGreyExampleSwiftTests/testBasicSelection")) } - // New @Test fun findTestNamesForTestTarget() { assumeFalse(isWindows) @@ -221,13 +220,14 @@ class XctestrunTest { Xctestrun.findTestNames(testTarget = "Incorrect", xctestrun = swiftXctestrun).sorted() } + @Test fun `find test names for xctestrun file containing multiple test targets`() { assumeFalse(isWindows) - val names = Xctestrun.findTestNames(testTarget = "SwiftTests1", xctestrun = multipleTargetsSwiftXctestrun).sorted() - assertThat(names).isEqualTo(listOf("SuiteA/testA1", "SuiteA/testA2", "SuiteB/testB1", "SuiteB/testB2")) + val names = Xctestrun.findTestNames(testTarget = "FlankExampleTests", xctestrun = multipleTargetsSwiftXctestrun).sorted() + assertThat(names).isEqualTo(listOf("FlankExampleTests/test1", "FlankExampleTests/test2")) - val names2 = Xctestrun.findTestNames(testTarget = "SwiftTests2", xctestrun = multipleTargetsSwiftXctestrun).sorted() - assertThat(names2).isEqualTo(listOf("SwiftTests2/tests2_test1", "SwiftTests2/tests2_test2")) + val names2 = Xctestrun.findTestNames(testTarget = "FlankExampleSecondTests", xctestrun = multipleTargetsSwiftXctestrun).sorted() + assertThat(names2).isEqualTo(listOf("FlankExampleSecondTests/test3", "FlankExampleSecondTests/test4")) } @Test From 7866caf94c0d41c8627fc92028b053941e86bf9d Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Wed, 14 Oct 2020 10:54:26 +0200 Subject: [PATCH 07/19] Reverted test changes in Debug.kt --- test_runner/src/test/kotlin/Debug.kt | 11 +++++---- .../test/kotlin/ftl/fixtures/flank2.ios.yml | 23 +------------------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/test_runner/src/test/kotlin/Debug.kt b/test_runner/src/test/kotlin/Debug.kt index 6bfc538043..608364e6bf 100644 --- a/test_runner/src/test/kotlin/Debug.kt +++ b/test_runner/src/test/kotlin/Debug.kt @@ -13,22 +13,23 @@ fun main() { val projectId = System.getenv("GOOGLE_CLOUD_PROJECT") ?: "YOUR PROJECT ID" -// val quantity = "multiple" -// val type = "flaky" + val quantity = "multiple" + val type = "flaky" // Bugsnag keeps the process alive so we must call exitProcess // https://github.com/bugsnag/bugsnag-java/issues/151 withGlobalExceptionHandling { CommandLine(Main()).execute( // "--debug", - "firebase", "test", "ios", + "firebase", + "test", + "android", "run", // "--dry", // "--dump-shards", "--output-style=single", // "--full-junit-result", // "--legacy-junit-result", -// "-c=src/test/kotlin/ftl/fixtures/test_app_cases/flank-$quantity-$type.yml", - "-c=test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml", + "-c=src/test/kotlin/ftl/fixtures/test_app_cases/flank-$quantity-$type.yml", "--project=$projectId" // "--client-details=key1=value1,key2=value2" ) diff --git a/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml b/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml index 6cd58c2ac7..3bb4d7c18f 100644 --- a/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml +++ b/test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml @@ -1,5 +1,5 @@ gcloud: - test: ./zsrc/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip + test: ./src/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip xctestrun-file: ./src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun results-bucket: tmp_bucket_2 record-video: true @@ -18,24 +18,3 @@ flank: - EarlGreyExampleSwiftTests/testWith.*$ test-targets-always-run: - EarlGreyExampleSwiftTests/testWithGreyAssertions - -#gcloud: -# test: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/multiple-test-targets/FlankTests.zip -# xctestrun-file: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/multiple-test-targets/FlankTests_iphoneos14.0-arm64.xctestrun -# # results-bucket: tmp_bucket_2 -# # record-video: true -# # timeout: 60m -# async: false -# device: -# - model: iphone8 -# version: 13.6 -# orientation: portrait -# locale: en_US -# -#flank: -## max-test-shards: 2 -## num-test-runs: 1 -## test-targets: -## - FlankExampleTests/test1 -## test-targets-always-run: -## - EarlGreyExampleSwiftTests/testWithGreyAssertions From aba2a7e57d586004e05df19ca66faf232073528d Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Thu, 15 Oct 2020 12:59:09 +0200 Subject: [PATCH 08/19] New test artifacts for iOS - added new iOS test project - created ops.sh scripts to generate test artifacts from it - adjusted fixture paths inside unit tests --- .gitignore | 1 + .../EarlGreyExample.xcodeproj/project.pbxproj | 16 +- .../EarlGreyExampleSwiftTests/EarlGrey.swift | 2 +- test_projects/ios/EarlGreyExample/ops.sh | 17 +- .../FlankExample.xcodeproj/project.pbxproj | 597 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/FlankExample.xcscheme | 98 +++ .../xcschemes/FlankTests.xcscheme | 102 +++ .../xcschemes/xcschememanagement.plist | 32 + .../FlankExample/AppDelegate.swift | 20 + .../AppIcon.appiconset/Contents.json | 98 +++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../FlankExample/Base.lproj/Main.storyboard | 24 + .../ios/FlankExample/FlankExample/Info.plist | 64 ++ .../FlankExample/SceneDelegate.swift | 53 ++ .../FlankExample/ViewController.swift | 18 + .../FlankExampleSecondTests.swift | 20 + .../FlankExampleSecondTests/Info.plist | 22 + .../FlankExampleTests/FlankExampleTests.swift | 21 + .../FlankExample/FlankExampleTests/Info.plist | 22 + test_projects/ios/FlankExample/ops.sh | 41 ++ test_projects/ops.sh | 2 + .../src/test/kotlin/ftl/ios/XctestrunTest.kt | 6 +- 25 files changed, 1305 insertions(+), 17 deletions(-) create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/project.pbxproj create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankExample.xcscheme create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankTests.xcscheme create mode 100644 test_projects/ios/FlankExample/FlankExample.xcodeproj/xcuserdata/zuziakaxel.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 test_projects/ios/FlankExample/FlankExample/AppDelegate.swift create mode 100644 test_projects/ios/FlankExample/FlankExample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 test_projects/ios/FlankExample/FlankExample/Assets.xcassets/Contents.json create mode 100644 test_projects/ios/FlankExample/FlankExample/Base.lproj/LaunchScreen.storyboard create mode 100644 test_projects/ios/FlankExample/FlankExample/Base.lproj/Main.storyboard create mode 100644 test_projects/ios/FlankExample/FlankExample/Info.plist create mode 100644 test_projects/ios/FlankExample/FlankExample/SceneDelegate.swift create mode 100644 test_projects/ios/FlankExample/FlankExample/ViewController.swift create mode 100644 test_projects/ios/FlankExample/FlankExampleSecondTests/FlankExampleSecondTests.swift create mode 100644 test_projects/ios/FlankExample/FlankExampleSecondTests/Info.plist create mode 100644 test_projects/ios/FlankExample/FlankExampleTests/FlankExampleTests.swift create mode 100644 test_projects/ios/FlankExample/FlankExampleTests/Info.plist create mode 100644 test_projects/ios/FlankExample/ops.sh diff --git a/.gitignore b/.gitignore index 9f2f7d3eb4..ff1ae0cba7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ test_runner/flank/ local.properties /report.json results +xcuserdata/ \ No newline at end of file diff --git a/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj b/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj index 03d7c54fdf..07123bd199 100644 --- a/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj +++ b/test_projects/ios/EarlGreyExample/EarlGreyExample.xcodeproj/project.pbxproj @@ -488,7 +488,7 @@ DEVELOPMENT_TEAM = AD2V26JBWL; ENABLE_TESTABILITY = YES; INFOPLIST_FILE = EarlGreyExampleSwiftTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGreySwiftTests; PRODUCT_MODULE_NAME = EarlGreyExampleTestsSwift; @@ -511,7 +511,7 @@ DEFINES_MODULE = NO; DEVELOPMENT_TEAM = L2UF9MLSM6; INFOPLIST_FILE = EarlGreyExampleSwiftTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGreySwiftTests; PRODUCT_MODULE_NAME = EarlGreyExampleTestsSwift; @@ -559,7 +559,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_MODULE_NAME = EarlGreyExample; @@ -600,7 +600,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_MODULE_NAME = EarlGreyExample; PRODUCT_NAME = EarlGreyExample; @@ -622,7 +622,7 @@ DEVELOPMENT_TEAM = AD2V26JBWL; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; INFOPLIST_FILE = "$(SRCROOT)/EarlGreyExample/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGrey; PRODUCT_MODULE_NAME = EarlGreyExampleSwift; @@ -645,7 +645,7 @@ DEVELOPMENT_TEAM = L2UF9MLSM6; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; INFOPLIST_FILE = "$(SRCROOT)/EarlGreyExample/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGrey; PRODUCT_MODULE_NAME = EarlGreyExampleSwift; @@ -680,7 +680,7 @@ $CONFIGURATION_TEMP_DIR/EarlGreyExampleSwift.build/DerivedSources, ); INFOPLIST_FILE = EarlGreyExample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGreyTests; PRODUCT_MODULE_NAME = EarlGreyExampleTests; @@ -714,7 +714,7 @@ $CONFIGURATION_TEMP_DIR/EarlGreyExampleSwift.build/DerivedSources, ); INFOPLIST_FILE = EarlGreyExample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.earlgrey.samples.EarlGreyTests; PRODUCT_MODULE_NAME = EarlGreyExampleTests; diff --git a/test_projects/ios/EarlGreyExample/EarlGreyExampleSwiftTests/EarlGrey.swift b/test_projects/ios/EarlGreyExample/EarlGreyExampleSwiftTests/EarlGrey.swift index f36384f4ee..b1395c102c 100644 --- a/test_projects/ios/EarlGreyExample/EarlGreyExampleSwiftTests/EarlGrey.swift +++ b/test_projects/ios/EarlGreyExample/EarlGreyExampleSwiftTests/EarlGrey.swift @@ -18,7 +18,7 @@ import EarlGrey import Foundation public func GREYAssert(_ expression: @autoclosure () -> Bool, reason: String) { - GREYAssert(expression, reason, details: "Expected expression to be true") + GREYAssert(expression(), reason, details: "Expected expression to be true") } public func GREYAssertTrue(_ expression: @autoclosure () -> Bool, reason: String) { diff --git a/test_projects/ios/EarlGreyExample/ops.sh b/test_projects/ios/EarlGreyExample/ops.sh index 9e13c035da..9ea3d2d552 100644 --- a/test_projects/ios/EarlGreyExample/ops.sh +++ b/test_projects/ios/EarlGreyExample/ops.sh @@ -52,20 +52,27 @@ function earl_grey_example() { local productsDir="$dir/build/Build/Products" - cp -Rf "$productsDir"/*-iphoneos "$FLANK_FIXTURES_TMP/" + # xcodebuild generates .xctestrun files names in format: PROJECTNAME_platform_version_architecture.xctestrun, code below removes "_platform_version_architecture" part + mv -f "$productsDir/EarlGreyExampleSwiftTests"*.xctestrun "$productsDir/EarlGreyExampleSwiftTests.xctestrun" + mv -f "$productsDir/EarlGreyExampleTests"*.xctestrun "$productsDir/EarlGreyExampleTests.xctestrun" - cp "$productsDir"/*.xctestrun "$FLANK_FIXTURES_TMP/" + mkdir -p "$FLANK_FIXTURES_TMP/ios/earl_grey_example/objc/" + mkdir -p "$FLANK_FIXTURES_TMP/ios/earl_grey_example/swift/" + + cp -Rf "$productsDir"/*-iphoneos "$FLANK_FIXTURES_TMP/ios/earl_grey_example/" + + cp "$productsDir"/*.xctestrun "$FLANK_FIXTURES_TMP/ios/earl_grey_example/" cp \ "$productsDir/Debug-iphoneos/EarlGreyExampleSwift.app/PlugIns/EarlGreyExampleTests.xctest/EarlGreyExampleTests" \ - "$FLANK_FIXTURES_TMP/objc/" + "$FLANK_FIXTURES_TMP/ios/earl_grey_example/objc/" cp \ "$productsDir/Debug-iphoneos/EarlGreyExampleSwift.app/PlugIns/EarlGreyExampleSwiftTests.xctest/EarlGreyExampleSwiftTests" \ - "$FLANK_FIXTURES_TMP/swift/" + "$FLANK_FIXTURES_TMP/ios/earl_grey_example/swift/" ;; esac done } -echo "iOS test projects ops loaded" +echo "iOS EarlGreyExample test projects ops loaded" diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.pbxproj b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..62c3124332 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.pbxproj @@ -0,0 +1,597 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 32230392252739ED0026C392 /* FlankExampleSecondTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32230391252739ED0026C392 /* FlankExampleSecondTests.swift */; }; + 32D8E37125137DA5002EE5D8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D8E37025137DA5002EE5D8 /* AppDelegate.swift */; }; + 32D8E37525137DA5002EE5D8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D8E37425137DA5002EE5D8 /* ViewController.swift */; }; + 32D8E37825137DA5002EE5D8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32D8E37625137DA5002EE5D8 /* Main.storyboard */; }; + 32D8E37A25137DA7002EE5D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32D8E37925137DA7002EE5D8 /* Assets.xcassets */; }; + 32D8E37D25137DA7002EE5D8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32D8E37B25137DA7002EE5D8 /* LaunchScreen.storyboard */; }; + 32D8E38825137DA7002EE5D8 /* FlankExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32D8E38725137DA7002EE5D8 /* FlankExampleTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 32230394252739ED0026C392 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 32D8E36525137DA5002EE5D8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 32D8E36C25137DA5002EE5D8; + remoteInfo = FlankExample; + }; + 32D8E38425137DA7002EE5D8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 32D8E36525137DA5002EE5D8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 32D8E36C25137DA5002EE5D8; + remoteInfo = FlankExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3223038F252739ED0026C392 /* FlankExampleSecondTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlankExampleSecondTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 32230391252739ED0026C392 /* FlankExampleSecondTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlankExampleSecondTests.swift; sourceTree = ""; }; + 32230393252739ED0026C392 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 32D8E36D25137DA5002EE5D8 /* FlankExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FlankExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 32D8E37025137DA5002EE5D8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 32D8E37425137DA5002EE5D8 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 32D8E37725137DA5002EE5D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 32D8E37925137DA7002EE5D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 32D8E37C25137DA7002EE5D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 32D8E37E25137DA7002EE5D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 32D8E38325137DA7002EE5D8 /* FlankExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlankExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 32D8E38725137DA7002EE5D8 /* FlankExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlankExampleTests.swift; sourceTree = ""; }; + 32D8E38925137DA7002EE5D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3223038C252739ED0026C392 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E36A25137DA5002EE5D8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E38025137DA7002EE5D8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 32230390252739ED0026C392 /* FlankExampleSecondTests */ = { + isa = PBXGroup; + children = ( + 32230391252739ED0026C392 /* FlankExampleSecondTests.swift */, + 32230393252739ED0026C392 /* Info.plist */, + ); + path = FlankExampleSecondTests; + sourceTree = ""; + }; + 32D8E36425137DA5002EE5D8 = { + isa = PBXGroup; + children = ( + 32D8E36F25137DA5002EE5D8 /* FlankExample */, + 32D8E38625137DA7002EE5D8 /* FlankExampleTests */, + 32230390252739ED0026C392 /* FlankExampleSecondTests */, + 32D8E36E25137DA5002EE5D8 /* Products */, + ); + sourceTree = ""; + }; + 32D8E36E25137DA5002EE5D8 /* Products */ = { + isa = PBXGroup; + children = ( + 32D8E36D25137DA5002EE5D8 /* FlankExample.app */, + 32D8E38325137DA7002EE5D8 /* FlankExampleTests.xctest */, + 3223038F252739ED0026C392 /* FlankExampleSecondTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 32D8E36F25137DA5002EE5D8 /* FlankExample */ = { + isa = PBXGroup; + children = ( + 32D8E37025137DA5002EE5D8 /* AppDelegate.swift */, + 32D8E37425137DA5002EE5D8 /* ViewController.swift */, + 32D8E37625137DA5002EE5D8 /* Main.storyboard */, + 32D8E37925137DA7002EE5D8 /* Assets.xcassets */, + 32D8E37B25137DA7002EE5D8 /* LaunchScreen.storyboard */, + 32D8E37E25137DA7002EE5D8 /* Info.plist */, + ); + path = FlankExample; + sourceTree = ""; + }; + 32D8E38625137DA7002EE5D8 /* FlankExampleTests */ = { + isa = PBXGroup; + children = ( + 32D8E38725137DA7002EE5D8 /* FlankExampleTests.swift */, + 32D8E38925137DA7002EE5D8 /* Info.plist */, + ); + path = FlankExampleTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 3223038E252739ED0026C392 /* FlankExampleSecondTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32230398252739ED0026C392 /* Build configuration list for PBXNativeTarget "FlankExampleSecondTests" */; + buildPhases = ( + 3223038B252739ED0026C392 /* Sources */, + 3223038C252739ED0026C392 /* Frameworks */, + 3223038D252739ED0026C392 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 32230395252739ED0026C392 /* PBXTargetDependency */, + ); + name = FlankExampleSecondTests; + productName = FlankExampleSecondTests; + productReference = 3223038F252739ED0026C392 /* FlankExampleSecondTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 32D8E36C25137DA5002EE5D8 /* FlankExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32D8E38C25137DA7002EE5D8 /* Build configuration list for PBXNativeTarget "FlankExample" */; + buildPhases = ( + 32D8E36925137DA5002EE5D8 /* Sources */, + 32D8E36A25137DA5002EE5D8 /* Frameworks */, + 32D8E36B25137DA5002EE5D8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FlankExample; + productName = FlankExample; + productReference = 32D8E36D25137DA5002EE5D8 /* FlankExample.app */; + productType = "com.apple.product-type.application"; + }; + 32D8E38225137DA7002EE5D8 /* FlankExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32D8E38F25137DA7002EE5D8 /* Build configuration list for PBXNativeTarget "FlankExampleTests" */; + buildPhases = ( + 32D8E37F25137DA7002EE5D8 /* Sources */, + 32D8E38025137DA7002EE5D8 /* Frameworks */, + 32D8E38125137DA7002EE5D8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 32D8E38525137DA7002EE5D8 /* PBXTargetDependency */, + ); + name = FlankExampleTests; + productName = FlankExampleTests; + productReference = 32D8E38325137DA7002EE5D8 /* FlankExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 32D8E36525137DA5002EE5D8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1200; + LastUpgradeCheck = 1170; + ORGANIZATIONNAME = gogoapps; + TargetAttributes = { + 3223038E252739ED0026C392 = { + CreatedOnToolsVersion = 12.0.1; + TestTargetID = 32D8E36C25137DA5002EE5D8; + }; + 32D8E36C25137DA5002EE5D8 = { + CreatedOnToolsVersion = 11.7; + }; + 32D8E38225137DA7002EE5D8 = { + CreatedOnToolsVersion = 11.7; + TestTargetID = 32D8E36C25137DA5002EE5D8; + }; + }; + }; + buildConfigurationList = 32D8E36825137DA5002EE5D8 /* Build configuration list for PBXProject "FlankExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 32D8E36425137DA5002EE5D8; + productRefGroup = 32D8E36E25137DA5002EE5D8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 32D8E36C25137DA5002EE5D8 /* FlankExample */, + 32D8E38225137DA7002EE5D8 /* FlankExampleTests */, + 3223038E252739ED0026C392 /* FlankExampleSecondTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3223038D252739ED0026C392 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E36B25137DA5002EE5D8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32D8E37D25137DA7002EE5D8 /* LaunchScreen.storyboard in Resources */, + 32D8E37A25137DA7002EE5D8 /* Assets.xcassets in Resources */, + 32D8E37825137DA5002EE5D8 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E38125137DA7002EE5D8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3223038B252739ED0026C392 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32230392252739ED0026C392 /* FlankExampleSecondTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E36925137DA5002EE5D8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32D8E37525137DA5002EE5D8 /* ViewController.swift in Sources */, + 32D8E37125137DA5002EE5D8 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32D8E37F25137DA7002EE5D8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32D8E38825137DA7002EE5D8 /* FlankExampleTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 32230395252739ED0026C392 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 32D8E36C25137DA5002EE5D8 /* FlankExample */; + targetProxy = 32230394252739ED0026C392 /* PBXContainerItemProxy */; + }; + 32D8E38525137DA7002EE5D8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 32D8E36C25137DA5002EE5D8 /* FlankExample */; + targetProxy = 32D8E38425137DA7002EE5D8 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 32D8E37625137DA5002EE5D8 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 32D8E37725137DA5002EE5D8 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 32D8E37B25137DA7002EE5D8 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 32D8E37C25137DA7002EE5D8 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 32230396252739ED0026C392 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExampleSecondTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExampleSecondTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FlankExample.app/FlankExample"; + }; + name = Debug; + }; + 32230397252739ED0026C392 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExampleSecondTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExampleSecondTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FlankExample.app/FlankExample"; + }; + name = Release; + }; + 32D8E38A25137DA7002EE5D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 32D8E38B25137DA7002EE5D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 32D8E38D25137DA7002EE5D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 32D8E38E25137DA7002EE5D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 32D8E39025137DA7002EE5D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FlankExample.app/FlankExample"; + }; + name = Debug; + }; + 32D8E39125137DA7002EE5D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = L2UF9MLSM6; + INFOPLIST_FILE = FlankExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.gogoapps.FlankExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FlankExample.app/FlankExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 32230398252739ED0026C392 /* Build configuration list for PBXNativeTarget "FlankExampleSecondTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32230396252739ED0026C392 /* Debug */, + 32230397252739ED0026C392 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32D8E36825137DA5002EE5D8 /* Build configuration list for PBXProject "FlankExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32D8E38A25137DA7002EE5D8 /* Debug */, + 32D8E38B25137DA7002EE5D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32D8E38C25137DA7002EE5D8 /* Build configuration list for PBXNativeTarget "FlankExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32D8E38D25137DA7002EE5D8 /* Debug */, + 32D8E38E25137DA7002EE5D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32D8E38F25137DA7002EE5D8 /* Build configuration list for PBXNativeTarget "FlankExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32D8E39025137DA7002EE5D8 /* Debug */, + 32D8E39125137DA7002EE5D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 32D8E36525137DA5002EE5D8 /* Project object */; +} diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..25c7096c71 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankExample.xcscheme b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankExample.xcscheme new file mode 100644 index 0000000000..fa89988d0e --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankExample.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankTests.xcscheme b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankTests.xcscheme new file mode 100644 index 0000000000..44df300958 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcshareddata/xcschemes/FlankTests.xcscheme @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcuserdata/zuziakaxel.xcuserdatad/xcschemes/xcschememanagement.plist b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcuserdata/zuziakaxel.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000000..1f27b1f23d --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample.xcodeproj/xcuserdata/zuziakaxel.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + FlankExample.xcscheme_^#shared#^_ + + orderHint + 0 + + FlankTests.xcscheme_^#shared#^_ + + orderHint + 1 + + + SuppressBuildableAutocreation + + 32D8E36C25137DA5002EE5D8 + + primary + + + 32D8E38225137DA7002EE5D8 + + primary + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample/AppDelegate.swift b/test_projects/ios/FlankExample/FlankExample/AppDelegate.swift new file mode 100644 index 0000000000..e169808b94 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/AppDelegate.swift @@ -0,0 +1,20 @@ +// +// AppDelegate.swift +// FlankExample +// +// Created by Axel Zuziak on 17/09/2020. +// Copyright © 2020 gogoapps. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } +} + diff --git a/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..9221b9bb1a --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/Contents.json b/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/test_projects/ios/FlankExample/FlankExample/Base.lproj/LaunchScreen.storyboard b/test_projects/ios/FlankExample/FlankExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..865e9329f3 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample/Base.lproj/Main.storyboard b/test_projects/ios/FlankExample/FlankExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..25a763858e --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_projects/ios/FlankExample/FlankExample/Info.plist b/test_projects/ios/FlankExample/FlankExample/Info.plist new file mode 100644 index 0000000000..2a3483c0d2 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/test_projects/ios/FlankExample/FlankExample/SceneDelegate.swift b/test_projects/ios/FlankExample/FlankExample/SceneDelegate.swift new file mode 100644 index 0000000000..775305a276 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/SceneDelegate.swift @@ -0,0 +1,53 @@ +// +// SceneDelegate.swift +// FlankExample +// +// Created by Axel Zuziak on 17/09/2020. +// Copyright © 2020 gogoapps. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/test_projects/ios/FlankExample/FlankExample/ViewController.swift b/test_projects/ios/FlankExample/FlankExample/ViewController.swift new file mode 100644 index 0000000000..46087b0f6b --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExample/ViewController.swift @@ -0,0 +1,18 @@ +// +// ViewController.swift +// FlankExample +// +// Created by Axel Zuziak on 17/09/2020. +// Copyright © 2020 gogoapps. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } +} + diff --git a/test_projects/ios/FlankExample/FlankExampleSecondTests/FlankExampleSecondTests.swift b/test_projects/ios/FlankExample/FlankExampleSecondTests/FlankExampleSecondTests.swift new file mode 100644 index 0000000000..46ba025b9a --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExampleSecondTests/FlankExampleSecondTests.swift @@ -0,0 +1,20 @@ +// +// FlankExampleSecondTests.swift +// FlankExampleSecondTests +// +// Created by Axel Zuziak on 02/10/2020. +// Copyright © 2020 gogoapps. All rights reserved. +// + +import XCTest + +class FlankExampleSecondTests: XCTestCase { + + func test3() { + XCTAssertEqual("", "") + } + + func test4() { + XCTAssertEqual("", "") + } +} diff --git a/test_projects/ios/FlankExample/FlankExampleSecondTests/Info.plist b/test_projects/ios/FlankExample/FlankExampleSecondTests/Info.plist new file mode 100644 index 0000000000..64d65ca495 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExampleSecondTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/test_projects/ios/FlankExample/FlankExampleTests/FlankExampleTests.swift b/test_projects/ios/FlankExample/FlankExampleTests/FlankExampleTests.swift new file mode 100644 index 0000000000..f0ec3dc6f2 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExampleTests/FlankExampleTests.swift @@ -0,0 +1,21 @@ +// +// FlankExampleTests.swift +// FlankExampleTests +// +// Created by Axel Zuziak on 17/09/2020. +// Copyright © 2020 gogoapps. All rights reserved. +// + +import XCTest +@testable import FlankExample + +class FlankExampleTests: XCTestCase { + + func test1() { + XCTAssertEqual("", "") + } + + func test2() { + XCTAssertEqual("", "") + } +} diff --git a/test_projects/ios/FlankExample/FlankExampleTests/Info.plist b/test_projects/ios/FlankExample/FlankExampleTests/Info.plist new file mode 100644 index 0000000000..64d65ca495 --- /dev/null +++ b/test_projects/ios/FlankExample/FlankExampleTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/test_projects/ios/FlankExample/ops.sh b/test_projects/ios/FlankExample/ops.sh new file mode 100644 index 0000000000..efdd90998f --- /dev/null +++ b/test_projects/ios/FlankExample/ops.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +FLANK_IOS_EXAMPLE="$TEST_PROJECTS_IOS/FlankExample" + +function flank_ios_example() { + local dir=$FLANK_IOS_EXAMPLE + local buildDir="$dir/build" + + for arg in "$@"; do case "$arg" in + + '--generate' | '-g') + + rm -rf "$buildDir" + + xcodebuild build-for-testing \ + -allowProvisioningUpdates \ + -project "$dir/FlankExample.xcodeproj" \ + -scheme "FlankTests" \ + -derivedDataPath "$buildDir" \ + -sdk iphoneos | + xcpretty + ;; + + '--copy' | '-c') + + local productsDir="$dir/build/Build/Products" + + # xcodebuild generates .xctestrun files names in format: PROJECTNAME_platform_version_architecture.xctestrun, code below removes "_platform_version_architecture" part + mv -f "$productsDir/"*.xctestrun "$productsDir/FlankExampleTests.xctestrun" + + mkdir -p "$FLANK_FIXTURES_TMP/ios/flank_ios_example/" + + cp -Rf "$productsDir"/*-iphoneos "$FLANK_FIXTURES_TMP/ios/flank_ios_example/" + + cp "$productsDir"/*.xctestrun "$FLANK_FIXTURES_TMP/ios/flank_ios_example/" + ;; + + esac done +} + +echo "iOS Flank Example test projects ops loaded" diff --git a/test_projects/ops.sh b/test_projects/ops.sh index 2aaf4a4c36..9a1e7914e0 100755 --- a/test_projects/ops.sh +++ b/test_projects/ops.sh @@ -5,6 +5,7 @@ TEST_PROJECTS_IOS="$TEST_PROJECTS/ios" . "$TEST_PROJECTS_ANDROID/ops.sh" . "$TEST_PROJECTS_IOS/EarlGreyExample/ops.sh" +. "$TEST_PROJECTS_IOS/FlankExample/ops.sh" function update_test_artifacts() { @@ -18,6 +19,7 @@ function update_test_artifacts() { ios) setup_ios_env earl_grey_example --generate --copy + flank_ios_example --generate --copy ;; go) diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 7ba18f833c..316c982b7d 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -16,8 +16,8 @@ import java.nio.file.Paths @RunWith(FlankTestRunner::class) class XctestrunTest { - private val swiftXctestrun = "$FIXTURES_PATH/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun" - private val multipleTargetsSwiftXctestrun = "$FIXTURES_PATH/axel/FlankTests_iphoneos14.0-arm64.xctestrun" + private val swiftXctestrun = "$FIXTURES_PATH/ios/earl_grey_example/EarlGreyExampleSwiftTests.xctestrun" + private val multipleTargetsSwiftXctestrun = "$FIXTURES_PATH/ios/flank_ios_example/FlankExampleTests.xctestrun" private val swiftTests = listOf( "EarlGreyExampleSwiftTests/testBasicSelection", @@ -44,7 +44,7 @@ class XctestrunTest { val result = Xctestrun.parse(swiftXctestrun) assertThat(arrayOf("EarlGreyExampleSwiftTests", "__xctestrun_metadata__")).isEqualTo(result.allKeys()) val dict = result["EarlGreyExampleSwiftTests"] as NSDictionary - assertThat(dict.count()).isEqualTo(19) + assertThat(dict.count()).isEqualTo(20) assertThat(dict.containsKey("OnlyTestIdentifiers")).isFalse() } From 3e6ff9391cbbea8653c3a145917812d805686ae5 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Thu, 15 Oct 2020 13:38:37 +0200 Subject: [PATCH 09/19] Undo changes in build.gradle.kts --- test_runner/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_runner/build.gradle.kts b/test_runner/build.gradle.kts index 0b3b8a0c3f..c01932edd4 100644 --- a/test_runner/build.gradle.kts +++ b/test_runner/build.gradle.kts @@ -139,7 +139,7 @@ detekt { input = files("src/main/kotlin", "src/test/kotlin") config = files("../config/detekt.yml") parallel = true - failFast = false // fail build on any finding + failFast = true // fail build on any finding autoCorrect = true reports { From 35878a50ad5de0b825377179df6dbbe6121b1e67 Mon Sep 17 00:00:00 2001 From: Axel Zuziak <31246956+axelzuziak-gogo@users.noreply.github.com> Date: Fri, 16 Oct 2020 13:15:59 +0200 Subject: [PATCH 10/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `findTestNamesForTarget` method Co-authored-by: Jan Góral <60390247+jan-gogo@users.noreply.github.com> --- .../src/main/kotlin/ftl/ios/Xctestrun.kt | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 80d0024d2d..4b42d163e7 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -100,21 +100,17 @@ object Xctestrun { } /* Finds tests for testTarget in xctestrun file */ - private fun findTestNamesForTarget(testTarget: String, xctestrun: File): List { - val rootDictionary = parse(xctestrun) - val testRoot = xctestrun.parent + "/" - - if (!rootDictionary.containsKey(testTarget)) { - throw FlankGeneralError("XCTestrun does not contain $testTarget test target.") - } - val testDictionary = (rootDictionary[testTarget] as NSDictionary) - - return testsForTarget( - testDictionary = testDictionary, - testRoot = testRoot, + private fun findTestNamesForTarget( + testTarget: String, + xctestrun: File + ): List = + testsForTarget( + testDictionary = parse(xctestrun)[testTarget] + as? NSDictionary + ?: throw FlankGeneralError("XCTestrun does not contain $testTarget test target."), + testRoot = xctestrun.parent + "/", testTarget = testTarget ).distinct() - } fun rewrite(xctestrun: String, methods: List): ByteArray { val xctestrunFile = File(xctestrun) From b406ba21994e9f848f40cf5ced2d92184be4e2cc Mon Sep 17 00:00:00 2001 From: Axel Zuziak <31246956+axelzuziak-gogo@users.noreply.github.com> Date: Fri, 16 Oct 2020 13:17:50 +0200 Subject: [PATCH 11/19] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Small XCTestRun's methods refactor Co-authored-by: Jan Góral <60390247+jan-gogo@users.noreply.github.com> --- test_runner/src/main/kotlin/ftl/args/IosArgs.kt | 11 +++++------ test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 5 ++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index f406c42e61..c707223164 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -80,18 +80,17 @@ private fun IosArgs.calculateShardChunks() = if (disableSharding) @VisibleForTesting internal fun filterTests( validTestMethods: XctestrunMethods, - testTargetsRgx: List + testTargetsRgx: List ): XctestrunMethods = if (testTargetsRgx.isEmpty()) validTestMethods - else validTestMethods.mapValues { - it.value.filter { test -> - testTargetsRgx.filterNotNull().forEach { target -> + else validTestMethods.mapValues { (_, tests) -> + tests.filter { test -> + testTargetsRgx.any { target -> try { - if (test.matches(target.toRegex())) return@filter true + test.matches(target.toRegex()) } catch (e: Exception) { throw FlankConfigurationError("Invalid regex: $target", e) } } - false } } diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 4b42d163e7..a3bd7e5cf9 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -83,12 +83,11 @@ object Xctestrun { return findTestNames(File(xctestrun)) } - fun findTestNames(testTarget: String, xctestrun: String): List { - return findTestNamesForTarget( + fun findTestNames(testTarget: String, xctestrun: String): List = + findTestNamesForTarget( testTarget = testTarget, xctestrun = File(xctestrun) ) - } /* Finds tests in a xctestrun file */ private fun findTestNames(xctestrun: File): XctestrunMethods = From 69c4a0eb5be5d9a145acaba83d148bbbf3b474c9 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Mon, 19 Oct 2020 10:04:55 +0200 Subject: [PATCH 12/19] Fixed code formatting to pass :detekt --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index a3bd7e5cf9..6884052f41 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -100,8 +100,8 @@ object Xctestrun { /* Finds tests for testTarget in xctestrun file */ private fun findTestNamesForTarget( - testTarget: String, - xctestrun: File + testTarget: String, + xctestrun: File ): List = testsForTarget( testDictionary = parse(xctestrun)[testTarget] From d8075f2f3fcc4cc4cd7eab064293601cb62d11b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Mon, 19 Oct 2020 12:52:36 +0200 Subject: [PATCH 13/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt Co-authored-by: pawelpasterz <32893017+pawelpasterz@users.noreply.github.com> --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 6884052f41..7db8441440 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -13,7 +13,7 @@ import java.nio.file.Paths /* { "TestTarget": ["method1", "method2"], - "TestTarget2: ["method3", "method4"] + "TestTarget2": ["method3", "method4"] } */ typealias XctestrunMethods = Map> From f669dea60be8286c07bbda87f2ef627ca527ea43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Mon, 19 Oct 2020 12:54:24 +0200 Subject: [PATCH 14/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index 7db8441440..cfb6e71e98 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -113,7 +113,7 @@ object Xctestrun { fun rewrite(xctestrun: String, methods: List): ByteArray { val xctestrunFile = File(xctestrun) - val methodsToRun = findTestNames(xctestrunFile).mapValues { it.value.filter { methods.contains(it) } } + val methodsToRun = findTestNames(xctestrunFile).mapValues { (_, list) -> list.filter(methods::contains) } return rewrite(parse(xctestrunFile), methodsToRun) } From 990864b1f793d9479b7b7b834f1bf36ddd9ba1b0 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Mon, 19 Oct 2020 17:45:22 +0200 Subject: [PATCH 15/19] Update test_runner/src/main/kotlin/ftl/args/IosArgs.kt - refactored filterTests method --- .../src/main/kotlin/ftl/args/IosArgs.kt | 23 +++++++++++-------- .../src/test/kotlin/ftl/args/IosArgsTest.kt | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt index c707223164..c921f2d517 100644 --- a/test_runner/src/main/kotlin/ftl/args/IosArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/IosArgs.kt @@ -6,6 +6,7 @@ import ftl.ios.XctestrunMethods import ftl.run.exception.FlankConfigurationError import ftl.shard.Chunk import ftl.util.FlankTestMethod +import java.lang.Exception data class IosArgs( val commonArgs: CommonArgs, @@ -80,17 +81,19 @@ private fun IosArgs.calculateShardChunks() = if (disableSharding) @VisibleForTesting internal fun filterTests( validTestMethods: XctestrunMethods, - testTargetsRgx: List + testTargets: List ): XctestrunMethods = - if (testTargetsRgx.isEmpty()) validTestMethods - else validTestMethods.mapValues { (_, tests) -> - tests.filter { test -> - testTargetsRgx.any { target -> - try { - test.matches(target.toRegex()) - } catch (e: Exception) { - throw FlankConfigurationError("Invalid regex: $target", e) - } + if (testTargets.isEmpty()) validTestMethods + else testTargets.map { testTarget -> + try { + testTarget.toRegex() + } catch (e: Exception) { + throw FlankConfigurationError("Invalid regex: $testTarget", e) + } + }.let { testTargetRgx -> + validTestMethods.mapValues { (_, tests) -> + tests.filter { test -> + testTargetRgx.any { regex -> test.matches(regex) } } } } diff --git a/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt b/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt index 0c0d11b543..fd93cce18b 100644 --- a/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt @@ -868,7 +868,7 @@ IosArgs @Test(expected = FlankConfigurationError::class) fun `invalid regex filter throws custom exception`() { val validTestMethods = mapOf("SampleXCTest" to listOf("test")) - filterTests(validTestMethods, testTargetsRgx = listOf("*.")) + filterTests(validTestMethods, testTargets = listOf("*.")) } @Test From 7a2d75b6d200388a08afe0ce90418df2bea1e274 Mon Sep 17 00:00:00 2001 From: Axel Zuziak Date: Mon, 19 Oct 2020 17:48:29 +0200 Subject: [PATCH 16/19] Fixed incorrect test artifacts path in ParseTest.kt --- test_runner/src/test/kotlin/ftl/ios/ParseTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt b/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt index f60288d62b..dec00410ff 100644 --- a/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/ParseTest.kt @@ -11,8 +11,8 @@ import org.junit.runner.RunWith @RunWith(FlankTestRunner::class) class ParseTest { - private val objcBinary = "$FIXTURES_PATH/objc/EarlGreyExampleTests" - private val swiftBinary = "$FIXTURES_PATH/swift/EarlGreyExampleSwiftTests" + private val objcBinary = "$FIXTURES_PATH/ios/earl_grey_example/objc/EarlGreyExampleTests" + private val swiftBinary = "$FIXTURES_PATH/ios/earl_grey_example/swift/EarlGreyExampleSwiftTests" private val objcTests = listOf( "EarlGreyExampleTests/testBasicSelection", From a52cc3dcaddd73f532299f910ceac3020ff798a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Fri, 23 Oct 2020 10:20:54 +0200 Subject: [PATCH 17/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index cfb6e71e98..ba235f193b 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -10,12 +10,6 @@ import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Paths -/* -{ - "TestTarget": ["method1", "method2"], - "TestTarget2": ["method3", "method4"] -} -*/ typealias XctestrunMethods = Map> object Xctestrun { From d211a21a930a19063f226dac328cfe501eb78f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Fri, 23 Oct 2020 10:21:04 +0200 Subject: [PATCH 18/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index ba235f193b..e06dbdcfc2 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -83,7 +83,6 @@ object Xctestrun { xctestrun = File(xctestrun) ) - /* Finds tests in a xctestrun file */ private fun findTestNames(xctestrun: File): XctestrunMethods = parse(xctestrun).allKeys().associate { testTarget -> testTarget to findTestNamesForTarget( From 0f4021ad9dc572f2fc17dde4a794bfa4ea57fea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Fri, 23 Oct 2020 10:21:20 +0200 Subject: [PATCH 19/19] Update test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt --- test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt index e06dbdcfc2..52e6e29869 100644 --- a/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt +++ b/test_runner/src/main/kotlin/ftl/ios/Xctestrun.kt @@ -91,7 +91,6 @@ object Xctestrun { ) } - /* Finds tests for testTarget in xctestrun file */ private fun findTestNamesForTarget( testTarget: String, xctestrun: File