Decoupled the Buttons specific logic from TulsiEndToEndTest. TulsiEndToEndTest is now just a parent class for other Tulsi end to end tests. Moved the Buttons test cases into a separate dedicated subclass.
PiperOrigin-RevId: 217768811
diff --git a/src/TulsiEndToEndTests/BUILD b/src/TulsiEndToEndTests/BUILD
index 7040e0c..08ea711 100644
--- a/src/TulsiEndToEndTests/BUILD
+++ b/src/TulsiEndToEndTests/BUILD
@@ -1,18 +1,36 @@
licenses(["notice"]) # Apache 2.0
+load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
load("//src/TulsiGeneratorIntegrationTests:tulsi_integration_test.bzl", "tulsi_integration_test")
test_suite(
name = "TulsiEndToEndTests",
)
+swift_library(
+ name = "TulsiEndToEndTestBase",
+ srcs = [
+ "TulsiEndToEndTest.swift",
+ ],
+ module_name = "TulsiEndToEndTestBase",
+ deps = [
+ "//src/TulsiGenerator:tulsi_generator_lib",
+ "//src/TulsiGeneratorIntegrationTests:BazelIntegrationTestCase",
+ ],
+)
+
tulsi_integration_test(
name = "TulsiEndToEndTest",
size = "large",
- srcs = ["TulsiEndToEndTest.swift"],
+ srcs = [
+ "ButtonsEndToEndTest.swift",
+ ],
data = [
"Resources/Buttons.tulsiproj",
"//:tulsi.zip",
"@build_bazel_rules_apple//examples/multi_platform/Buttons:all_files",
],
+ deps = [
+ ":TulsiEndToEndTestBase",
+ ],
)
diff --git a/src/TulsiEndToEndTests/ButtonsEndToEndTest.swift b/src/TulsiEndToEndTests/ButtonsEndToEndTest.swift
new file mode 100644
index 0000000..d226679
--- /dev/null
+++ b/src/TulsiEndToEndTests/ButtonsEndToEndTest.swift
@@ -0,0 +1,61 @@
+
+// Copyright 2016 The Tulsi Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import XCTest
+@testable import BazelIntegrationTestCase
+@testable import TulsiEndToEndTestBase
+
+
+// End to end test that generates the Buttons project and runs its unit tests.
+class ButtonsEndToEndTest: TulsiEndToEndTest {
+ override func setUp() {
+ super.setUp()
+
+ if (!copyDataToFakeWorkspace("build_bazel_rules_apple/examples/multi_platform/Buttons")) {
+ XCTFail("Failed to copy Buttons files to fake execroot.")
+ }
+
+ if (!copyDataToFakeWorkspace("src/TulsiEndToEndTests/Resources")) {
+ XCTFail("Failed to copy Buttons tulsiproj to fake execroot.")
+ }
+ }
+
+ func testButtons() throws {
+ let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
+ let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
+ config: "Buttons")
+ XCTAssert(fileManager.fileExists(atPath: xcodeProjectURL.path), "Xcode project was not generated.")
+ testXcodeProject(xcodeProjectURL, scheme: "ButtonsTests")
+ }
+
+ func testButtonsWithCanaryBazel() throws {
+ if let canaryBazelURL = fakeBazelWorkspace.canaryBazelURL {
+ XCTAssert(fileManager.fileExists(atPath: canaryBazelURL.path), "Bazel canary is missing.")
+ bazelURL = canaryBazelURL
+ let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
+ let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
+ config: "Buttons")
+ testXcodeProject(xcodeProjectURL, scheme: "ButtonsLogicTests")
+ }
+ }
+
+ func testInvalidConfig() throws {
+ let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
+ let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
+ config: "InvalidConfig")
+ XCTAssertFalse(fileManager.fileExists(atPath: xcodeProjectURL.path), "Xcode project was generated despite invalid config.")
+ }
+}
+
diff --git a/src/TulsiEndToEndTests/TulsiEndToEndTest.swift b/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
index f8606ff..5a70346 100644
--- a/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
+++ b/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
@@ -18,40 +18,17 @@
@testable import TulsiGenerator
-// End to end tests that generate an xcodeproj with the Tulsi binary and runs tests on the xcodeproj
-// to verify it was generated correctly.
+// Parent class for end to end tests that generate an xcodeproj with the Tulsi binary and verify the
+// generated xcodeproj by running the projects unit tests.
class TulsiEndToEndTest: BazelIntegrationTestCase {
let fileManager = FileManager.default
+ var runfilesWorkspaceURL: URL! = nil
override func setUp() {
super.setUp()
-
- let runfilesWorkspaceURL = fakeBazelWorkspace.runfilesWorkspaceURL
-
- // Takes a short path to data files and adds them to the correct location in the workspace.
- func copyDataToFakeWorkspace(_ path: String) -> Bool {
- let sourceURL = runfilesWorkspaceURL.appendingPathComponent(path, isDirectory: true)
- let destURL = workspaceRootURL.appendingPathComponent(path, isDirectory: true)
- do {
- if fileManager.fileExists(atPath: destURL.path) {
- try fileManager.removeItem(at: destURL)
- }
- // Symlinks cause issues with Tulsi and Storyboards so must deep copy any data files.
- try fileManager.deepCopyItem(at: sourceURL, to: destURL)
- return true
- } catch let e as NSError {
- print(e.localizedDescription)
- return false
- }
- }
-
- if (!copyDataToFakeWorkspace("build_bazel_rules_apple/examples/multi_platform/Buttons")) {
- XCTFail("Failed to copy Buttons files to fake execroot.")
- }
-
- if (!copyDataToFakeWorkspace("src/TulsiEndToEndTests/Resources")) {
- XCTFail("Failed to copy Buttons tulsiproj to fake execroot.")
- }
+ super.continueAfterFailure = false
+ runfilesWorkspaceURL = fakeBazelWorkspace.runfilesWorkspaceURL
+ XCTAssertNotNil(runfilesWorkspaceURL, "runfilesWorkspaceURL must be not be nil after setup.")
// Unzip the Tulsi.app bundle to the temp space.
let semaphore = DispatchSemaphore(value: 0)
@@ -71,6 +48,28 @@
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
}
+ // Takes a short path to data files and adds them to the fake Bazel workspace.
+ func copyDataToFakeWorkspace(_ path: String) -> Bool {
+ let sourceURL = runfilesWorkspaceURL.appendingPathComponent(path, isDirectory: false)
+ let destURL = workspaceRootURL.appendingPathComponent(path, isDirectory: false)
+ do {
+ if(!fileManager.fileExists(atPath: sourceURL.path)) {
+ XCTFail("Source file \(sourceURL.path) does not exist.")
+ }
+ if fileManager.fileExists(atPath: destURL.path) {
+ try fileManager.removeItem(at: destURL)
+ }
+
+ // Symlinks cause issues with Tulsi and Storyboards so must deep copy any data files.
+ try fileManager.deepCopyItem(at: sourceURL, to: destURL)
+ return true
+ } catch let e as NSError {
+ print(e.localizedDescription)
+ return false
+ }
+ }
+
+ // Runs the Tulsi binary with the given Tulsi project and config to generate an Xcode project.
func generateXcodeProject(tulsiProject path: String, config: String) -> URL{
let tulsiBinURL = workspaceRootURL.appendingPathComponent("Tulsi.app/Contents/MacOS/Tulsi", isDirectory: false)
XCTAssert(fileManager.fileExists(atPath: tulsiBinURL.path), "Tulsi binary is missing.")
@@ -105,6 +104,7 @@
let filename = TulsiGeneratorConfig.sanitizeFilename("\(config).xcodeproj")
let xcodeProjectURL = workspaceRootURL.appendingPathComponent(filename, isDirectory: true)
+ // Remove Xcode project after each test method.
addTeardownBlock {
do {
if self.fileManager.fileExists(atPath: xcodeProjectURL.path) {
@@ -119,8 +119,8 @@
return xcodeProjectURL
}
+ // Runs Xcode tests on the given Xcode project and scheme.
func testXcodeProject(_ xcodeProjectURL: URL, scheme: String) {
- // Run Xcode tests.
let semaphore = DispatchSemaphore(value: 0)
let xcodeTest = TulsiProcessRunner.createProcess("/usr/bin/xcodebuild",
arguments: ["test",
@@ -144,32 +144,6 @@
xcodeTest.launch()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
}
-
- func testButtons() throws {
- let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
- let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
- config: "Buttons")
- XCTAssert(fileManager.fileExists(atPath: xcodeProjectURL.path), "Xcode project was not generated.")
- testXcodeProject(xcodeProjectURL, scheme: "ButtonsTests")
- }
-
- func testButtonsWithCanaryBazel() throws {
- if let canaryBazelURL = fakeBazelWorkspace.canaryBazelURL {
- XCTAssert(fileManager.fileExists(atPath: canaryBazelURL.path), "Bazel canary is missing.")
- bazelURL = canaryBazelURL
- let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
- let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
- config: "Buttons")
- testXcodeProject(xcodeProjectURL, scheme: "ButtonsLogicTests")
- }
- }
-
- func testInvalidConfig() throws {
- let buttonsProjectPath = "src/TulsiEndToEndTests/Resources/Buttons.tulsiproj"
- let xcodeProjectURL = generateXcodeProject(tulsiProject: buttonsProjectPath,
- config: "InvalidConfig")
- XCTAssertFalse(fileManager.fileExists(atPath: xcodeProjectURL.path), "Xcode project was generated despite invalid config.")
- }
}
extension FileManager {
@@ -177,7 +151,15 @@
func deepCopyItem(at sourceURL: URL, to destURL: URL) throws {
do {
try self.createDirectory(atPath: destURL.deletingLastPathComponent().path, withIntermediateDirectories: true)
- try self.copyItem(at: sourceURL, to: destURL)
+ let rootPath = sourceURL.path
+ if let rootAttributes = try? self.attributesOfItem(atPath: rootPath) {
+ if rootAttributes[FileAttributeKey.type] as? FileAttributeType == FileAttributeType.typeSymbolicLink {
+ let resolvedRootPath = try self.destinationOfSymbolicLink(atPath: rootPath)
+ try self.copyItem(atPath: resolvedRootPath, toPath: destURL.path)
+ } else {
+ try self.copyItem(at: sourceURL, to: destURL)
+ }
+ }
let path = destURL.path
if let paths = self.subpaths(atPath: path) {