Skip to content

Commit

Permalink
Fix ObservableCollection<Array<T>> subscript issue
Browse files Browse the repository at this point in the history
  • Loading branch information
srdanrasic committed Nov 22, 2015
1 parent b43fd63 commit be9d892
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 4 deletions.
4 changes: 2 additions & 2 deletions ReactiveKit.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = "ReactiveKit"
s.version = "1.0.4"
s.version = "1.0.5"
s.summary = "A Swift Reactive Programming Framework"
s.description = "ReactiveKit is a collection of Swift frameworks for reactive and functional reactive programming."
s.homepage = "https://github.com/ReactiveKit/ReactiveKit"
s.license = 'MIT'
s.author = { "Srdan Rasic" => "[email protected]" }
s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v1.0.4" }
s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v1.0.5" }

s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
Expand Down
4 changes: 4 additions & 0 deletions ReactiveKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
16C33B831BEFBAC800A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
16C33B841BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
16C33B851BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
16EABAD01C01AD82008B20BD /* ObservableCollectionSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16EABACF1C01AD82008B20BD /* ObservableCollectionSpec.swift */; };
16F0B8761BEFC3850071847A /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 16F0B8751BEFC3850071847A /* Quick.framework */; };
16F0B8781BEFC3890071847A /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 16F0B8771BEFC3890071847A /* Nimble.framework */; };
EC0DF29A1BF48FF400DFF3E6 /* MutableObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0DF2991BF48FF400DFF3E6 /* MutableObservable.swift */; };
Expand Down Expand Up @@ -159,6 +160,7 @@
16C33AF91BEFB72500A0DBE0 /* ReactiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
16C33B161BEFB9CB00A0DBE0 /* ReactiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
16C33B241BEFBA0100A0DBE0 /* ReactiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
16EABACF1C01AD82008B20BD /* ObservableCollectionSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableCollectionSpec.swift; sourceTree = "<group>"; };
16F0B8751BEFC3850071847A /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = "../Carthage/Checkouts/Quick/build/Debug-iphoneos/Quick.framework"; sourceTree = "<group>"; };
16F0B8771BEFC3890071847A /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = "../Carthage/Checkouts/Nimble/build/Debug-iphoneos/Nimble.framework"; sourceTree = "<group>"; };
EC0DF2991BF48FF400DFF3E6 /* MutableObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MutableObservable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -306,6 +308,7 @@
children = (
ECBCCDDF1BEB6B9B00723476 /* StreamSpec.swift */,
EC835BE11BEC923400463098 /* OperationSpec.swift */,
16EABACF1C01AD82008B20BD /* ObservableCollectionSpec.swift */,
16F0B8791BEFC3A10071847A /* Dependencies */,
ECBCCDE11BEB6B9B00723476 /* Info.plist */,
);
Expand Down Expand Up @@ -763,6 +766,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
16EABAD01C01AD82008B20BD /* ObservableCollectionSpec.swift in Sources */,
EC835BE21BEC923400463098 /* OperationSpec.swift in Sources */,
ECBCCDE01BEB6B9B00723476 /* StreamSpec.swift in Sources */,
);
Expand Down
2 changes: 1 addition & 1 deletion ReactiveKit/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>1.0.4</string>
<string>1.0.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ extension ObservableCollectionType where Collection == Array<Element> {

public subscript(index: Collection.Index) -> Collection.Generator.Element {
get {
return self[index]
return collection[index]
}
set {
var new = collection
Expand Down
190 changes: 190 additions & 0 deletions ReactiveKitTests/ObservableCollectionSpec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//
// ObservableCollectionSpec.swift
// ReactiveKit
//
// Created by Srdan Rasic on 22/11/15.
// Copyright © 2015 Srdan Rasic. All rights reserved.
//

import Quick
import Nimble
@testable import ReactiveKit

class ObservableCollectionSpec: QuickSpec {

override func spec() {

// MARK: - Array

describe("ObservableCollection<Array<T>>") {
var observableCollection: ObservableCollection<[Int]>!

beforeEach {
observableCollection = ObservableCollection([1, 2, 3])
}

context("when observed") {
var observedEvents: [ObservableCollectionEvent<[Int]>] = []

beforeEach {
observedEvents = []
observableCollection.observe(on: ImmediateExecutionContext) {
observedEvents.append($0)
}
}

it("generates initial event") {
expect(observedEvents[0]).to(equal(ObservableCollectionEvent(collection: [1, 2, 3], inserts: [], deletes: [], updates: [])))
}

describe("append") {
beforeEach {
observableCollection.append(4)
}

it("appends") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [1, 2, 3, 4], inserts: [3], deletes: [], updates: [])))
}
}

describe("insert") {
beforeEach {
observableCollection.insert(0, atIndex: 0)
}

it("inserts") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [0, 1, 2, 3], inserts: [0], deletes: [], updates: [])))
}
}

describe("insertContentsOf") {
beforeEach {
observableCollection.insertContentsOf([10, 11], at: 1)
}

it("insertContentsOf") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [1, 10, 11, 2, 3], inserts: [1, 2], deletes: [], updates: [])))
}
}

describe("removeAtIndex") {
beforeEach {
observableCollection.removeAtIndex(1)
}

it("removeAtIndex") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [1, 3], inserts: [], deletes: [1], updates: [])))
}
}

describe("removeLast") {
beforeEach {
observableCollection.removeLast()
}

it("removeLast") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [1, 2], inserts: [], deletes: [2], updates: [])))
}
}

describe("removeAll") {
beforeEach {
observableCollection.removeAll()
}

it("removeAll") {
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [], inserts: [], deletes: [0, 1, 2], updates: [])))
}
}

describe("subscript") {
beforeEach {
observableCollection[1] = 20
}

it("subscript") {
expect(observableCollection[1]) == 20
expect(observedEvents[1]).to(equal(ObservableCollectionEvent(collection: [1, 20, 3], inserts: [], deletes: [], updates: [1])))
}
}
}
}

// MARK: - Set

describe("ObservableCollection<Set<T>>") {
var observableCollection: ObservableCollection<Set<Int>>!

beforeEach {
observableCollection = ObservableCollection([1, 2, 3])
}

context("when observed") {
var observedEvents: [ObservableCollectionEvent<Set<Int>>] = []

beforeEach {
observedEvents = []
observableCollection.observe(on: ImmediateExecutionContext) {
observedEvents.append($0)
}
}

it("generates initial event") {
expect(observedEvents[0]).to(equal(ObservableCollectionEvent(collection: [1, 2, 3], inserts: [], deletes: [], updates: [])))
}

describe("contains") {
it("contains") {
expect(observableCollection.contains(1)) == true
expect(observableCollection.contains(5)) == false
}
}

describe("insert") {
beforeEach {
observableCollection.insert(0)
}

it("inserts") {
expect(observedEvents[1].collection).to(contain(0))
}
}

describe("remove") {
beforeEach {
observableCollection.remove(1)
}

it("remove") {
expect(observedEvents[1].collection).toNot(contain(0))
}
}
}
}
}
}

// MARK: - Helpers

public func equal<C: CollectionType where C.Generator.Element: Equatable>(expectedValue: ObservableCollectionEvent<C>) -> MatcherFunc<ObservableCollectionEvent<C>> {
return MatcherFunc { actualExpression, failureMessage in
failureMessage.postfixMessage = "equal <\(expectedValue)>"
return try! actualExpression.evaluate()! == expectedValue
}
}


func == <C: CollectionType where C.Generator.Element: Equatable, C.Index: Equatable>(left: ObservableCollectionEvent<C>, right: ObservableCollectionEvent<C>) -> Bool {
return left.collection == right.collection && left.inserts == right.inserts && left.updates == right.updates && left.deletes == right.deletes
}

func == <C: CollectionType where C.Generator.Element: Equatable>(left: C, right: C) -> Bool {
guard left.count == right.count else { return false }
for (l, r) in zip(left, right) {
if l != r {
return false
}
}
return true
}

0 comments on commit be9d892

Please sign in to comment.