diff --git a/.swift-version b/.swift-version index 9f55b2cc..a3ec5a4b 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.0 +3.2 diff --git a/.travis.yml b/.travis.yml index 4eb5a5ab..c228b128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,14 @@ branches: only: - master - travis + - swift-3 language: objective-c os: osx -osx_image: xcode8.3 +osx_image: xcode9.1 env: - scheme='Siesta macOS' platform='OS X' + - scheme='Siesta iOS' platform='iOS Simulator' ios_version='11.1' ios_device='iPhone X' - scheme='Siesta iOS' platform='iOS Simulator' ios_version='10.3.1' ios_device='iPhone SE' - scheme='Siesta iOS' platform='iOS Simulator' ios_version='9.3' ios_device='iPhone 6' - scheme='Siesta iOS' platform='iOS Simulator' ios_version='8.1' ios_device='iPhone 4s' @@ -62,7 +64,7 @@ script: | # Optional pre-download, because builds are so slow on Travis, and Carthage builds _everything_: echo "Downloading prebuilt dependencies" - curl https://innig.net/tmp/siesta-deps-swift3.tar.bz2 | bzcat | tar xv + curl https://innig.net/tmp/siesta-deps-swift-3.tar.bz2 | bzcat | tar xv # Uncomment to build with Carthage instead: #echo "Building dependencies" diff --git a/Cartfile.resolved b/Cartfile.resolved index d30829e3..2ee56558 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,4 +1,4 @@ -github "Alamofire/Alamofire" "4.4.0" -github "Quick/Nimble" "v6.1.0" +github "Alamofire/Alamofire" "4.5.1" +github "Quick/Nimble" "v7.0.2" github "pcantrell/Nocilla" "bd7ec7caa0576f08c00bbbf993a9204f93be16e3" -github "pcantrell/Quick" "1c2c4056049e52d25fc48171ab62ab9d33821b47" +github "pcantrell/Quick" "ea7d540048645e84748310854e10c19ad8a1b404" diff --git a/Examples/GithubBrowser/Podfile.lock b/Examples/GithubBrowser/Podfile.lock index de97ed84..33efebbb 100644 --- a/Examples/GithubBrowser/Podfile.lock +++ b/Examples/GithubBrowser/Podfile.lock @@ -1,8 +1,8 @@ PODS: - - Siesta/Core (1.2.1) - - Siesta/UI (1.2.1): + - Siesta/Core (1.2.2) + - Siesta/UI (1.2.2): - Siesta/Core - - SwiftyJSON (3.1.4) + - SwiftyJSON (4.0.0) DEPENDENCIES: - Siesta/UI (from `../..`) @@ -13,8 +13,8 @@ EXTERNAL SOURCES: :path: ../.. SPEC CHECKSUMS: - Siesta: f47c4e6016bc2c249c46f2a70167ff0835dfefe1 - SwiftyJSON: c2842d878f95482ffceec5709abc3d05680c0220 + Siesta: 98822f001d2f6b79ac746aecfd571888e31ba3af + SwiftyJSON: 070dabdcb1beb81b247c65ffa3a79dbbfb3b48aa PODFILE CHECKSUM: 185541f66e3c53d1269ded59a72f9c99e6a2d105 diff --git a/Siesta.xcodeproj/project.pbxproj b/Siesta.xcodeproj/project.pbxproj index 584e24f2..94d4904b 100644 --- a/Siesta.xcodeproj/project.pbxproj +++ b/Siesta.xcodeproj/project.pbxproj @@ -1495,7 +1495,6 @@ SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 3.1; }; @@ -1519,7 +1518,6 @@ PRODUCT_NAME = Siesta; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 3.1; }; @@ -1543,7 +1541,6 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.1; }; @@ -1566,7 +1563,6 @@ PRODUCT_NAME = Siesta; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.1; }; @@ -1584,7 +1580,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Debug; @@ -1600,7 +1595,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.bustoutsolutions.Siesta-TvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Release; @@ -1679,7 +1673,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 3.2; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1727,7 +1721,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 3.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; diff --git a/Source/Siesta/Support/DebugFormatting.swift b/Source/Siesta/Support/DebugFormatting.swift index d6ed8842..90d97884 100644 --- a/Source/Siesta/Support/DebugFormatting.swift +++ b/Source/Siesta/Support/DebugFormatting.swift @@ -28,7 +28,7 @@ internal func debugStr( if consolidateWhitespace { s = s.replacing(regex: whitespacePat, with: " ") } - if let truncate = truncate, s.characters.count > truncate + if let truncate = truncate, s.count > truncate { s = s.substring(to: s.index(s.startIndex, offsetBy: truncate)) + "…" } return s diff --git a/Source/Siesta/Support/Logging.swift b/Source/Siesta/Support/Logging.swift index 56f5450c..306ca2c6 100644 --- a/Source/Siesta/Support/Logging.swift +++ b/Source/Siesta/Support/Logging.swift @@ -54,7 +54,7 @@ public enum LogCategory public static var enabled = Set() } -private let maxCategoryNameLength = LogCategory.all.map { Int(String(describing: $0).characters.count) }.max() ?? 0 +private let maxCategoryNameLength = LogCategory.all.map { Int(String(describing: $0).count) }.max() ?? 0 /// Inject your custom logger to do something other than print to stdout. public var logger: (LogCategory, String) -> Void = diff --git a/Source/Siesta/Support/String+Siesta.swift b/Source/Siesta/Support/String+Siesta.swift index 6afde21c..5805912a 100644 --- a/Source/Siesta/Support/String+Siesta.swift +++ b/Source/Siesta/Support/String+Siesta.swift @@ -13,7 +13,7 @@ internal extension String func stripPrefix(_ prefix: String) -> String { return hasPrefix(prefix) - ? self[characters.index(startIndex, offsetBy: prefix.characters.count) ..< endIndex] + ? self[index(startIndex, offsetBy: prefix.count) ..< endIndex] : self } diff --git a/Tests/Functional/ProgressSpec.swift b/Tests/Functional/ProgressSpec.swift index 53bb9230..54d46b31 100644 --- a/Tests/Functional/ProgressSpec.swift +++ b/Tests/Functional/ProgressSpec.swift @@ -272,7 +272,7 @@ class ProgressSpec: ResourceSpecBase { var progressReports: [Double] = [] - let expectation = QuickSpec.current().expectation(description: "recordProgressUntil") + let expectation = QuickSpec.current.expectation(description: "recordProgressUntil") var fulfilled = false let reqStub = stubRequest(resource, "GET").andReturn(200).delay() @@ -286,7 +286,7 @@ class ProgressSpec: ResourceSpecBase } } setup(req) - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) _ = reqStub.go() awaitNewData(req) diff --git a/Tests/Functional/RequestSpec.swift b/Tests/Functional/RequestSpec.swift index 85e821ad..10cc22fa 100644 --- a/Tests/Functional/RequestSpec.swift +++ b/Tests/Functional/RequestSpec.swift @@ -342,13 +342,13 @@ class RequestSpec: ResourceSpecBase func expectResonseText(_ request: Request, text: String) { - let expectation = QuickSpec.current().expectation(description: "response text") + let expectation = QuickSpec.current.expectation(description: "response text") request.onSuccess { expectation.fulfill() expect($0.typedContent()) == text } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) } let oldRequest = specVar @@ -669,6 +669,10 @@ class RequestSpec: ResourceSpecBase _ = reqStub.go() awaitFailure(originalReq, alreadyCompleted: true) expectResult("custom", for: chainedReq, alreadyCompleted: true) + + // For whatever reason, this spec is especially prone to hitting Nocilla’s + // quirk of making cancelled requests go through anyway + Thread.sleep(forTimeInterval: 0.02) } } diff --git a/Tests/Functional/ResourceObserversSpec.swift b/Tests/Functional/ResourceObserversSpec.swift index 01fcdb0c..1d70adf6 100644 --- a/Tests/Functional/ResourceObserversSpec.swift +++ b/Tests/Functional/ResourceObserversSpec.swift @@ -433,7 +433,7 @@ class ResourceObserversSpec: ResourceSpecBase it("stops observing when owner is deallocated") { let observer = TestObserverWithExpectations() - var owner: AnyObject? = "foo" as NSString + var owner: AnyObject? = NSObject() observer.expect(.observerAdded) resource().addObserver(observer, owner: owner!) diff --git a/Tests/Functional/ResourceSpecBase.swift b/Tests/Functional/ResourceSpecBase.swift index 5cf5b1b9..39fb00c5 100644 --- a/Tests/Functional/ResourceSpecBase.swift +++ b/Tests/Functional/ResourceSpecBase.swift @@ -87,7 +87,7 @@ class ResourceSpecBase: SiestaSpec // Embedding the spec name in the API’s URL makes it easier to track down unstubbed requests, which sometimes // don’t arrive until a following spec has already started. - return "https://" + QuickSpec.current().description + return "https://" + QuickSpec.current.description .replacing(regex: "_[A-Za-z]+Specswift_\\d+\\]$", with: "") .replacing(regex: "[^A-Za-z0-9_]+", with: ".") .replacing(regex: "^\\.+|\\.+$", with: "") @@ -106,45 +106,45 @@ func stubRequest(_ resource: () -> Resource, _ method: String) -> LSStubRequestD func awaitNewData(_ req: Siesta.Request, alreadyCompleted: Bool = false) { expect(req.isCompleted) == alreadyCompleted - let responseExpectation = QuickSpec.current().expectation(description: "awaiting response callback: \(req)") - let successExpectation = QuickSpec.current().expectation(description: "awaiting success callback: \(req)") - let newDataExpectation = QuickSpec.current().expectation(description: "awaiting newData callback: \(req)") + let responseExpectation = QuickSpec.current.expectation(description: "awaiting response callback: \(req)") + let successExpectation = QuickSpec.current.expectation(description: "awaiting success callback: \(req)") + let newDataExpectation = QuickSpec.current.expectation(description: "awaiting newData callback: \(req)") req.onCompletion { _ in responseExpectation.fulfill() } .onSuccess { _ in successExpectation.fulfill() } .onFailure { _ in fail("error callback should not be called") } .onNewData { _ in newDataExpectation.fulfill() } .onNotModified { _ in fail("notModified callback should not be called") } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) expect(req.isCompleted) == true } func awaitNotModified(_ req: Siesta.Request) { expect(req.isCompleted) == false - let responseExpectation = QuickSpec.current().expectation(description: "awaiting response callback: \(req)") - let successExpectation = QuickSpec.current().expectation(description: "awaiting success callback: \(req)") - let notModifiedExpectation = QuickSpec.current().expectation(description: "awaiting notModified callback: \(req)") + let responseExpectation = QuickSpec.current.expectation(description: "awaiting response callback: \(req)") + let successExpectation = QuickSpec.current.expectation(description: "awaiting success callback: \(req)") + let notModifiedExpectation = QuickSpec.current.expectation(description: "awaiting notModified callback: \(req)") req.onCompletion { _ in responseExpectation.fulfill() } .onSuccess { _ in successExpectation.fulfill() } .onFailure { _ in fail("error callback should not be called") } .onNewData { _ in fail("newData callback should not be called") } .onNotModified { _ in notModifiedExpectation.fulfill() } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) expect(req.isCompleted) == true } func awaitFailure(_ req: Siesta.Request, alreadyCompleted: Bool = false) { expect(req.isCompleted) == alreadyCompleted - let responseExpectation = QuickSpec.current().expectation(description: "awaiting response callback: \(req)") - let errorExpectation = QuickSpec.current().expectation(description: "awaiting failure callback: \(req)") + let responseExpectation = QuickSpec.current.expectation(description: "awaiting response callback: \(req)") + let errorExpectation = QuickSpec.current.expectation(description: "awaiting failure callback: \(req)") req.onCompletion { _ in responseExpectation.fulfill() } .onFailure { _ in errorExpectation.fulfill() } .onSuccess { _ in fail("success callback should not be called") } .onNewData { _ in fail("newData callback should not be called") } .onNotModified { _ in fail("notModified callback should not be called") } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) expect(req.isCompleted) == true // When cancelling a request, Siesta immediately kills its end of the request, then sends a cancellation to the @@ -159,9 +159,9 @@ func awaitUnderlyingNetworkRequest(_ req: Siesta.Request) { if let netReq = req as? NetworkRequest { - let networkExpectation = QuickSpec.current().expectation(description: "awaiting underlying network response: \(req)") + let networkExpectation = QuickSpec.current.expectation(description: "awaiting underlying network response: \(req)") pollUnderlyingCompletion(netReq, expectation: networkExpectation) - QuickSpec.current().waitForExpectations(timeout: 1.0) + QuickSpec.current.waitForExpectations(timeout: 1.0) } } @@ -192,9 +192,9 @@ func setResourceTime(_ time: TimeInterval) func awaitObserverCleanup(for resource: Resource?) { - let cleanupExpectation = QuickSpec.current().expectation(description: "awaitObserverCleanup") + let cleanupExpectation = QuickSpec.current.expectation(description: "awaitObserverCleanup") DispatchQueue.main.async { cleanupExpectation.fulfill() } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) } diff --git a/Tests/Functional/ResourceStateSpec.swift b/Tests/Functional/ResourceStateSpec.swift index 25392ecf..6673778e 100644 --- a/Tests/Functional/ResourceStateSpec.swift +++ b/Tests/Functional/ResourceStateSpec.swift @@ -487,12 +487,12 @@ class ResourceRequestsSpec: ResourceSpecBase { it("cancels load if resource has loses observers during delay") { - let expectation = QuickSpec.current().expectation(description: "cancelLoadIfUnobserved(afterDelay:") + let expectation = QuickSpec.current.expectation(description: "cancelLoadIfUnobserved(afterDelay:") resource().addObserver(owner: owner!) { _ in } resource().cancelLoadIfUnobserved(afterDelay: 0.001) { expectation.fulfill() } owner = nil - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) _ = reqStub().go() awaitFailure(req(), alreadyCompleted: true) @@ -500,11 +500,11 @@ class ResourceRequestsSpec: ResourceSpecBase it("does not cancel load if resource gains an observer during delay") { - let expectation = QuickSpec.current().expectation(description: "cancelLoadIfUnobserved(afterDelay:") + let expectation = QuickSpec.current.expectation(description: "cancelLoadIfUnobserved(afterDelay:") resource().cancelLoadIfUnobserved(afterDelay: 0.001) { expectation.fulfill() } resource().addObserver(owner: owner!) { _ in } - QuickSpec.current().waitForExpectations(timeout: 1) + QuickSpec.current.waitForExpectations(timeout: 1) _ = reqStub().go() awaitNewData(req())