fixes the unit tests for the rx ios example

This commit is contained in:
Jamie Pinkham 2016-06-20 14:04:42 -04:00
parent ff0d588189
commit ced6ce3a7e
7 changed files with 56 additions and 55 deletions

View File

@ -10,7 +10,7 @@ import Foundation
import RxSwift
class MockGitHubAPI : GitHubAPI {
let _usernameAvailable: String -> Observable<Bool>
let _usernameAvailable: (String) -> Observable<Bool>
let _signup: (String, String) -> Observable<Bool>
init(
@ -21,11 +21,11 @@ class MockGitHubAPI : GitHubAPI {
_signup = signup
}
func usernameAvailable(username: String) -> Observable<Bool> {
func usernameAvailable(_ username: String) -> Observable<Bool> {
return _usernameAvailable(username)
}
func signup(username: String, password: String) -> Observable<Bool> {
func signup(_ username: String, password: String) -> Observable<Bool> {
return _signup(username, password)
}
}

View File

@ -10,20 +10,20 @@ import Foundation
import RxSwift
class MockWireframe : Wireframe {
let _openURL: (NSURL) -> ()
let _openURL: (URL) -> ()
let _promptFor: (String, Any, [Any]) -> Observable<Any>
init(openURL: (NSURL) -> () = notImplementedSync(),
init(openURL: (URL) -> () = notImplementedSync(),
promptFor: (String, Any, [Any]) -> Observable<Any> = notImplemented()) {
_openURL = openURL
_promptFor = promptFor
}
func openURL(URL: NSURL) {
_openURL(URL)
func open(url: URL) {
_openURL(url)
}
func promptFor<Action: CustomStringConvertible>(message: String, cancelAction: Action, actions: [Action]) -> Observable<Action> {
func promptFor<Action: CustomStringConvertible>(_ message: String, cancelAction: Action, actions: [Action]) -> Observable<Action> {
return _promptFor(message, cancelAction, actions.map { $0 as Any }).map { $0 as! Action }
}
}

View File

@ -16,15 +16,15 @@ extension ValidationResult : Equatable {
func == (lhs: ValidationResult, rhs: ValidationResult) -> Bool {
switch (lhs, rhs) {
case (.OK, .OK):
case (.ok, .ok):
return true
case (.Empty, .Empty):
case (.empty, .empty):
return true
case (.Validating, .Validating):
case (.validating, .validating):
return true
case (.Failed, .Failed):
case (.failed, .failed):
return true
default:
return false
}
}
}

View File

@ -12,7 +12,7 @@ import RxSwift
import RxTests
import RxCocoa
let resolution: NSTimeInterval = 0.2 // seconds
let resolution: TimeInterval = 0.2 // seconds
// MARK: Concrete tests
@ -29,10 +29,10 @@ class RxExample_iOSTests
"#u" : NSError(domain: NSURLErrorDomain, code: NSURLErrorTimedOut, userInfo: nil)
]
let validations = [
"e" : ValidationResult.Empty,
"f" : ValidationResult.Failed(message: ""),
"o" : ValidationResult.OK(message: "Validated"),
"v" : ValidationResult.Validating
"e" : ValidationResult.empty,
"f" : ValidationResult.failed(message: ""),
"o" : ValidationResult.ok(message: "Validated"),
"v" : ValidationResult.validating
]
let stringValues = [
@ -56,7 +56,7 @@ class RxExample_iOSTests
let scheduler = TestScheduler(initialClock: 0, resolution: resolution, simulateProcessingDelay: false)
// mock the universe
let mockAPI = mockGithubAPI(scheduler)
let mockAPI = mockGithubAPI(scheduler: scheduler)
// expected events and test data
let (
@ -68,13 +68,13 @@ class RxExample_iOSTests
expectedValidatedUsernameEvents,
expectedSignupEnabledEvents
) = (
scheduler.parseEventsAndTimes("e---u1----u2-----u3-----------------", values: stringValues).first!,
scheduler.parseEventsAndTimes("e----------------------p1-----------", values: stringValues).first!,
scheduler.parseEventsAndTimes("e---------------------------p2---p1-", values: stringValues).first!,
scheduler.parseEventsAndTimes("------------------------------------", values: events).first!,
scheduler.parseEventsAndTimes(timeline: "e---u1----u2-----u3-----------------", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "e----------------------p1-----------", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "e---------------------------p2---p1-", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "------------------------------------", values: events).first!,
scheduler.parseEventsAndTimes("e---v--f--v--f---v--o----------------", values: validations).first!,
scheduler.parseEventsAndTimes("f--------------------------------t---", values: booleans).first!
scheduler.parseEventsAndTimes(timeline: "e---v--f--v--f---v--o----------------", values: validations).first!,
scheduler.parseEventsAndTimes(timeline: "f--------------------------------t---", values: booleans).first!
)
let wireframe = MockWireframe()
@ -95,8 +95,8 @@ class RxExample_iOSTests
)
// run experiment
let recordedSignupEnabled = scheduler.record(viewModel.signupEnabled)
let recordedValidatedUsername = scheduler.record(viewModel.validatedUsername)
let recordedSignupEnabled = scheduler.record(source: viewModel.signupEnabled)
let recordedValidatedUsername = scheduler.record(source: viewModel.validatedUsername)
scheduler.start()
@ -109,7 +109,7 @@ class RxExample_iOSTests
let scheduler = TestScheduler(initialClock: 0, resolution: resolution, simulateProcessingDelay: false)
// mock the universe
let mockAPI = mockGithubAPI(scheduler)
let mockAPI = mockGithubAPI(scheduler: scheduler)
// expected events and test data
let (
@ -121,13 +121,13 @@ class RxExample_iOSTests
expectedValidatedUsernameEvents,
expectedSignupEnabledEvents
) = (
scheduler.parseEventsAndTimes("e---u1----u2-----u3-----------------", values: stringValues).first!,
scheduler.parseEventsAndTimes("e----------------------p1-----------", values: stringValues).first!,
scheduler.parseEventsAndTimes("e---------------------------p2---p1-", values: stringValues).first!,
scheduler.parseEventsAndTimes("------------------------------------", values: events).first!,
scheduler.parseEventsAndTimes(timeline: "e---u1----u2-----u3-----------------", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "e----------------------p1-----------", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "e---------------------------p2---p1-", values: stringValues).first!,
scheduler.parseEventsAndTimes(timeline: "------------------------------------", values: events).first!,
scheduler.parseEventsAndTimes("e---v--f--v--f---v--o----------------", values: validations).first!,
scheduler.parseEventsAndTimes("f--------------------------------t---", values: booleans).first!
scheduler.parseEventsAndTimes(timeline: "e---v--f--v--f---v--o----------------", values: validations).first!,
scheduler.parseEventsAndTimes(timeline: "f--------------------------------t---", values: booleans).first!
)
let wireframe = MockWireframe()
@ -156,8 +156,8 @@ class RxExample_iOSTests
*/
driveOnScheduler(scheduler) {
// run experiment
let recordedSignupEnabled = scheduler.record(viewModel.signupEnabled)
let recordedValidatedUsername = scheduler.record(viewModel.validatedUsername)
let recordedSignupEnabled = scheduler.record(source: viewModel.signupEnabled)
let recordedValidatedUsername = scheduler.record(source: viewModel.validatedUsername)
scheduler.start()
@ -173,7 +173,7 @@ class RxExample_iOSTests
extension RxExample_iOSTests {
func mockGithubAPI(scheduler: TestScheduler) -> GitHubAPI {
return MockGitHubAPI(
usernameAvailable: scheduler.mock(booleans, errors: errors) { (username) -> String in
usernameAvailable: scheduler.mock(values: booleans, errors: errors) { (username) -> String in
if username == "secretusername" {
return "---t"
}
@ -184,7 +184,7 @@ extension RxExample_iOSTests {
return "---f"
}
},
signup: scheduler.mock(booleans, errors: errors) { (username, password) -> String in
signup: scheduler.mock(values: booleans, errors: errors) { (username, password) -> String in
if username == "secretusername" && password == "secret" {
return "--t"
}

View File

@ -44,14 +44,15 @@ extension TestScheduler {
func parseEventsAndTimes<T>(timeline: String, values: [String: T], errors: [String: ErrorProtocol] = [:]) -> [[Recorded<Event<T>>]] {
//print("parsing: \(timeline)")
typealias RecordedEvent = Recorded<Event<T>>
let timelines = timeline.componentsSeparatedByString("|")
let timelines = timeline.components(separatedBy: "|")
let allExceptLast = timelines[0 ..< timelines.count - 1]
return (allExceptLast.map { $0 + "|" } + [timelines.last!])
.filter { $0.characters.count > 0 }
.map { timeline -> [Recorded<Event<T>>] in
let segments = timeline.componentsSeparatedByString("-")
let segments = timeline.components(separatedBy:"-")
let (time: _, events: events) = segments.reduce((time: 0, events: [RecordedEvent]())) { state, event in
let tickIncrement = event.characters.count + 1
@ -60,12 +61,12 @@ extension TestScheduler {
}
if event == "#" {
let errorEvent = RecordedEvent(time: state.time, event: Event<T>.Error(NSError(domain: "Any error domain", code: -1, userInfo: nil)))
let errorEvent = RecordedEvent(time: state.time, event: Event<T>.error(NSError(domain: "Any error domain", code: -1, userInfo: nil)))
return (state.time + tickIncrement, state.events + [errorEvent])
}
if event == "|" {
let completed = RecordedEvent(time: state.time, event: Event<T>.Completed)
let completed = RecordedEvent(time: state.time, event: Event<T>.completed)
return (state.time + tickIncrement, state.events + [completed])
}
@ -74,11 +75,11 @@ extension TestScheduler {
fatalError("Value with key \(event) not registered as value:\n\(values)\nor error:\n\(errors)")
}
let nextEvent = RecordedEvent(time: state.time, event: Event<T>.Error(error))
let nextEvent = RecordedEvent(time: state.time, event: Event<T>.error(error))
return (state.time + tickIncrement, state.events + [nextEvent])
}
let nextEvent = RecordedEvent(time: state.time, event: Event<T>.Next(next))
let nextEvent = RecordedEvent(time: state.time, event: Event<T>.next(next))
return (state.time + tickIncrement, state.events + [nextEvent])
}
@ -96,7 +97,7 @@ extension TestScheduler {
- returns: Driver specified by timeline and values.
*/
func createDriver<T>(timeline: String, values: [String: T]) -> Driver<T> {
return createObservable(timeline, values: values, errors: [:]).asDriver(onErrorRecover: { (error) -> Driver<T> in
return createObservable(timeline: timeline, values: values, errors: [:]).asDriver(onErrorRecover: { (error) -> Driver<T> in
fatalError("This can't error out")
return Driver.never()
})
@ -112,7 +113,7 @@ extension TestScheduler {
- returns: Observable sequence specified by timeline and values.
*/
func createObservable<T>(timeline: String, values: [String: T], errors: [String: ErrorProtocol] = [:]) -> Observable<T> {
let events = self.parseEventsAndTimes(timeline, values: values, errors: errors)
let events = self.parseEventsAndTimes(timeline: timeline, values: values, errors: errors)
return createObservable(events)
}
@ -123,7 +124,7 @@ extension TestScheduler {
- returns: Observable sequence specified by timeline and values.
*/
func createObservable<T>(events: [Recorded<Event<T>>]) -> Observable<T> {
func createObservable<T>(_ events: [Recorded<Event<T>>]) -> Observable<T> {
return createObservable([events])
}
@ -137,7 +138,7 @@ extension TestScheduler {
- returns: Observable sequence specified by timeline and values.
*/
func createObservable<T>(events: [[Recorded<Event<T>>]]) -> Observable<T> {
func createObservable<T>(_ events: [[Recorded<Event<T>>]]) -> Observable<T> {
var attemptCount = 0
print("created for \(events)")
@ -147,7 +148,7 @@ extension TestScheduler {
}
let scheduledEvents = events[attemptCount].map { event in
return self.scheduleRelative((), dueTime: resolution * NSTimeInterval(event.time)) { _ in
return self.scheduleRelative((), dueTime: resolution * TimeInterval(event.time)) { _ in
observer.on(event.value)
return NopDisposable.instance
}
@ -173,11 +174,11 @@ extension TestScheduler {
- returns: Implementation of method that accepts arguments with parameter `Arg` and returns observable sequence
with parameter `Ret`.
*/
func mock<Arg, Ret>(values: [String: Ret], errors: [String: ErrorProtocol] = [:], timelineSelector: Arg -> String) -> Arg -> Observable<Ret> {
func mock<Arg, Ret>(values: [String: Ret], errors: [String: ErrorProtocol] = [:], timelineSelector: (Arg) -> String) -> (Arg) -> Observable<Ret> {
return { (parameters: Arg) -> Observable<Ret> in
let timeline = timelineSelector(parameters)
return self.createObservable(timeline, values: values, errors: errors)
return self.createObservable(timeline: timeline, values: values, errors: errors)
}
}

View File

@ -107,7 +107,7 @@ class WikipediaSearchViewController: ViewController {
resultsTableView.rx_modelSelected(SearchResultViewModel.self)
.asDriver()
.driveNext { searchResult in
wireframe.openURL(searchResult.searchResult.URL)
wireframe.open(url:searchResult.searchResult.URL)
}
.addDisposableTo(disposeBag)
}

View File

@ -23,7 +23,7 @@ enum RetryResult {
}
protocol Wireframe {
func openURL(_ URL: URL)
func open(url: URL)
func promptFor<Action: CustomStringConvertible>(_ message: String, cancelAction: Action, actions: [Action]) -> Observable<Action>
}
@ -31,9 +31,9 @@ protocol Wireframe {
class DefaultWireframe: Wireframe {
static let sharedInstance = DefaultWireframe()
func openURL(_ URL: Foundation.URL) {
func open(url: URL) {
#if os(iOS)
UIApplication.shared().openURL(URL)
UIApplication.shared().openURL(url)
#elseif os(OSX)
NSWorkspace.shared().open(URL)
#endif