Skip to content
This repository has been archived by the owner on Jul 21, 2021. It is now read-only.

Commit

Permalink
Swift 3 support (venmo#65)
Browse files Browse the repository at this point in the history
* Update to Swift 3

* Bump version 0.4.0

* Rename HTTPURLResponse file too

* Prefer private over fileprivate

* Fix serializating HTTPURLResponse

* Don't say we failed if we didn't

* Swift 3.0.1

* tvOS target

* Swift 3.0.1

* Fix tvOS deployment target

* Fix upload tests

* Explicitly set SWIFT_VERSION

Without this, Xcode complains about the legacy Swift version not being
set.

* Remove explicit toolchain from CI

* Specify SDK for CI

* Add destinations for CI

...because Travis CI is so good.

* Use latest version of Xcode

* Clean up spacing
  • Loading branch information
eliperkins authored and olegdanu-newstore committed Sep 28, 2018
1 parent 5594464 commit 7401695
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 85 deletions.
11 changes: 6 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
language: objective-c # lol
osx_image: xcode8
osx_image: xcode8.2
xcode_project: DVR.xcodeproj

script: xcodebuild -scheme "$TRAVIS_XCODE_SCHEME" test
script: xcodebuild -scheme "$TRAVIS_XCODE_SCHEME" -sdk "$TRAVIS_XCODE_SDK" -destination "$DESTINATION" test

matrix:
include:
- xcode_scheme: DVR-iOS
xcode_sdk: iphonesimulator
env:
- DESTINATION="OS=10.1,name=iPhone 7 Plus"
- xcode_scheme: DVR-OSX
xcode_sdk: macosx

env:
TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3
env:
- DESTINATION="arch=x86_64"
34 changes: 15 additions & 19 deletions DVR.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0810;
LastUpgradeCheck = 1000;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = Venmo;
TargetAttributes = {
2104F52D1DC658580039CA14 = {
Expand Down Expand Up @@ -622,6 +622,7 @@
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
Expand All @@ -644,6 +645,7 @@
PRODUCT_NAME = DVR;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
Expand All @@ -662,6 +664,7 @@
PRODUCT_NAME = DVRTests;
SDKROOT = appletvos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -678,6 +681,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.dvr.tests;
PRODUCT_NAME = DVRTests;
SDKROOT = appletvos;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -690,22 +694,14 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
Expand Down Expand Up @@ -735,7 +731,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 3.0.1;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
Expand All @@ -753,22 +749,14 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
Expand All @@ -791,7 +779,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 3.0.1;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
VALIDATE_PRODUCT = YES;
Expand All @@ -816,6 +804,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR;
PRODUCT_NAME = DVR;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -834,6 +823,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR;
PRODUCT_NAME = DVR;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -845,6 +835,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR.iostests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -856,6 +847,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR.iostests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -875,6 +867,7 @@
PRODUCT_NAME = DVR;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -894,6 +887,7 @@
PRODUCT_NAME = DVR;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -907,6 +901,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR.osxtests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -920,6 +915,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.venmo.DVR.osxtests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion DVR.xcodeproj/xcshareddata/xcschemes/DVR-tvOS.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
26 changes: 2 additions & 24 deletions DVR/Cassette.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@ struct Cassette {

// MARK: - Functions

func interactionForRequest(_ request: URLRequest, ignoreBaseURL: Bool) -> Interaction? {
func interactionForRequest(_ request: URLRequest) -> Interaction? {
for interaction in interactions {
let interactionRequest = interaction.request

guard let interactionURL = interactionRequest.url,
let requestURL = request.url else {
return nil
}
// Note: We don't check headers right now
if interactionRequest.httpMethod == request.httpMethod && interactionURL.isEqual(to: requestURL, ignoreBaseURL: ignoreBaseURL) && interactionRequest.hasHTTPBodyEqualToThatOfRequest(request) {
if interactionRequest.httpMethod == request.httpMethod && interactionRequest.url == request.url && interactionRequest.hasHTTPBodyEqualToThatOfRequest(request) {
return interaction
}
}
Expand Down Expand Up @@ -57,24 +53,6 @@ extension Cassette {
}
}

private extension URL {
/**
Method used to check if it is equal with the provided url.
- parameter url: The url to compare against.
- parameter ignoreBaseURL: Bool flag for ignoring the baseURL when comparing against the provided url.
- returns: true if is equal with the provided url, false otherwhise.
*/
func isEqual(to url: URL, ignoreBaseURL: Bool = false) -> Bool {
if ignoreBaseURL {
return self.relativePath == url.relativePath
} else {
return self == url
}
}
}

private extension URLRequest {
func hasHTTPBodyEqualToThatOfRequest(_ request: URLRequest) -> Bool {
guard let body1 = self.httpBody,
Expand Down
5 changes: 3 additions & 2 deletions DVR/HTTPURLResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ extension Foundation.HTTPURLResponse {

extension HTTPURLResponse {
convenience init(dictionary: [String: Any]) {
let url = URL(string: dictionary["url"] as! String)!
self.init(url: url, mimeType: nil, expectedContentLength: 0, textEncodingName: nil)
let url = URL(string: dictionary["url"] as! String)!

self.init(url: url, mimeType: nil, expectedContentLength: 0, textEncodingName: nil)

if let headers = dictionary["headers"] as? [String: String] {
allHeaderFields = headers
Expand Down
2 changes: 1 addition & 1 deletion DVR/Interaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ extension Interaction {
init?(dictionary: [String: Any]) {
guard let request = dictionary["request"] as? [String: Any],
let response = dictionary["response"] as? [String: Any],
let recordedAt = dictionary["recorded_at"] as? Double else { return nil }
let recordedAt = dictionary["recorded_at"] as? Int else { return nil }

self.request = NSMutableURLRequest(dictionary: request) as URLRequest
self.response = HTTPURLResponse(dictionary: response)
Expand Down
2 changes: 1 addition & 1 deletion DVR/Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.4.8n8</string>
<string>0.4.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
29 changes: 12 additions & 17 deletions DVR/Session.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@ open class Session: URLSession {
open let cassetteName: String
open let backingSession: URLSession
open var recordingEnabled = true
/**
Bool flag for ignoring the baseURL when comparing the request url with the url stored in the cassette.
- Note: Defalt value is false, change to true if you need to ignore the base url and compare only the relative paths of the urls not the entire url.
*/
public var ignoreBaseURL = false

private let testBundle: Bundle

private var recording = false
private var needsPersistence = false
private var outstandingTasks = [URLSessionTask]()
private var completedInteractions = [Interaction]()
private var completionBlock: (() -> Void)?
private var completionBlock: ((Void) -> Void)?

override open var delegate: URLSessionDelegate? {
return backingSession.delegate
Expand All @@ -43,23 +38,23 @@ open class Session: URLSession {
return addDataTask(request)
}

open override func dataTask(with request: URLRequest, completionHandler: @escaping ((Data?, Foundation.URLResponse?, Error?) -> Void)) -> URLSessionDataTask {
open override func dataTask(with request: URLRequest, completionHandler: @escaping ((Data?, Foundation.URLResponse?, Error?) -> Void)) -> URLSessionDataTask {
return addDataTask(request, completionHandler: completionHandler)
}

open override func downloadTask(with request: URLRequest) -> URLSessionDownloadTask {
return addDownloadTask(request)
}

open override func downloadTask(with request: URLRequest, completionHandler: @escaping (URL?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionDownloadTask {
open override func downloadTask(with request: URLRequest, completionHandler: @escaping (URL?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionDownloadTask {
return addDownloadTask(request, completionHandler: completionHandler)
}

open override func uploadTask(with request: URLRequest, from bodyData: Data) -> URLSessionUploadTask {
return addUploadTask(request, fromData: bodyData)
}

open override func uploadTask(with request: URLRequest, from bodyData: Data?, completionHandler: @escaping (Data?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionUploadTask {
open override func uploadTask(with request: URLRequest, from bodyData: Data?, completionHandler: @escaping (Data?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionUploadTask {
return addUploadTask(request, fromData: bodyData, completionHandler: completionHandler)
}

Expand All @@ -68,7 +63,7 @@ open class Session: URLSession {
return addUploadTask(request, fromData: data)
}

open override func uploadTask(with request: URLRequest, fromFile fileURL: URL, completionHandler: @escaping (Data?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionUploadTask {
open override func uploadTask(with request: URLRequest, fromFile fileURL: URL, completionHandler: @escaping (Data?, Foundation.URLResponse?, Error?) -> Void) -> URLSessionUploadTask {
let data = try! Data(contentsOf: fileURL)
return addUploadTask(request, fromData: data, completionHandler: completionHandler)
}
Expand Down Expand Up @@ -98,7 +93,7 @@ open class Session: URLSession {
/// This only needs to be called if you call `beginRecording`. `completion` will be called on the main queue after
/// the completion block of the last task is called. `completion` is useful for fulfilling an expectation you setup
/// before calling `beginRecording`.
open func endRecording(_ completion: (() -> Void)? = nil) {
open func endRecording(_ completion: ((Void) -> Void)? = nil) {
if !recording {
return
}
Expand Down Expand Up @@ -193,11 +188,11 @@ open class Session: URLSession {
let outputDirectory = (self.outputDirectory as NSString).expandingTildeInPath
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: outputDirectory) {
do {
try fileManager.createDirectory(atPath: outputDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
print("[DVR] Failed to create cassettes directory.")
}
do {
try fileManager.createDirectory(atPath: outputDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
print("[DVR] Failed to create cassettes directory.")
}
}

let cassette = Cassette(name: cassetteName, interactions: interactions)
Expand All @@ -219,7 +214,7 @@ open class Session: URLSession {
if let data = string.data(using: String.Encoding.utf8.rawValue) {
try? data.write(to: URL(fileURLWithPath: outputPath), options: [.atomic])
print("[DVR] Persisted cassette at \(outputPath). Please add this file to your test target")
return
return
}

print("[DVR] Failed to persist cassette.")
Expand Down
6 changes: 3 additions & 3 deletions DVR/SessionDataTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ final class SessionDataTask: URLSessionDataTask {
let cassette = session.cassette

// Find interaction
if let interaction = session.cassette?.interactionForRequest(request, ignoreBaseURL: session.ignoreBaseURL) {
self.interaction = interaction
if let interaction = session.cassette?.interactionForRequest(request) {
self.interaction = interaction
// Forward completion
if let completion = completion {
queue.async {
Expand Down Expand Up @@ -79,7 +79,7 @@ final class SessionDataTask: URLSessionDataTask {
// Create interaction
this.interaction = Interaction(request: this.request, response: response, responseData: data)
this.session.finishTask(this, interaction: this.interaction!, playback: false)
})
})
task.resume()
}
}
Loading

0 comments on commit 7401695

Please sign in to comment.