Skip to content

Instantly share code, notes, and snippets.

@thelbane
Created June 11, 2017 20:18
Show Gist options
  • Save thelbane/09764d4d12319b846d01ff6e7ca4cb1c to your computer and use it in GitHub Desktop.
Save thelbane/09764d4d12319b846d01ff6e7ca4cb1c to your computer and use it in GitHub Desktop.
Tests for general KVO and non-KVO observable properties
public class ObservableTests : XCTestCase {
public func testFilters() {
var expectedValues = [0,2,4,6,8]
let expect = expectation(description: "Odd numbers filtered out")
expect.expectedFulfillmentCount = UInt(expectedValues.count)
let observable = Observable(0)
observable
.filter { $0 % 2 == 0 }
.subscribe {
XCTAssertEqual($0, expectedValues.remove(at: 0))
expect.fulfill()
}
for i in 1..<9 { observable.value = i }
wait(for: [expect], timeout: 10.0)
}
public func testSkipNils() {
let inputs:[String?] = [nil,"Jon",nil,"Jan",nil,"Doreen","Jack","Jon"]
var expectedOutputs = ["Mike","Jon","Jan","Doreen","Jack","Jon"]
let expect = expectation(description: "Skips nils")
expect.expectedFulfillmentCount = UInt(expectedOutputs.count)
let observable = Observable<String?>("Mike")
observable
.skipNils()
.subscribe { val in
let compare = expectedOutputs.remove(at: 0)
XCTAssertEqual(val, compare)
expect.fulfill()
}
inputs.forEach { observable.value = $0 }
wait(for: [expect], timeout: 10.0)
}
public func testSkipRepeats() {
let inputs = ["Mike","Jon","Jon","Jon","Jan","Jan","Doreen","Jack","Jon"]
var expectedOutputs = ["Mike","Jon","Jan","Doreen","Jack","Jon"]
let expect = expectation(description: "Skips repeats")
expect.expectedFulfillmentCount = UInt(expectedOutputs.count)
let observable = Observable("Mike")
observable
.skipRepeats()
.subscribe {
XCTAssertEqual($0, expectedOutputs.remove(at: 0))
expect.fulfill()
}
inputs.forEach { observable.value = $0 }
wait(for: [expect], timeout: 10.0)
}
public func testMapping() {
let testValues = ["jack","jill","mike","margaret","steve"]
var capitalizedResults = ["Jack","Jill","Mike","Margaret","Steve"]
var lengthResults = [4,4,4,8,5]
let observable = Observable("jack")
let capitalized = observable.map { $0.capitalized }
let expectCapitalized = expectation(description: "Strings are capitalized")
expectCapitalized.expectedFulfillmentCount = UInt(capitalizedResults.count)
let length = capitalized.map { $0.characters.count }
let expectLength = expectation(description: "Strings are capitalized")
expectLength.expectedFulfillmentCount = UInt(lengthResults.count)
capitalized.subscribe {
XCTAssertEqual($0, capitalizedResults.remove(at: 0))
expectCapitalized.fulfill()
}
length.subscribe {
XCTAssertEqual($0, lengthResults.remove(at: 0))
expectLength.fulfill()
}
for (index, element) in testValues.enumerated() where index != 0 {
observable.value = element
}
wait(for: [expectCapitalized, expectLength], timeout: 10.0)
}
public func testKeyValueObserving() {
var expectedFirstNames = ["Jack","Mike","Charles","Alice"]
let expect = expectation(description: "First names")
expect.expectedFulfillmentCount = UInt(expectedFirstNames.count)
class TestClass: NSObject {
dynamic var firstName = "Jack"
}
let tc = TestClass()
XCTAssertEqual(tc.firstName, "Jack")
let kvo = KVObservable<String>(tc, #keyPath(TestClass.firstName))
XCTAssertEqual(kvo.value, "Jack")
kvo.subscribe {
let nextName = expectedFirstNames.remove(at: 0)
XCTAssertEqual($0, nextName)
XCTAssertEqual(kvo.value, nextName)
expect.fulfill()
}
// First expected name ("Jack") is satisfied upon subscription
tc.firstName = "Mike"
tc.firstName = "Charles"
tc.firstName = "Alice"
wait(for: [expect], timeout: 10.0)
}
public func testCombineLatest() {
var expectedNames = ["Jenny Jones","Bob Jones","Bob Newhart","Bob Davis","Gina Davis"]
let expect = expectation(description: "Full names")
expect.expectedFulfillmentCount = UInt(expectedNames.count)
class TestClass: NSObject {
dynamic var firstName = "Jenny"
}
let tc = TestClass()
let firstName = KVObservable<String>(tc, #keyPath(TestClass.firstName))
let lastName = Observable("Jones")
combineLatest(firstName, lastName)
.map { "\($0.0) \($0.1)" }
.subscribe {
XCTAssertEqual($0, expectedNames.remove(at: 0))
expect.fulfill()
}
// First expected full name ("Jenny Jones") is satisfied upon subscription
tc.firstName = "Bob"
lastName.value = "Newhart"
lastName.value = "Davis"
tc.firstName = "Gina"
wait(for: [expect], timeout: 10.0)
}
public func testCombineLatestThree() {
let expectedResult = "abc"
let a = Observable("a")
let b = Observable("b")
let c = Observable("c")
let abc = combineLatest(a, b, c).map { "\($0)\($1)\($2)" }
XCTAssertEqual(abc.value, expectedResult)
}
public func testCombineLatestFour() {
let expectedResult = "abcd"
let a = Observable("a")
let b = Observable("b")
let c = Observable("c")
let d = Observable("d")
let abcd = combineLatest(a, b, c, d).map { "\($0)\($1)\($2)\($3)" }
XCTAssertEqual(abcd.value, expectedResult)
}
public func testStrongObservable() {
var obs: Observable<Int>? = Observable(5)
var ref: Observable<Int>?
ref = obs
let expect = expectation(description: "Strong reference")
expect.expectedFulfillmentCount = 5
obs!.subscribe { _ in
expect.fulfill()
}
ref!.value = 4
obs = nil
if let ref = ref {
ref.value = 3
ref.value = 2
ref.value = 1
}
wait(for: [expect], timeout: 10.0)
}
public func testWeakObservable() {
var obs: Observable<Int>? = Observable(5)
weak var ref: Observable<Int>?
ref = obs
let expect = expectation(description: "Weak reference")
expect.expectedFulfillmentCount = 2
obs!.subscribe { _ in
expect.fulfill()
}
ref!.value = 4
obs = nil
if let ref = ref {
ref.value = 3
ref.value = 2
ref.value = 1
}
wait(for: [expect], timeout: 10.0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment