com.fofx.observething 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.md.meta +7 -0
- package/Runtime/CollectionIdProvider.cs +72 -0
- package/Runtime/CollectionIdProvider.cs.meta +2 -0
- package/Runtime/IObservable.cs +66 -0
- package/Runtime/IObservable.cs.meta +2 -0
- package/Runtime/Implementations/Observable.cs +30 -0
- package/Runtime/Implementations/Observable.cs.meta +2 -0
- package/Runtime/Implementations/ObservableBase.cs +173 -0
- package/Runtime/Implementations/ObservableBase.cs.meta +2 -0
- package/Runtime/Implementations/ObservableCollection.cs +141 -0
- package/Runtime/Implementations/ObservableCollection.cs.meta +2 -0
- package/Runtime/Implementations/ObservableDictionary.cs +166 -0
- package/Runtime/Implementations/ObservableDictionary.cs.meta +2 -0
- package/Runtime/Implementations/ObservableList.cs +163 -0
- package/Runtime/Implementations/ObservableList.cs.meta +2 -0
- package/Runtime/Implementations/ObservableSet.cs +137 -0
- package/Runtime/Implementations/ObservableSet.cs.meta +2 -0
- package/Runtime/Implementations/ObservableValue.cs +59 -0
- package/Runtime/Implementations/ObservableValue.cs.meta +2 -0
- package/Runtime/Implementations.meta +8 -0
- package/Runtime/Observables/BatchObservable.cs +72 -0
- package/Runtime/Observables/BatchObservable.cs.meta +2 -0
- package/Runtime/Observables/CastObservable.cs +128 -0
- package/Runtime/Observables/CastObservable.cs.meta +2 -0
- package/Runtime/Observables/CombineObservable.cs +96 -0
- package/Runtime/Observables/CombineObservable.cs.meta +2 -0
- package/Runtime/Observables/CombineValueObservable.cs +319 -0
- package/Runtime/Observables/CombineValueObservable.cs.meta +2 -0
- package/Runtime/Observables/ConcatObservable.cs +75 -0
- package/Runtime/Observables/ConcatObservable.cs.meta +2 -0
- package/Runtime/Observables/ContainsObservable.cs +71 -0
- package/Runtime/Observables/ContainsObservable.cs.meta +2 -0
- package/Runtime/Observables/CountObservable.cs +29 -0
- package/Runtime/Observables/CountObservable.cs.meta +2 -0
- package/Runtime/Observables/DistinctObservable.cs +55 -0
- package/Runtime/Observables/DistinctObservable.cs.meta +2 -0
- package/Runtime/Observables/FirstObservable.cs +53 -0
- package/Runtime/Observables/FirstObservable.cs.meta +2 -0
- package/Runtime/Observables/IndexOfObservable.cs +83 -0
- package/Runtime/Observables/IndexOfObservable.cs.meta +2 -0
- package/Runtime/Observables/OperationStreamObservable.cs +194 -0
- package/Runtime/Observables/OperationStreamObservable.cs.meta +2 -0
- package/Runtime/Observables/OrderByObservable.cs +116 -0
- package/Runtime/Observables/OrderByObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectCollectionObservable.cs +29 -0
- package/Runtime/Observables/SelectCollectionObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectListObservable.cs +29 -0
- package/Runtime/Observables/SelectListObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectManyObservable.cs +78 -0
- package/Runtime/Observables/SelectManyObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectValueObservable.cs +28 -0
- package/Runtime/Observables/SelectValueObservable.cs.meta +2 -0
- package/Runtime/Observables/SkipWhileObservable.cs +32 -0
- package/Runtime/Observables/SkipWhileObservable.cs.meta +2 -0
- package/Runtime/Observables/ThenObservable.cs +209 -0
- package/Runtime/Observables/ThenObservable.cs.meta +2 -0
- package/Runtime/Observables/ToDictionaryObservable.cs +35 -0
- package/Runtime/Observables/ToDictionaryObservable.cs.meta +2 -0
- package/Runtime/Observables/TrackObservable.cs +74 -0
- package/Runtime/Observables/TrackObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapCollectionObservable.cs +64 -0
- package/Runtime/Observables/UnwrapCollectionObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapListObservable.cs +69 -0
- package/Runtime/Observables/UnwrapListObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapValueObservable.cs +56 -0
- package/Runtime/Observables/UnwrapValueObservable.cs.meta +2 -0
- package/Runtime/Observables/WhereObservable.cs +85 -0
- package/Runtime/Observables/WhereObservable.cs.meta +2 -0
- package/Runtime/Observables/WithPreviousObservable.cs +36 -0
- package/Runtime/Observables/WithPreviousObservable.cs.meta +2 -0
- package/Runtime/Observables.cs +467 -0
- package/Runtime/Observables.cs.meta +2 -0
- package/Runtime/Observables.meta +8 -0
- package/Runtime/ObservationContext.cs +126 -0
- package/Runtime/ObservationContext.cs.meta +2 -0
- package/Runtime/Observers.cs +403 -0
- package/Runtime/Observers.cs.meta +2 -0
- package/Runtime/Operators/BatchOperator.cs +71 -0
- package/Runtime/Operators/BatchOperator.cs.meta +2 -0
- package/Runtime/Operators/CollectionOperator.cs +30 -0
- package/Runtime/Operators/CollectionOperator.cs.meta +2 -0
- package/Runtime/Operators/DictionaryOperator.cs +45 -0
- package/Runtime/Operators/DictionaryOperator.cs.meta +2 -0
- package/Runtime/Operators/IInitializationOperationsProvider.cs +10 -0
- package/Runtime/Operators/IInitializationOperationsProvider.cs.meta +2 -0
- package/Runtime/Operators/ListOperator.cs +44 -0
- package/Runtime/Operators/ListOperator.cs.meta +2 -0
- package/Runtime/Operators/ObservableOperator.cs +75 -0
- package/Runtime/Operators/ObservableOperator.cs.meta +2 -0
- package/Runtime/Operators/Operator.cs +65 -0
- package/Runtime/Operators/Operator.cs.meta +2 -0
- package/Runtime/Operators/SetOperator.cs +44 -0
- package/Runtime/Operators/SetOperator.cs.meta +2 -0
- package/Runtime/Operators/ValueOperator.cs +30 -0
- package/Runtime/Operators/ValueOperator.cs.meta +2 -0
- package/Runtime/Operators.meta +8 -0
- package/Runtime/PriorityQueue.cs +1096 -0
- package/Runtime/PriorityQueue.cs.meta +2 -0
- package/Runtime/com.fofx.observething.asmdef +14 -0
- package/Runtime/com.fofx.observething.asmdef.meta +7 -0
- package/Runtime.meta +8 -0
- package/Tests/CollectionObservableTests.cs +739 -0
- package/Tests/CollectionObservableTests.cs.meta +2 -0
- package/Tests/DictionaryObservableTests.cs +85 -0
- package/Tests/DictionaryObservableTests.cs.meta +2 -0
- package/Tests/ListObservableTests.cs +148 -0
- package/Tests/ListObservableTests.cs.meta +2 -0
- package/Tests/ObservationContextTests.cs +359 -0
- package/Tests/ObservationContextTests.cs.meta +2 -0
- package/Tests/ValueObservableTests.cs +322 -0
- package/Tests/ValueObservableTests.cs.meta +2 -0
- package/Tests/com.fofx.observething.tests.asmdef +24 -0
- package/Tests/com.fofx.observething.tests.asmdef.meta +7 -0
- package/Tests.meta +8 -0
- package/package.json +24 -0
- package/package.json.meta +7 -0
|
@@ -0,0 +1,739 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using NUnit.Framework;
|
|
5
|
+
using UnityEngine.TestTools;
|
|
6
|
+
|
|
7
|
+
namespace ObserveThing.Tests
|
|
8
|
+
{
|
|
9
|
+
public class CollectionObservableTests
|
|
10
|
+
{
|
|
11
|
+
[SetUp]
|
|
12
|
+
public void SetUp()
|
|
13
|
+
{
|
|
14
|
+
Settings.DefaultExceptionHandler = UnityEngine.Debug.LogException;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private T Peek<T>(IValueObservable<T> observable)
|
|
18
|
+
{
|
|
19
|
+
T result = default;
|
|
20
|
+
var observer = observable.Subscribe(x => result = x);
|
|
21
|
+
observer.Dispose();
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private List<T> Peek<T>(IListObservable<T> observable)
|
|
26
|
+
{
|
|
27
|
+
List<T> result = new List<T>();
|
|
28
|
+
var observer = observable.Subscribe((index, x) => result.Add(x));
|
|
29
|
+
observer.Dispose();
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private void AreEqual<T>(T expected, IValueObservable<T> observable)
|
|
34
|
+
=> Assert.AreEqual(expected, Peek(observable));
|
|
35
|
+
|
|
36
|
+
private void AreEqual<T>(IEnumerable<T> expected, IEnumerable<IValueObservable<T>> actual)
|
|
37
|
+
=> Assert.AreEqual(expected, actual.Select(x => Peek(x)));
|
|
38
|
+
|
|
39
|
+
private void AreEqual<T>(IEnumerable<T> expected, IValueObservable<T> observable)
|
|
40
|
+
=> Assert.AreEqual(expected, observable);
|
|
41
|
+
|
|
42
|
+
[Test]
|
|
43
|
+
public void TestOrderBy()
|
|
44
|
+
{
|
|
45
|
+
int callCount = 0;
|
|
46
|
+
List<ObservableValue<int>> results = new List<ObservableValue<int>>();
|
|
47
|
+
Exception exception = default;
|
|
48
|
+
bool disposed = false;
|
|
49
|
+
|
|
50
|
+
var list = new ObservableList<ObservableValue<int>>();
|
|
51
|
+
var orderBy = list.ObservableOrderBy(x => x.AsObservable()).Subscribe(
|
|
52
|
+
onAdd: (index, value) =>
|
|
53
|
+
{
|
|
54
|
+
callCount++;
|
|
55
|
+
results.Insert(index, value);
|
|
56
|
+
},
|
|
57
|
+
onRemove: (index, value) =>
|
|
58
|
+
{
|
|
59
|
+
callCount++;
|
|
60
|
+
results.RemoveAt(index);
|
|
61
|
+
},
|
|
62
|
+
onError: exc => exception = exc,
|
|
63
|
+
onDispose: () => disposed = true
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
var v1 = new ObservableValue<int>(2);
|
|
67
|
+
|
|
68
|
+
list.Add(new ObservableValue<int>(1));
|
|
69
|
+
list.Add(v1);
|
|
70
|
+
list.Add(new ObservableValue<int>(13));
|
|
71
|
+
list.Add(new ObservableValue<int>(2));
|
|
72
|
+
list.Add(new ObservableValue<int>(4));
|
|
73
|
+
|
|
74
|
+
Assert.AreEqual(5, callCount);
|
|
75
|
+
|
|
76
|
+
AreEqual(new int[] { 1, 2, 2, 4, 13 }, results);
|
|
77
|
+
|
|
78
|
+
list.Remove(results[1]);
|
|
79
|
+
|
|
80
|
+
Assert.AreEqual(6, callCount);
|
|
81
|
+
AreEqual(new int[] { 1, 2, 4, 13 }, results);
|
|
82
|
+
|
|
83
|
+
results[1].value = 22;
|
|
84
|
+
|
|
85
|
+
Assert.AreEqual(8, callCount);
|
|
86
|
+
AreEqual(new int[] { 1, 4, 13, 22 }, results);
|
|
87
|
+
|
|
88
|
+
results[2].value = -33;
|
|
89
|
+
|
|
90
|
+
Assert.AreEqual(10, callCount);
|
|
91
|
+
AreEqual(new int[] { -33, 1, 4, 22 }, results);
|
|
92
|
+
|
|
93
|
+
var multiAdd = new ObservableValue<int>(3);
|
|
94
|
+
|
|
95
|
+
list.Add(multiAdd);
|
|
96
|
+
list.Add(multiAdd);
|
|
97
|
+
list.Add(multiAdd);
|
|
98
|
+
list.Add(multiAdd);
|
|
99
|
+
list.Add(multiAdd);
|
|
100
|
+
|
|
101
|
+
Assert.AreEqual(15, callCount);
|
|
102
|
+
AreEqual(new int[] { -33, 1, 3, 3, 3, 3, 3, 4, 22 }, results);
|
|
103
|
+
|
|
104
|
+
multiAdd.value = 10;
|
|
105
|
+
|
|
106
|
+
Assert.AreEqual(25, callCount);
|
|
107
|
+
AreEqual(new int[] { -33, 1, 4, 10, 10, 10, 10, 10, 22 }, results);
|
|
108
|
+
|
|
109
|
+
list.Remove(multiAdd);
|
|
110
|
+
list.Remove(multiAdd);
|
|
111
|
+
|
|
112
|
+
Assert.AreEqual(27, callCount);
|
|
113
|
+
AreEqual(new int[] { -33, 1, 4, 10, 10, 10, 22 }, results);
|
|
114
|
+
|
|
115
|
+
multiAdd.value = 1;
|
|
116
|
+
|
|
117
|
+
Assert.AreEqual(33, callCount);
|
|
118
|
+
AreEqual(new int[] { -33, 1, 1, 1, 1, 4, 22 }, results);
|
|
119
|
+
|
|
120
|
+
multiAdd.value = 5;
|
|
121
|
+
|
|
122
|
+
Assert.AreEqual(39, callCount);
|
|
123
|
+
AreEqual(new int[] { -33, 1, 4, 5, 5, 5, 22 }, results);
|
|
124
|
+
|
|
125
|
+
orderBy.Dispose();
|
|
126
|
+
Assert.IsTrue(disposed);
|
|
127
|
+
|
|
128
|
+
list.Remove(results[1]);
|
|
129
|
+
Assert.AreEqual(39, callCount);
|
|
130
|
+
AreEqual(new int[] { -33, 1, 4, 5, 5, 5, 22 }, results);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[Test]
|
|
134
|
+
public void TestOrderByExternalCollection()
|
|
135
|
+
{
|
|
136
|
+
ObservableList<string> source = new ObservableList<string>();
|
|
137
|
+
List<string> destination = new List<string>();
|
|
138
|
+
|
|
139
|
+
source
|
|
140
|
+
.ObservableSelect(x => x)
|
|
141
|
+
.ObservableOrderBy(x => source.ObservableIndexOf(x).ObservableSelect(x => x.found ? x.index : -1))
|
|
142
|
+
.Subscribe(
|
|
143
|
+
onAdd: (index, value) => destination.Insert(index, value),
|
|
144
|
+
onRemove: (index, value) => destination.RemoveAt(index)
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
source.Add("cat");
|
|
148
|
+
source.Add("dog");
|
|
149
|
+
source.Add("frog");
|
|
150
|
+
|
|
151
|
+
Assert.That(destination, Is.EqualTo(source));
|
|
152
|
+
|
|
153
|
+
source.Remove("dog");
|
|
154
|
+
source.Add("me");
|
|
155
|
+
source.Insert(0, "meee");
|
|
156
|
+
|
|
157
|
+
Assert.That(destination, Is.EqualTo(source));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public struct TestStruct
|
|
161
|
+
{
|
|
162
|
+
public int value;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
[Test]
|
|
166
|
+
public void TestOrderByExternalStructCollection()
|
|
167
|
+
{
|
|
168
|
+
ObservableList<TestStruct> source = new ObservableList<TestStruct>();
|
|
169
|
+
List<TestStruct> destination = new List<TestStruct>();
|
|
170
|
+
|
|
171
|
+
source
|
|
172
|
+
.ObservableSelect(x => x)
|
|
173
|
+
.ObservableWhere(x => true)
|
|
174
|
+
.ObservableOrderBy(x => source.ObservableIndexOf(x).ObservableSelect(x => x.found ? x.index : -1))
|
|
175
|
+
.Subscribe(
|
|
176
|
+
onAdd: (index, value) => destination.Insert(index, value),
|
|
177
|
+
onRemove: (index, value) => destination.RemoveAt(index)
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
source.Add(new TestStruct() { value = 1 });
|
|
181
|
+
source.Add(new TestStruct() { value = 2 });
|
|
182
|
+
source.Add(new TestStruct() { value = 3 });
|
|
183
|
+
|
|
184
|
+
Assert.That(destination, Is.EqualTo(source));
|
|
185
|
+
|
|
186
|
+
source.Remove(new TestStruct() { value = 2 });
|
|
187
|
+
source.Add(new TestStruct() { value = 4 });
|
|
188
|
+
source.Insert(0, new TestStruct() { value = 10 });
|
|
189
|
+
|
|
190
|
+
Assert.That(destination, Is.EqualTo(source));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
[Test]
|
|
194
|
+
public void TestWhere()
|
|
195
|
+
{
|
|
196
|
+
int callCount = 0;
|
|
197
|
+
List<ObservableValue<int>> results = new List<ObservableValue<int>>();
|
|
198
|
+
Exception exception = default;
|
|
199
|
+
bool disposed = false;
|
|
200
|
+
|
|
201
|
+
var list = new ObservableList<ObservableValue<int>>();
|
|
202
|
+
var where = list.ObservableWhere(x => x.ObservableSelect(x => x % 2 == 0)).Subscribe(
|
|
203
|
+
onAdd: x =>
|
|
204
|
+
{
|
|
205
|
+
callCount++;
|
|
206
|
+
results.Add(x);
|
|
207
|
+
},
|
|
208
|
+
onRemove: x =>
|
|
209
|
+
{
|
|
210
|
+
callCount++;
|
|
211
|
+
results.Remove(x);
|
|
212
|
+
},
|
|
213
|
+
exc => exception = exc,
|
|
214
|
+
() => disposed = true
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
var v1 = new ObservableValue<int>(1);
|
|
218
|
+
var v2 = new ObservableValue<int>(6);
|
|
219
|
+
var v3 = new ObservableValue<int>(13);
|
|
220
|
+
var v4 = new ObservableValue<int>(2);
|
|
221
|
+
var v5 = new ObservableValue<int>(4);
|
|
222
|
+
|
|
223
|
+
list.Add(v1);
|
|
224
|
+
list.Add(v2);
|
|
225
|
+
list.Add(v3);
|
|
226
|
+
list.Add(v4);
|
|
227
|
+
list.Add(v5);
|
|
228
|
+
|
|
229
|
+
Assert.AreEqual(3, callCount);
|
|
230
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v4, v5 }));
|
|
231
|
+
|
|
232
|
+
list.Remove(v4);
|
|
233
|
+
|
|
234
|
+
Assert.AreEqual(4, callCount);
|
|
235
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
236
|
+
|
|
237
|
+
list.Remove(v3);
|
|
238
|
+
|
|
239
|
+
Assert.AreEqual(4, callCount);
|
|
240
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
241
|
+
|
|
242
|
+
list.Add(v3);
|
|
243
|
+
|
|
244
|
+
Assert.AreEqual(4, callCount);
|
|
245
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
246
|
+
|
|
247
|
+
var v6 = new ObservableValue<int>(8);
|
|
248
|
+
|
|
249
|
+
list.Add(v6);
|
|
250
|
+
|
|
251
|
+
Assert.AreEqual(5, callCount);
|
|
252
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5, v6 }));
|
|
253
|
+
|
|
254
|
+
v6.value = 7;
|
|
255
|
+
|
|
256
|
+
Assert.AreEqual(6, callCount);
|
|
257
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
258
|
+
|
|
259
|
+
v2.value = 8;
|
|
260
|
+
|
|
261
|
+
Assert.AreEqual(6, callCount);
|
|
262
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
263
|
+
|
|
264
|
+
where.Dispose();
|
|
265
|
+
Assert.IsTrue(disposed);
|
|
266
|
+
|
|
267
|
+
list.Remove(v2);
|
|
268
|
+
|
|
269
|
+
Assert.AreEqual(6, callCount);
|
|
270
|
+
Assert.That(results, Is.EquivalentTo(new[] { v2, v5 }));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
[Test]
|
|
274
|
+
public void TestDistinct()
|
|
275
|
+
{
|
|
276
|
+
int callCount = 0;
|
|
277
|
+
List<int> results = new List<int>();
|
|
278
|
+
Exception exception = default;
|
|
279
|
+
bool disposed = false;
|
|
280
|
+
|
|
281
|
+
var list = new ObservableList<int>();
|
|
282
|
+
var distinct = list.ObservableDistinct().Subscribe(
|
|
283
|
+
onAdd: x =>
|
|
284
|
+
{
|
|
285
|
+
callCount++;
|
|
286
|
+
results.Add(x);
|
|
287
|
+
},
|
|
288
|
+
onRemove: x =>
|
|
289
|
+
{
|
|
290
|
+
callCount++;
|
|
291
|
+
results.Remove(x);
|
|
292
|
+
},
|
|
293
|
+
exc => exception = exc,
|
|
294
|
+
() => disposed = true
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
list.Add(1);
|
|
298
|
+
list.Add(6);
|
|
299
|
+
list.Add(6);
|
|
300
|
+
list.Add(6);
|
|
301
|
+
list.Add(13);
|
|
302
|
+
list.Add(2);
|
|
303
|
+
list.Add(4);
|
|
304
|
+
list.Add(4);
|
|
305
|
+
|
|
306
|
+
Assert.AreEqual(5, callCount);
|
|
307
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 6, 2, 4, 13 }));
|
|
308
|
+
|
|
309
|
+
list.Remove(4);
|
|
310
|
+
|
|
311
|
+
Assert.AreEqual(5, callCount);
|
|
312
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 6, 2, 4, 13 }));
|
|
313
|
+
|
|
314
|
+
list.Remove(1);
|
|
315
|
+
|
|
316
|
+
Assert.AreEqual(6, callCount);
|
|
317
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 6, 2, 4, 13 }));
|
|
318
|
+
|
|
319
|
+
list.Add(13);
|
|
320
|
+
|
|
321
|
+
Assert.AreEqual(6, callCount);
|
|
322
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 6, 2, 4, 13 }));
|
|
323
|
+
|
|
324
|
+
distinct.Dispose();
|
|
325
|
+
Assert.IsTrue(disposed);
|
|
326
|
+
|
|
327
|
+
list.Add(100);
|
|
328
|
+
|
|
329
|
+
Assert.AreEqual(6, callCount);
|
|
330
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 6, 2, 4, 13 }));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
[Test]
|
|
334
|
+
public void TestConcat()
|
|
335
|
+
{
|
|
336
|
+
int callCount = 0;
|
|
337
|
+
List<int> results = new List<int>();
|
|
338
|
+
Exception exception = default;
|
|
339
|
+
bool disposed = false;
|
|
340
|
+
|
|
341
|
+
var list1 = new ObservableList<int>();
|
|
342
|
+
var list2 = new ObservableList<int>();
|
|
343
|
+
var concat = list1.ObservableConcat(list2.AsObservable()).Subscribe(
|
|
344
|
+
onAdd: x =>
|
|
345
|
+
{
|
|
346
|
+
callCount++;
|
|
347
|
+
results.Add(x);
|
|
348
|
+
},
|
|
349
|
+
onRemove: x =>
|
|
350
|
+
{
|
|
351
|
+
callCount++;
|
|
352
|
+
results.Remove(x);
|
|
353
|
+
},
|
|
354
|
+
exc => exception = exc,
|
|
355
|
+
() => disposed = true
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
list1.Add(1);
|
|
359
|
+
list1.Add(2);
|
|
360
|
+
list1.Add(3);
|
|
361
|
+
|
|
362
|
+
list2.Add(4);
|
|
363
|
+
list2.Add(5);
|
|
364
|
+
list2.Add(6);
|
|
365
|
+
|
|
366
|
+
Assert.AreEqual(6, callCount);
|
|
367
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6 }));
|
|
368
|
+
|
|
369
|
+
list2.Add(7);
|
|
370
|
+
|
|
371
|
+
Assert.AreEqual(7, callCount);
|
|
372
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6, 7 }));
|
|
373
|
+
|
|
374
|
+
list2.Remove(4);
|
|
375
|
+
|
|
376
|
+
Assert.AreEqual(8, callCount);
|
|
377
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 5, 6, 7 }));
|
|
378
|
+
|
|
379
|
+
list1.Add(8);
|
|
380
|
+
|
|
381
|
+
Assert.AreEqual(9, callCount);
|
|
382
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 5, 6, 7, 8 }));
|
|
383
|
+
|
|
384
|
+
list1.Remove(3);
|
|
385
|
+
|
|
386
|
+
Assert.AreEqual(10, callCount);
|
|
387
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 5, 6, 7, 8 }));
|
|
388
|
+
|
|
389
|
+
list2.Add(8);
|
|
390
|
+
|
|
391
|
+
Assert.AreEqual(11, callCount);
|
|
392
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 5, 6, 7, 8, 8 }));
|
|
393
|
+
|
|
394
|
+
list1.Remove(8);
|
|
395
|
+
|
|
396
|
+
Assert.AreEqual(12, callCount);
|
|
397
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 5, 6, 7, 8 }));
|
|
398
|
+
|
|
399
|
+
list1.Dispose();
|
|
400
|
+
Assert.IsTrue(disposed);
|
|
401
|
+
|
|
402
|
+
list2.Add(100);
|
|
403
|
+
|
|
404
|
+
Assert.AreEqual(12, callCount);
|
|
405
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 5, 6, 7, 8 }));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
[Test]
|
|
409
|
+
public void TestSelectMany()
|
|
410
|
+
{
|
|
411
|
+
int callCount = 0;
|
|
412
|
+
List<int> results = new List<int>();
|
|
413
|
+
Exception exception = default;
|
|
414
|
+
bool disposed = false;
|
|
415
|
+
|
|
416
|
+
var list = new ObservableList<ObservableList<int>>();
|
|
417
|
+
var selectMany = list.ObservableSelectMany(x => x.AsObservable()).Subscribe(
|
|
418
|
+
x =>
|
|
419
|
+
{
|
|
420
|
+
callCount++;
|
|
421
|
+
results.Add(x);
|
|
422
|
+
},
|
|
423
|
+
x =>
|
|
424
|
+
{
|
|
425
|
+
callCount++;
|
|
426
|
+
results.Remove(x);
|
|
427
|
+
},
|
|
428
|
+
exc => exception = exc,
|
|
429
|
+
() => disposed = true
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
var arr1 = new ObservableList<int>(new[] { 1, 2, 3 });
|
|
433
|
+
var arr2 = new ObservableList<int>(new[] { 4, 5, 6 });
|
|
434
|
+
var arr3 = new ObservableList<int>(new[] { 7, 8, 9 });
|
|
435
|
+
|
|
436
|
+
list.Add(arr1);
|
|
437
|
+
list.Add(arr2);
|
|
438
|
+
list.Add(arr3);
|
|
439
|
+
|
|
440
|
+
Assert.AreEqual(9, callCount);
|
|
441
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
|
|
442
|
+
|
|
443
|
+
list.Remove(arr2);
|
|
444
|
+
|
|
445
|
+
Assert.AreEqual(12, callCount);
|
|
446
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 7, 8, 9 }));
|
|
447
|
+
|
|
448
|
+
list.Add(arr2);
|
|
449
|
+
list.Add(arr2);
|
|
450
|
+
|
|
451
|
+
Assert.AreEqual(18, callCount);
|
|
452
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9 }));
|
|
453
|
+
|
|
454
|
+
arr1.Add(100);
|
|
455
|
+
|
|
456
|
+
Assert.AreEqual(19, callCount);
|
|
457
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9, 100 }));
|
|
458
|
+
|
|
459
|
+
arr3.Remove(9);
|
|
460
|
+
|
|
461
|
+
Assert.AreEqual(20, callCount);
|
|
462
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 100 }));
|
|
463
|
+
|
|
464
|
+
arr2.Remove(5);
|
|
465
|
+
|
|
466
|
+
Assert.AreEqual(22, callCount);
|
|
467
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 6, 4, 6, 7, 8, 100 }));
|
|
468
|
+
|
|
469
|
+
arr2.Add(44);
|
|
470
|
+
|
|
471
|
+
Assert.AreEqual(24, callCount);
|
|
472
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 6, 4, 6, 7, 8, 100, 44, 44 }));
|
|
473
|
+
|
|
474
|
+
list.Dispose();
|
|
475
|
+
Assert.IsTrue(disposed);
|
|
476
|
+
|
|
477
|
+
Assert.Throws(typeof(ObjectDisposedException), () => list.Add(arr1));
|
|
478
|
+
|
|
479
|
+
Assert.AreEqual(24, callCount);
|
|
480
|
+
Assert.That(results, Is.EquivalentTo(new int[] { 1, 2, 3, 4, 6, 4, 6, 7, 8, 100, 44, 44 }));
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
[Test]
|
|
484
|
+
public void TestSelect()
|
|
485
|
+
{
|
|
486
|
+
var result = new List<string>();
|
|
487
|
+
var list = new ObservableList<int>();
|
|
488
|
+
bool disposed = false;
|
|
489
|
+
bool receivedCall = false;
|
|
490
|
+
|
|
491
|
+
var select = list.ObservableSelect(x => x.ToString()).Subscribe(
|
|
492
|
+
onAdd: x =>
|
|
493
|
+
{
|
|
494
|
+
result.Add(x);
|
|
495
|
+
receivedCall = true;
|
|
496
|
+
},
|
|
497
|
+
onRemove: x =>
|
|
498
|
+
{
|
|
499
|
+
result.Remove(x);
|
|
500
|
+
receivedCall = true;
|
|
501
|
+
},
|
|
502
|
+
onDispose: () => disposed = true
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
list.Add(1);
|
|
506
|
+
list.Add(1);
|
|
507
|
+
list.Add(2);
|
|
508
|
+
list.Add(3);
|
|
509
|
+
list.Add(4);
|
|
510
|
+
list.Add(45);
|
|
511
|
+
|
|
512
|
+
CollectionAssert.AreEquivalent(
|
|
513
|
+
Enumerable.Select(list, x => x.ToString()),
|
|
514
|
+
result
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
list.Remove(3);
|
|
518
|
+
list.Remove(3);
|
|
519
|
+
list.Add(1);
|
|
520
|
+
list.Add(45);
|
|
521
|
+
list.Remove(45);
|
|
522
|
+
|
|
523
|
+
CollectionAssert.AreEquivalent(
|
|
524
|
+
Enumerable.Select(list, x => x.ToString()),
|
|
525
|
+
result
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
list.Clear();
|
|
529
|
+
|
|
530
|
+
CollectionAssert.AreEquivalent(
|
|
531
|
+
Enumerable.Select(list, x => x.ToString()),
|
|
532
|
+
result
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
receivedCall = false;
|
|
536
|
+
select.Dispose();
|
|
537
|
+
|
|
538
|
+
list.Add(234);
|
|
539
|
+
|
|
540
|
+
Assert.IsTrue(disposed);
|
|
541
|
+
Assert.IsFalse(receivedCall);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
[Test]
|
|
545
|
+
public void TestShallowCopy()
|
|
546
|
+
{
|
|
547
|
+
bool disposed = false;
|
|
548
|
+
bool callReceived = false;
|
|
549
|
+
var result = new List<float>();
|
|
550
|
+
var source = new ObservableList<ObservableValue<float>>(
|
|
551
|
+
new ObservableValue<float>(1),
|
|
552
|
+
new ObservableValue<float>(2),
|
|
553
|
+
new ObservableValue<float>(3)
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
var stream = source.ObservableUnwrap().Subscribe(
|
|
557
|
+
onAdd: (_, x) =>
|
|
558
|
+
{
|
|
559
|
+
result.Add(x);
|
|
560
|
+
callReceived = true;
|
|
561
|
+
},
|
|
562
|
+
onRemove: (_, x) =>
|
|
563
|
+
{
|
|
564
|
+
result.Remove(x);
|
|
565
|
+
callReceived = true;
|
|
566
|
+
},
|
|
567
|
+
onDispose: () => disposed = true
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
Assert.That(result, Is.EquivalentTo(new float[] { 1, 2, 3 }));
|
|
571
|
+
|
|
572
|
+
((ObservableValue<float>)source[1]).value = 3;
|
|
573
|
+
|
|
574
|
+
Assert.That(result, Is.EquivalentTo(new float[] { 1, 3, 3 }));
|
|
575
|
+
|
|
576
|
+
var removed = source[1];
|
|
577
|
+
source.RemoveAt(1);
|
|
578
|
+
|
|
579
|
+
Assert.That(result, Is.EquivalentTo(new float[] { 1, 3 }));
|
|
580
|
+
|
|
581
|
+
((ObservableValue<float>)removed).value = 100;
|
|
582
|
+
|
|
583
|
+
Assert.That(result, Is.EquivalentTo(new float[] { 1, 3 }));
|
|
584
|
+
|
|
585
|
+
source.Add(new ObservableValue<float>(55));
|
|
586
|
+
source.Add(new ObservableValue<float>(55));
|
|
587
|
+
source.Add(new ObservableValue<float>(1));
|
|
588
|
+
|
|
589
|
+
Assert.That(result, Is.EquivalentTo(new float[] { 1, 1, 3, 55, 55 }));
|
|
590
|
+
|
|
591
|
+
source.Clear();
|
|
592
|
+
|
|
593
|
+
Assert.That(result, Is.EquivalentTo(new float[] { }));
|
|
594
|
+
|
|
595
|
+
callReceived = false;
|
|
596
|
+
stream.Dispose();
|
|
597
|
+
|
|
598
|
+
source.Add(new ObservableValue<float>(100));
|
|
599
|
+
Assert.IsTrue(disposed);
|
|
600
|
+
Assert.IsFalse(callReceived);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
public class TestElement
|
|
604
|
+
{
|
|
605
|
+
public ObservableValue<int> intValue = new ObservableValue<int>();
|
|
606
|
+
public ObservableValue<string> stringValue = new ObservableValue<string>();
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
[Test]
|
|
610
|
+
public void TestErrorLog()
|
|
611
|
+
{
|
|
612
|
+
var dict = new ObservableDictionary<int, string>();
|
|
613
|
+
var stream = dict.ObservableSelect(x =>
|
|
614
|
+
{
|
|
615
|
+
if (x.Key != 0)
|
|
616
|
+
throw new Exception("Oh no! First");
|
|
617
|
+
|
|
618
|
+
return x.Key;
|
|
619
|
+
|
|
620
|
+
}).ObservableSelect(x =>
|
|
621
|
+
{
|
|
622
|
+
if (x != 0)
|
|
623
|
+
throw new Exception("Oh no! Second");
|
|
624
|
+
|
|
625
|
+
return x;
|
|
626
|
+
|
|
627
|
+
}).Subscribe(onAdd: null, onRemove: null, onError: null, onDispose: null);
|
|
628
|
+
|
|
629
|
+
LogAssert.Expect(UnityEngine.LogType.Exception, "Exception: Oh no! First");
|
|
630
|
+
dict.Add(10, "cat");
|
|
631
|
+
|
|
632
|
+
LogAssert.Expect(UnityEngine.LogType.Exception, "Exception: Oh no! First");
|
|
633
|
+
dict.Add(11, "dog");
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
[Test]
|
|
637
|
+
public void TestFirst()
|
|
638
|
+
{
|
|
639
|
+
(bool found, ObservableValue<int> value) result = default;
|
|
640
|
+
bool receivedCall = false;
|
|
641
|
+
bool disposed = false;
|
|
642
|
+
|
|
643
|
+
var source = new ObservableList<ObservableValue<int>>(
|
|
644
|
+
new ObservableValue<int>(1),
|
|
645
|
+
new ObservableValue<int>(4),
|
|
646
|
+
new ObservableValue<int>(4),
|
|
647
|
+
new ObservableValue<int>(13)
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
var subscription = source.ObservableFirst(x => x.ObservableSelect(x => x == 4))
|
|
651
|
+
.Subscribe(
|
|
652
|
+
onNext: x =>
|
|
653
|
+
{
|
|
654
|
+
result = new(x.found, x.value);
|
|
655
|
+
receivedCall = true;
|
|
656
|
+
},
|
|
657
|
+
onDispose: () => disposed = true
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
Assert.IsTrue(result.found);
|
|
661
|
+
Assert.AreEqual(source[1], result.value);
|
|
662
|
+
|
|
663
|
+
source[1].value = 100;
|
|
664
|
+
|
|
665
|
+
Assert.IsTrue(result.found);
|
|
666
|
+
Assert.AreEqual(source[2], result.value);
|
|
667
|
+
|
|
668
|
+
source.RemoveAt(2);
|
|
669
|
+
|
|
670
|
+
Assert.IsFalse(result.found);
|
|
671
|
+
Assert.IsNull(result.value);
|
|
672
|
+
|
|
673
|
+
source[0].value = 4;
|
|
674
|
+
|
|
675
|
+
Assert.IsTrue(result.found);
|
|
676
|
+
Assert.AreEqual(source[0], result.value);
|
|
677
|
+
|
|
678
|
+
source.Dispose();
|
|
679
|
+
|
|
680
|
+
Assert.IsTrue(disposed);
|
|
681
|
+
|
|
682
|
+
receivedCall = false;
|
|
683
|
+
source[0].value = 0;
|
|
684
|
+
|
|
685
|
+
Assert.IsFalse(receivedCall);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
[Test]
|
|
689
|
+
public void TestFirstOrDefault()
|
|
690
|
+
{
|
|
691
|
+
ObservableValue<int> result = default;
|
|
692
|
+
bool receivedCall = false;
|
|
693
|
+
bool disposed = false;
|
|
694
|
+
|
|
695
|
+
var source = new ObservableList<ObservableValue<int>>(
|
|
696
|
+
new ObservableValue<int>(1),
|
|
697
|
+
new ObservableValue<int>(4),
|
|
698
|
+
new ObservableValue<int>(4),
|
|
699
|
+
new ObservableValue<int>(13)
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
var subscription = source.ObservableFirstOrDefault(x => x.ObservableSelect(x => x == 4))
|
|
703
|
+
.Subscribe(
|
|
704
|
+
onNext: x =>
|
|
705
|
+
{
|
|
706
|
+
result = x;
|
|
707
|
+
receivedCall = true;
|
|
708
|
+
},
|
|
709
|
+
onDispose: () => disposed = true
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
Assert.IsNotNull(result);
|
|
713
|
+
Assert.AreEqual(source[1], result);
|
|
714
|
+
|
|
715
|
+
source[1].value = 100;
|
|
716
|
+
|
|
717
|
+
Assert.IsNotNull(result);
|
|
718
|
+
Assert.AreEqual(source[2], result);
|
|
719
|
+
|
|
720
|
+
source.RemoveAt(2);
|
|
721
|
+
|
|
722
|
+
Assert.IsNull(result);
|
|
723
|
+
|
|
724
|
+
source[0].value = 4;
|
|
725
|
+
|
|
726
|
+
Assert.IsNotNull(result);
|
|
727
|
+
Assert.AreEqual(source[0], result);
|
|
728
|
+
|
|
729
|
+
source.Dispose();
|
|
730
|
+
|
|
731
|
+
Assert.IsTrue(disposed);
|
|
732
|
+
|
|
733
|
+
receivedCall = false;
|
|
734
|
+
source[0].value = 0;
|
|
735
|
+
|
|
736
|
+
Assert.IsFalse(receivedCall);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|