From 36d18e0f34457d4682fea1d68e2e65e8800f87fc Mon Sep 17 00:00:00 2001
From: Glenn <5834289+glennawatson@users.noreply.github.com>
Date: Thu, 26 Nov 2020 08:01:53 +0000
Subject: [PATCH] feature: Update to rx 5.0.0 and .net 5 and nullability (#440)
---
.github/workflows/ci-build.yml | 50 +-
src/Directory.Build.props | 8 +-
src/Directory.build.targets | 5 +
.../Cache/SourceCache.cs | 5 +-
src/DynamicData.Benchmarks/List/GroupAdd.cs | 3 +-
.../List/GroupRemove.cs | 3 +-
src/DynamicData.Benchmarks/List/SourceList.cs | 5 +-
.../AggregationTests/AggregationFixture.cs | 78 +-
.../AggregationTests/AverageFixture.cs | 54 +-
.../AggregationTests/MaxFixture.cs | 54 +-
.../AggregationTests/MinFixture.cs | 53 +-
.../AggregationTests/SumFixture.cs | 54 +-
src/DynamicData.Tests/AutoRefreshFilter.cs | 37 +-
.../Binding/BindingLIstBindListFixture.cs | 59 +-
.../Binding/BindingListBindCacheFixture.cs | 67 +-
.../BindingListBindCacheSortedFixture.cs | 181 +-
.../Binding/BindingListToChangeSetFixture.cs | 86 +-
...eeplyNestedNotifyPropertyChangedFixture.cs | 223 +-
.../IObservableListBindCacheFixture.cs | 78 +-
.../IObservableListBindCacheSortedFixture.cs | 267 +-
.../Binding/IObservableListBindListFixture.cs | 86 +-
.../Binding/NotifyPropertyChangedExFixture.cs | 90 +-
.../ObservableCollectionBindCacheFixture.cs | 88 +-
...ervableCollectionBindCacheSortedFixture.cs | 222 +-
.../ObservableCollectionBindListFixture.cs | 65 +-
...bleCollectionExtendedToChangeSetFixture.cs | 47 +-
.../ObservableCollectionToChangeSetFixture.cs | 50 +-
...yObservableCollectionToChangeSetFixture.cs | 99 +-
src/DynamicData.Tests/Cache/AndFixture.cs | 54 +-
.../Cache/AutoRefreshFixture.cs | 157 +-
src/DynamicData.Tests/Cache/BatchFixture.cs | 15 +-
src/DynamicData.Tests/Cache/BatchIfFixture.cs | 104 +-
.../Cache/BatchIfWithTimeOutFixture.cs | 231 +-
.../Cache/BufferInitialFixture.cs | 32 +-
.../Cache/ChangesReducerFixture.cs | 115 +-
.../Cache/DeferUntilLoadedFixture.cs | 29 +-
.../Cache/DisposeManyFixture.cs | 63 +-
.../Cache/DistinctFixture.cs | 151 +-
.../Cache/DynamicAndFixture.cs | 114 +-
.../Cache/DynamicExceptFixture.cs | 108 +-
.../Cache/DynamicOrFixture.cs | 111 +-
.../Cache/DynamicXorFixture.cs | 109 +-
.../Cache/EditDiffFixture.cs | 126 +-
...eObservableToObservableChangeSetFixture.cs | 111 +-
src/DynamicData.Tests/Cache/ExceptFixture.cs | 38 +-
.../Cache/ExpireAfterFixture.cs | 68 +-
.../Cache/FilterControllerFixture.cs | 274 +-
src/DynamicData.Tests/Cache/FilterFixture.cs | 107 +-
.../Cache/FilterOnPropertyFixture.cs | 68 +-
.../Cache/FilterParallelFixture.cs | 72 +-
.../Cache/ForEachChangeFixture.cs | 19 +-
.../Cache/FromAsyncFixture.cs | 41 +-
.../Cache/FullJoinFixture.cs | 312 +-
.../Cache/FullJoinManyFixture.cs | 166 +-
.../Cache/GroupControllerFixture.cs | 49 +-
.../GroupControllerForFilteredItemsFixture.cs | 52 +-
src/DynamicData.Tests/Cache/GroupFixture.cs | 355 +-
.../Cache/GroupFromDistinctFixture.cs | 32 +-
.../Cache/GroupImmutableFixture.cs | 195 +-
.../Cache/GroupOnPropertyFixture.cs | 81 +-
...roupOnPropertyWithImmutableStateFixture.cs | 75 +-
.../Cache/IgnoreUpdateFixture.cs | 28 +-
.../Cache/IncludeUpdateFixture.cs | 28 +-
.../Cache/InnerJoinFixture.cs | 297 +-
.../Cache/InnerJoinFixtureRaceCondition.cs | 38 +-
.../Cache/InnerJoinManyFixture.cs | 161 +-
.../Cache/KeyValueCollectionEx.cs | 10 +-
.../Cache/LeftJoinFixture.cs | 301 +-
.../Cache/LeftJoinManyFixture.cs | 158 +-
.../Cache/MergeManyFixture.cs | 82 +-
.../Cache/MergeManyItemsFixture.cs | 110 +-
.../Cache/MergeManyWithKeyOverloadFixture.cs | 127 +-
.../Cache/MonitorStatusFixture.cs | 73 +-
.../Cache/ObservableCachePreviewFixture.cs | 148 +-
.../Cache/ObservableChangeSetFixture.cs | 187 +-
.../ObservableToObservableChangeSetFixture.cs | 168 +-
src/DynamicData.Tests/Cache/OnItemFixture.cs | 14 +-
src/DynamicData.Tests/Cache/OrFixture.cs | 38 +-
src/DynamicData.Tests/Cache/PageFixture.cs | 103 +-
.../Cache/QueryWhenChangedFixture.cs | 61 +-
.../Cache/RefCountFixture.cs | 106 +-
.../Cache/RightJoinFixture.cs | 293 +-
.../Cache/RightJoinManyFixture.cs | 162 +-
.../Cache/SizeLimitFixture.cs | 86 +-
src/DynamicData.Tests/Cache/SortFixture.cs | 1247 ++-
.../Cache/SortObservableFixtureFixture.cs | 79 +-
.../Cache/SourceCacheFixture.cs | 108 +-
.../Cache/SubscribeManyFixture.cs | 86 +-
src/DynamicData.Tests/Cache/SwitchFixture.cs | 44 +-
.../Cache/TimeExpiryFixture.cs | 60 +-
.../Cache/ToObservableChangeSetFixture.cs | 43 +-
...bservableChangeSetFixtureWithCompletion.cs | 27 +-
.../Cache/ToSortedCollectionFixture.cs | 91 +-
.../Cache/TransformAsyncFixture.cs | 305 +-
.../Cache/TransformFixture.cs | 239 +-
.../Cache/TransformFixtureParallel.cs | 130 +-
.../Cache/TransformManyFixture.cs | 50 +-
.../TransformManyObservableCacheFixture.cs | 276 +-
.../Cache/TransformManyRefreshFixture.cs | 43 +-
.../Cache/TransformManySimpleFixture.cs | 123 +-
.../Cache/TransformSafeAsyncFixture.cs | 134 +-
.../Cache/TransformSafeFixture.cs | 105 +-
.../Cache/TransformSafeParallelFixture.cs | 101 +-
.../Cache/TransformTreeFixture.cs | 293 +-
.../Cache/TransformTreeWithRefreshFixture.cs | 168 +-
.../Cache/TrueForAllFixture.cs | 74 +-
.../Cache/TrueForAnyFixture.cs | 59 +-
src/DynamicData.Tests/Cache/WatchFixture.cs | 65 +-
src/DynamicData.Tests/Cache/WatcherFixture.cs | 86 +-
src/DynamicData.Tests/Cache/XorFixture.cs | 44 +-
src/DynamicData.Tests/Domain/Animal.cs | 30 +-
.../Domain/ParentAndChildren.cs | 47 +-
src/DynamicData.Tests/Domain/ParentChild.cs | 7 +-
src/DynamicData.Tests/Domain/Person.cs | 72 +-
.../Domain/PersonEmployment.cs | 39 +-
src/DynamicData.Tests/Domain/PersonObs.cs | 66 +-
.../Domain/PersonWithChildren.cs | 25 +-
.../Domain/PersonWithEmployment.cs | 6 +-
.../Domain/PersonWithFriends.cs | 20 +-
.../Domain/PersonWithGender.cs | 40 +-
.../Domain/PersonWithRelations.cs | 30 +-
src/DynamicData.Tests/Domain/Pet.cs | 8 +-
.../Domain/RandomPersonGenerator.cs | 69 +-
.../Domain/SelfObservingPerson.cs | 26 +-
.../DynamicData.Tests.csproj | 10 +-
src/DynamicData.Tests/EnumerableExFixtures.cs | 39 +-
.../Kernal/CacheUpdaterFixture.cs | 13 +-
.../Kernal/DistinctUpdateFixture.cs | 6 +-
src/DynamicData.Tests/Kernal/EnumerableEx.cs | 49 +-
.../Kernal/KeyValueFixture.cs | 6 +-
src/DynamicData.Tests/Kernal/OptionFixture.cs | 75 +-
.../Kernal/SourceUpdaterFixture.cs | 9 +-
src/DynamicData.Tests/Kernal/UpdateFixture.cs | 6 +-
src/DynamicData.Tests/List/AndFixture.cs | 53 +-
.../List/AutoRefreshFixture.cs | 641 +-
src/DynamicData.Tests/List/BatchFixture.cs | 24 +-
src/DynamicData.Tests/List/BatchIfFixture.cs | 73 +-
.../List/BatchIfWithTimeOutFixture.cs | 67 +-
src/DynamicData.Tests/List/BufferFixture.cs | 19 +-
.../List/BufferInitialFixture.cs | 32 +-
src/DynamicData.Tests/List/CastFixture.cs | 28 +-
.../List/ChangeAwareListFixture.cs | 156 +-
.../List/CloneChangesFixture.cs | 119 +-
src/DynamicData.Tests/List/CloneFixture.cs | 78 +-
.../List/CreationFixtures.cs | 28 +-
.../List/DeferUntilLoadedFixture.cs | 29 +-
.../List/DisposeManyFixture.cs | 57 +-
.../List/DistinctValuesFixture.cs | 99 +-
.../List/DynamicAndFixture.cs | 108 +-
.../List/DynamicExceptFixture.cs | 157 +-
.../List/DynamicOrFixture.cs | 139 +-
.../List/DynamicXOrFixture.cs | 134 +-
src/DynamicData.Tests/List/EditDiffFixture.cs | 51 +-
src/DynamicData.Tests/List/ExceptFixture.cs | 77 +-
.../List/ExpireAfterFixture.cs | 58 +-
...terControllerFixtureWithClearAndReplace.cs | 198 +-
.../FilterControllerFixtureWithDiffSet.cs | 170 +-
src/DynamicData.Tests/List/FilterFixture.cs | 164 +-
.../List/FilterOnObservableFixture.cs | 127 +-
.../List/FilterOnPropertyFixture.cs | 87 +-
.../List/FilterWithObservable.cs | 273 +-
.../List/ForEachChangeFixture.cs | 43 +-
.../List/FromAsyncFixture.cs | 36 +-
.../List/GroupImmutableFixture.cs | 201 +-
src/DynamicData.Tests/List/GroupOnFixture.cs | 45 +-
.../List/GroupOnPropertyFixture.cs | 87 +-
...roupOnPropertyWithImmutableStateFixture.cs | 77 +-
.../List/MergeManyChangeSetsFixture.cs | 11 +-
.../List/MergeManyFixture.cs | 81 +-
src/DynamicData.Tests/List/OrFixture.cs | 55 +-
src/DynamicData.Tests/List/PageFixture.cs | 150 +-
.../List/QueryWhenChangedFixture.cs | 77 +-
.../List/RecursiveTransformManyFixture.cs | 46 +-
src/DynamicData.Tests/List/RefCountFixture.cs | 88 +-
.../List/RemoveManyFixture.cs | 29 +-
src/DynamicData.Tests/List/ReverseFixture.cs | 74 +-
src/DynamicData.Tests/List/SelectFixture.cs | 99 +-
.../List/SizeLimitFixture.cs | 46 +-
src/DynamicData.Tests/List/SortFixture.cs | 90 +-
.../List/SortMutableFixture.cs | 141 +-
.../List/SortPrimitiveFixture.cs | 12 +-
.../List/SourceListPreviewFixture.cs | 160 +-
.../List/SubscribeManyFixture.cs | 92 +-
src/DynamicData.Tests/List/SwitchFixture.cs | 50 +-
.../List/ToObservableChangeSetFixture.cs | 44 +-
.../List/TransformAsyncFixture.cs | 23 +-
.../List/TransformFixture.cs | 128 +-
.../List/TransformManyFixture.cs | 190 +-
...ransformManyObservableCollectionFixture.cs | 366 +-
.../List/TransformManyProjectionFixture.cs | 201 +-
.../List/TransformManyRefreshFixture.cs | 44 +-
.../List/VirtualisationFixture.cs | 81 +-
src/DynamicData.Tests/List/XOrFixture.cs | 65 +-
.../Utilities/SelectManyExtensions.cs | 69 +-
.../Aggregation/AggregateEnumerator.cs | 14 +-
src/DynamicData/Aggregation/AggregateItem.cs | 36 +-
src/DynamicData/Aggregation/AggregateType.cs | 10 +-
src/DynamicData/Aggregation/AggregationEx.cs | 140 +-
src/DynamicData/Aggregation/Avg.cs | 5 +-
src/DynamicData/Aggregation/AvgEx.cs | 426 +-
src/DynamicData/Aggregation/CountEx.cs | 72 +-
.../Aggregation/IAggregateChangeSet.cs | 8 +-
src/DynamicData/Aggregation/MaxEx.cs | 200 +-
src/DynamicData/Aggregation/StdDev.cs | 4 +-
src/DynamicData/Aggregation/StdDevEx.cs | 217 +-
src/DynamicData/Aggregation/SumEx.cs | 351 +-
src/DynamicData/Alias/ObservableCacheAlias.cs | 414 +-
src/DynamicData/Alias/ObservableListAlias.cs | 114 +-
src/DynamicData/Attributes.cs | 4 +-
.../Binding/AbstractNotifyPropertyChanged.cs | 56 +-
src/DynamicData/Binding/BindingListAdaptor.cs | 50 +-
.../Binding/BindingListEventsSuspender.cs | 17 +-
src/DynamicData/Binding/BindingListEx.cs | 135 +-
src/DynamicData/Binding/ExpressionBuilder.cs | 160 +-
src/DynamicData/Binding/IEvaluateAware.cs | 8 +-
src/DynamicData/Binding/IIndexAware.cs | 6 +-
.../INotifyCollectionChangedSuspender.cs | 12 +-
.../Binding/IObservableCollection.cs | 24 +-
.../Binding/IObservableCollectionAdaptor.cs | 9 +-
src/DynamicData/Binding/IObservableListEx.cs | 133 +-
.../ISortedObservableCollectionAdaptor.cs | 9 +-
.../Binding/NotifyPropertyChangedEx.cs | 451 +-
src/DynamicData/Binding/Observable.cs | 18 +
.../Binding/ObservableCollectionAdaptor.cs | 42 +-
.../Binding/ObservableCollectionEx.cs | 187 +-
.../Binding/ObservableCollectionExtended.cs | 196 +-
.../Binding/ObservablePropertyFactory.cs | 74 +-
.../Binding/ObservablePropertyFactoryCache.cs | 44 +-
.../Binding/ObservablePropertyPart.cs | 10 +-
src/DynamicData/Binding/PropertyValue.cs | 110 +-
src/DynamicData/Binding/SortDirection.cs | 10 +-
src/DynamicData/Binding/SortExpression.cs | 12 +-
.../Binding/SortExpressionComparer.cs | 73 +-
.../Binding/SortedBindingListAdaptor.cs | 24 +-
.../SortedObservableCollectionAdaptor.cs | 24 +-
src/DynamicData/Cache/CacheChangeSetEx.cs | 23 +
src/DynamicData/Cache/Change.cs | 112 +-
src/DynamicData/Cache/ChangeAwareCache.cs | 236 +-
src/DynamicData/Cache/ChangeReason.cs | 26 +-
src/DynamicData/Cache/ChangeSet.cs | 52 +-
src/DynamicData/Cache/DistinctChangeSet.cs | 8 +-
src/DynamicData/Cache/GroupChangeSet.cs | 15 +-
src/DynamicData/Cache/ICache.cs | 47 +-
src/DynamicData/Cache/ICacheUpdater.cs | 100 +-
src/DynamicData/Cache/IChangeSet.cs | 7 +-
src/DynamicData/Cache/IChangeSetAdaptor.cs | 11 +-
src/DynamicData/Cache/IConnectableCache.cs | 45 +
src/DynamicData/Cache/IDistinctChangeSet.cs | 11 +-
src/DynamicData/Cache/IGroup.cs | 15 +-
src/DynamicData/Cache/IGroupChangeSet.cs | 19 +-
src/DynamicData/Cache/IGrouping.cs | 32 +-
.../Cache/IImmutableGroupChangeSet.cs | 13 +-
src/DynamicData/Cache/IIntermediateCache.cs | 8 +-
src/DynamicData/Cache/IKey.cs | 18 +
src/DynamicData/Cache/IKeyValue.cs | 23 +-
src/DynamicData/Cache/IKeyValueCollection.cs | 23 +-
src/DynamicData/Cache/IObservableCache.cs | 59 +-
src/DynamicData/Cache/IPageRequest.cs | 13 +-
src/DynamicData/Cache/IPageResponse.cs | 23 +-
src/DynamicData/Cache/IPagedChangeSet.cs | 10 +-
src/DynamicData/Cache/IQuery.cs | 35 +-
src/DynamicData/Cache/ISortedChangeSet.cs | 12 +-
.../Cache/ISortedChangeSetAdaptor.cs | 10 +-
src/DynamicData/Cache/ISourceCache.cs | 20 +-
src/DynamicData/Cache/ISourceUpdater.cs | 32 +-
src/DynamicData/Cache/IVirtualChangeSet.cs | 12 +-
src/DynamicData/Cache/IVirtualParameters.cs | 27 -
src/DynamicData/Cache/IVirtualRequest.cs | 13 +-
src/DynamicData/Cache/IVirtualResponse.cs | 30 +
src/DynamicData/Cache/IndexedItem.cs | 66 +-
src/DynamicData/Cache/IntermediateCache.cs | 123 +-
.../Cache/Internal/AbstractFilter.cs | 59 +-
.../Internal/AnonymousObservableCache.cs | 42 +-
.../Cache/Internal/AnonymousQuery.cs | 10 +-
src/DynamicData/Cache/Internal/AutoRefresh.cs | 66 +-
src/DynamicData/Cache/Internal/BatchIf.cs | 177 +-
src/DynamicData/Cache/Internal/Cache.cs | 93 +-
src/DynamicData/Cache/Internal/CacheEx.cs | 23 +-
.../Cache/Internal/CacheUpdater.cs | 250 +-
src/DynamicData/Cache/Internal/Cast.cs | 26 +-
.../Cache/Internal/ChangesReducer.cs | 6 +-
.../Cache/Internal/CombineOperator.cs | 14 +-
src/DynamicData/Cache/Internal/Combiner.cs | 92 +-
.../Cache/Internal/DeferUntilLoaded.cs | 22 +-
.../Cache/Internal/DictionaryExtensions.cs | 4 +-
src/DynamicData/Cache/Internal/DisposeMany.cs | 75 +-
.../Cache/Internal/DistinctCalculator.cs | 59 +-
.../Cache/Internal/DynamicCombiner.cs | 228 +-
.../Cache/Internal/DynamicFilter.cs | 100 +-
src/DynamicData/Cache/Internal/EditDiff.cs | 46 +-
.../Cache/Internal/ExpirableItem.cs | 47 +-
src/DynamicData/Cache/Internal/FilterEx.cs | 108 +-
.../Cache/Internal/FilterOnProperty.cs | 23 +-
.../Cache/Internal/FilteredIndexCalculator.cs | 78 +-
src/DynamicData/Cache/Internal/FinallySafe.cs | 66 +-
src/DynamicData/Cache/Internal/FullJoin.cs | 202 +-
.../Cache/Internal/FullJoinMany.cs | 22 +-
.../Cache/Internal/GroupImmutable.cs | 320 -
src/DynamicData/Cache/Internal/GroupOn.cs | 366 +-
.../Cache/Internal/GroupOnImmutable.cs | 314 +
.../Cache/Internal/GroupOnProperty.cs | 54 +-
.../GroupOnPropertyWithImmutableState.cs | 50 +-
src/DynamicData/Cache/Internal/IFilter.cs | 25 +-
.../Cache/Internal/IKeySelector.cs | 16 +-
.../Cache/Internal/ImmutableGroup.cs | 57 +-
.../Cache/Internal/ImmutableGroupChangeSet.cs | 13 +-
.../Cache/Internal/IndexAndNode.cs | 21 +-
.../Cache/Internal/IndexCalculator.cs | 229 +-
src/DynamicData/Cache/Internal/InnerJoin.cs | 198 +-
.../Cache/Internal/InnerJoinMany.cs | 14 +-
src/DynamicData/Cache/Internal/KeyComparer.cs | 8 +-
src/DynamicData/Cache/Internal/KeySelector.cs | 4 +-
.../Cache/Internal/KeySelectorException.cs | 15 +-
.../Cache/Internal/KeyValueCollection.cs | 15 +-
.../Cache/Internal/KeyValueComparer.cs | 25 +-
src/DynamicData/Cache/Internal/LeftJoin.cs | 206 +-
.../Cache/Internal/LeftJoinMany.cs | 22 +-
.../Cache/Internal/LockFreeObservableCache.cs | 197 +-
.../Cache/Internal/ManagedGroup.cs | 67 +-
src/DynamicData/Cache/Internal/MergeMany.cs | 22 +-
.../Cache/Internal/MergeManyItems.cs | 19 +-
.../Cache/Internal/ObservableWithValue.cs | 11 +-
src/DynamicData/Cache/Internal/Page.cs | 89 +-
.../Cache/Internal/QueryWhenChanged.cs | 64 +-
.../Cache/Internal/ReaderWriter.cs | 220 +-
src/DynamicData/Cache/Internal/RefCount.cs | 67 +-
.../Cache/Internal/RemoveKeyEnumerator.cs | 40 +-
src/DynamicData/Cache/Internal/RightJoin.cs | 202 +-
.../Cache/Internal/RightJoinMany.cs | 16 +-
src/DynamicData/Cache/Internal/SizeExpirer.cs | 52 +-
src/DynamicData/Cache/Internal/SizeLimiter.cs | 33 +-
src/DynamicData/Cache/Internal/Sort.cs | 170 +-
.../Cache/Internal/SpecifiedGrouper.cs | 106 +-
.../Cache/Internal/StaticFilter.cs | 28 +-
.../Cache/Internal/StatusMonitor.cs | 82 +-
.../Cache/Internal/SubscribeMany.cs | 26 +-
src/DynamicData/Cache/Internal/Switch.cs | 39 +-
src/DynamicData/Cache/Internal/TimeExpirer.cs | 174 +-
.../Cache/Internal/ToObservableChangeSet.cs | 194 +-
src/DynamicData/Cache/Internal/Transform.cs | 116 +-
.../Cache/Internal/TransformAsync.cs | 153 +-
.../Cache/Internal/TransformMany.cs | 265 +-
.../Internal/TransformWithForcedTransform.cs | 53 +-
src/DynamicData/Cache/Internal/TreeBuilder.cs | 401 +-
src/DynamicData/Cache/Internal/TrueFor.cs | 38 +-
.../{Virtualiser.cs => Virtualise.cs} | 63 +-
src/DynamicData/Cache/MissingKeyException.cs | 11 +-
src/DynamicData/Cache/Node.cs | 149 +-
src/DynamicData/Cache/ObservableCache.cs | 257 +-
src/DynamicData/Cache/ObservableCacheEx.cs | 6937 ++++++++---------
src/DynamicData/Cache/PageRequest.cs | 72 +-
src/DynamicData/Cache/PageResponse.cs | 72 +-
src/DynamicData/Cache/PagedChangeSet.cs | 47 +-
src/DynamicData/Cache/SortOptimisations.cs | 15 +-
src/DynamicData/Cache/SortReason.cs | 9 +-
src/DynamicData/Cache/SortedChangeSet.cs | 35 +-
src/DynamicData/Cache/SourceCache.cs | 54 +-
src/DynamicData/Cache/SourceCacheEx.cs | 11 +-
.../Cache/Tests/ChangeSetAggregator.cs | 48 +-
.../Tests/DistinctChangeSetAggregator.cs | 55 +-
.../Cache/Tests/PagedChangeSetAggregator.cs | 56 +-
.../Cache/Tests/SortedChangeSetAggregator.cs | 48 +-
src/DynamicData/Cache/Tests/TestEx.cs | 47 +-
.../Cache/Tests/VirtualChangeSetAggregator.cs | 48 +-
src/DynamicData/Cache/VirtualChangeSet.cs | 65 +-
src/DynamicData/Cache/VirtualRequest.cs | 92 +-
src/DynamicData/Cache/VirtualResponse.cs | 69 +-
src/DynamicData/Constants.cs | 11 +
.../Diagnostics/ChangeStatistics.cs | 118 +-
src/DynamicData/Diagnostics/ChangeSummary.cs | 52 +-
.../Diagnostics/DiagnosticOperators.cs | 77 +-
src/DynamicData/DynamicData.csproj | 6 +-
.../DynamicData.csproj.DotSettings | 16 +-
src/DynamicData/EnumerableEx.cs | 92 +-
.../Experimental/ExperimentalEx.cs | 17 +-
.../Experimental/ISubjectWithRefCount.cs | 10 +-
src/DynamicData/Experimental/IWatcher.cs | 11 +-
.../Experimental/SubjectWithRefCount.cs | 51 +-
src/DynamicData/Experimental/Watcher.cs | 109 +-
src/DynamicData/IChangeSet.cs | 32 +-
src/DynamicData/Kernel/ConnectionStatus.cs | 6 +-
src/DynamicData/Kernel/DoubleCheck.cs | 54 -
src/DynamicData/Kernel/EnumerableEx.cs | 110 +-
src/DynamicData/Kernel/EnumerableIList.cs | 83 +-
src/DynamicData/Kernel/EnumeratorIList.cs | 42 +
src/DynamicData/Kernel/Error.cs | 39 +-
src/DynamicData/Kernel/IEnumerableIList.cs | 22 +
src/DynamicData/Kernel/ISupportsCapacity.cs | 22 +
src/DynamicData/Kernel/ISupportsCapcity.cs | 12 -
src/DynamicData/Kernel/InternalEx.cs | 86 +-
src/DynamicData/Kernel/ItemWithIndex.cs | 69 +-
src/DynamicData/Kernel/ItemWithValue.cs | 77 +-
src/DynamicData/Kernel/OptionElse.cs | 12 +-
src/DynamicData/Kernel/OptionExtensions.cs | 251 +-
src/DynamicData/Kernel/Optional.cs | 172 +-
src/DynamicData/Kernel/ParallelEx.cs | 33 +-
.../Kernel/ReadOnlyCollectionLight.cs | 12 +-
.../Kernel/ReferenceEqualityComparer.cs | 10 +-
src/DynamicData/List/Change.cs | 95 +-
src/DynamicData/List/ChangeAwareList.cs | 736 +-
.../List/ChangeAwareListWithRefCounts.cs | 35 +-
src/DynamicData/List/ChangeSet.cs | 47 +-
src/DynamicData/List/ChangeSetEx.cs | 116 +-
src/DynamicData/List/ChangeType.cs | 12 +-
src/DynamicData/List/IChangeSet.cs | 8 +-
src/DynamicData/List/IChangeSetAdaptor.cs | 8 +-
src/DynamicData/List/IExtendedList.cs | 35 +-
src/DynamicData/List/IGroup.cs | 9 +-
src/DynamicData/List/IGrouping.cs | 15 +-
src/DynamicData/List/IObservableList.cs | 37 +-
src/DynamicData/List/IPageChangeSet.cs | 4 +-
src/DynamicData/List/ISourceList.cs | 10 +-
src/DynamicData/List/IVirtualChangeSet.cs | 7 +-
.../List/Internal/AnonymousObservableList.cs | 16 +-
src/DynamicData/List/Internal/AutoRefresh.cs | 79 +-
src/DynamicData/List/Internal/BufferIf.cs | 137 +-
src/DynamicData/List/Internal/Combiner.cs | 163 +-
.../List/Internal/DeferUntilLoaded.cs | 15 +-
src/DynamicData/List/Internal/Distinct.cs | 132 +-
.../List/Internal/DynamicCombiner.cs | 283 +-
src/DynamicData/List/Internal/EditDiff.cs | 30 +-
.../List/Internal/ExpirableItem.cs | 43 +-
src/DynamicData/List/Internal/ExpireAfter.cs | 128 +-
src/DynamicData/List/Internal/Filter.cs | 293 +-
.../List/Internal/FilterOnObservable.cs | 177 +-
.../List/Internal/FilterOnProperty.cs | 21 +-
src/DynamicData/List/Internal/FilterStatic.cs | 91 +-
src/DynamicData/List/Internal/Group.cs | 61 +-
src/DynamicData/List/Internal/GroupOn.cs | 388 +-
.../List/Internal/GroupOnImmutable.cs | 405 +-
.../List/Internal/GroupOnProperty.cs | 51 +-
.../GroupOnPropertyWithImmutableState.cs | 47 +-
.../List/Internal/ImmutableGroup.cs | 40 +-
src/DynamicData/List/Internal/LimitSizeTo.cs | 50 +
src/DynamicData/List/Internal/MergeMany.cs | 20 +-
src/DynamicData/List/Internal/OnBeingAdded.cs | 10 +-
.../List/Internal/OnBeingRemoved.cs | 33 +-
src/DynamicData/List/Internal/Pager.cs | 106 +-
.../List/Internal/QueryWhenChanged.cs | 21 +-
src/DynamicData/List/Internal/ReaderWriter.cs | 114 +-
src/DynamicData/List/Internal/RefCount.cs | 64 +-
.../List/Internal/ReferenceCountTracker.cs | 41 +-
src/DynamicData/List/Internal/SizeLimiter.cs | 56 -
src/DynamicData/List/Internal/Sort.cs | 269 +-
.../List/Internal/SubscribeMany.cs | 18 +-
src/DynamicData/List/Internal/Switch.cs | 41 +-
.../List/Internal/ToObservableChangeSet.cs | 163 +-
.../List/Internal/TransformAsync.cs | 265 +-
.../List/Internal/TransformMany.cs | 569 +-
src/DynamicData/List/Internal/Transformer.cs | 206 +-
.../List/Internal/UnifiedChange.cs | 43 +-
src/DynamicData/List/Internal/Virtualiser.cs | 85 +-
src/DynamicData/List/ItemChange.cs | 125 +-
src/DynamicData/List/Linq/AddKeyEnumerator.cs | 17 +-
.../List/Linq/ItemChangeEnumerator.cs | 10 +-
.../{ReverseEnumerator.cs => Reverser.cs} | 4 +-
.../List/Linq/UnifiedChangeEnumerator.cs | 8 +-
.../List/Linq/WithoutIndexEnumerator.cs | 10 +-
src/DynamicData/List/ListChangeReason.cs | 21 +-
src/DynamicData/List/ListEx.cs | 927 ++-
src/DynamicData/List/ListFilterPolicy.cs | 7 +-
src/DynamicData/List/ObservableListEx.cs | 2780 +++----
src/DynamicData/List/PageChangeSet.cs | 23 +-
src/DynamicData/List/RangeChange.cs | 82 +-
src/DynamicData/List/SortException.cs | 19 +-
src/DynamicData/List/SortOptions.cs | 9 +-
src/DynamicData/List/SourceList.cs | 209 +-
.../List/SourceListEditConvenienceEx.cs | 188 +-
src/DynamicData/List/SourceListEx.cs | 19 +-
.../List/Tests/ChangeSetAggregator.cs | 44 +-
.../List/Tests/{TestEx.cs => ListTextEx.cs} | 13 +-
.../List/UnspecifiedIndexException.cs | 9 +-
src/DynamicData/List/VirtualChangeSet.cs | 22 +-
src/DynamicData/ObservableChangeSet.cs | 532 +-
src/DynamicData/ObsoleteEx.cs | 12 +-
.../{PLinqFilteredUpdater.cs => PFilter.cs} | 48 +-
.../Platforms/net45/PSubscribeMany.cs | 30 +-
src/DynamicData/Platforms/net45/PTransform.cs | 38 +-
src/DynamicData/Platforms/net45/ParallelEx.cs | 36 +-
.../Platforms/net45/ParallelOperators.cs | 174 +-
.../Platforms/net45/ParallelType.cs | 16 +-
.../Platforms/net45/ParallelisationOptions.cs | 33 +-
src/DynamicData/Properties/Annotations.cs | 1060 ---
src/analyzers.ruleset | 7 +-
src/stylecop.json | 44 +
485 files changed, 26270 insertions(+), 27875 deletions(-)
create mode 100644 src/DynamicData/Binding/Observable.cs
create mode 100644 src/DynamicData/Cache/CacheChangeSetEx.cs
create mode 100644 src/DynamicData/Cache/IConnectableCache.cs
create mode 100644 src/DynamicData/Cache/IKey.cs
delete mode 100644 src/DynamicData/Cache/IVirtualParameters.cs
create mode 100644 src/DynamicData/Cache/IVirtualResponse.cs
delete mode 100644 src/DynamicData/Cache/Internal/GroupImmutable.cs
create mode 100644 src/DynamicData/Cache/Internal/GroupOnImmutable.cs
rename src/DynamicData/Cache/Internal/{Virtualiser.cs => Virtualise.cs} (65%)
create mode 100644 src/DynamicData/Constants.cs
delete mode 100644 src/DynamicData/Kernel/DoubleCheck.cs
create mode 100644 src/DynamicData/Kernel/EnumeratorIList.cs
create mode 100644 src/DynamicData/Kernel/IEnumerableIList.cs
create mode 100644 src/DynamicData/Kernel/ISupportsCapacity.cs
delete mode 100644 src/DynamicData/Kernel/ISupportsCapcity.cs
create mode 100644 src/DynamicData/List/Internal/LimitSizeTo.cs
delete mode 100644 src/DynamicData/List/Internal/SizeLimiter.cs
rename src/DynamicData/List/Linq/{ReverseEnumerator.cs => Reverser.cs} (97%)
rename src/DynamicData/List/Tests/{TestEx.cs => ListTextEx.cs} (61%)
rename src/DynamicData/Platforms/net45/{PLinqFilteredUpdater.cs => PFilter.cs} (76%)
delete mode 100644 src/DynamicData/Properties/Annotations.cs
create mode 100644 src/stylecop.json
diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 52dadda62..26c19f769 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -27,6 +27,18 @@ jobs:
with:
dotnet-version: 3.1.x
+ - name: Install .NET 5
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 5.0.x
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v1.0.2
+
+ - name: Update VS2019
+ shell: powershell
+ run: Start-Process -Wait -PassThru -FilePath "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" -ArgumentList "update --passive --norestart --installpath ""C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise"""
+
- name: NBGV
id: nbgv
uses: dotnet/nbgv@master
@@ -37,29 +49,28 @@ jobs:
run: dotnet restore
working-directory: src
- - name: Add MSBuild to PATH
- uses: microsoft/setup-msbuild@v1.0.2
-
- name: Build
- run: msbuild /t:build,pack /maxcpucount /p:NoPackageAnalysis=true /verbosity:minimal /p:Configuration=${{ env.configuration }}
+ run: msbuild /t:build,pack /nowarn:MSB4011 /maxcpucount /p:NoPackageAnalysis=true /verbosity:minimal /p:Configuration=${{ env.configuration }}
working-directory: src
- - name: Install Report Generator
- run: dotnet tool install --global dotnet-reportgenerator-globaltool
-
- - name: Run Unit Tests
- run: dotnet test --no-build /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput="../../artifacts/coverage/coverage.xml" /p:Include="[${{ env.productNamespacePrefix}}*]*" /p:Exclude="[${{ env.productNamespacePrefix}}*Tests.*]*"
- working-directory: src
-
- - name: Generate Coverage Report
- run: reportgenerator -reports:"coverage.*.xml" -targetdir:report-output
- working-directory: artifacts/coverage
+ - name: Run Unit Tests and Generate Coverage
+ uses: glennawatson/coverlet-msbuild@v1
+ with:
+ project-files: '**/*Tests*.csproj'
+ no-build: true
+ exclude-filter: '[${{env.productNamespacePrefix}}.*.Tests.*]*'
+ include-filter: '[${{env.productNamespacePrefix}}*]*'
+ output-format: cobertura
+ output: '../../artifacts/'
+ configuration: ${{ env.configuration }}
- name: Upload Code Coverage
- uses: codecov/codecov-action@v1
- with:
- token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
- directory: artifacts/coverage
+ shell: bash
+ run: |
+ echo $PWD
+ bash <(curl -s https://codecov.io/bash) -X gcov -X coveragepy -t ${{ env.CODECOV_TOKEN }} -s '$PWD/artifacts' -f '*.xml'
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Create NuGet Artifacts
uses: actions/upload-artifact@master
@@ -80,7 +91,7 @@ jobs:
- name: Download NuGet Packages
uses: actions/download-artifact@v2
with:
- name: nuget
+ name: nuget
- name: Changelog
uses: glennawatson/ChangeLog@v1
@@ -102,4 +113,3 @@ jobs:
SOURCE_URL: https://api.nuget.org/v3/index.json
run: |
dotnet nuget push -s ${{ env.SOURCE_URL }} -k ${{ env.NUGET_AUTH_TOKEN }} **/*.nupkg
-
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 1903f52f9..8872086b6 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -27,6 +27,7 @@
true
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
+ CS8600;CS8602;CS8603;CS8604;CS8605;CS8606;CS8607;CS8608;CS8609;CS8610;CS8611;CS8612;CS8613;CS8614;CS8615;CS8616;CS8617;CS8618;CS8619;CS8620;CS8621;CS8622;CS8623;CS8624;CS8625;CS8626;CS8627;CS8628;CS8629;CS8630;CS8634;CS8766;CS8767
@@ -54,9 +55,12 @@
-
-
+
+
+
+
+
diff --git a/src/Directory.build.targets b/src/Directory.build.targets
index 4b8aa2f3b..37f649997 100644
--- a/src/Directory.build.targets
+++ b/src/Directory.build.targets
@@ -18,4 +18,9 @@
$(DefineConstants);NETCOREAPP;P_LINQ;SUPPORTS_BINDINGLIST
+
+
+ $(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST
+
+
diff --git a/src/DynamicData.Benchmarks/Cache/SourceCache.cs b/src/DynamicData.Benchmarks/Cache/SourceCache.cs
index 1d695aca5..ecf4265ab 100644
--- a/src/DynamicData.Benchmarks/Cache/SourceCache.cs
+++ b/src/DynamicData.Benchmarks/Cache/SourceCache.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for full license information.
using System.Linq;
+
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
@@ -24,12 +25,12 @@ public BenchmarkItem(int id)
public class SourceCache
{
private SourceCache _cache;
- private BenchmarkItem[] _items = Enumerable.Range(1,100).Select(i=> new BenchmarkItem(i)).ToArray();
+ private BenchmarkItem[] _items = Enumerable.Range(1, 100).Select(i => new BenchmarkItem(i)).ToArray();
[GlobalSetup]
public void Setup()
{
- _cache = new SourceCache(i=> i.Id);
+ _cache = new SourceCache(i => i.Id);
}
[Params(1, 100, 1_000, 10_000, 100_000)]
diff --git a/src/DynamicData.Benchmarks/List/GroupAdd.cs b/src/DynamicData.Benchmarks/List/GroupAdd.cs
index 1377c6f81..eb013336e 100644
--- a/src/DynamicData.Benchmarks/List/GroupAdd.cs
+++ b/src/DynamicData.Benchmarks/List/GroupAdd.cs
@@ -4,6 +4,7 @@
using System;
using System.Linq;
+
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
@@ -16,7 +17,7 @@ public class GroupAdd
{
private IDisposable _groupSubscription;
private SourceList _sourceList;
- private int[] _items = Enumerable.Range(1,100).ToArray();
+ private int[] _items = Enumerable.Range(1, 100).ToArray();
[Params(1, 100, 1_000, 10_000, 100_000)]
public int N;
diff --git a/src/DynamicData.Benchmarks/List/GroupRemove.cs b/src/DynamicData.Benchmarks/List/GroupRemove.cs
index 2d0ca301e..c362b903b 100644
--- a/src/DynamicData.Benchmarks/List/GroupRemove.cs
+++ b/src/DynamicData.Benchmarks/List/GroupRemove.cs
@@ -4,6 +4,7 @@
using System;
using System.Linq;
+
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
@@ -47,7 +48,7 @@ public void Teardown()
public void Remove() => _sourceList.RemoveAt(_items[0]);
[Benchmark]
- public void RemoveRange() => _sourceList.RemoveRange(40,20);
+ public void RemoveRange() => _sourceList.RemoveRange(40, 20);
[Benchmark]
public void Clear() => _sourceList.Clear();
diff --git a/src/DynamicData.Benchmarks/List/SourceList.cs b/src/DynamicData.Benchmarks/List/SourceList.cs
index c2c5292e0..2ed4100d1 100644
--- a/src/DynamicData.Benchmarks/List/SourceList.cs
+++ b/src/DynamicData.Benchmarks/List/SourceList.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for full license information.
using System.Linq;
+
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
@@ -13,7 +14,7 @@ namespace DynamicData.Benchmarks.List
[MarkdownExporterAttribute.GitHub]
public class SourceList
{
- private SourceList _sourceList;
+ private SourceList _sourceList;
private string[] _items;
[Params(1, 100, 1_000, 10_000, 100_000)]
@@ -36,6 +37,6 @@ public void SetupIteration()
public void AddRange() => _sourceList.AddRange(_items);
[Benchmark]
- public void Insert() => _sourceList.InsertRange(_items,0);
+ public void Insert() => _sourceList.InsertRange(_items, 0);
}
}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs b/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs
index e8e6dafea..24462c1ba 100644
--- a/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs
+++ b/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs
@@ -1,19 +1,22 @@
using System;
using System.Reactive.Linq;
+
using DynamicData.Aggregation;
using DynamicData.Kernel;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.AggregationTests
{
-
- public class AggregationFixture: IDisposable
+ public class AggregationFixture : IDisposable
{
- private readonly SourceCache _source;
private readonly IObservable _accumulator;
+ private readonly SourceCache _source;
+
///
/// Initialises this instance.
///
@@ -21,28 +24,24 @@ public AggregationFixture()
{
_source = new SourceCache(p => p.Name);
- _accumulator = _source.Connect()
- .ForAggregation()
- .Scan(0, (current, items) =>
- {
- items.ForEach(x =>
- {
- if (x.Type == AggregateType.Add)
- {
- current = current + x.Item.Age;
- }
- else
- {
- current = current - x.Item.Age;
- }
- });
- return current;
- });
- }
-
- public void Dispose()
- {
- _source.Dispose();
+ _accumulator = _source.Connect().ForAggregation().Scan(
+ 0,
+ (current, items) =>
+ {
+ items.ForEach(
+ x =>
+ {
+ if (x.Type == AggregateType.Add)
+ {
+ current += x.Item.Age;
+ }
+ else
+ {
+ current -= x.Item.Age;
+ }
+ });
+ return current;
+ });
}
[Fact]
@@ -51,11 +50,12 @@ public void CanAccumulate()
int latest = 0;
int counter = 0;
- var accumulator = _accumulator.Subscribe(value =>
- {
- latest = value;
- counter++;
- });
+ var accumulator = _accumulator.Subscribe(
+ value =>
+ {
+ latest = value;
+ counter++;
+ });
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("B", 20));
@@ -74,11 +74,12 @@ public void CanHandleUpdatedItem()
int latest = 0;
int counter = 0;
- var accumulator = _accumulator.Subscribe(value =>
- {
- latest = value;
- counter++;
- });
+ var accumulator = _accumulator.Subscribe(
+ value =>
+ {
+ latest = value;
+ counter++;
+ });
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("A", 15));
@@ -87,5 +88,10 @@ public void CanHandleUpdatedItem()
latest.Should().Be(15, "Accumulated value should be 60");
accumulator.Dispose();
}
+
+ public void Dispose()
+ {
+ _source.Dispose();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AggregationTests/AverageFixture.cs b/src/DynamicData.Tests/AggregationTests/AverageFixture.cs
index 46c5ef5a6..53c9d620c 100644
--- a/src/DynamicData.Tests/AggregationTests/AverageFixture.cs
+++ b/src/DynamicData.Tests/AggregationTests/AverageFixture.cs
@@ -1,13 +1,15 @@
using System;
+
using DynamicData.Aggregation;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.AggregationTests
{
-
- public class AverageFixture: IDisposable
+ public class AverageFixture : IDisposable
{
private readonly SourceCache _source;
@@ -16,19 +18,12 @@ public AverageFixture()
_source = new SourceCache(p => p.Name);
}
- public void Dispose()
- {
- _source.Dispose();
- }
-
[Fact]
public void AddedItemsContributeToSum()
{
double avg = 0;
- var accumulator = _source.Connect()
- .Avg(p => p.Age)
- .Subscribe(x => avg = x);
+ var accumulator = _source.Connect().Avg(p => p.Age).Subscribe(x => avg = x);
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("B", 20));
@@ -39,22 +34,9 @@ public void AddedItemsContributeToSum()
accumulator.Dispose();
}
- [Fact]
- public void RemoveProduceCorrectResult()
+ public void Dispose()
{
- double avg = 0;
-
- var accumulator = _source.Connect()
- .Avg(p => p.Age)
- .Subscribe(x => avg = x);
-
- _source.AddOrUpdate(new Person("A", 10));
- _source.AddOrUpdate(new Person("B", 20));
- _source.AddOrUpdate(new Person("C", 30));
-
- _source.Remove("A");
- avg.Should().Be(25, "Average value should be 25 after remove");
- accumulator.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -64,10 +46,7 @@ public void InlineChangeReEvaluatesTotals()
var somepropChanged = _source.Connect().WhenValueChanged(p => p.Age);
- var accumulator = _source.Connect()
- .Avg(p => p.Age)
- .InvalidateWhen(somepropChanged)
- .Subscribe(x => avg = x);
+ var accumulator = _source.Connect().Avg(p => p.Age).InvalidateWhen(somepropChanged).Subscribe(x => avg = x);
var personb = new Person("B", 5);
_source.AddOrUpdate(new Person("A", 10));
@@ -82,5 +61,20 @@ public void InlineChangeReEvaluatesTotals()
accumulator.Dispose();
}
+ [Fact]
+ public void RemoveProduceCorrectResult()
+ {
+ double avg = 0;
+
+ var accumulator = _source.Connect().Avg(p => p.Age).Subscribe(x => avg = x);
+
+ _source.AddOrUpdate(new Person("A", 10));
+ _source.AddOrUpdate(new Person("B", 20));
+ _source.AddOrUpdate(new Person("C", 30));
+
+ _source.Remove("A");
+ avg.Should().Be(25, "Average value should be 25 after remove");
+ accumulator.Dispose();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AggregationTests/MaxFixture.cs b/src/DynamicData.Tests/AggregationTests/MaxFixture.cs
index 95a6f8326..04880c5e6 100644
--- a/src/DynamicData.Tests/AggregationTests/MaxFixture.cs
+++ b/src/DynamicData.Tests/AggregationTests/MaxFixture.cs
@@ -1,13 +1,15 @@
using System;
+
using DynamicData.Aggregation;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.AggregationTests
{
-
- public class MaxFixture: IDisposable
+ public class MaxFixture : IDisposable
{
private readonly SourceCache _source;
@@ -16,19 +18,12 @@ public MaxFixture()
_source = new SourceCache(p => p.Name);
}
- public void Dispose()
- {
- _source.Dispose();
- }
-
[Fact]
public void AddItems()
{
var result = 0;
- var accumulator = _source.Connect()
- .Maximum(p => p.Age)
- .Subscribe(x => result = x);
+ var accumulator = _source.Connect().Maximum(p => p.Age).Subscribe(x => result = x);
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("B", 20));
@@ -39,22 +34,9 @@ public void AddItems()
accumulator.Dispose();
}
- [Fact]
- public void RemoveItems()
+ public void Dispose()
{
- var result = 0;
-
- var accumulator = _source.Connect()
- .Maximum(p => p.Age)
- .Subscribe(x => result = x);
-
- _source.AddOrUpdate(new Person("A", 10));
- _source.AddOrUpdate(new Person("B", 20));
- _source.AddOrUpdate(new Person("C", 30));
-
- _source.Remove("C");
- result.Should().Be(20, "Max value should be 20 after remove");
- accumulator.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -64,10 +46,7 @@ public void InlineChangeReEvaluatesTotals()
var somepropChanged = _source.Connect().WhenValueChanged(p => p.Age);
- var accumulator = _source.Connect()
- .Maximum(p => p.Age)
- .InvalidateWhen(somepropChanged)
- .Subscribe(x => max = x);
+ var accumulator = _source.Connect().Maximum(p => p.Age).InvalidateWhen(somepropChanged).Subscribe(x => max = x);
var personc = new Person("C", 5);
_source.AddOrUpdate(new Person("A", 10));
@@ -82,5 +61,20 @@ public void InlineChangeReEvaluatesTotals()
accumulator.Dispose();
}
+ [Fact]
+ public void RemoveItems()
+ {
+ var result = 0;
+
+ var accumulator = _source.Connect().Maximum(p => p.Age).Subscribe(x => result = x);
+
+ _source.AddOrUpdate(new Person("A", 10));
+ _source.AddOrUpdate(new Person("B", 20));
+ _source.AddOrUpdate(new Person("C", 30));
+
+ _source.Remove("C");
+ result.Should().Be(20, "Max value should be 20 after remove");
+ accumulator.Dispose();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AggregationTests/MinFixture.cs b/src/DynamicData.Tests/AggregationTests/MinFixture.cs
index b29e3a2d5..f42927ef7 100644
--- a/src/DynamicData.Tests/AggregationTests/MinFixture.cs
+++ b/src/DynamicData.Tests/AggregationTests/MinFixture.cs
@@ -1,12 +1,15 @@
using System;
+
using DynamicData.Aggregation;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.AggregationTests
{
- public class MinFixture: IDisposable
+ public class MinFixture : IDisposable
{
private readonly SourceCache _source;
@@ -15,19 +18,12 @@ public MinFixture()
_source = new SourceCache(p => p.Name);
}
- public void Dispose()
- {
- _source.Dispose();
- }
-
[Fact]
public void AddedItemsContributeToSum()
{
var result = 0;
- var accumulator = _source.Connect()
- .Minimum(p => p.Age)
- .Subscribe(x => result = x);
+ var accumulator = _source.Connect().Minimum(p => p.Age).Subscribe(x => result = x);
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("B", 20));
@@ -38,22 +34,9 @@ public void AddedItemsContributeToSum()
accumulator.Dispose();
}
- [Fact]
- public void RemoveProduceCorrectResult()
+ public void Dispose()
{
- var result = 0;
-
- var accumulator = _source.Connect()
- .Minimum(p => p.Age)
- .Subscribe(x => result = x);
-
- _source.AddOrUpdate(new Person("A", 10));
- _source.AddOrUpdate(new Person("B", 20));
- _source.AddOrUpdate(new Person("C", 30));
-
- _source.Remove("A");
- result.Should().Be(20, "Min value should be 20 after remove");
- accumulator.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -63,10 +46,7 @@ public void InlineChangeReEvaluatesTotals()
var somepropChanged = _source.Connect().WhenValueChanged(p => p.Age);
- var accumulator = _source.Connect()
- .Minimum(p => p.Age)
- .InvalidateWhen(somepropChanged)
- .Subscribe(x => min = x);
+ var accumulator = _source.Connect().Minimum(p => p.Age).InvalidateWhen(somepropChanged).Subscribe(x => min = x);
var personc = new Person("C", 5);
_source.AddOrUpdate(new Person("A", 10));
@@ -82,5 +62,20 @@ public void InlineChangeReEvaluatesTotals()
accumulator.Dispose();
}
+ [Fact]
+ public void RemoveProduceCorrectResult()
+ {
+ var result = 0;
+
+ var accumulator = _source.Connect().Minimum(p => p.Age).Subscribe(x => result = x);
+
+ _source.AddOrUpdate(new Person("A", 10));
+ _source.AddOrUpdate(new Person("B", 20));
+ _source.AddOrUpdate(new Person("C", 30));
+
+ _source.Remove("A");
+ result.Should().Be(20, "Min value should be 20 after remove");
+ accumulator.Dispose();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AggregationTests/SumFixture.cs b/src/DynamicData.Tests/AggregationTests/SumFixture.cs
index ae822bccd..cd2b7ff7b 100644
--- a/src/DynamicData.Tests/AggregationTests/SumFixture.cs
+++ b/src/DynamicData.Tests/AggregationTests/SumFixture.cs
@@ -1,13 +1,15 @@
using System;
+
using DynamicData.Aggregation;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.AggregationTests
{
-
- public class SumFixture: IDisposable
+ public class SumFixture : IDisposable
{
private readonly SourceCache _source;
@@ -16,19 +18,12 @@ public SumFixture()
_source = new SourceCache(p => p.Name);
}
- public void Dispose()
- {
- _source.Dispose();
- }
-
[Fact]
public void AddedItemsContributeToSum()
{
int sum = 0;
- var accumulator = _source.Connect()
- .Sum(p => p.Age)
- .Subscribe(x => sum = x);
+ var accumulator = _source.Connect().Sum(p => p.Age).Subscribe(x => sum = x);
_source.AddOrUpdate(new Person("A", 10));
_source.AddOrUpdate(new Person("B", 20));
@@ -39,22 +34,9 @@ public void AddedItemsContributeToSum()
accumulator.Dispose();
}
- [Fact]
- public void RemoveProduceCorrectResult()
+ public void Dispose()
{
- int sum = 0;
-
- var accumulator = _source.Connect()
- .Sum(p => p.Age)
- .Subscribe(x => sum = x);
-
- _source.AddOrUpdate(new Person("A", 10));
- _source.AddOrUpdate(new Person("B", 20));
- _source.AddOrUpdate(new Person("C", 30));
-
- _source.Remove("A");
- sum.Should().Be(50, "Accumulated value should be 50 after remove");
- accumulator.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -64,10 +46,7 @@ public void InlineChangeReEvaluatesTotals()
var somepropChanged = _source.Connect().WhenValueChanged(p => p.Age);
- var accumulator = _source.Connect()
- .Sum(p => p.Age)
- .InvalidateWhen(somepropChanged)
- .Subscribe(x => sum = x);
+ var accumulator = _source.Connect().Sum(p => p.Age).InvalidateWhen(somepropChanged).Subscribe(x => sum = x);
var personb = new Person("B", 5);
_source.AddOrUpdate(new Person("A", 10));
@@ -82,5 +61,20 @@ public void InlineChangeReEvaluatesTotals()
accumulator.Dispose();
}
+ [Fact]
+ public void RemoveProduceCorrectResult()
+ {
+ int sum = 0;
+
+ var accumulator = _source.Connect().Sum(p => p.Age).Subscribe(x => sum = x);
+
+ _source.AddOrUpdate(new Person("A", 10));
+ _source.AddOrUpdate(new Person("B", 20));
+ _source.AddOrUpdate(new Person("C", 30));
+
+ _source.Remove("A");
+ sum.Should().Be(50, "Accumulated value should be 50 after remove");
+ accumulator.Dispose();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/AutoRefreshFilter.cs b/src/DynamicData.Tests/AutoRefreshFilter.cs
index dda051770..ae14237ff 100644
--- a/src/DynamicData.Tests/AutoRefreshFilter.cs
+++ b/src/DynamicData.Tests/AutoRefreshFilter.cs
@@ -1,6 +1,8 @@
using System;
using System.ComponentModel;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests
@@ -16,32 +18,37 @@ public void Test()
var i3 = new Item("I3");
var obsList = new SourceList- ();
- obsList.AddRange(new[] {a0, i1, i2, i3});
+ obsList.AddRange(new[] { a0, i1, i2, i3 });
- var obsListDerived = obsList.Connect()
- .AutoRefresh(x => x.Name)
- .Filter(x => x.Name.Contains("I"))
- .AsObservableList();
+ var obsListDerived = obsList.Connect().AutoRefresh(x => x.Name).Filter(x => x.Name.Contains("I")).AsObservableList();
obsListDerived.Count.Should().Be(3);
- obsListDerived.Items.Should().BeEquivalentTo(new [] {i1, i2, i3});
+ obsListDerived.Items.Should().BeEquivalentTo(i1, i2, i3);
i1.Name = "X2";
obsListDerived.Count.Should().Be(2);
- obsListDerived.Items.Should().BeEquivalentTo(new[] {i2, i3});
+ obsListDerived.Items.Should().BeEquivalentTo(i2, i3);
a0.Name = "I0";
obsListDerived.Count.Should().Be(3);
- obsListDerived.Items.Should().BeEquivalentTo(new[] {a0, i2, i3});
+ obsListDerived.Items.Should().BeEquivalentTo(a0, i2, i3);
}
}
public class Item : INotifyPropertyChanged
{
- public Guid Id { get; }
-
private string _name;
+ public Item(string name)
+ {
+ Id = Guid.NewGuid();
+ _name = name;
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ public Guid Id { get; }
+
public string Name
{
get => _name;
@@ -51,13 +58,5 @@ public string Name
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
-
- public Item(string name)
- {
- Id = Guid.NewGuid();
- Name = name;
- }
-
- public event PropertyChangedEventHandler PropertyChanged;
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/BindingLIstBindListFixture.cs b/src/DynamicData.Tests/Binding/BindingLIstBindListFixture.cs
index d0167f700..86d129d3f 100644
--- a/src/DynamicData.Tests/Binding/BindingLIstBindListFixture.cs
+++ b/src/DynamicData.Tests/Binding/BindingLIstBindListFixture.cs
@@ -3,19 +3,24 @@
using System;
using System.ComponentModel;
using System.Linq;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
public class BindingLIstBindListFixture : IDisposable
{
+ private readonly IDisposable _binder;
+
private readonly BindingList _collection;
+
+ private readonly RandomPersonGenerator _generator = new();
+
private readonly SourceList _source;
- private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
public BindingLIstBindListFixture()
{
@@ -24,10 +29,14 @@ public BindingLIstBindListFixture()
_binder = _source.Connect().Bind(_collection).Subscribe();
}
- public void Dispose()
+ [Fact]
+ public void AddRange()
{
- _binder.Dispose();
- _source.Dispose();
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+
+ _collection.Count.Should().Be(100, "Should be 100 items in the collection");
+ _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
}
[Fact]
@@ -41,15 +50,18 @@ public void AddToSourceAddsToDestination()
}
[Fact]
- public void UpdateToSourceUpdatesTheDestination()
+ public void Clear()
{
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.Add(person);
- _source.Replace(person, personUpdated);
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+ _source.Clear();
+ _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ }
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -63,22 +75,15 @@ public void RemoveSourceRemovesFromTheDestination()
}
[Fact]
- public void AddRange()
+ public void UpdateToSourceUpdatesTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
-
- _collection.Count.Should().Be(100, "Should be 100 items in the collection");
- _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
- }
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.Add(person);
+ _source.Replace(person, personUpdated);
- [Fact]
- public void Clear()
- {
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
- _source.Clear();
- _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
}
}
}
diff --git a/src/DynamicData.Tests/Binding/BindingListBindCacheFixture.cs b/src/DynamicData.Tests/Binding/BindingListBindCacheFixture.cs
index 713c5db5e..e45c55516 100644
--- a/src/DynamicData.Tests/Binding/BindingListBindCacheFixture.cs
+++ b/src/DynamicData.Tests/Binding/BindingListBindCacheFixture.cs
@@ -3,19 +3,24 @@
using System;
using System.ComponentModel;
using System.Linq;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
public class BindingListCacheFixture : IDisposable
{
- private readonly BindingList _collection = new BindingList();
- private readonly ISourceCache _source;
private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly BindingList _collection = new();
+
+ private readonly RandomPersonGenerator _generator = new();
+
+ private readonly ISourceCache _source;
public BindingListCacheFixture()
{
@@ -23,12 +28,6 @@ public BindingListCacheFixture()
_binder = _source.Connect().Bind(_collection).Subscribe();
}
- public void Dispose()
- {
- _binder.Dispose();
- _source.Dispose();
- }
-
[Fact]
public void AddToSourceAddsToDestination()
{
@@ -40,15 +39,28 @@ public void AddToSourceAddsToDestination()
}
[Fact]
- public void UpdateToSourceUpdatesTheDestination()
+ public void BatchAdd()
{
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.AddOrUpdate(person);
- _source.AddOrUpdate(personUpdated);
+ var people = _generator.Take(100).ToList();
+ _source.AddOrUpdate(people);
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
+ _collection.Count.Should().Be(100, "Should be 100 items in the collection");
+ _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
+ }
+
+ [Fact]
+ public void BatchRemove()
+ {
+ var people = _generator.Take(100).ToList();
+ _source.AddOrUpdate(people);
+ _source.Clear();
+ _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ }
+
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -62,22 +74,15 @@ public void RemoveSourceRemovesFromTheDestination()
}
[Fact]
- public void BatchAdd()
+ public void UpdateToSourceUpdatesTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddOrUpdate(people);
-
- _collection.Count.Should().Be(100, "Should be 100 items in the collection");
- _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
- }
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.AddOrUpdate(person);
+ _source.AddOrUpdate(personUpdated);
- [Fact]
- public void BatchRemove()
- {
- var people = _generator.Take(100).ToList();
- _source.AddOrUpdate(people);
- _source.Clear();
- _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
}
}
}
diff --git a/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs b/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs
index a7394f1f3..db2080220 100644
--- a/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs
+++ b/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs
@@ -4,36 +4,33 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
public class BindingListBindCacheSortedFixture : IDisposable
{
- private readonly BindingList _collection;
- private readonly ISourceCache _source;
private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly BindingList _collection;
+
private readonly IComparer _comparer = SortExpressionComparer.Ascending(p => p.Name);
+ private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly ISourceCache _source;
+
public BindingListBindCacheSortedFixture()
{
_collection = new BindingList();
- _source = new SourceCache(p => p.Name);
- _binder = _source.Connect()
- .Sort(_comparer, resetThreshold: 25)
- .Bind(_collection)
- .Subscribe();
- }
-
- public void Dispose()
- {
- _binder.Dispose();
- _source.Dispose();
+ _source = new SourceCache(p => p.Name);
+ _binder = _source.Connect().Sort(_comparer, resetThreshold: 25).Bind(_collection).Subscribe();
}
[Fact]
@@ -46,28 +43,6 @@ public void AddToSourceAddsToDestination()
_collection.First().Should().Be(person, "Should be same person");
}
- [Fact]
- public void UpdateToSourceUpdatesTheDestination()
- {
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.AddOrUpdate(person);
- _source.AddOrUpdate(personUpdated);
-
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
- }
-
- [Fact]
- public void RemoveSourceRemovesFromTheDestination()
- {
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
- _source.Remove(person);
-
- _collection.Count.Should().Be(0, "Should be 1 item in the collection");
- }
-
[Fact]
public void BatchAdd()
{
@@ -95,6 +70,12 @@ public void CollectionIsInSortOrder()
sorted.Should().BeEquivalentTo(_collection.ToList());
}
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
+ }
+
[Fact]
public void LargeUpdateInvokesAReset()
{
@@ -103,15 +84,25 @@ public void LargeUpdateInvokesAReset()
bool invoked = false;
_collection.ListChanged += (sender, e) =>
- {
- invoked = true;
- e.ListChangedType.Should().Be(ListChangedType.Reset);
- };
+ {
+ invoked = true;
+ e.ListChangedType.Should().Be(ListChangedType.Reset);
+ };
_source.AddOrUpdate(_generator.Take(100));
invoked.Should().BeTrue();
}
+ [Fact]
+ public void RemoveSourceRemovesFromTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
+ _source.Remove(person);
+
+ _collection.Count.Should().Be(0, "Should be 1 item in the collection");
+ }
+
[Fact]
public void SmallChangeDoesNotInvokeReset()
{
@@ -121,61 +112,73 @@ public void SmallChangeDoesNotInvokeReset()
bool invoked = false;
bool resetInvoked = false;
_collection.ListChanged += (sender, e) =>
- {
- invoked = true;
- if (e.ListChangedType == ListChangedType.Reset)
{
- resetInvoked = true;
- }
- };
+ invoked = true;
+ if (e.ListChangedType == ListChangedType.Reset)
+ {
+ resetInvoked = true;
+ }
+ };
_source.AddOrUpdate(_generator.Take(24));
invoked.Should().BeTrue();
resetInvoked.Should().BeFalse();
}
- [Fact]
- public void TreatMovesAsRemoveAdd()
- {
- var cache = new SourceCache(p => p.Name);
-
- var people = Enumerable.Range(0,10).Select(age => new Person("Person" + age, age)).ToList();
- var importantGuy = people.First();
- cache.AddOrUpdate(people);
-
- ISortedChangeSet latestSetWithoutMoves = null;
- ISortedChangeSet latestSetWithMoves = null;
-
- var boundList1 = new ObservableCollectionExtended();
- var boundList2 = new ObservableCollectionExtended();
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .TreatMovesAsRemoveAdd()
- .Bind(boundList1)
- .Subscribe(set => latestSetWithoutMoves = set))
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .Bind(boundList2)
- .Subscribe(set => latestSetWithMoves = set))
- {
-
- importantGuy.Age = importantGuy.Age + 200;
-
- latestSetWithoutMoves.Removes.Should().Be(1);
- latestSetWithoutMoves.Adds.Should().Be(1);
- latestSetWithoutMoves.Moves.Should().Be(0);
- latestSetWithoutMoves.Updates.Should().Be(0);
-
- latestSetWithMoves.Moves.Should().Be(1);
- latestSetWithMoves.Updates.Should().Be(0);
- latestSetWithMoves.Removes.Should().Be(0);
- latestSetWithMoves.Adds.Should().Be(0);
- }
- }
+ [Fact]
+ public void TreatMovesAsRemoveAdd()
+ {
+ var cache = new SourceCache(p => p.Name);
+
+ var people = Enumerable.Range(0, 10).Select(age => new Person("Person" + age, age)).ToList();
+ var importantGuy = people.First();
+ cache.AddOrUpdate(people);
+
+ ISortedChangeSet? latestSetWithoutMoves = null;
+ ISortedChangeSet? latestSetWithMoves = null;
+
+ var boundList1 = new ObservableCollectionExtended();
+ var boundList2 = new ObservableCollectionExtended();
+
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).TreatMovesAsRemoveAdd().Bind(boundList1).Subscribe(set => latestSetWithoutMoves = set))
+
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).Bind(boundList2).Subscribe(set => latestSetWithMoves = set))
+ {
+ if (latestSetWithoutMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithoutMoves));
+ }
+
+ if (latestSetWithMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithMoves));
+ }
+
+ importantGuy.Age += 200;
+ latestSetWithoutMoves.Should().NotBeNull();
+ latestSetWithoutMoves.Removes.Should().Be(1);
+ latestSetWithoutMoves.Adds.Should().Be(1);
+ latestSetWithoutMoves.Moves.Should().Be(0);
+ latestSetWithoutMoves.Updates.Should().Be(0);
+
+ latestSetWithMoves.Moves.Should().Be(1);
+ latestSetWithMoves.Updates.Should().Be(0);
+ latestSetWithMoves.Removes.Should().Be(0);
+ latestSetWithMoves.Adds.Should().Be(0);
+ }
+ }
+
+ [Fact]
+ public void UpdateToSourceUpdatesTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.AddOrUpdate(person);
+ _source.AddOrUpdate(personUpdated);
+
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
+ }
}
}
#endif
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs
index 1e759ab8f..fb646be3f 100644
--- a/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs
+++ b/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs
@@ -1,8 +1,11 @@
using System;
using System.ComponentModel;
using System.Linq;
+
using DynamicData.Binding;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
@@ -10,6 +13,7 @@ namespace DynamicData.Tests.Binding
public class BindingListToChangeSetFixture : IDisposable
{
private readonly TestBindingList _collection;
+
private readonly ChangeSetAggregator _results;
public BindingListToChangeSetFixture()
@@ -18,11 +22,6 @@ public BindingListToChangeSetFixture()
_results = _collection.ToObservableChangeSet().AsAggregator();
}
- public void Dispose()
- {
- _results.Dispose();
- }
-
[Fact]
public void Add()
{
@@ -33,16 +32,9 @@ public void Add()
_results.Data.Items.First().Should().Be(1);
}
- [Fact]
- public void Remove()
+ public void Dispose()
{
- _collection.AddRange(Enumerable.Range(1, 10));
-
- _collection.Remove(3);
-
- _results.Data.Count.Should().Be(9);
- _results.Data.Items.Contains(3).Should().BeFalse();
- _results.Data.Items.Should().BeEquivalentTo(_collection);
+ _results.Dispose();
}
[Fact]
@@ -54,28 +46,6 @@ public void Duplicates()
_results.Data.Count.Should().Be(2);
}
- [Fact]
- public void Replace()
- {
- _collection.AddRange(Enumerable.Range(1, 10));
- _collection[8] = 20;
-
- _results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
- }
-
- [Fact]
- public void ResetFiresClearsAndAdds()
- {
- _collection.AddRange(Enumerable.Range(1, 10));
-
- _collection.Reset();
- _results.Data.Items.Should().BeEquivalentTo(_collection);
-
- var resetNotification = _results.Messages.Last();
- resetNotification.Removes.Should().Be(10);
- resetNotification.Adds.Should().Be(10);
- }
-
[Fact]
public void RaiseListChangedEvents()
{
@@ -96,17 +66,13 @@ public void RefreshCausesReplace()
// Arrange
var sourceCache = new SourceCache
- (item => item.Id);
- var item1 = new Item(name: "Old Name");
+ var item1 = new Item("Old Name");
sourceCache.AddOrUpdate(item1);
var collection = new TestBindingList
- ();
- var sourceCacheResults = sourceCache
- .Connect()
- .AutoRefresh(item => item.Name)
- .Bind(collection)
- .AsAggregator();
+ var sourceCacheResults = sourceCache.Connect().AutoRefresh(item => item.Name).Bind(collection).AsAggregator();
var collectionResults = collection.ToObservableChangeSet().AsAggregator();
@@ -129,6 +95,40 @@ public void RefreshCausesReplace()
collectionResults.Dispose();
}
+ [Fact]
+ public void Remove()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+
+ _collection.Remove(3);
+
+ _results.Data.Count.Should().Be(9);
+ _results.Data.Items.Contains(3).Should().BeFalse();
+ _results.Data.Items.Should().BeEquivalentTo(_collection);
+ }
+
+ [Fact]
+ public void Replace()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+ _collection[8] = 20;
+
+ _results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
+ }
+
+ [Fact]
+ public void ResetFiresClearsAndAdds()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+
+ _collection.Reset();
+ _results.Data.Items.Should().BeEquivalentTo(_collection);
+
+ var resetNotification = _results.Messages.Last();
+ resetNotification.Removes.Should().Be(10);
+ resetNotification.Adds.Should().Be(10);
+ }
+
private class TestBindingList : BindingList
{
public void Reset()
@@ -137,4 +137,4 @@ public void Reset()
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs b/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs
index 0e324829b..ae7d33860 100644
--- a/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs
+++ b/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs
@@ -2,22 +2,46 @@
using System.Diagnostics;
using System.Linq;
using System.Reactive.Linq;
+
using DynamicData.Binding;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
public class DeeplyNestedNotifyPropertyChangedFixture
{
+ [Fact]
+ public void DepthOfOne()
+ {
+ var instance = new ClassA { Name = "Someone" };
+
+ var chain = instance.WhenPropertyChanged(a => a.Name, true);
+ string? result = null;
+
+ var subscription = chain.Subscribe(notification => result = notification?.Value);
+
+ result.Should().Be("Someone");
+
+ instance.Name = "Else";
+ result.Should().Be("Else");
+
+ instance.Name = null;
+ result.Should().Be(null);
+
+ instance.Name = "NotNull";
+ result.Should().Be("NotNull");
+ }
+
[Fact]
public void NotifiesInitialValue_WithFallback()
{
- var instance = new ClassA {Child = new ClassB {Age = 10}};
+ var instance = new ClassA { Child = new ClassB { Age = 10 } };
//provide a fallback so a value can always be obtained
- var chain = instance.WhenChanged(a => a.Child.Age, (sender, a) => a, () => -1);
+ var chain = instance.WhenChanged(a => a!.Child!.Age, (sender, a) => a, () => -1);
int? result = null;
@@ -28,7 +52,7 @@ public void NotifiesInitialValue_WithFallback()
instance.Child.Age = 22;
result.Should().Be(22);
- instance.Child = new ClassB {Age = 25};
+ instance.Child = new ClassB { Age = 25 };
result.Should().Be(25);
instance.Child.Age = 26;
@@ -45,7 +69,7 @@ public void NotifiesInitialValueAndNullChild()
{
var instance = new ClassA();
- var chain = instance.WhenPropertyChanged(a => a.Child.Age, true);
+ var chain = instance.WhenPropertyChanged(a => a.Child!.Age, true);
int? result = null;
var subscription = chain.Subscribe(notification => result = notification?.Value);
@@ -63,26 +87,29 @@ public void NotifiesInitialValueAndNullChild()
instance.Child.Age = 26;
result.Should().Be(26);
instance.Child = null;
-
}
[Fact]
- public void WithoutInitialValue()
+ public void NullChildWithInitialValue()
{
- var instance = new ClassA {Name="TestClass", Child = new ClassB {Age = 10}};
+ var instance = new ClassA();
- var chain = instance.WhenPropertyChanged(a => a.Child.Age, false);
+ var chain = instance.WhenPropertyChanged(a => a!.Child!.Age, true);
int? result = null;
- var subscription = chain.Subscribe(notification => result = notification.Value);
+ var subscription = chain.Subscribe(notification => result = notification?.Value);
result.Should().Be(null);
+ instance.Child = new ClassB { Age = 21 };
+ result.Should().Be(21);
+
instance.Child.Age = 22;
result.Should().Be(22);
- instance.Child = new ClassB {Age = 25};
+ instance.Child = new ClassB { Age = 25 };
result.Should().Be(25);
+
instance.Child.Age = 30;
result.Should().Be(30);
}
@@ -92,7 +119,7 @@ public void NullChildWithoutInitialValue()
{
var instance = new ClassA();
- var chain = instance.WhenPropertyChanged(a => a.Child.Age, false);
+ var chain = instance.WhenPropertyChanged(a => a!.Child!.Age, false);
int? result = null;
var subscription = chain.Subscribe(notification => result = notification.Value);
@@ -113,99 +140,92 @@ public void NullChildWithoutInitialValue()
}
[Fact]
- public void NullChildWithInitialValue()
+ public void WithoutInitialValue()
{
- var instance = new ClassA();
+ var instance = new ClassA { Name = "TestClass", Child = new ClassB { Age = 10 } };
- var chain = instance.WhenPropertyChanged(a => a.Child.Age, true);
+ var chain = instance.WhenPropertyChanged(a => a!.Child!.Age, false);
int? result = null;
- var subscription = chain.Subscribe(notification => result = notification?.Value);
+ var subscription = chain.Subscribe(notification => result = notification.Value);
result.Should().Be(null);
- instance.Child = new ClassB { Age = 21 };
- result.Should().Be(21);
-
instance.Child.Age = 22;
result.Should().Be(22);
instance.Child = new ClassB { Age = 25 };
result.Should().Be(25);
-
instance.Child.Age = 30;
result.Should().Be(30);
}
- [Fact]
- public void DepthOfOne()
- {
- var instance = new ClassA {Name="Someone"};
-
- var chain = instance.WhenPropertyChanged(a => a.Name, true);
- string result = null;
-
- var subscription = chain.Subscribe(notification => result = notification?.Value);
-
- result.Should().Be("Someone");
-
- instance.Name = "Else";
- result.Should().Be("Else");
-
- instance.Name = null;
- result.Should().Be(null);
-
- instance.Name = "NotNull";
- result.Should().Be("NotNull");
-
- }
-
- // [Fact]
- // [Trait("Manual run for benchmarking","xx")]
+ // [Fact]
+ // [Trait("Manual run for benchmarking","xx")]
private void StressIt()
{
var list = new SourceList();
- var items = Enumerable.Range(1, 10_000)
- .Select(i => new ClassA { Name = i.ToString(), Child = new ClassB { Age = i } })
- .ToArray();
+ var items = Enumerable.Range(1, 10_000).Select(i => new ClassA { Name = i.ToString(), Child = new ClassB { Age = i } }).ToArray();
list.AddRange(items);
var sw = new Stopwatch();
- // var factory =
+ // var factory =
- var myObservable = list.Connect()
- .Do(_ => sw.Start())
- .WhenPropertyChanged(a => a.Child.Age, false)
- .Do(_ => sw.Stop())
- .Subscribe();
+ var myObservable = list.Connect().Do(_ => sw.Start()).WhenPropertyChanged(a => a!.Child!.Age, false).Do(_ => sw.Stop()).Subscribe();
+
+ if (items.Length > 1 && items[1].Child is not null)
+ {
+#pragma warning disable CS8602 // Dereference of a possibly null reference.
+ items[1].Child.Age = -1;
+#pragma warning restore CS8602 // Dereference of a possibly null reference.
+ }
+ else
+ {
+ throw new InvalidOperationException(nameof(items));
+ }
- items[1].Child.Age=-1;
Console.WriteLine($"{sw.ElapsedMilliseconds}");
}
- public class ClassA: AbstractNotifyPropertyChanged, IEquatable
+ public class ClassA : AbstractNotifyPropertyChanged, IEquatable
{
- private string _name;
+ private ClassB? _classB;
+
+ private string? _name;
+
+ public ClassB? Child
+ {
+ get => _classB;
+ set => SetAndRaise(ref _classB, value);
+ }
- public string Name
+ public string? Name
{
get => _name;
set => SetAndRaise(ref _name, value);
}
- private ClassB _classB;
-
- public ClassB Child
+ /// Returns a value that indicates whether the values of two objects are equal.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// true if the and parameters have the same value; otherwise, false.
+ public static bool operator ==(ClassA left, ClassA right)
{
- get => _classB;
- set => SetAndRaise(ref _classB, value);
+ return Equals(left, right);
}
- #region Equality
+ /// Returns a value that indicates whether two objects have different values.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// true if and are not equal; otherwise, false.
+ public static bool operator !=(ClassA left, ClassA right)
+ {
+ return !Equals(left, right);
+ }
- public bool Equals(ClassA other)
+ public bool Equals(ClassA? other)
{
if (ReferenceEquals(null, other))
{
@@ -220,7 +240,7 @@ public bool Equals(ClassA other)
return string.Equals(_name, other._name) && Equals(_classB, other._classB);
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
{
@@ -237,37 +257,17 @@ public override bool Equals(object obj)
return false;
}
- return Equals((ClassA) obj);
+ return Equals((ClassA)obj);
}
public override int GetHashCode()
{
unchecked
{
- return ((_name != null ? _name.GetHashCode() : 0) * 397) ^ (_classB != null ? _classB.GetHashCode() : 0);
+ return ((_name is not null ? _name.GetHashCode() : 0) * 397) ^ (_classB is not null ? _classB.GetHashCode() : 0);
}
}
- /// Returns a value that indicates whether the values of two objects are equal.
- /// The first value to compare.
- /// The second value to compare.
- /// true if the and parameters have the same value; otherwise, false.
- public static bool operator ==(ClassA left, ClassA right)
- {
- return Equals(left, right);
- }
-
- /// Returns a value that indicates whether two objects have different values.
- /// The first value to compare.
- /// The second value to compare.
- /// true if and are not equal; otherwise, false.
- public static bool operator !=(ClassA left, ClassA right)
- {
- return !Equals(left, right);
- }
-
- #endregion
-
public override string ToString()
{
return $"ClassA: Name={Name}, {nameof(Child)}: {Child}";
@@ -284,9 +284,25 @@ public int Age
set => SetAndRaise(ref _age, value);
}
- #region Equality
+ /// Returns a value that indicates whether the values of two objects are equal.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// true if the and parameters have the same value; otherwise, false.
+ public static bool operator ==(ClassB left, ClassB right)
+ {
+ return Equals(left, right);
+ }
- public bool Equals(ClassB other)
+ /// Returns a value that indicates whether two objects have different values.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// true if and are not equal; otherwise, false.
+ public static bool operator !=(ClassB left, ClassB right)
+ {
+ return !Equals(left, right);
+ }
+
+ public bool Equals(ClassB? other)
{
if (ReferenceEquals(null, other))
{
@@ -301,7 +317,7 @@ public bool Equals(ClassB other)
return _age == other._age;
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
{
@@ -318,7 +334,7 @@ public override bool Equals(object obj)
return false;
}
- return Equals((ClassB) obj);
+ return Equals((ClassB)obj);
}
public override int GetHashCode()
@@ -326,31 +342,10 @@ public override int GetHashCode()
return _age;
}
- /// Returns a value that indicates whether the values of two objects are equal.
- /// The first value to compare.
- /// The second value to compare.
- /// true if the and parameters have the same value; otherwise, false.
- public static bool operator ==(ClassB left, ClassB right)
- {
- return Equals(left, right);
- }
-
- /// Returns a value that indicates whether two objects have different values.
- /// The first value to compare.
- /// The second value to compare.
- /// true if and are not equal; otherwise, false.
- public static bool operator !=(ClassB left, ClassB right)
- {
- return !Equals(left, right);
- }
-
- #endregion
-
public override string ToString()
{
return $"{nameof(Age)}: {Age}";
}
}
-
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs
index f705a3ab2..4f00124f9 100644
--- a/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs
+++ b/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs
@@ -1,40 +1,35 @@
using System;
using System.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class IObservableListBindCacheFixture: IDisposable
+ public class IObservableListBindCacheFixture : IDisposable
{
+ private readonly RandomPersonGenerator _generator = new();
+
private readonly IObservableList _list;
+
private readonly ChangeSetAggregator _listNotifications;
+
private readonly ISourceCache _source;
+
private readonly ChangeSetAggregator _sourceCacheNotifications;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
public IObservableListBindCacheFixture()
{
_source = new SourceCache(p => p.Name);
- _sourceCacheNotifications = _source
- .Connect()
- .AutoRefresh()
- .BindToObservableList(out _list)
- .AsAggregator();
+ _sourceCacheNotifications = _source.Connect().AutoRefresh().BindToObservableList(out _list).AsAggregator();
_listNotifications = _list.Connect().AsAggregator();
}
- public void Dispose()
- {
- _sourceCacheNotifications.Dispose();
- _listNotifications.Dispose();
- _source.Dispose();
- }
-
[Fact]
public void AddToSourceAddsToDestination()
{
@@ -45,28 +40,6 @@ public void AddToSourceAddsToDestination()
_list.Items.First().Should().Be(person, "Should be same person");
}
- [Fact]
- public void UpdateToSourceUpdatesTheDestination()
- {
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.AddOrUpdate(person);
- _source.AddOrUpdate(personUpdated);
-
- _list.Count.Should().Be(1, "Should be 1 item in the collection");
- _list.Items.First().Should().Be(personUpdated, "Should be updated person");
- }
-
- [Fact]
- public void RemoveSourceRemovesFromTheDestination()
- {
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
- _source.Remove(person);
-
- _list.Count.Should().Be(0, "Should be 1 item in the collection");
- }
-
[Fact]
public void BatchAdd()
{
@@ -86,6 +59,13 @@ public void BatchRemove()
_list.Count.Should().Be(0, "Should be 100 items in the collection");
}
+ public void Dispose()
+ {
+ _sourceCacheNotifications.Dispose();
+ _listNotifications.Dispose();
+ _source.Dispose();
+ }
+
[Fact]
public void ListRecievesRefresh()
{
@@ -97,5 +77,27 @@ public void ListRecievesRefresh()
_listNotifications.Messages.Count().Should().Be(2);
_listNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh);
}
+
+ [Fact]
+ public void RemoveSourceRemovesFromTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
+ _source.Remove(person);
+
+ _list.Count.Should().Be(0, "Should be 1 item in the collection");
+ }
+
+ [Fact]
+ public void UpdateToSourceUpdatesTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.AddOrUpdate(person);
+ _source.AddOrUpdate(personUpdated);
+
+ _list.Count.Should().Be(1, "Should be 1 item in the collection");
+ _list.Items.First().Should().Be(personUpdated, "Should be updated person");
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs
index 2963887db..92f7f4fd5 100644
--- a/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs
+++ b/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs
@@ -1,41 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reactive.Linq;
using System.Reactive.Subjects;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
public class IObservableListBindCacheSortedFixture : IDisposable
{
private static readonly IComparer _comparerAgeAscThanNameAsc = SortExpressionComparer.Ascending(p => p.Age).ThenByAscending(p => p.Name);
+
private static readonly IComparer _comparerNameDesc = SortExpressionComparer.Descending(p => p.Name);
+ private readonly BehaviorSubject> _comparer = new BehaviorSubject>(_comparerAgeAscThanNameAsc);
+
+ private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
private readonly IObservableList _list;
+
private readonly ChangeSetAggregator _listNotifications;
+
private readonly ISourceCache _source;
+
private readonly SortedChangeSetAggregator _sourceCacheNotifications;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
- private readonly BehaviorSubject> _comparer = new BehaviorSubject>(_comparerAgeAscThanNameAsc);
public IObservableListBindCacheSortedFixture()
{
_source = new SourceCache(p => p.Name);
- _sourceCacheNotifications = _source
- .Connect()
- .AutoRefresh()
- .Sort(_comparer, resetThreshold: 10)
- .BindToObservableList(out _list)
- .AsAggregator();
+ _sourceCacheNotifications = _source.Connect().AutoRefresh().Sort(_comparer, resetThreshold: 10).BindToObservableList(out _list).AsAggregator();
_listNotifications = _list.Connect().AsAggregator();
}
+ [Fact]
+ public void AddToSourceAddsToDestination()
+ {
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
+
+ _list.Count.Should().Be(1, "Should be 1 item in the collection");
+ _list.Items.First().Should().Be(person, "Should be same person");
+ }
+
+ [Fact]
+ public void BatchAdd()
+ {
+ var people = _generator.Take(15).ToList();
+ _source.AddOrUpdate(people);
+
+ var sorted = people.OrderBy(p => p, _comparerAgeAscThanNameAsc).ToList();
+
+ _list.Count.Should().Be(15, "Should be 15 items in the collection");
+ _list.Items.Should().Equal(sorted, "Collections should be equivalent");
+ }
+
+ [Fact]
+ public void BatchRemove()
+ {
+ var people = _generator.Take(100).ToList();
+ _source.AddOrUpdate(people);
+ _source.Clear();
+ _list.Count.Should().Be(0, "Should be 0 items in the collection");
+ }
+
+ [Fact]
+ public void CollectionIsInSortOrder()
+ {
+ _source.AddOrUpdate(_generator.Take(100));
+ var sorted = _source.Items.OrderBy(p => p, _comparerAgeAscThanNameAsc).ToList();
+ sorted.Should().Equal(_list.Items);
+ }
+
public void Dispose()
{
_sourceCacheNotifications.Dispose();
@@ -54,19 +95,14 @@ public void InitialBindWithExistingData()
source.AddOrUpdate(person2); // Add out of order to assert intial order
source.AddOrUpdate(person1);
- var sourceCacheNotifications = source
- .Connect()
- .AutoRefresh()
- .Sort(_comparer, resetThreshold: 10)
- .BindToObservableList(out var list)
- .AsAggregator();
+ var sourceCacheNotifications = source.Connect().AutoRefresh().Sort(_comparer, resetThreshold: 10).BindToObservableList(out var list).AsAggregator();
var listNotifications = list.Connect().AsAggregator();
// Assert
listNotifications.Messages.Count().Should().Be(1);
listNotifications.Messages.First().First().Reason.Should().Be(ListChangeReason.AddRange);
- list.Items.Should().Equal(new Person[] { person1, person2 });
+ list.Items.Should().Equal(person1, person2);
// Clean up
source.Dispose();
@@ -76,69 +112,60 @@ public void InitialBindWithExistingData()
}
[Fact]
- public void AddToSourceAddsToDestination()
+ public void ListRecievesMoves()
{
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
+ var person1 = new Person("Person1", 10);
+ var person2 = new Person("Person2", 20);
+ var person3 = new Person("Person3", 30);
- _list.Count.Should().Be(1, "Should be 1 item in the collection");
- _list.Items.First().Should().Be(person, "Should be same person");
- }
+ _source.AddOrUpdate(new Person[] { person1, person2, person3 });
- [Fact]
- public void UpdateToSourceUpdatesTheDestination()
- {
- var person1 = new Person("Adult1", 20);
- var person2 = new Person("Adult2", 30);
- var personUpdated1 = new Person("Adult1", 40);
+ // Move person 3 to the front on the line
+ person3.Age = 1;
- _source.AddOrUpdate(person1);
- _source.AddOrUpdate(person2);
+ // 1 ChangeSet with AddRange & 1 ChangeSet with Refresh & Move
+ _listNotifications.Messages.Count().Should().Be(2);
- _list.Items.Should().Equal(new Person[] { person1, person2 });
+ // Assert AddRange
+ var addChangeSet = _listNotifications.Messages.First();
+ addChangeSet.First().Reason.Should().Be(ListChangeReason.AddRange);
- _source.AddOrUpdate(personUpdated1);
+ // Assert Refresh & Move
+ var refreshAndMoveChangeSet = _listNotifications.Messages.Last();
- _list.Items.Should().Equal(new Person[] { person2, personUpdated1 });
- }
+ refreshAndMoveChangeSet.Count.Should().Be(2);
- [Fact]
- public void RemoveSourceRemovesFromTheDestination()
- {
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
- _source.Remove(person);
+ var refreshChange = refreshAndMoveChangeSet.First();
+ refreshChange.Reason.Should().Be(ListChangeReason.Refresh);
+ refreshChange.Item.Current.Should().Be(person3);
- _list.Count.Should().Be(0, "Should be 1 item in the collection");
+ var moveChange = refreshAndMoveChangeSet.Last();
+ moveChange.Reason.Should().Be(ListChangeReason.Moved);
+ moveChange.Item.Current.Should().Be(person3);
+ moveChange.Item.PreviousIndex.Should().Be(2);
+ moveChange.Item.CurrentIndex.Should().Be(0);
}
[Fact]
- public void BatchAdd()
+ public void ListRecievesRefresh()
{
- var people = _generator.Take(15).ToList();
- _source.AddOrUpdate(people);
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
- var sorted = people.OrderBy(p => p, _comparerAgeAscThanNameAsc).ToList();
+ person.Age = 60;
- _list.Count.Should().Be(15, "Should be 15 items in the collection");
- _list.Items.Should().Equal(sorted, "Collections should be equivalent");
+ _listNotifications.Messages.Count().Should().Be(2);
+ _listNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh);
}
[Fact]
- public void BatchRemove()
+ public void RemoveSourceRemovesFromTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddOrUpdate(people);
- _source.Clear();
- _list.Count.Should().Be(0, "Should be 0 items in the collection");
- }
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
+ _source.Remove(person);
- [Fact]
- public void CollectionIsInSortOrder()
- {
- _source.AddOrUpdate(_generator.Take(100));
- var sorted = _source.Items.OrderBy(p => p, _comparerAgeAscThanNameAsc).ToList();
- sorted.Should().Equal(_list.Items);
+ _list.Count.Should().Be(0, "Should be 1 item in the collection");
}
[Fact]
@@ -155,97 +182,67 @@ public void Reset()
_list.Items.Should().Equal(sorted);
_listNotifications.Messages.Count().Should().Be(2); // Initial loading change set and a reset change due to a change over the reset threshold.
- _listNotifications.Messages[0].First().Reason.Should().Be(ListChangeReason.AddRange);// initial loading
- _listNotifications.Messages[1].Count.Should().Be(2);// Reset
+ _listNotifications.Messages[0].First().Reason.Should().Be(ListChangeReason.AddRange); // initial loading
+ _listNotifications.Messages[1].Count.Should().Be(2); // Reset
_listNotifications.Messages[1].First().Reason.Should().Be(ListChangeReason.Clear); // reset
_listNotifications.Messages[1].Last().Reason.Should().Be(ListChangeReason.AddRange); // reset
}
[Fact]
- public void ListRecievesRefresh()
+ public void TreatMovesAsRemoveAdd()
{
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
+ var cache = new SourceCache(p => p.Name);
- person.Age = 60;
+ var people = Enumerable.Range(0, 10).Select(age => new Person("Person" + age, age)).ToList();
+ var importantGuy = people.First();
+ cache.AddOrUpdate(people);
- _listNotifications.Messages.Count().Should().Be(2);
- _listNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh);
- }
+ ISortedChangeSet? latestSetWithoutMoves = null;
+ ISortedChangeSet? latestSetWithMoves = null;
- [Fact]
- public void ListRecievesMoves()
- {
- var person1 = new Person("Person1", 10);
- var person2 = new Person("Person2", 20);
- var person3 = new Person("Person3", 30);
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).TreatMovesAsRemoveAdd().BindToObservableList(out var boundList1).Subscribe(set => latestSetWithoutMoves = set))
- _source.AddOrUpdate(new Person[] { person1, person2, person3 });
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).BindToObservableList(out var boundList2).Subscribe(set => latestSetWithMoves = set))
+ {
+ importantGuy.Age += 200;
- // Move person 3 to the front on the line
- person3.Age = 1;
+ if (latestSetWithoutMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithoutMoves));
+ }
- // 1 ChangeSet with AddRange & 1 ChangeSet with Refresh & Move
- _listNotifications.Messages.Count().Should().Be(2);
+ if (latestSetWithMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithMoves));
+ }
- // Assert AddRange
- var addChangeSet = _listNotifications.Messages.First();
- addChangeSet.First().Reason.Should().Be(ListChangeReason.AddRange);
+ latestSetWithoutMoves.Removes.Should().Be(1);
+ latestSetWithoutMoves.Adds.Should().Be(1);
+ latestSetWithoutMoves.Moves.Should().Be(0);
+ latestSetWithoutMoves.Updates.Should().Be(0);
- // Assert Refresh & Move
- var refreshAndMoveChangeSet = _listNotifications.Messages.Last();
+ latestSetWithMoves.Moves.Should().Be(1);
+ latestSetWithMoves.Updates.Should().Be(0);
+ latestSetWithMoves.Removes.Should().Be(0);
+ latestSetWithMoves.Adds.Should().Be(0);
+ }
+ }
- refreshAndMoveChangeSet.Count.Should().Be(2);
+ [Fact]
+ public void UpdateToSourceUpdatesTheDestination()
+ {
+ var person1 = new Person("Adult1", 20);
+ var person2 = new Person("Adult2", 30);
+ var personUpdated1 = new Person("Adult1", 40);
- var refreshChange = refreshAndMoveChangeSet.First();
- refreshChange.Reason.Should().Be(ListChangeReason.Refresh);
- refreshChange.Item.Current.Should().Be(person3);
+ _source.AddOrUpdate(person1);
+ _source.AddOrUpdate(person2);
- var moveChange = refreshAndMoveChangeSet.Last();
- moveChange.Reason.Should().Be(ListChangeReason.Moved);
- moveChange.Item.Current.Should().Be(person3);
- moveChange.Item.PreviousIndex.Should().Be(2);
- moveChange.Item.CurrentIndex.Should().Be(0);
- }
+ _list.Items.Should().Equal(person1, person2);
- [Fact]
- public void TreatMovesAsRemoveAdd()
- {
- var cache = new SourceCache(p => p.Name);
-
- var people = Enumerable.Range(0,10).Select(age => new Person("Person" + age, age)).ToList();
- var importantGuy = people.First();
- cache.AddOrUpdate(people);
-
- ISortedChangeSet latestSetWithoutMoves = null;
- ISortedChangeSet latestSetWithMoves = null;
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .TreatMovesAsRemoveAdd()
- .BindToObservableList(out var boundList1)
- .Subscribe(set => latestSetWithoutMoves = set))
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .BindToObservableList(out var boundList2)
- .Subscribe(set => latestSetWithMoves = set))
- {
-
- importantGuy.Age = importantGuy.Age + 200;
-
- latestSetWithoutMoves.Removes.Should().Be(1);
- latestSetWithoutMoves.Adds.Should().Be(1);
- latestSetWithoutMoves.Moves.Should().Be(0);
- latestSetWithoutMoves.Updates.Should().Be(0);
-
- latestSetWithMoves.Moves.Should().Be(1);
- latestSetWithMoves.Updates.Should().Be(0);
- latestSetWithMoves.Removes.Should().Be(0);
- latestSetWithMoves.Adds.Should().Be(0);
- }
- }
+ _source.AddOrUpdate(personUpdated1);
+
+ _list.Items.Should().Equal(person2, personUpdated1);
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs
index 36fcf98cb..35b8ad3b7 100644
--- a/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs
+++ b/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs
@@ -1,38 +1,43 @@
using System;
using System.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class IObservableListBindListFixture: IDisposable
+ public class IObservableListBindListFixture : IDisposable
{
+ private readonly RandomPersonGenerator _generator = new();
+
private readonly IObservableList _list;
+
private readonly ChangeSetAggregator _observableListNotifications;
+
private readonly SourceList _source;
+
private readonly ChangeSetAggregator _sourceListNotifications;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
public IObservableListBindListFixture()
{
_source = new SourceList();
- _sourceListNotifications = _source
- .Connect()
- .AutoRefresh()
- .BindToObservableList(out _list)
- .AsAggregator();
+ _sourceListNotifications = _source.Connect().AutoRefresh().BindToObservableList(out _list).AsAggregator();
_observableListNotifications = _list.Connect().AsAggregator();
}
- public void Dispose()
+ [Fact]
+ public void AddRange()
{
- _sourceListNotifications.Dispose();
- _observableListNotifications.Dispose();
- _source.Dispose();
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+
+ _list.Count.Should().Be(100, "Should be 100 items in the collection");
+ _list.Should().BeEquivalentTo(_list, "Collections should be equivalent");
}
[Fact]
@@ -46,56 +51,53 @@ public void AddToSourceAddsToDestination()
}
[Fact]
- public void UpdateToSourceUpdatesTheDestination()
+ public void Clear()
{
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.Add(person);
- _source.Replace(person, personUpdated);
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+ _source.Clear();
+ _list.Count.Should().Be(0, "Should be 100 items in the collection");
+ }
- _list.Count.Should().Be(1, "Should be 1 item in the collection");
- _list.Items.First().Should().Be(personUpdated, "Should be updated person");
+ public void Dispose()
+ {
+ _sourceListNotifications.Dispose();
+ _observableListNotifications.Dispose();
+ _source.Dispose();
}
[Fact]
- public void RemoveSourceRemovesFromTheDestination()
+ public void ListRecievesRefresh()
{
var person = new Person("Adult1", 50);
_source.Add(person);
- _source.Remove(person);
-
- _list.Count.Should().Be(0, "Should be 1 item in the collection");
- }
- [Fact]
- public void AddRange()
- {
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
+ person.Age = 60;
- _list.Count.Should().Be(100, "Should be 100 items in the collection");
- _list.Should().BeEquivalentTo(_list, "Collections should be equivalent");
+ _observableListNotifications.Messages.Count().Should().Be(2);
+ _observableListNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh);
}
[Fact]
- public void Clear()
+ public void RemoveSourceRemovesFromTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
- _source.Clear();
- _list.Count.Should().Be(0, "Should be 100 items in the collection");
+ var person = new Person("Adult1", 50);
+ _source.Add(person);
+ _source.Remove(person);
+
+ _list.Count.Should().Be(0, "Should be 1 item in the collection");
}
[Fact]
- public void ListRecievesRefresh()
+ public void UpdateToSourceUpdatesTheDestination()
{
var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
_source.Add(person);
+ _source.Replace(person, personUpdated);
- person.Age = 60;
-
- _observableListNotifications.Messages.Count().Should().Be(2);
- _observableListNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh);
+ _list.Count.Should().Be(1, "Should be 1 item in the collection");
+ _list.Items.First().Should().Be(personUpdated, "Should be updated person");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/NotifyPropertyChangedExFixture.cs b/src/DynamicData.Tests/Binding/NotifyPropertyChangedExFixture.cs
index 532e24a18..8a2620d5a 100644
--- a/src/DynamicData.Tests/Binding/NotifyPropertyChangedExFixture.cs
+++ b/src/DynamicData.Tests/Binding/NotifyPropertyChangedExFixture.cs
@@ -1,55 +1,20 @@
using System;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
public class NotifyPropertyChangedExFixture
{
- [Theory,
- InlineData(true),
- InlineData(false)]
- public void SubscribeToValueChangeForAllItemsInList( bool notifyOnInitialValue)
- {
- var lastAgeChange = -1;
- var source = new SourceList();
- source.Connect().WhenValueChanged(p => p.Age, notifyOnInitialValue).Subscribe(i => lastAgeChange = i);
- var person = new Person("Name", 10);
- var anotherPerson = new Person("AnotherName", 10);
- source.Add(person);
- source.Add(anotherPerson);
-
- (notifyOnInitialValue ? 10 : -1).Should().Be(lastAgeChange);
- person.Age = 12;
- 12.Should().Be(lastAgeChange);
- anotherPerson.Age = 13;
- 13.Should().Be(lastAgeChange);
- }
-
- [Theory,
- InlineData(true),
- InlineData(false)]
- public void SubscribeToValueChangedOnASingleItem( bool notifyOnInitialValue)
- {
- var age = -1;
- var person = new Person("Name", 10);
- person.WhenValueChanged(p => p.Age, notifyOnInitialValue).Subscribe(i => age = i);
-
- (notifyOnInitialValue ? 10 : -1).Should().Be(age);
- person.Age = 12;
- 12.Should().Be(age);
- person.Age = 13;
- 13.Should().Be(age);
- }
-
- [Theory,
- InlineData(true),
- InlineData(false)]
- public void SubscribeToPropertyChangeForAllItemsInList( bool notifyOnInitialValue)
+ [Theory, InlineData(true), InlineData(false)]
+ public void SubscribeToPropertyChangeForAllItemsInList(bool notifyOnInitialValue)
{
- var lastChange = new PropertyValue(null, -1);
+ var lastChange = new PropertyValue(new Person(), -1);
var source = new SourceList();
source.Connect().WhenPropertyChanged(p => p.Age, notifyOnInitialValue).Subscribe(c => lastChange = c);
var person = new Person("Name", 10);
@@ -64,7 +29,7 @@ public void SubscribeToPropertyChangeForAllItemsInList( bool notifyOnInitialValu
}
else
{
- lastChange.Sender.Should().BeNull();
+ lastChange.Sender.Name.Should().Be("unknown");
(-1).Should().Be(lastChange.Value);
}
@@ -76,12 +41,10 @@ public void SubscribeToPropertyChangeForAllItemsInList( bool notifyOnInitialValu
13.Should().Be(lastChange.Value);
}
- [Theory,
- InlineData(true),
- InlineData(false)]
- public void SubscribeToProperyChangedOnASingleItem( bool notifyOnInitialValue)
+ [Theory, InlineData(true), InlineData(false)]
+ public void SubscribeToProperyChangedOnASingleItem(bool notifyOnInitialValue)
{
- var lastChange = new PropertyValue(null, -1);
+ var lastChange = new PropertyValue(new Person(), -1);
var person = new Person("Name", 10);
person.WhenPropertyChanged(p => p.Age, notifyOnInitialValue).Subscribe(c => lastChange = c);
@@ -92,7 +55,7 @@ public void SubscribeToProperyChangedOnASingleItem( bool notifyOnInitialValue)
}
else
{
- lastChange.Sender.Should().BeNull();
+ lastChange.Sender.Name.Should().Be("unknown");
(-1).Should().Be(lastChange.Value);
}
@@ -104,5 +67,36 @@ public void SubscribeToProperyChangedOnASingleItem( bool notifyOnInitialValue)
13.Should().Be(lastChange.Value);
}
+ [Theory, InlineData(true), InlineData(false)]
+ public void SubscribeToValueChangedOnASingleItem(bool notifyOnInitialValue)
+ {
+ var age = -1;
+ var person = new Person("Name", 10);
+ person.WhenValueChanged(p => p.Age, notifyOnInitialValue).Subscribe(i => age = i);
+
+ (notifyOnInitialValue ? 10 : -1).Should().Be(age);
+ person.Age = 12;
+ 12.Should().Be(age);
+ person.Age = 13;
+ 13.Should().Be(age);
+ }
+
+ [Theory, InlineData(true), InlineData(false)]
+ public void SubscribeToValueChangeForAllItemsInList(bool notifyOnInitialValue)
+ {
+ var lastAgeChange = -1;
+ var source = new SourceList();
+ source.Connect().WhenValueChanged(p => p.Age, notifyOnInitialValue).Subscribe(i => lastAgeChange = i);
+ var person = new Person("Name", 10);
+ var anotherPerson = new Person("AnotherName", 10);
+ source.Add(person);
+ source.Add(anotherPerson);
+
+ (notifyOnInitialValue ? 10 : -1).Should().Be(lastAgeChange);
+ person.Age = 12;
+ 12.Should().Be(lastAgeChange);
+ anotherPerson.Age = 13;
+ 13.Should().Be(lastAgeChange);
+ }
}
}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheFixture.cs
index dbc633907..1737c413c 100644
--- a/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheFixture.cs
+++ b/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheFixture.cs
@@ -2,20 +2,25 @@
using System.Collections.Specialized;
using System.Linq;
using System.Reactive.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ObservableCollectionBindCacheFixture: IDisposable
+ public class ObservableCollectionBindCacheFixture : IDisposable
{
- private readonly ObservableCollectionExtended _collection = new ObservableCollectionExtended();
- private readonly ISourceCache _source;
private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly ObservableCollectionExtended _collection = new();
+
+ private readonly RandomPersonGenerator _generator = new();
+
+ private readonly ISourceCache _source;
public ObservableCollectionBindCacheFixture()
{
@@ -23,12 +28,6 @@ public ObservableCollectionBindCacheFixture()
_binder = _source.Connect().Bind(_collection).Subscribe();
}
- public void Dispose()
- {
- _binder.Dispose();
- _source.Dispose();
- }
-
[Fact]
public void AddToSourceAddsToDestination()
{
@@ -40,34 +39,28 @@ public void AddToSourceAddsToDestination()
}
[Fact]
- public void UpdateToSourceUpdatesTheDestination()
+ public void BatchAdd()
{
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.AddOrUpdate(person);
- _source.AddOrUpdate(personUpdated);
+ var people = _generator.Take(100).ToList();
+ _source.AddOrUpdate(people);
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
+ _collection.Count.Should().Be(100, "Should be 100 items in the collection");
+ _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
}
[Fact]
- public void UpdateToSourceSendsReplaceOnDestination()
+ public void BatchRemove()
{
- var person = new Person("Adult1", 50);
- var anotherPerson = new Person("Adult1", 51);
- NotifyCollectionChangedAction action = default;
- _source.AddOrUpdate(person);
-
- using (_collection
- .ObserveCollectionChanges()
- .Select(x => x.EventArgs.Action)
- .Subscribe(updateType => action = updateType))
- {
- _source.AddOrUpdate(anotherPerson);
- }
+ var people = _generator.Take(100).ToList();
+ _source.AddOrUpdate(people);
+ _source.Clear();
+ _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ }
- action.Should().Be(NotifyCollectionChangedAction.Replace, "The notification type should be Replace");
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -81,22 +74,31 @@ public void RemoveSourceRemovesFromTheDestination()
}
[Fact]
- public void BatchAdd()
+ public void UpdateToSourceSendsReplaceOnDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddOrUpdate(people);
+ var person = new Person("Adult1", 50);
+ var anotherPerson = new Person("Adult1", 51);
+ NotifyCollectionChangedAction action = default;
+ _source.AddOrUpdate(person);
- _collection.Count.Should().Be(100, "Should be 100 items in the collection");
- _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
+ using (_collection.ObserveCollectionChanges().Select(x => x.EventArgs.Action).Subscribe(updateType => action = updateType))
+ {
+ _source.AddOrUpdate(anotherPerson);
+ }
+
+ action.Should().Be(NotifyCollectionChangedAction.Replace, "The notification type should be Replace");
}
[Fact]
- public void BatchRemove()
+ public void UpdateToSourceUpdatesTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddOrUpdate(people);
- _source.Clear();
- _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.AddOrUpdate(person);
+ _source.AddOrUpdate(personUpdated);
+
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheSortedFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheSortedFixture.cs
index ec95c1287..35a99f622 100644
--- a/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheSortedFixture.cs
+++ b/src/DynamicData.Tests/Binding/ObservableCollectionBindCacheSortedFixture.cs
@@ -3,36 +3,33 @@
using System.Collections.Specialized;
using System.Linq;
using System.Reactive.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ObservableCollectionBindCacheSortedFixture: IDisposable
+ public class ObservableCollectionBindCacheSortedFixture : IDisposable
{
- private readonly ObservableCollectionExtended _collection = new ObservableCollectionExtended();
- private readonly ISourceCache _source;
private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly ObservableCollectionExtended _collection = new ObservableCollectionExtended();
+
private readonly IComparer _comparer = SortExpressionComparer.Ascending(p => p.Name);
+ private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly ISourceCache _source;
+
public ObservableCollectionBindCacheSortedFixture()
{
_collection = new ObservableCollectionExtended();
_source = new SourceCache(p => p.Name);
- _binder = _source.Connect()
- .Sort(_comparer, resetThreshold: 25)
- .Bind(_collection)
- .Subscribe();
- }
-
- public void Dispose()
- {
- _binder.Dispose();
- _source.Dispose();
+ _binder = _source.Connect().Sort(_comparer, resetThreshold: 25).Bind(_collection).Subscribe();
}
[Fact]
@@ -45,28 +42,6 @@ public void AddToSourceAddsToDestination()
_collection.First().Should().Be(person, "Should be same person");
}
- [Fact]
- public void UpdateToSourceUpdatesTheDestination()
- {
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.AddOrUpdate(person);
- _source.AddOrUpdate(personUpdated);
-
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
- }
-
- [Fact]
- public void RemoveSourceRemovesFromTheDestination()
- {
- var person = new Person("Adult1", 50);
- _source.AddOrUpdate(person);
- _source.Remove(person);
-
- _collection.Count.Should().Be(0, "Should be 1 item in the collection");
- }
-
[Fact]
public void BatchAdd()
{
@@ -94,6 +69,12 @@ public void CollectionIsInSortOrder()
sorted.Should().BeEquivalentTo(_collection.ToList());
}
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
+ }
+
[Fact]
public void LargeUpdateInvokesAReset()
{
@@ -102,15 +83,25 @@ public void LargeUpdateInvokesAReset()
bool invoked = false;
_collection.CollectionChanged += (sender, e) =>
- {
- invoked = true;
- e.Action.Should().Be(NotifyCollectionChangedAction.Reset);
- };
+ {
+ invoked = true;
+ e.Action.Should().Be(NotifyCollectionChangedAction.Reset);
+ };
_source.AddOrUpdate(_generator.Take(100));
invoked.Should().BeTrue();
}
+ [Fact]
+ public void RemoveSourceRemovesFromTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ _source.AddOrUpdate(person);
+ _source.Remove(person);
+
+ _collection.Count.Should().Be(0, "Should be 1 item in the collection");
+ }
+
[Fact]
public void SmallChangeDoesNotInvokeReset()
{
@@ -120,84 +111,60 @@ public void SmallChangeDoesNotInvokeReset()
bool invoked = false;
bool resetInvoked = false;
_collection.CollectionChanged += (sender, e) =>
- {
- invoked = true;
- if (e.Action == NotifyCollectionChangedAction.Reset)
{
- resetInvoked = true;
- }
- };
+ invoked = true;
+ if (e.Action == NotifyCollectionChangedAction.Reset)
+ {
+ resetInvoked = true;
+ }
+ };
_source.AddOrUpdate(_generator.Take(24));
invoked.Should().BeTrue();
resetInvoked.Should().BeFalse();
}
- [Fact]
- public void TreatMovesAsRemoveAdd()
- {
- var cache = new SourceCache(p => p.Name);
-
- var people = Enumerable.Range(0,10).Select(age => new Person("Person" + age, age)).ToList();
- var importantGuy = people.First();
- cache.AddOrUpdate(people);
-
- ISortedChangeSet latestSetWithoutMoves = null;
- ISortedChangeSet latestSetWithMoves = null;
-
- var boundList1 = new ObservableCollectionExtended();
- var boundList2 = new ObservableCollectionExtended();
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .TreatMovesAsRemoveAdd()
- .Bind(boundList1)
- .Subscribe(set => latestSetWithoutMoves = set))
-
- using (cache.Connect()
- .AutoRefresh(p => p.Age)
- .Sort(SortExpressionComparer.Ascending(p => p.Age))
- .Bind(boundList2)
- .Subscribe(set => latestSetWithMoves = set))
- {
-
- importantGuy.Age = importantGuy.Age + 200;
-
- latestSetWithoutMoves.Removes.Should().Be(1);
- latestSetWithoutMoves.Adds.Should().Be(1);
- latestSetWithoutMoves.Moves.Should().Be(0);
- latestSetWithoutMoves.Updates.Should().Be(0);
-
- latestSetWithMoves.Moves.Should().Be(1);
- latestSetWithMoves.Updates.Should().Be(0);
- latestSetWithMoves.Removes.Should().Be(0);
- latestSetWithMoves.Adds.Should().Be(0);
- }
- }
-
[Fact]
- public void UpdateToSourceSendsReplaceIfSortingIsNotAffected()
+ public void TreatMovesAsRemoveAdd()
{
- var person1 = new Person("Adult1", 10);
- var person2 = new Person("Adult2", 11);
+ var cache = new SourceCache(p => p.Name);
- NotifyCollectionChangedAction action = default;
- _source.AddOrUpdate(person1);
- _source.AddOrUpdate(person2);
+ var people = Enumerable.Range(0, 10).Select(age => new Person("Person" + age, age)).ToList();
+ var importantGuy = people.First();
+ cache.AddOrUpdate(people);
- var person2Updated = new Person("Adult2", 12);
+ ISortedChangeSet? latestSetWithoutMoves = null;
+ ISortedChangeSet? latestSetWithMoves = null;
- using (_collection
- .ObserveCollectionChanges()
- .Select(change => change.EventArgs.Action)
- .Subscribe(act => action = act))
+ var boundList1 = new ObservableCollectionExtended();
+ var boundList2 = new ObservableCollectionExtended();
+
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).TreatMovesAsRemoveAdd().Bind(boundList1).Subscribe(set => latestSetWithoutMoves = set))
+
+ using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer.Ascending(p => p.Age)).Bind(boundList2).Subscribe(set => latestSetWithMoves = set))
{
- _source.AddOrUpdate(person2Updated);
- }
+ importantGuy.Age += 200;
- action.Should().Be(NotifyCollectionChangedAction.Replace, "The notification type should be Replace");
- _collection.Should().Equal(person1, person2Updated);
+ if (latestSetWithoutMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithoutMoves));
+ }
+
+ if (latestSetWithMoves is null)
+ {
+ throw new InvalidOperationException(nameof(latestSetWithMoves));
+ }
+
+ latestSetWithoutMoves.Removes.Should().Be(1);
+ latestSetWithoutMoves.Adds.Should().Be(1);
+ latestSetWithoutMoves.Moves.Should().Be(0);
+ latestSetWithoutMoves.Updates.Should().Be(0);
+
+ latestSetWithMoves.Moves.Should().Be(1);
+ latestSetWithMoves.Updates.Should().Be(0);
+ latestSetWithMoves.Removes.Should().Be(0);
+ latestSetWithMoves.Adds.Should().Be(0);
+ }
}
[Fact]
@@ -211,18 +178,12 @@ public void UpdateToSourceSendsRemoveAndAddIfSortingIsAffected()
var collection = new ObservableCollectionExtended();
using (var source = new SourceCache(person => person.Name))
- using (source.Connect()
- .Sort(SortExpressionComparer.Ascending(person => person.Age))
- .Bind(collection)
- .Subscribe())
+ using (source.Connect().Sort(SortExpressionComparer.Ascending(person => person.Age)).Bind(collection).Subscribe())
{
source.AddOrUpdate(person1);
source.AddOrUpdate(person2);
- using (collection
- .ObserveCollectionChanges()
- .Select(change => change.EventArgs.Action)
- .Subscribe(act => actions.Add(act)))
+ using (collection.ObserveCollectionChanges().Select(change => change.EventArgs.Action).Subscribe(act => actions.Add(act)))
{
source.AddOrUpdate(person2Updated);
}
@@ -231,5 +192,38 @@ public void UpdateToSourceSendsRemoveAndAddIfSortingIsAffected()
actions.Should().Equal(NotifyCollectionChangedAction.Remove, NotifyCollectionChangedAction.Add);
collection.Should().Equal(person2Updated, person1);
}
+
+ [Fact]
+ public void UpdateToSourceSendsReplaceIfSortingIsNotAffected()
+ {
+ var person1 = new Person("Adult1", 10);
+ var person2 = new Person("Adult2", 11);
+
+ NotifyCollectionChangedAction action = default;
+ _source.AddOrUpdate(person1);
+ _source.AddOrUpdate(person2);
+
+ var person2Updated = new Person("Adult2", 12);
+
+ using (_collection.ObserveCollectionChanges().Select(change => change.EventArgs.Action).Subscribe(act => action = act))
+ {
+ _source.AddOrUpdate(person2Updated);
+ }
+
+ action.Should().Be(NotifyCollectionChangedAction.Replace, "The notification type should be Replace");
+ _collection.Should().Equal(person1, person2Updated);
+ }
+
+ [Fact]
+ public void UpdateToSourceUpdatesTheDestination()
+ {
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.AddOrUpdate(person);
+ _source.AddOrUpdate(personUpdated);
+
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionBindListFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionBindListFixture.cs
index 8f8402a8e..ca0dbbbcd 100644
--- a/src/DynamicData.Tests/Binding/ObservableCollectionBindListFixture.cs
+++ b/src/DynamicData.Tests/Binding/ObservableCollectionBindListFixture.cs
@@ -1,19 +1,24 @@
using System;
using System.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ObservableCollectionBindListFixture: IDisposable
+ public class ObservableCollectionBindListFixture : IDisposable
{
- private readonly ObservableCollectionExtended _collection = new ObservableCollectionExtended();
- private readonly SourceList _source;
private readonly IDisposable _binder;
- private readonly RandomPersonGenerator _generator = new RandomPersonGenerator();
+
+ private readonly ObservableCollectionExtended _collection = new();
+
+ private readonly RandomPersonGenerator _generator = new();
+
+ private readonly SourceList _source;
public ObservableCollectionBindListFixture()
{
@@ -22,10 +27,14 @@ public ObservableCollectionBindListFixture()
_binder = _source.Connect().Bind(_collection).Subscribe();
}
- public void Dispose()
+ [Fact]
+ public void AddRange()
{
- _binder.Dispose();
- _source.Dispose();
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+
+ _collection.Count.Should().Be(100, "Should be 100 items in the collection");
+ _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
}
[Fact]
@@ -39,15 +48,18 @@ public void AddToSourceAddsToDestination()
}
[Fact]
- public void UpdateToSourceUpdatesTheDestination()
+ public void Clear()
{
- var person = new Person("Adult1", 50);
- var personUpdated = new Person("Adult1", 51);
- _source.Add(person);
- _source.Replace(person, personUpdated);
+ var people = _generator.Take(100).ToList();
+ _source.AddRange(people);
+ _source.Clear();
+ _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ }
- _collection.Count.Should().Be(1, "Should be 1 item in the collection");
- _collection.First().Should().Be(personUpdated, "Should be updated person");
+ public void Dispose()
+ {
+ _binder.Dispose();
+ _source.Dispose();
}
[Fact]
@@ -61,22 +73,15 @@ public void RemoveSourceRemovesFromTheDestination()
}
[Fact]
- public void AddRange()
+ public void UpdateToSourceUpdatesTheDestination()
{
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
-
- _collection.Count.Should().Be(100, "Should be 100 items in the collection");
- _collection.Should().BeEquivalentTo(_collection, "Collections should be equivalent");
- }
+ var person = new Person("Adult1", 50);
+ var personUpdated = new Person("Adult1", 51);
+ _source.Add(person);
+ _source.Replace(person, personUpdated);
- [Fact]
- public void Clear()
- {
- var people = _generator.Take(100).ToList();
- _source.AddRange(people);
- _source.Clear();
- _collection.Count.Should().Be(0, "Should be 100 items in the collection");
+ _collection.Count.Should().Be(1, "Should be 1 item in the collection");
+ _collection.First().Should().Be(personUpdated, "Should be updated person");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs
index 783d43285..8d100b81d 100644
--- a/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs
+++ b/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs
@@ -1,17 +1,21 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
+
using DynamicData.Binding;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ObservableCollectionExtendedToChangeSetFixture: IDisposable
+ public class ObservableCollectionExtendedToChangeSetFixture : IDisposable
{
private readonly ObservableCollectionExtended _collection;
+
private readonly ChangeSetAggregator _results;
+
private readonly ReadOnlyObservableCollection _target;
public ObservableCollectionExtendedToChangeSetFixture()
@@ -21,11 +25,30 @@ public ObservableCollectionExtendedToChangeSetFixture()
_results = _target.ToObservableChangeSet().AsAggregator();
}
+ [Fact]
+ public void Add()
+ {
+ _collection.Add(1);
+
+ _results.Messages.Count.Should().Be(1);
+ _results.Data.Count.Should().Be(1);
+ _results.Data.Items.First().Should().Be(1);
+ }
+
public void Dispose()
{
_results.Dispose();
}
+ [Fact]
+ public void Duplicates()
+ {
+ _collection.Add(1);
+ _collection.Add(1);
+
+ _results.Data.Count.Should().Be(2);
+ }
+
[Fact]
public void Move()
{
@@ -39,16 +62,6 @@ public void Move()
_results.Data.Items.Should().BeEquivalentTo(_target);
}
- [Fact]
- public void Add()
- {
- _collection.Add(1);
-
- _results.Messages.Count.Should().Be(1);
- _results.Data.Count.Should().Be(1);
- _results.Data.Items.First().Should().Be(1);
- }
-
[Fact]
public void Remove()
{
@@ -61,15 +74,6 @@ public void Remove()
_results.Data.Items.Should().BeEquivalentTo(_target);
}
- [Fact]
- public void Duplicates()
- {
- _collection.Add(1);
- _collection.Add(1);
-
- _results.Data.Count.Should().Be(2);
- }
-
[Fact]
public void Replace()
{
@@ -77,7 +81,6 @@ public void Replace()
_collection[8] = 20;
_results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
-
}
//[Fact]
diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs
index a62c89eb8..4b81ca7b4 100644
--- a/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs
+++ b/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs
@@ -2,16 +2,19 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
+
using DynamicData.Binding;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ObservableCollectionToChangeSetFixture: IDisposable
+ public class ObservableCollectionToChangeSetFixture : IDisposable
{
private readonly TestObservableCollection _collection;
+
private readonly ChangeSetAggregator _results;
public ObservableCollectionToChangeSetFixture()
@@ -20,11 +23,30 @@ public ObservableCollectionToChangeSetFixture()
_results = _collection.ToObservableChangeSet().AsAggregator();
}
+ [Fact]
+ public void Add()
+ {
+ _collection.Add(1);
+
+ _results.Messages.Count.Should().Be(1);
+ _results.Data.Count.Should().Be(1);
+ _results.Data.Items.First().Should().Be(1);
+ }
+
public void Dispose()
{
_results.Dispose();
}
+ [Fact]
+ public void Duplicates()
+ {
+ _collection.Add(1);
+ _collection.Add(1);
+
+ _results.Data.Count.Should().Be(2);
+ }
+
[Fact]
public void Move()
{
@@ -38,16 +60,6 @@ public void Move()
_results.Data.Items.Should().BeEquivalentTo(_collection);
}
- [Fact]
- public void Add()
- {
- _collection.Add(1);
-
- _results.Messages.Count.Should().Be(1);
- _results.Data.Count.Should().Be(1);
- _results.Data.Items.First().Should().Be(1);
- }
-
[Fact]
public void Remove()
{
@@ -60,23 +72,13 @@ public void Remove()
_results.Data.Items.Should().BeEquivalentTo(_collection);
}
- [Fact]
- public void Duplicates()
- {
- _collection.Add(1);
- _collection.Add(1);
-
- _results.Data.Count.Should().Be(2);
- }
-
[Fact]
public void Replace()
{
_collection.AddRange(Enumerable.Range(1, 10));
_collection[8] = 20;
- _results.Data.Items.Should().BeEquivalentTo(new []{1,2,3,4,5,6,7,8,20,10});
-
+ _results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
}
[Fact]
@@ -100,4 +102,4 @@ public void Reset()
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs
index 858808b7a..4c4948220 100644
--- a/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs
+++ b/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs
@@ -2,18 +2,21 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
-using System.Reactive.Linq;
+
using DynamicData.Binding;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Binding
{
-
- public class ReadOnlyObservableCollectionToChangeSetFixture: IDisposable
+ public class ReadOnlyObservableCollectionToChangeSetFixture : IDisposable
{
private readonly TestObservableCollection _collection;
+
private readonly ChangeSetAggregator _results;
+
private readonly ReadOnlyObservableCollection _target;
public ReadOnlyObservableCollectionToChangeSetFixture()
@@ -23,24 +26,6 @@ public ReadOnlyObservableCollectionToChangeSetFixture()
_results = _target.ToObservableChangeSet().AsAggregator();
}
- public void Dispose()
- {
- _results.Dispose();
- }
-
- [Fact]
- public void Move()
- {
- _collection.AddRange(Enumerable.Range(1, 10));
-
- _results.Data.Items.Should().BeEquivalentTo(_target);
- _collection.Move(5, 8);
- _results.Data.Items.Should().BeEquivalentTo(_target);
-
- _collection.Move(7, 1);
- _results.Data.Items.Should().BeEquivalentTo(_target);
- }
-
[Fact]
public void Add()
{
@@ -51,16 +36,9 @@ public void Add()
_results.Data.Items.First().Should().Be(1);
}
- [Fact]
- public void Remove()
+ public void Dispose()
{
- _collection.AddRange(Enumerable.Range(1, 10));
-
- _collection.Remove(3);
-
- _results.Data.Count.Should().Be(9);
- _results.Data.Items.Contains(3).Should().BeFalse();
- _results.Data.Items.Should().BeEquivalentTo(_target);
+ _results.Dispose();
}
[Fact]
@@ -73,25 +51,16 @@ public void Duplicates()
}
[Fact]
- public void Replace()
- {
- _collection.AddRange(Enumerable.Range(1, 10));
- _collection[8] = 20;
-
- _results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
- }
-
- [Fact]
- public void ResetFiresClearsAndAdds()
+ public void Move()
{
_collection.AddRange(Enumerable.Range(1, 10));
- _collection.Reset();
+ _results.Data.Items.Should().BeEquivalentTo(_target);
+ _collection.Move(5, 8);
_results.Data.Items.Should().BeEquivalentTo(_target);
- var resetNotification = _results.Messages.Last();
- resetNotification.Removes.Should().Be(10);
- resetNotification.Adds.Should().Be(10);
+ _collection.Move(7, 1);
+ _results.Data.Items.Should().BeEquivalentTo(_target);
}
[Fact]
@@ -100,15 +69,11 @@ public void RefreshNotSupported()
// Arrange
var sourceCache = new SourceCache
- (item => item.Id);
- var item1 = new Item(name: "Old Name");
+ var item1 = new Item("Old Name");
sourceCache.AddOrUpdate(item1);
- var sourceCacheResults = sourceCache
- .Connect()
- .AutoRefresh(item => item.Name)
- .Bind(out var collection)
- .AsAggregator();
+ var sourceCacheResults = sourceCache.Connect().AutoRefresh(item => item.Name).Bind(out var collection).AsAggregator();
var collectionResults = collection.ToObservableChangeSet().AsAggregator();
@@ -130,6 +95,40 @@ public void RefreshNotSupported()
collectionResults.Dispose();
}
+ [Fact]
+ public void Remove()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+
+ _collection.Remove(3);
+
+ _results.Data.Count.Should().Be(9);
+ _results.Data.Items.Contains(3).Should().BeFalse();
+ _results.Data.Items.Should().BeEquivalentTo(_target);
+ }
+
+ [Fact]
+ public void Replace()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+ _collection[8] = 20;
+
+ _results.Data.Items.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 20, 10 });
+ }
+
+ [Fact]
+ public void ResetFiresClearsAndAdds()
+ {
+ _collection.AddRange(Enumerable.Range(1, 10));
+
+ _collection.Reset();
+ _results.Data.Items.Should().BeEquivalentTo(_target);
+
+ var resetNotification = _results.Messages.Last();
+ resetNotification.Removes.Should().Be(10);
+ resetNotification.Adds.Should().Be(10);
+ }
+
private class TestObservableCollection : ObservableCollection
{
public void Reset()
diff --git a/src/DynamicData.Tests/Cache/AndFixture.cs b/src/DynamicData.Tests/Cache/AndFixture.cs
index a5b3257cf..0199ccab1 100644
--- a/src/DynamicData.Tests/Cache/AndFixture.cs
+++ b/src/DynamicData.Tests/Cache/AndFixture.cs
@@ -1,13 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
-
public class AndFixture : AndFixtureBase
{
protected override IObservable> CreateObservable()
@@ -25,11 +27,13 @@ protected override IObservable> CreateObservable()
}
}
- public abstract class AndFixtureBase: IDisposable
+ public abstract class AndFixtureBase : IDisposable
{
protected ISourceCache _source1;
+
protected ISourceCache _source2;
- private ChangeSetAggregator _results;
+
+ private readonly ChangeSetAggregator _results;
protected AndFixtureBase()
{
@@ -38,8 +42,6 @@ protected AndFixtureBase()
_results = CreateObservable().AsAggregator();
}
- protected abstract IObservable> CreateObservable();
-
public void Dispose()
{
_source1.Dispose();
@@ -48,36 +50,37 @@ public void Dispose()
}
[Fact]
- public void UpdatingOneSourceOnlyProducesNoResults()
+ public void RemovingFromOneRemovesFromResult()
{
var person = new Person("Adult1", 50);
_source1.AddOrUpdate(person);
+ _source2.AddOrUpdate(person);
- _results.Messages.Count.Should().Be(0, "Should have no updates");
+ _source2.Remove(person);
+ _results.Messages.Count.Should().Be(2, "Should be 2 updates");
_results.Data.Count.Should().Be(0, "Cache should have no items");
}
[Fact]
- public void UpdatingBothProducesResults()
+ public void StartingWithNonEmptySourceProducesNoResult()
{
- var person = new Person("Adult1", 50);
+ var person = new Person("Adult", 50);
_source1.AddOrUpdate(person);
- _source2.AddOrUpdate(person);
- _results.Messages.Count.Should().Be(1, "Should have no updates");
- _results.Data.Count.Should().Be(1, "Cache should have no items");
- _results.Data.Items.First().Should().Be(person, "Should be same person");
+
+ using var result = CreateObservable().AsAggregator();
+ _results.Messages.Count.Should().Be(0, "Should have no updates");
+ result.Data.Count.Should().Be(0, "Cache should have no items");
}
[Fact]
- public void RemovingFromOneRemovesFromResult()
+ public void UpdatingBothProducesResults()
{
var person = new Person("Adult1", 50);
_source1.AddOrUpdate(person);
_source2.AddOrUpdate(person);
-
- _source2.Remove(person);
- _results.Messages.Count.Should().Be(2, "Should be 2 updates");
- _results.Data.Count.Should().Be(0, "Cache should have no items");
+ _results.Messages.Count.Should().Be(1, "Should have no updates");
+ _results.Data.Count.Should().Be(1, "Cache should have no items");
+ _results.Data.Items.First().Should().Be(person, "Should be same person");
}
[Fact]
@@ -95,16 +98,15 @@ public void UpdatingOneProducesOnlyOneUpdate()
}
[Fact]
- public void StartingWithNonEmptySourceProducesNoResult()
+ public void UpdatingOneSourceOnlyProducesNoResults()
{
- var person = new Person("Adult", 50);
+ var person = new Person("Adult1", 50);
_source1.AddOrUpdate(person);
- using (var result = CreateObservable().AsAggregator())
- {
- _results.Messages.Count.Should().Be(0, "Should have no updates");
- result.Data.Count.Should().Be(0, "Cache should have no items");
- }
+ _results.Messages.Count.Should().Be(0, "Should have no updates");
+ _results.Data.Count.Should().Be(0, "Cache should have no items");
}
+
+ protected abstract IObservable> CreateObservable();
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs b/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs
index 7c4dda6a5..996356fae 100644
--- a/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs
+++ b/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs
@@ -2,110 +2,100 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
+
using DynamicData.Binding;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
-
public class AutoRefreshFixture
{
[Fact]
public void AutoRefresh()
{
- var items = Enumerable.Range(1, 100)
- .Select(i => new Person("Person" + i, 1))
- .ToArray();
+ var items = Enumerable.Range(1, 100).Select(i => new Person("Person" + i, 1)).ToArray();
//result should only be true when all items are set to true
- using (var cache = new SourceCache(m => m.Name))
- using (var results = cache.Connect().AutoRefresh(p=>p.Age).AsAggregator())
- {
- cache.AddOrUpdate(items);
-
- results.Data.Count.Should().Be(100);
- results.Messages.Count.Should().Be(1);
-
- items[0].Age = 10;
- results.Data.Count.Should().Be(100);
- results.Messages.Count.Should().Be(2);
-
- results.Messages[1].First().Reason.Should().Be(ChangeReason.Refresh);
-
- //remove an item and check no change is fired
- var toRemove = items[1];
- cache.Remove(toRemove);
- results.Data.Count.Should().Be(99);
- results.Messages.Count.Should().Be(3);
- toRemove.Age = 100;
- results.Messages.Count.Should().Be(3);
-
- //add it back in and check it updates
- cache.AddOrUpdate(toRemove);
- results.Messages.Count.Should().Be(4);
- toRemove.Age = 101;
- results.Messages.Count.Should().Be(5);
-
- results.Messages.Last().First().Reason.Should().Be(ChangeReason.Refresh);
- }
+ using var cache = new SourceCache(m => m.Name);
+ using var results = cache.Connect().AutoRefresh(p => p.Age).AsAggregator();
+ cache.AddOrUpdate(items);
+
+ results.Data.Count.Should().Be(100);
+ results.Messages.Count.Should().Be(1);
+
+ items[0].Age = 10;
+ results.Data.Count.Should().Be(100);
+ results.Messages.Count.Should().Be(2);
+
+ results.Messages[1].First().Reason.Should().Be(ChangeReason.Refresh);
+
+ //remove an item and check no change is fired
+ var toRemove = items[1];
+ cache.Remove(toRemove);
+ results.Data.Count.Should().Be(99);
+ results.Messages.Count.Should().Be(3);
+ toRemove.Age = 100;
+ results.Messages.Count.Should().Be(3);
+
+ //add it back in and check it updates
+ cache.AddOrUpdate(toRemove);
+ results.Messages.Count.Should().Be(4);
+ toRemove.Age = 101;
+ results.Messages.Count.Should().Be(5);
+
+ results.Messages.Last().First().Reason.Should().Be(ChangeReason.Refresh);
}
[Fact]
public void AutoRefreshFromObservable()
{
- var items = Enumerable.Range(1, 100)
- .Select(i => new Person("Person" + i, 1))
- .ToArray();
+ var items = Enumerable.Range(1, 100).Select(i => new Person("Person" + i, 1)).ToArray();
//result should only be true when all items are set to true
- using (var cache = new SourceCache(m => m.Name))
- using (var results = cache.Connect().AutoRefreshOnObservable(p => p.WhenAnyPropertyChanged()).AsAggregator())
- {
- cache.AddOrUpdate(items);
-
- results.Data.Count.Should().Be(100);
- results.Messages.Count.Should().Be(1);
-
- items[0].Age = 10;
- results.Data.Count.Should().Be(100);
- results.Messages.Count.Should().Be(2);
-
- results.Messages[1].First().Reason.Should().Be(ChangeReason.Refresh);
-
- //remove an item and check no change is fired
- var toRemove = items[1];
- cache.Remove(toRemove);
- results.Data.Count.Should().Be(99);
- results.Messages.Count.Should().Be(3);
- toRemove.Age = 100;
- results.Messages.Count.Should().Be(3);
-
- //add it back in and check it updates
- cache.AddOrUpdate(toRemove);
- results.Messages.Count.Should().Be(4);
- toRemove.Age = 101;
- results.Messages.Count.Should().Be(5);
-
- results.Messages.Last().First().Reason.Should().Be(ChangeReason.Refresh);
- }
+ using var cache = new SourceCache(m => m.Name);
+ using var results = cache.Connect().AutoRefreshOnObservable(p => p.WhenAnyPropertyChanged()).AsAggregator();
+ cache.AddOrUpdate(items);
+
+ results.Data.Count.Should().Be(100);
+ results.Messages.Count.Should().Be(1);
+
+ items[0].Age = 10;
+ results.Data.Count.Should().Be(100);
+ results.Messages.Count.Should().Be(2);
+
+ results.Messages[1].First().Reason.Should().Be(ChangeReason.Refresh);
+
+ //remove an item and check no change is fired
+ var toRemove = items[1];
+ cache.Remove(toRemove);
+ results.Data.Count.Should().Be(99);
+ results.Messages.Count.Should().Be(3);
+ toRemove.Age = 100;
+ results.Messages.Count.Should().Be(3);
+
+ //add it back in and check it updates
+ cache.AddOrUpdate(toRemove);
+ results.Messages.Count.Should().Be(4);
+ toRemove.Age = 101;
+ results.Messages.Count.Should().Be(5);
+
+ results.Messages.Last().First().Reason.Should().Be(ChangeReason.Refresh);
}
[Fact]
public void MakeSelectMagicWorkWithObservable()
{
- var initialItem = new IntHolder() { Value = 1, Description = "Initial Description" };
+ var initialItem = new IntHolder { Value = 1, Description = "Initial Description" };
var sourceList = new SourceList();
sourceList.Add(initialItem);
- var descriptionStream = sourceList
- .Connect()
- .AutoRefresh(intHolder => intHolder.Description)
- .Transform(intHolder => intHolder.Description, true)
- .Do(x => { }) // <--- Add break point here to check the overload fixes it
- .Bind(out ReadOnlyObservableCollection resultCollection);
+ var descriptionStream = sourceList.Connect().AutoRefresh(intHolder => intHolder!.Description).Transform(intHolder => intHolder!.Description, true).Do(x => { }) // <--- Add break point here to check the overload fixes it
+ .Bind(out ReadOnlyObservableCollection resultCollection);
using (descriptionStream.Subscribe())
{
@@ -119,20 +109,21 @@ public void MakeSelectMagicWorkWithObservable()
public class IntHolder : AbstractNotifyPropertyChanged
{
+ public string? _description_;
+
public int _value;
- public int Value
- {
- get => _value;
- set => SetAndRaise(ref _value, value);
- }
- public string _description_;
- public string Description
+ public string? Description
{
get => _description_;
set => SetAndRaise(ref _description_, value);
}
- }
+ public int Value
+ {
+ get => _value;
+ set => SetAndRaise(ref _value, value);
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/BatchFixture.cs b/src/DynamicData.Tests/Cache/BatchFixture.cs
index 791640dac..490deefc8 100644
--- a/src/DynamicData.Tests/Cache/BatchFixture.cs
+++ b/src/DynamicData.Tests/Cache/BatchFixture.cs
@@ -1,19 +1,24 @@
using System;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Microsoft.Reactive.Testing;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
-
- public class BatchFixture: IDisposable
+ public class BatchFixture : IDisposable
{
- private readonly ISourceCache _source;
private readonly ChangeSetAggregator _results;
+
private readonly TestScheduler _scheduler;
- public BatchFixture()
+ private readonly ISourceCache _source;
+
+ public BatchFixture()
{
_scheduler = new TestScheduler();
_source = new SourceCache(p => p.Key);
@@ -43,4 +48,4 @@ public void ResultsWillBeReceivedAfterClosingBuffer()
_results.Messages.Count.Should().Be(1, "Should be 1 update");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/BatchIfFixture.cs b/src/DynamicData.Tests/Cache/BatchIfFixture.cs
index 209f5da88..16e8ebb00 100644
--- a/src/DynamicData.Tests/Cache/BatchIfFixture.cs
+++ b/src/DynamicData.Tests/Cache/BatchIfFixture.cs
@@ -1,33 +1,70 @@
using System;
using System.Reactive.Linq;
using System.Reactive.Subjects;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Microsoft.Reactive.Testing;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
- public class BatchIfFixture: IDisposable
+ public class BatchIfFixture : IDisposable
{
- private readonly ISourceCache _source;
+ private readonly ISubject _pausingSubject = new Subject();
+
private readonly ChangeSetAggregator _results;
+
private readonly TestScheduler _scheduler;
- private readonly ISubject _pausingSubject = new Subject();
- public BatchIfFixture()
+ private readonly ISourceCache _source;
+
+ public BatchIfFixture()
{
_scheduler = new TestScheduler();
_source = new SourceCache(p => p.Key);
_results = _source.Connect().BatchIf(_pausingSubject, _scheduler).AsAggregator();
- // _results = _source.Connect().BatchIf(new BehaviorSubject(true), scheduler: _scheduler).AsAggregator();
+ // _results = _source.Connect().BatchIf(new BehaviorSubject(true), scheduler: _scheduler).AsAggregator();
}
- public void Dispose()
+ [Fact]
+ public void CanToggleSuspendResume()
{
- _results.Dispose();
- _source.Dispose();
+ _pausingSubject.OnNext(true);
+ ////advance otherwise nothing happens
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
+
+ _source.AddOrUpdate(new Person("A", 1));
+
+ //go forward an arbitary amount of time
+ _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
+ _results.Messages.Count.Should().Be(0, "There should be no messages");
+
+ _pausingSubject.OnNext(false);
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
+
+ _source.AddOrUpdate(new Person("B", 1));
+
+ _results.Messages.Count.Should().Be(2, "There should be 2 messages");
+
+ _pausingSubject.OnNext(true);
+ ////advance otherwise nothing happens
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
+
+ _source.AddOrUpdate(new Person("C", 1));
+
+ //go forward an arbitary amount of time
+ _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
+ _results.Messages.Count.Should().Be(2, "There should be 2 messages");
+
+ _pausingSubject.OnNext(false);
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
+
+ _results.Messages.Count.Should().Be(3, "There should be 3 messages");
}
///
@@ -36,16 +73,11 @@ public void Dispose()
[Fact]
public void ChangesNotLostIfConsumerIsRunningOnDifferentThread()
{
-
var producerScheduler = new TestScheduler();
var consumerScheduler = new TestScheduler();
//Note consumer is running on a different scheduler
- _source.Connect()
- .BatchIf(_pausingSubject, producerScheduler)
- .ObserveOn(consumerScheduler)
- .Bind(out var target)
- .AsAggregator();
+ _source.Connect().BatchIf(_pausingSubject, producerScheduler).ObserveOn(consumerScheduler).Bind(out var target).AsAggregator();
_source.AddOrUpdate(new Person("A", 1));
@@ -79,6 +111,12 @@ public void ChangesNotLostIfConsumerIsRunningOnDifferentThread()
target.Count.Should().Be(2, "There should be 2 message");
}
+ public void Dispose()
+ {
+ _results.Dispose();
+ _source.Dispose();
+ }
+
[Fact]
public void NoResultsWillBeReceivedIfPaused()
{
@@ -102,41 +140,5 @@ public void ResultsWillBeReceivedIfNotPaused()
_scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
_results.Messages.Count.Should().Be(1, "Should be 1 update");
}
-
- [Fact]
- public void CanToggleSuspendResume()
- {
- _pausingSubject.OnNext(true);
- ////advance otherwise nothing happens
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
-
- _source.AddOrUpdate(new Person("A", 1));
-
- //go forward an arbitary amount of time
- _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
- _results.Messages.Count.Should().Be(0, "There should be no messages");
-
- _pausingSubject.OnNext(false);
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
-
- _source.AddOrUpdate(new Person("B", 1));
-
- _results.Messages.Count.Should().Be(2, "There should be 2 messages");
-
- _pausingSubject.OnNext(true);
- ////advance otherwise nothing happens
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
-
- _source.AddOrUpdate(new Person("C", 1));
-
- //go forward an arbitary amount of time
- _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
- _results.Messages.Count.Should().Be(2, "There should be 2 messages");
-
- _pausingSubject.OnNext(false);
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
-
- _results.Messages.Count.Should().Be(3, "There should be 3 messages");
- }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs b/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs
index 5e2364ba2..5d3b8f957 100644
--- a/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs
+++ b/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs
@@ -2,99 +2,102 @@
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Microsoft.Reactive.Testing;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
public class BatchIfWithTimeoutFixture : IDisposable
{
- private readonly ISourceCache _source;
private readonly TestScheduler _scheduler;
+ private readonly ISourceCache _source;
+
public BatchIfWithTimeoutFixture()
{
_scheduler = new TestScheduler();
_source = new SourceCache(p => p.Key);
}
+ public void Dispose()
+ {
+ _source.Dispose();
+ }
+
[Fact]
public void InitialPause()
{
var pausingSubject = new Subject();
- using (var results = _source.Connect().BatchIf(pausingSubject, true, _scheduler).AsAggregator())
- {
- // no results because the initial pause state is pause
- _source.AddOrUpdate(new Person("A", 1));
- results.Data.Count.Should().Be(0);
-
- //resume and expect a result
- pausingSubject.OnNext(false);
- results.Data.Count.Should().Be(1);
-
- //add another in the window where there is no pause
- _source.AddOrUpdate(new Person("B", 1));
- results.Data.Count.Should().Be(2);
-
- // pause again
- pausingSubject.OnNext(true);
- _source.AddOrUpdate(new Person("C", 1));
- results.Data.Count.Should().Be(2);
-
- //resume for the second time
- pausingSubject.OnNext(false);
- results.Data.Count.Should().Be(3);
- }
+ using var results = _source.Connect().BatchIf(pausingSubject, true, _scheduler).AsAggregator();
+ // no results because the initial pause state is pause
+ _source.AddOrUpdate(new Person("A", 1));
+ results.Data.Count.Should().Be(0);
+
+ //resume and expect a result
+ pausingSubject.OnNext(false);
+ results.Data.Count.Should().Be(1);
+
+ //add another in the window where there is no pause
+ _source.AddOrUpdate(new Person("B", 1));
+ results.Data.Count.Should().Be(2);
+
+ // pause again
+ pausingSubject.OnNext(true);
+ _source.AddOrUpdate(new Person("C", 1));
+ results.Data.Count.Should().Be(2);
+
+ //resume for the second time
+ pausingSubject.OnNext(false);
+ results.Data.Count.Should().Be(3);
}
[Fact]
public void Timeout()
{
var pausingSubject = new Subject();
- using (var results = _source.Connect().BatchIf(pausingSubject, TimeSpan.FromSeconds(1), _scheduler).AsAggregator())
- {
- // no results because the initial pause state is pause
- _source.AddOrUpdate(new Person("A", 1));
- results.Data.Count.Should().Be(1);
-
- // pause and add
- pausingSubject.OnNext(true);
- _source.AddOrUpdate(new Person("B", 1));
- results.Data.Count.Should().Be(1);
-
- //resume before timeout ends
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(500).Ticks);
- results.Data.Count.Should().Be(1);
-
- pausingSubject.OnNext(false);
- results.Data.Count.Should().Be(2);
-
- //pause and advance past timeout window
- pausingSubject.OnNext(true);
- _source.AddOrUpdate(new Person("C", 1));
- _scheduler.AdvanceBy(TimeSpan.FromSeconds(2.1).Ticks);
- results.Data.Count.Should().Be(3);
-
- _source.AddOrUpdate(new Person("D", 1));
- results.Data.Count.Should().Be(4);
- }
- }
+ using var results = _source.Connect().BatchIf(pausingSubject, TimeSpan.FromSeconds(1), _scheduler).AsAggregator();
+ // no results because the initial pause state is pause
+ _source.AddOrUpdate(new Person("A", 1));
+ results.Data.Count.Should().Be(1);
- public void Dispose()
- {
- _source.Dispose();
- }
+ // pause and add
+ pausingSubject.OnNext(true);
+ _source.AddOrUpdate(new Person("B", 1));
+ results.Data.Count.Should().Be(1);
+
+ //resume before timeout ends
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(500).Ticks);
+ results.Data.Count.Should().Be(1);
+
+ pausingSubject.OnNext(false);
+ results.Data.Count.Should().Be(2);
+
+ //pause and advance past timeout window
+ pausingSubject.OnNext(true);
+ _source.AddOrUpdate(new Person("C", 1));
+ _scheduler.AdvanceBy(TimeSpan.FromSeconds(2.1).Ticks);
+ results.Data.Count.Should().Be(3);
+ _source.AddOrUpdate(new Person("D", 1));
+ results.Data.Count.Should().Be(4);
+ }
}
public class BatchIfWithTimeOutFixture : IDisposable
{
- private readonly ISourceCache _source;
+ private readonly ISubject _pausingSubject = new Subject();
+
private readonly ChangeSetAggregator _results;
+
private readonly TestScheduler _scheduler;
- private readonly ISubject _pausingSubject = new Subject();
+
+ private readonly ISourceCache _source;
public BatchIfWithTimeOutFixture()
{
@@ -103,72 +106,49 @@ public BatchIfWithTimeOutFixture()
_results = _source.Connect().BatchIf(_pausingSubject, TimeSpan.FromMinutes(1), _scheduler).AsAggregator();
}
- public void Dispose()
- {
- _results.Dispose();
- _source.Dispose();
- _pausingSubject.OnCompleted();
- }
-
[Fact]
- public void WillApplyTimeout()
+ public void CanToggleSuspendResume()
{
_pausingSubject.OnNext(true);
-
- //should timeout
- _scheduler.AdvanceBy(TimeSpan.FromSeconds(61).Ticks);
+ ////advance otherwise nothing happens
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
_source.AddOrUpdate(new Person("A", 1));
- _results.Messages.Count.Should().Be(1, "There should be 1 messages");
- }
+ //go forward an arbitary amount of time
+ _results.Messages.Count.Should().Be(0, "There should be no messages");
- [Fact]
- public void NoResultsWillBeReceivedIfPaused()
- {
- _pausingSubject.OnNext(true);
- //advance otherwise nothing happens
+ _pausingSubject.OnNext(false);
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
- _source.AddOrUpdate(new Person("A", 1));
+ _source.AddOrUpdate(new Person("B", 1));
- _results.Messages.Count.Should().Be(0, "There should be no messages");
+ _results.Messages.Count.Should().Be(2, "There should be 2 messages");
}
- [Fact]
- public void ResultsWillBeReceivedIfNotPaused()
+ public void Dispose()
{
- _source.AddOrUpdate(new Person("A", 1));
-
- //go forward an arbitary amount of time
- _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
- _results.Messages.Count.Should().Be(1, "Should be 1 update");
+ _results.Dispose();
+ _source.Dispose();
+ _pausingSubject.OnCompleted();
}
[Fact]
- public void CanToggleSuspendResume()
+ public void NoResultsWillBeReceivedIfPaused()
{
_pausingSubject.OnNext(true);
- ////advance otherwise nothing happens
+ //advance otherwise nothing happens
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
_source.AddOrUpdate(new Person("A", 1));
- //go forward an arbitary amount of time
_results.Messages.Count.Should().Be(0, "There should be no messages");
-
- _pausingSubject.OnNext(false);
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks);
-
- _source.AddOrUpdate(new Person("B", 1));
-
- _results.Messages.Count.Should().Be(2, "There should be 2 messages");
}
[Fact]
- public void PublishesOnTimerCompletion()
+ public void PublishesOnIntervalEvent()
{
- var intervalTimer = Observable.Timer(TimeSpan.FromMilliseconds(5), _scheduler).Select(_ => Unit.Default);
+ var intervalTimer = Observable.Interval(TimeSpan.FromMilliseconds(5), _scheduler).Select(_ => Unit.Default);
var results = _source.Connect().BatchIf(_pausingSubject, true, intervalTimer, _scheduler).AsAggregator();
//Buffering
@@ -176,25 +156,33 @@ public void PublishesOnTimerCompletion()
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
results.Messages.Count.Should().Be(0, "There should be 0 messages");
- //Timer should event, buffered items delivered
+ //Interval Fires and drains buffer
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(1, "There should be 1 messages");
- //Unbuffered from here
+ //Buffering again
_source.AddOrUpdate(new Person("B", 2));
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
+ results.Messages.Count.Should().Be(1, "There should be 1 messages");
+
+ //Interval Fires and drains buffer
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(2, "There should be 2 messages");
- //Unbuffered from here
+ //Buffering again
_source.AddOrUpdate(new Person("C", 3));
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
+ results.Messages.Count.Should().Be(2, "There should be 2 messages");
+
+ //Interval Fires and drains buffer
+ _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(3, "There should be 3 messages");
}
[Fact]
- public void PublishesOnIntervalEvent()
+ public void PublishesOnTimerCompletion()
{
- var intervalTimer = Observable.Interval(TimeSpan.FromMilliseconds(5), _scheduler).Select(_ => Unit.Default);
+ var intervalTimer = Observable.Timer(TimeSpan.FromMilliseconds(5), _scheduler).Select(_ => Unit.Default);
var results = _source.Connect().BatchIf(_pausingSubject, true, intervalTimer, _scheduler).AsAggregator();
//Buffering
@@ -202,27 +190,42 @@ public void PublishesOnIntervalEvent()
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
results.Messages.Count.Should().Be(0, "There should be 0 messages");
- //Interval Fires and drains buffer
+ //Timer should event, buffered items delivered
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(1, "There should be 1 messages");
- //Buffering again
+ //Unbuffered from here
_source.AddOrUpdate(new Person("B", 2));
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
- results.Messages.Count.Should().Be(1, "There should be 1 messages");
-
- //Interval Fires and drains buffer
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(2, "There should be 2 messages");
- //Buffering again
+ //Unbuffered from here
_source.AddOrUpdate(new Person("C", 3));
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(1).Ticks);
- results.Messages.Count.Should().Be(2, "There should be 2 messages");
-
- //Interval Fires and drains buffer
- _scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5).Ticks);
results.Messages.Count.Should().Be(3, "There should be 3 messages");
}
+
+ [Fact]
+ public void ResultsWillBeReceivedIfNotPaused()
+ {
+ _source.AddOrUpdate(new Person("A", 1));
+
+ //go forward an arbitary amount of time
+ _scheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
+ _results.Messages.Count.Should().Be(1, "Should be 1 update");
+ }
+
+ [Fact]
+ public void WillApplyTimeout()
+ {
+ _pausingSubject.OnNext(true);
+
+ //should timeout
+ _scheduler.AdvanceBy(TimeSpan.FromSeconds(61).Ticks);
+
+ _source.AddOrUpdate(new Person("A", 1));
+
+ _results.Messages.Count.Should().Be(1, "There should be 1 messages");
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/BufferInitialFixture.cs b/src/DynamicData.Tests/Cache/BufferInitialFixture.cs
index 2285e80be..be2774244 100644
--- a/src/DynamicData.Tests/Cache/BufferInitialFixture.cs
+++ b/src/DynamicData.Tests/Cache/BufferInitialFixture.cs
@@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
+
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Microsoft.Reactive.Testing;
+
using Xunit;
namespace DynamicData.Tests.Cache
@@ -17,27 +21,25 @@ public void BufferInitial()
{
var scheduler = new TestScheduler();
- using (var cache = new SourceCache(i => i.Name))
- using (var aggregator = cache.Connect().BufferInitial(TimeSpan.FromSeconds(1), scheduler).AsAggregator())
+ using var cache = new SourceCache(i => i.Name);
+ using var aggregator = cache.Connect().BufferInitial(TimeSpan.FromSeconds(1), scheduler).AsAggregator();
+ foreach (var item in People)
{
- foreach (var item in People)
- {
- cache.AddOrUpdate(item);
- }
+ cache.AddOrUpdate(item);
+ }
- aggregator.Data.Count.Should().Be(0);
- aggregator.Messages.Count.Should().Be(0);
+ aggregator.Data.Count.Should().Be(0);
+ aggregator.Messages.Count.Should().Be(0);
- scheduler.Start();
+ scheduler.Start();
- aggregator.Data.Count.Should().Be(10_000);
- aggregator.Messages.Count.Should().Be(1);
+ aggregator.Data.Count.Should().Be(10_000);
+ aggregator.Messages.Count.Should().Be(1);
- cache.AddOrUpdate(new Person("_New",1));
+ cache.AddOrUpdate(new Person("_New", 1));
- aggregator.Data.Count.Should().Be(10_001);
- aggregator.Messages.Count.Should().Be(2);
- }
+ aggregator.Data.Count.Should().Be(10_001);
+ aggregator.Messages.Count.Should().Be(2);
}
}
}
\ No newline at end of file
diff --git a/src/DynamicData.Tests/Cache/ChangesReducerFixture.cs b/src/DynamicData.Tests/Cache/ChangesReducerFixture.cs
index f27715fc6..7b78ab17e 100644
--- a/src/DynamicData.Tests/Cache/ChangesReducerFixture.cs
+++ b/src/DynamicData.Tests/Cache/ChangesReducerFixture.cs
@@ -1,41 +1,68 @@
using System.Collections.Generic;
using System.Linq;
+
using DynamicData.Cache.Internal;
using DynamicData.Kernel;
using DynamicData.Tests.Domain;
+
using FluentAssertions;
+
using Xunit;
namespace DynamicData.Tests.Cache
{
public class ChangesReducerFixture
{
- private static Person _testEntity = new Person("test", "test", 32);
- private static int _testIndex = 0;
- private static Change[] _changes = new[]
+ private static readonly Person _testEntity = new Person("test", "test", 32);
+
+ private static readonly int _testIndex = 0;
+
+ private static readonly Change[] _changes = new[]
+ {
+ new Change(ChangeReason.Add, _testEntity.Key, _testEntity, _testIndex),
+ new Change(ChangeReason.Remove, _testEntity.Key, _testEntity, _testIndex),
+ new Change(ChangeReason.Moved, _testEntity.Key, _testEntity, _testEntity, _testIndex, _testIndex + 1),
+ new Change(ChangeReason.Update, _testEntity.Key, _testEntity, _testEntity, _testIndex),
+ new Change(ChangeReason.Refresh, _testEntity.Key, _testEntity, _testIndex)
+ };
+
+ // ReSharper disable once MemberCanBePrivate.Global
+ public static IEnumerable