Skip to content

Commit 2814dc3

Browse files
author
Guido Marucci Blas
committed
Merge pull request #16 from jkennington/master
Add .Update operation and fix .Insert operation
2 parents f1f7c48 + ad7859f commit 2814dc3

File tree

5 files changed

+90
-8
lines changed

5 files changed

+90
-8
lines changed

ReactiveArray/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>0.3.0</string>
18+
<string>0.4.0</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>

ReactiveArray/Operation.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public enum Operation<T>: CustomDebugStringConvertible {
1212

1313
case Append(value: T)
1414
case Insert(value: T, atIndex: Int)
15+
case Update(value: T, atIndex: Int)
1516
case RemoveElement(atIndex: Int)
1617

1718
public func map<U>(mapper: T -> U) -> Operation<U> {
@@ -21,6 +22,8 @@ public enum Operation<T>: CustomDebugStringConvertible {
2122
result = Operation<U>.Append(value: mapper(value))
2223
case .Insert(let value, let index):
2324
result = Operation<U>.Insert(value: mapper(value), atIndex: index)
25+
case .Update(let value, let index):
26+
result = Operation<U>.Update(value: mapper(value), atIndex: index)
2427
case .RemoveElement(let index):
2528
result = Operation<U>.RemoveElement(atIndex: index)
2629
}
@@ -34,6 +37,8 @@ public enum Operation<T>: CustomDebugStringConvertible {
3437
description = ".Append(value:\(value))"
3538
case .Insert(let value, let index):
3639
description = ".Insert(value: \(value), atIndex:\(index))"
40+
case .Update(let value, let index):
41+
description = ".Update(value: \(value), atIndex:\(index))"
3742
case .RemoveElement(let index):
3843
description = ".RemoveElement(atIndex:\(index))"
3944
}
@@ -46,6 +51,8 @@ public enum Operation<T>: CustomDebugStringConvertible {
4651
return value
4752
case .Insert(let value, _):
4853
return value
54+
case .Update(let value, _):
55+
return value
4956
default:
5057
return Optional.None
5158
}
@@ -59,6 +66,8 @@ public func ==<T: Equatable>(lhs: Operation<T>, rhs: Operation<T>) -> Bool {
5966
return leftValue == rightValue
6067
case (.Insert(let leftValue, let leftIndex), .Insert(let rightValue, let rightIndex)):
6168
return leftIndex == rightIndex && leftValue == rightValue
69+
case (.Update(let leftValue, let leftIndex), .Update(let rightValue, let rightIndex)):
70+
return leftIndex == rightIndex && leftValue == rightValue
6271
case (.RemoveElement(let leftIndex), .RemoveElement(let rightIndex)):
6372
return leftIndex == rightIndex
6473
default:

ReactiveArray/ReactiveArray.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public final class ReactiveArray<T>: CollectionType, MutableCollectionType, Cust
103103
return _elements[index]
104104
}
105105
set(newValue) {
106-
insert(newValue, atIndex: index)
106+
update(newValue, atIndex: index)
107107
}
108108
}
109109

@@ -117,6 +117,11 @@ public final class ReactiveArray<T>: CollectionType, MutableCollectionType, Cust
117117
_sink(Event.Next(operation))
118118
}
119119

120+
public func update(element: T, atIndex index: Int) {
121+
let operation: Operation<T> = .Update(value: element, atIndex: index)
122+
_sink(Event.Next(operation))
123+
}
124+
120125
public func removeAtIndex(index:Int) {
121126
let operation: Operation<T> = .RemoveElement(atIndex: index)
122127
_sink(Event.Next(operation))
@@ -136,6 +141,8 @@ public final class ReactiveArray<T>: CollectionType, MutableCollectionType, Cust
136141
_elements.append(value)
137142
_mutableCount.value = _elements.count
138143
case .Insert(let value, let index):
144+
_elements.insert(value, atIndex: index)
145+
case .Update(let value, let index):
139146
_elements[index] = value
140147
case .RemoveElement(let index):
141148
_elements.removeAtIndex(index)

ReactiveArrayTests/OperationSpec.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ class OperationSpec: QuickSpec {
4949

5050
}
5151

52+
context("when the operation is an Update operation") {
53+
54+
beforeEach {
55+
operation = Operation.Update(value: 10, atIndex: 5)
56+
}
57+
58+
it("maps the value to be updated") {
59+
let mappedOperation = operation.map { $0 * 2 }
60+
61+
let areEqual = mappedOperation == Operation.Update(value: 20, atIndex: 5)
62+
expect(areEqual).to(beTrue())
63+
}
64+
65+
}
66+
5267
context("when the operation is a Delete operation") {
5368

5469
beforeEach {
@@ -92,6 +107,18 @@ class OperationSpec: QuickSpec {
92107

93108
}
94109

110+
context("when the operation is an Update operation") {
111+
112+
beforeEach {
113+
operation = Operation.Update(value: 10, atIndex: 5)
114+
}
115+
116+
it("returns the updated value") {
117+
expect(operation.value).to(equal(10))
118+
}
119+
120+
}
121+
95122
context("when the operation is an Remove operation") {
96123

97124
beforeEach {

ReactiveArrayTests/ReactiveArraySpec.swift

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private func waitForOperation<T>(fromProducer producer: SignalProducer<Operation
1515
when: () -> (),
1616
onAppend: T -> () = { fail("Invalid operation type: .Append(\($0))") },
1717
onInsert: (T, Int) -> () = { fail("Invalid operation type: .Insert(\($0), \($1))") },
18+
onUpdate: (T, Int) -> () = { fail("Invalid operation type: .Update(\($0), \($1))") },
1819
onDelete: Int -> () = { fail("Invalid operation type: .Delete(\($0))") }) {
1920

2021
waitUntil { done in
@@ -24,6 +25,8 @@ private func waitForOperation<T>(fromProducer producer: SignalProducer<Operation
2425
onAppend(value)
2526
case .Insert(let value, let index):
2627
onInsert(value, index)
28+
case .Update(let value, let index):
29+
onUpdate(value, index)
2730
case .RemoveElement(let index):
2831
onDelete(index)
2932
}
@@ -38,19 +41,21 @@ private func waitForOperation<T>(fromSignal signal: Signal<Operation<T>, NoError
3841
when: () -> (),
3942
onAppend: T -> () = { fail("Invalid operation type: .Append(\($0))") },
4043
onInsert: (T, Int) -> () = { fail("Invalid operation type: .Insert(\($0), \($1))") },
44+
onUpdate: (T, Int) -> () = { fail("Invalid operation type: .Update(\($0), \($1))") },
4145
onDelete: Int -> () = { fail("Invalid operation type: .Delete(\($0))") }) {
4246

4347
let producer = SignalProducer<Operation<T>, NoError> { (observer, disposable) in signal.observe(observer) }
44-
waitForOperation(fromProducer: producer, when: when, onAppend: onAppend, onInsert: onInsert, onDelete: onDelete)
48+
waitForOperation(fromProducer: producer, when: when, onAppend: onAppend, onInsert: onInsert, onUpdate: onUpdate, onDelete: onDelete)
4549
}
4650

4751
private func waitForOperation<T>(fromArray array: ReactiveArray<T>,
4852
when: () -> (),
4953
onAppend: T -> () = { fail("Invalid operation type: .Append(\($0))") },
5054
onInsert: (T, Int) -> () = { fail("Invalid operation type: .Insert(\($0), \($1))") },
55+
onUpdate: (T, Int) -> () = { fail("Invalid operation type: .Update(\($0), \($1))") },
5156
onDelete: Int -> () = { fail("Invalid operation type: .Delete(\($0))") }) {
5257

53-
waitForOperation(fromSignal: array.signal, when: when, onAppend: onAppend, onInsert: onInsert, onDelete: onDelete)
58+
waitForOperation(fromSignal: array.signal, when: when, onAppend: onAppend, onInsert: onInsert, onUpdate: onUpdate, onDelete: onDelete)
5459
}
5560

5661
class ReactiveArraySpec: QuickSpec {
@@ -101,6 +106,7 @@ class ReactiveArraySpec: QuickSpec {
101106
array.insert(5, atIndex: 1)
102107

103108
expect(array[1]).to(equal(5))
109+
expect(array.toArray()).to(equal([1,5,2,3,4]))
104110
}
105111

106112
it("signals an insert operation") {
@@ -171,15 +177,16 @@ class ReactiveArraySpec: QuickSpec {
171177
array[1] = 5
172178

173179
expect(array[1]).to(equal(5))
180+
expect(array.toArray()).to(equal([1,5,3,4]))
174181
}
175182

176-
it("signals an insert operation") {
183+
it("signals an update operation") {
177184
waitForOperation(
178185
fromArray: array,
179186
when: {
180187
array[1] = 5
181188
},
182-
onInsert: { (value, index) in
189+
onUpdate: { (value, index) in
183190
expect(value).to(equal(5))
184191
expect(index).to(equal(1))
185192
}
@@ -210,7 +217,7 @@ class ReactiveArraySpec: QuickSpec {
210217
when: {
211218
array[1] = 5
212219
},
213-
onInsert: { (value, index) in
220+
onUpdate: { (value, index) in
214221
expect(value).to(equal(15))
215222
expect(index).to(equal(1))
216223
}
@@ -365,6 +372,23 @@ class ReactiveArraySpec: QuickSpec {
365372

366373
}
367374

375+
context("when an update operation is executed") {
376+
377+
it("signals the operations") {
378+
waitForOperation(
379+
fromSignal: array.signal,
380+
when: {
381+
array[1] = 5
382+
},
383+
onUpdate: { (value, index) in
384+
expect(value).to(equal(5))
385+
expect(index).to(equal(1))
386+
}
387+
)
388+
}
389+
390+
}
391+
368392
context("when a delete operation is executed") {
369393

370394
it("signals the operations") {
@@ -411,7 +435,7 @@ class ReactiveArraySpec: QuickSpec {
411435
.take(1)
412436
.collect()
413437
.startWithNext { counts in
414-
expect(counts).to(equal([countBeforeOperation + 1]))
438+
expect(counts).to(equal([countBeforeOperation + 2]))
415439
done()
416440
}
417441

@@ -422,6 +446,21 @@ class ReactiveArraySpec: QuickSpec {
422446

423447
}
424448

449+
context("when an update operation is executed") {
450+
451+
beforeEach {
452+
producer = producer.skip(1)
453+
}
454+
455+
it("updates the count") {
456+
waitUntil { done in
457+
array[1] = 656
458+
expect(array.count).to(equal(countBeforeOperation))
459+
done()
460+
}
461+
}
462+
463+
}
425464

426465
context("when an append operation is executed") {
427466

0 commit comments

Comments
 (0)