From 5b3eb8015814377611a869a47714050d19f18e47 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 27 Aug 2024 23:28:30 +0900 Subject: [PATCH] c --- sandbox/ConsoleApp/Program.cs | 20 +- .../FreezedDictionary.cs | 59 ---- src/ObservableCollections/FreezedList.cs | 61 ---- .../IObservableCollection.cs | 89 +----- .../ISynchronizedViewFilter.cs | 48 ++- .../Internal/FreezedView.cs | 264 ----------------- .../Internal/SortedView.cs | 259 ---------------- .../Internal/SortedViewViewComparer.cs | 278 ------------------ .../ObservableDictionary.Views.cs | 6 +- .../ObservableFixedSizeRingBuffer.cs | 4 +- .../ObservableHashSet.Views.cs | 5 +- .../ObservableList.Views.cs | 9 +- .../ObservableQueue.Views.cs | 7 +- .../ObservableRingBuffer.Views.cs | 5 +- .../ObservableStack.Views.cs | 6 +- ...ronizedView.cs => SynchronizedViewList.cs} | 33 +-- .../ObservableDictionaryTest.cs | 141 --------- .../ObservableHashSetTest.cs | 62 ---- .../ObservableListTest.cs | 239 ++++++--------- .../ObservableQueueTest.cs | 111 ++++--- .../ObservableRingBufferTest.cs | 2 - .../ObservableStackTest.cs | 67 ----- .../SortedViewTest.cs | 70 ----- .../SortedViewViewComparerTest.cs | 73 ----- .../ToNotifyCollectionChangedTest.cs | 4 +- .../ViewContainer.cs | 130 ++++---- 26 files changed, 269 insertions(+), 1783 deletions(-) delete mode 100644 src/ObservableCollections/FreezedDictionary.cs delete mode 100644 src/ObservableCollections/FreezedList.cs delete mode 100644 src/ObservableCollections/Internal/FreezedView.cs delete mode 100644 src/ObservableCollections/Internal/SortedView.cs delete mode 100644 src/ObservableCollections/Internal/SortedViewViewComparer.cs rename src/ObservableCollections/{Internal/NotifyCollectionChangedSynchronizedView.cs => SynchronizedViewList.cs} (90%) delete mode 100644 tests/ObservableCollections.Tests/SortedViewTest.cs delete mode 100644 tests/ObservableCollections.Tests/SortedViewViewComparerTest.cs diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 758e3d5..63eb431 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -33,13 +33,13 @@ var viewModels = models.CreateView(x => new ViewModel Value = "@" + x }); -viewModels.AttachFilter(new HogeFilter(), true); +viewModels.AttachFilter(new HogeFilter()); models.Add(100); -foreach (var (x, xs) in viewModels) +foreach (var x in viewModels) { - System.Console.WriteLine(xs.Value); + System.Console.WriteLine(x); } class ViewModel @@ -48,23 +48,13 @@ class ViewModel public string Value { get; set; } = default!; } -class HogeFilter : ISynchronizedViewFilter +class HogeFilter : ISynchronizedViewFilter { - public bool IsMatch(int value, ViewModel view) + public bool IsMatch(int value) { return value % 2 == 0; } - public void WhenTrue(int value, ViewModel view) - { - view.Value = $"@{value} (even)"; - } - - public void WhenFalse(int value, ViewModel view) - { - view.Value = $"@{value} (odd)"; - } - public void OnCollectionChanged(in SynchronizedViewChangedEventArgs eventArgs) { switch (eventArgs.Action) diff --git a/src/ObservableCollections/FreezedDictionary.cs b/src/ObservableCollections/FreezedDictionary.cs deleted file mode 100644 index c973850..0000000 --- a/src/ObservableCollections/FreezedDictionary.cs +++ /dev/null @@ -1,59 +0,0 @@ -#nullable disable - -using ObservableCollections.Internal; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -namespace ObservableCollections -{ - public sealed class FreezedDictionary : IReadOnlyDictionary, IFreezedCollection> - where TKey : notnull - { - readonly IReadOnlyDictionary dictionary; - - public FreezedDictionary(IReadOnlyDictionary dictionary) - { - this.dictionary = dictionary; - } - - public TValue this[TKey key] => dictionary[key]; - - public IEnumerable Keys => dictionary.Keys; - - public IEnumerable Values => dictionary.Values; - - public int Count => dictionary.Count; - - public bool ContainsKey(TKey key) - { - return dictionary.ContainsKey(key); - } - - public IEnumerator> GetEnumerator() - { - return dictionary.GetEnumerator(); - } - - public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) - { - return dictionary.TryGetValue(key, out value); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)dictionary).GetEnumerator(); - } - - public ISynchronizedView, TView> CreateView(Func, TView> transform, bool reverse = false) - { - return new FreezedView, TView>(dictionary, transform, reverse); - } - - public ISortableSynchronizedView, TView> CreateSortableView(Func, TView> transform) - { - return new FreezedSortableView, TView>(dictionary, transform); - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/FreezedList.cs b/src/ObservableCollections/FreezedList.cs deleted file mode 100644 index f7666e5..0000000 --- a/src/ObservableCollections/FreezedList.cs +++ /dev/null @@ -1,61 +0,0 @@ -using ObservableCollections.Internal; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace ObservableCollections -{ - public sealed class FreezedList : IReadOnlyList, IFreezedCollection - { - readonly IReadOnlyList list; - - public T this[int index] - { - get - { - return list[index]; - } - } - - public int Count - { - get - { - return list.Count; - } - } - - public bool IsReadOnly => true; - - public FreezedList(IReadOnlyList list) - { - this.list = list; - } - - public ISynchronizedView CreateView(Func transform, bool reverse = false) - { - return new FreezedView(list, transform, reverse); - } - - public ISortableSynchronizedView CreateSortableView(Func transform) - { - return new FreezedSortableView(list, transform); - } - - public bool Contains(T item) - { - return list.Contains(item); - } - - public IEnumerator GetEnumerator() - { - return list.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/IObservableCollection.cs b/src/ObservableCollections/IObservableCollection.cs index 78b0d78..0568de1 100644 --- a/src/ObservableCollections/IObservableCollection.cs +++ b/src/ObservableCollections/IObservableCollection.cs @@ -1,4 +1,3 @@ -using ObservableCollections.Internal; using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -7,6 +6,7 @@ using System.ComponentModel; namespace ObservableCollections { public delegate void NotifyCollectionChangedEventHandler(in NotifyCollectionChangedEventArgs e); + public delegate void NotifyViewChangedEventHandler(in SynchronizedViewChangedEventArgs e); public interface IObservableCollection : IReadOnlyCollection { @@ -25,12 +25,6 @@ namespace ObservableCollections { } - public interface IFreezedCollection - { - ISynchronizedView CreateView(Func transform, bool reverse = false); - ISortableSynchronizedView CreateSortableView(Func transform); - } - public interface ISynchronizedView : IReadOnlyCollection, IDisposable { object SyncRoot { get; } @@ -39,7 +33,7 @@ namespace ObservableCollections IEnumerable<(T Value, TView View)> Unfiltered { get; } int UnfilteredCount { get; } - event Action>? ViewChanged; + event NotifyViewChangedEventHandler? ViewChanged; event Action? CollectionStateChanged; void AttachFilter(ISynchronizedViewFilter filter); @@ -49,17 +43,6 @@ namespace ObservableCollections INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher); } - public interface ISortableSynchronizedView : ISynchronizedView - { - void Sort(IComparer comparer); - void Sort(IComparer viewComparer); - } - - // will be implemented in the future? - //public interface IGroupedSynchoronizedView : ILookup, ISynchronizedView - //{ - //} - public interface ISynchronizedViewList : IReadOnlyList, IDisposable { } @@ -67,72 +50,4 @@ namespace ObservableCollections public interface INotifyCollectionChangedSynchronizedView : IReadOnlyCollection, INotifyCollectionChanged, INotifyPropertyChanged, IDisposable { } - - public static class ObservableCollectionsExtensions - { - public static ISynchronizedView CreateSortedView(this IObservableCollection source, Func identitySelector, Func transform, IComparer comparer) - where TKey : notnull - { - return new SortedView(source, identitySelector, transform, comparer); - } - - public static ISynchronizedView CreateSortedView(this IObservableCollection source, Func identitySelector, Func transform, IComparer viewComparer) - where TKey : notnull - { - return new SortedViewViewComparer(source, identitySelector, transform, viewComparer); - } - - public static ISynchronizedView CreateSortedView(this IObservableCollection source, Func identitySelector, Func transform, Func compareSelector, bool ascending = true) - where TKey : notnull - { - return source.CreateSortedView(identitySelector, transform, new AnonymousComparer(compareSelector, ascending)); - } - - public static ISortableSynchronizedView CreateSortableView(this IFreezedCollection source, Func transform, IComparer initialSort) - { - var view = source.CreateSortableView(transform); - view.Sort(initialSort); - return view; - } - - public static ISortableSynchronizedView CreateSortableView(this IFreezedCollection source, Func transform, IComparer initialViewSort) - { - var view = source.CreateSortableView(transform); - view.Sort(initialViewSort); - return view; - } - - public static ISortableSynchronizedView CreateSortableView(this IFreezedCollection source, Func transform, Func initialCompareSelector, bool ascending = true) - { - var view = source.CreateSortableView(transform); - view.Sort(initialCompareSelector, ascending); - return view; - } - - public static void Sort(this ISortableSynchronizedView source, Func compareSelector, bool ascending = true) - { - source.Sort(new AnonymousComparer(compareSelector, ascending)); - } - - class AnonymousComparer : IComparer - { - readonly Func selector; - readonly int f; - - public AnonymousComparer(Func selector, bool ascending) - { - this.selector = selector; - this.f = ascending ? 1 : -1; - } - - public int Compare(T? x, T? y) - { - if (x == null && y == null) return 0; - if (x == null) return 1 * f; - if (y == null) return -1 * f; - - return Comparer.Default.Compare(selector(x), selector(y)) * f; - } - } - } } \ No newline at end of file diff --git a/src/ObservableCollections/ISynchronizedViewFilter.cs b/src/ObservableCollections/ISynchronizedViewFilter.cs index 85c0b11..84108a0 100644 --- a/src/ObservableCollections/ISynchronizedViewFilter.cs +++ b/src/ObservableCollections/ISynchronizedViewFilter.cs @@ -3,8 +3,8 @@ using System.Collections.Specialized; namespace ObservableCollections { - public readonly struct SynchronizedViewChangedEventArgs( - NotifyViewChangedAction action, + public readonly ref struct SynchronizedViewChangedEventArgs( + NotifyCollectionChangedAction action, T newValue = default!, T oldValue = default!, TView newView = default!, @@ -12,7 +12,7 @@ namespace ObservableCollections int newViewIndex = -1, int oldViewIndex = -1) { - public readonly NotifyViewChangedAction Action = action; + public readonly NotifyCollectionChangedAction Action = action; public readonly T NewValue = newValue; public readonly T OldValue = oldValue; public readonly TView NewView = newView; @@ -21,16 +21,6 @@ namespace ObservableCollections public readonly int OldViewIndex = oldViewIndex; } - public enum NotifyViewChangedAction - { - Add = 0, - Remove = 1, - Replace = 2, - Move = 3, - Reset = 4, - FilterReset = 5, - } - public interface ISynchronizedViewFilter { bool IsMatch(T value); @@ -60,12 +50,12 @@ namespace ObservableCollections return filter == SynchronizedViewFilter.Null; } - internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, Action>? ev, (T value, TView view) value, int index) + internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, (T value, TView view) value, int index) { InvokeOnAdd(collection, ref filteredCount, ev, value.value, value.view, index); } - internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, int index) + internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, T value, TView view, int index) { var isMatch = collection.Filter.IsMatch(value); if (isMatch) @@ -73,17 +63,17 @@ namespace ObservableCollections filteredCount++; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); } } } - internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, Action>? ev, (T value, TView view) value, int oldIndex) + internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, (T value, TView view) value, int oldIndex) { InvokeOnRemove(collection, ref filteredCount, ev, value.value, value.view, oldIndex); } - internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, int oldIndex) + internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, T value, TView view, int oldIndex) { var isMatch = collection.Filter.IsMatch(value); if (isMatch) @@ -91,17 +81,17 @@ namespace ObservableCollections filteredCount--; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); } } } - internal static void InvokeOnMove(this ISynchronizedView collection, ref int filteredCount, Action>? ev, (T value, TView view) value, int index, int oldIndex) + internal static void InvokeOnMove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, (T value, TView view) value, int index, int oldIndex) { InvokeOnMove(collection, ref filteredCount, ev, value.value, value.view, index, oldIndex); } - internal static void InvokeOnMove(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, int index, int oldIndex) + internal static void InvokeOnMove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, T value, TView view, int index, int oldIndex) { if (ev != null) { @@ -109,17 +99,17 @@ namespace ObservableCollections var isMatch = collection.Filter.IsMatch(value); if (isMatch) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Move, newValue: value, newView: view, newViewIndex: index, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Move, newValue: value, newView: view, newViewIndex: index, oldViewIndex: oldIndex)); } } } - internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, Action>? ev, (T value, TView view) value, (T value, TView view) oldValue, int index, int oldIndex = -1) + internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, (T value, TView view) value, (T value, TView view) oldValue, int index, int oldIndex = -1) { InvokeOnReplace(collection, ref filteredCount, ev, value.value, value.view, oldValue.value, oldValue.view, index, oldIndex); } - internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, T oldValue, TView oldView, int index, int oldIndex = -1) + internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, T value, TView view, T oldValue, TView oldView, int index, int oldIndex = -1) { var oldMatched = collection.Filter.IsMatch(oldValue); var newMatched = collection.Filter.IsMatch(value); @@ -129,7 +119,7 @@ namespace ObservableCollections { if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Replace, newValue: value, newView: view, oldValue: oldValue, oldView: oldView, newViewIndex: index, oldViewIndex: oldIndex >= 0 ? oldIndex : index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Replace, newValue: value, newView: view, oldValue: oldValue, oldView: oldView, newViewIndex: index, oldViewIndex: oldIndex >= 0 ? oldIndex : index)); } } else if (oldMatched) @@ -138,7 +128,7 @@ namespace ObservableCollections filteredCount--; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); } } @@ -148,17 +138,17 @@ namespace ObservableCollections filteredCount++; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); } } } - internal static void InvokeOnReset(this ISynchronizedView collection, ref int filteredCount, Action>? ev) + internal static void InvokeOnReset(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev) { filteredCount = 0; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Reset)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } } diff --git a/src/ObservableCollections/Internal/FreezedView.cs b/src/ObservableCollections/Internal/FreezedView.cs deleted file mode 100644 index f256fb7..0000000 --- a/src/ObservableCollections/Internal/FreezedView.cs +++ /dev/null @@ -1,264 +0,0 @@ -#pragma warning disable CS0067 - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; - -namespace ObservableCollections.Internal -{ - internal sealed class FreezedView : ISynchronizedView - { - readonly bool reverse; - readonly List<(T, TView)> list; - - ISynchronizedViewFilter filter; - - public ISynchronizedViewFilter CurrentFilter - { - get { lock (SyncRoot) return filter; } - } - - public event Action? CollectionStateChanged; - public event NotifyCollectionChangedEventHandler? RoutingCollectionChanged; - - public object SyncRoot { get; } = new object(); - - public FreezedView(IEnumerable source, Func selector, bool reverse) - { - this.reverse = reverse; - this.filter = SynchronizedViewFilter.Null; - this.list = source.Select(x => (x, selector(x))).ToList(); - } - - public int Count - { - get - { - lock (SyncRoot) - { - return list.Count; - } - } - } - - public void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForCurrentElements = false) - { - lock (SyncRoot) - { - this.filter = filter; - for (var i = 0; i < list.Count; i++) - { - var (value, view) = list[i]; - if (invokeAddEventForCurrentElements) - { - filter.InvokeOnAdd(value, view, i); - } - else - { - filter.InvokeOnAttach(value, view); - } - } - } - } - - public void ResetFilter(Action? resetAction) - { - lock (SyncRoot) - { - this.filter = SynchronizedViewFilter.Null; - if (resetAction != null) - { - foreach (var (item, view) in list) - { - resetAction(item, view); - } - } - } - } - - public IEnumerator<(T, TView)> GetEnumerator() - { - lock (SyncRoot) - { - if (!reverse) - { - foreach (var item in list) - { - if (filter.IsMatch(item.Item1, item.Item2)) - { - yield return item; - } - } - } - else - { - foreach (var item in list.AsEnumerable().Reverse()) - { - if (filter.IsMatch(item.Item1, item.Item2)) - { - yield return item; - } - } - } - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public void Dispose() - { - - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged() - { - return new NotifyCollectionChangedSynchronizedView(this, null); - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) - { - return new NotifyCollectionChangedSynchronizedView(this, collectionEventDispatcher); - } - } - - internal sealed class FreezedSortableView : ISortableSynchronizedView - { - readonly (T, TView)[] array; - - ISynchronizedViewFilter filter; - - public ISynchronizedViewFilter CurrentFilter - { - get { lock (SyncRoot) return filter; } - } - - public event Action? CollectionStateChanged; - public event NotifyCollectionChangedEventHandler? RoutingCollectionChanged; - - public object SyncRoot { get; } = new object(); - - public FreezedSortableView(IEnumerable source, Func selector) - { - this.filter = SynchronizedViewFilter.Null; - this.array = source.Select(x => (x, selector(x))).ToArray(); - } - - public int Count - { - get - { - lock (SyncRoot) - { - return array.Length; - } - } - } - - public void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForCurrentElements = false) - { - lock (SyncRoot) - { - this.filter = filter; - for (var i = 0; i < array.Length; i++) - { - var (value, view) = array[i]; - if (invokeAddEventForCurrentElements) - { - filter.InvokeOnAdd(value, view, i); - } - else - { - filter.InvokeOnAttach(value, view); - } - } - } - } - - public void ResetFilter(Action? resetAction) - { - lock (SyncRoot) - { - this.filter = SynchronizedViewFilter.Null; - if (resetAction != null) - { - foreach (var (item, view) in array) - { - resetAction(item, view); - } - } - } - } - - public IEnumerator<(T, TView)> GetEnumerator() - { - lock (SyncRoot) - { - foreach (var item in array) - { - if (filter.IsMatch(item.Item1, item.Item2)) - { - yield return item; - } - } - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public void Dispose() - { - } - - public void Sort(IComparer comparer) - { - Array.Sort(array, new TComparer(comparer)); - } - - public void Sort(IComparer viewComparer) - { - Array.Sort(array, new TViewComparer(viewComparer)); - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged() - { - return new NotifyCollectionChangedSynchronizedView(this, null); - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) - { - return new NotifyCollectionChangedSynchronizedView(this, collectionEventDispatcher); - } - - class TComparer : IComparer<(T, TView)> - { - readonly IComparer comparer; - - public TComparer(IComparer comparer) - { - this.comparer = comparer; - } - - public int Compare((T, TView) x, (T, TView) y) - { - return comparer.Compare(x.Item1, y.Item1); - } - } - - class TViewComparer : IComparer<(T, TView)> - { - readonly IComparer comparer; - - public TViewComparer(IComparer comparer) - { - this.comparer = comparer; - } - - public int Compare((T, TView) x, (T, TView) y) - { - return comparer.Compare(x.Item2, y.Item2); - } - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/Internal/SortedView.cs b/src/ObservableCollections/Internal/SortedView.cs deleted file mode 100644 index a0a6559..0000000 --- a/src/ObservableCollections/Internal/SortedView.cs +++ /dev/null @@ -1,259 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace ObservableCollections.Internal -{ - internal class SortedView : ISynchronizedView - where TKey : notnull - { - public ISynchronizedViewFilter CurrentFilter - { - get { lock (SyncRoot) return filter; } - } - - readonly IObservableCollection source; - readonly Func transform; - readonly Func identitySelector; - readonly SortedList<(T Value, TKey Key), (T Value, TView View)> list; - - ISynchronizedViewFilter filter; - - public event NotifyCollectionChangedEventHandler? RoutingCollectionChanged; - public event Action? CollectionStateChanged; - - public object SyncRoot { get; } = new object(); - - public SortedView(IObservableCollection source, Func identitySelector, Func transform, IComparer comparer) - { - this.source = source; - this.identitySelector = identitySelector; - this.transform = transform; - this.filter = SynchronizedViewFilter.Null; - lock (source.SyncRoot) - { - var dict = new Dictionary<(T, TKey), (T, TView)>(source.Count); - foreach (var v in source) - { - dict.Add((v, identitySelector(v)), (v, transform(v))); - } - - this.list = new SortedList<(T Value, TKey Key), (T Value, TView View)>(dict, new Comparer(comparer)); - this.source.CollectionChanged += SourceCollectionChanged; - } - } - - public int Count - { - get - { - lock (SyncRoot) - { - return list.Count; - } - } - } - - public void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForCurrentElements = false) - { - lock (SyncRoot) - { - this.filter = filter; - var i = 0; - foreach (var (_, (value, view)) in list) - { - if (invokeAddEventForCurrentElements) - { - filter.InvokeOnAdd(value, view, i++); - } - else - { - filter.InvokeOnAttach(value, view); - } - } - } - } - - public void ResetFilter(Action? resetAction) - { - lock (SyncRoot) - { - this.filter = SynchronizedViewFilter.Null; - if (resetAction != null) - { - foreach (var (_, (value, view)) in list) - { - resetAction(value, view); - } - } - } - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged() - { - lock (SyncRoot) - { - return new NotifyCollectionChangedSynchronizedView(this, null); - } - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) - { - lock (SyncRoot) - { - return new NotifyCollectionChangedSynchronizedView(this, collectionEventDispatcher); - } - } - - public IEnumerator<(T, TView)> GetEnumerator() - { - lock (SyncRoot) - { - foreach (var item in list) - { - if (filter.IsMatch(item.Value.Value, item.Value.View)) - { - yield return item.Value; - } - } - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public void Dispose() - { - this.source.CollectionChanged -= SourceCollectionChanged; - } - - private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs e) - { - lock (SyncRoot) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - { - // Add, Insert - if (e.IsSingleItem) - { - var value = e.NewItem; - var view = transform(value); - var id = identitySelector(value); - list.Add((value, id), (value, view)); - var index = list.IndexOfKey((value, id)); - filter.InvokeOnAdd(value, view, index); - } - else - { - foreach (var value in e.NewItems) - { - var view = transform(value); - var id = identitySelector(value); - list.Add((value, id), (value, view)); - var index = list.IndexOfKey((value, id)); - filter.InvokeOnAdd(value, view, index); - } - } - } - break; - case NotifyCollectionChangedAction.Remove: - { - if (e.IsSingleItem) - { - var value = e.OldItem; - var id = identitySelector(value); - var key = (value, id); - if (list.TryGetValue(key, out var v)) - { - var index = list.IndexOfKey(key); - list.RemoveAt(index); - filter.InvokeOnRemove(v.Value, v.View, index); - } - } - else - { - foreach (var value in e.OldItems) - { - var id = identitySelector(value); - var key = (value, id); - if (list.TryGetValue(key, out var v)) - { - var index = list.IndexOfKey((value, id)); - list.RemoveAt(index); - filter.InvokeOnRemove(v.Value, v.View, index); - } - } - } - } - break; - case NotifyCollectionChangedAction.Replace: - // ReplaceRange is not supported in all ObservableCollections collections - // Replace is remove old item and insert new item. - { - var oldValue = e.OldItem; - var oldKey = (oldValue, identitySelector(oldValue)); - var oldIndex = -1; - if (list.TryGetValue(oldKey, out var o)) - { - oldIndex = list.IndexOfKey(oldKey); - list.RemoveAt(oldIndex); - } - - var value = e.NewItem; - var view = transform(value); - var id = identitySelector(value); - list.Add((value, id), (value, view)); - var newIndex = list.IndexOfKey((value, id)); - - filter.InvokeOnReplace((value, view), o, newIndex, oldIndex: oldIndex); - } - break; - case NotifyCollectionChangedAction.Move: - { - // Move(index change) does not affect sorted list. - var oldValue = e.OldItem; - var oldKey = (oldValue, identitySelector(oldValue)); - if (list.TryGetValue(oldKey, out var v)) - { - var index = list.IndexOfKey(oldKey); - filter.InvokeOnMove(v, index, index); - } - } - break; - case NotifyCollectionChangedAction.Reset: - list.Clear(); - filter.InvokeOnReset(); - break; - default: - break; - } - - RoutingCollectionChanged?.Invoke(e); - CollectionStateChanged?.Invoke(e.Action); - } - } - - sealed class Comparer : IComparer<(T value, TKey id)> - { - readonly IComparer comparer; - - public Comparer(IComparer comparer) - { - this.comparer = comparer; - } - - public int Compare((T value, TKey id) x, (T value, TKey id) y) - { - var compare = comparer.Compare(x.value, y.value); - if (compare == 0) - { - compare = Comparer.Default.Compare(x.id, y.id); - } - - return compare; - } - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/Internal/SortedViewViewComparer.cs b/src/ObservableCollections/Internal/SortedViewViewComparer.cs deleted file mode 100644 index b247118..0000000 --- a/src/ObservableCollections/Internal/SortedViewViewComparer.cs +++ /dev/null @@ -1,278 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; - -namespace ObservableCollections.Internal -{ - internal class SortedViewViewComparer : ISynchronizedView - where TKey : notnull - { - readonly IObservableCollection source; - readonly Func transform; - readonly Func identitySelector; - readonly Dictionary viewMap; // view-map needs to use in remove. - readonly SortedList<(TView View, TKey Key), (T Value, TView View)> list; - - ISynchronizedViewFilter filter; - - public event NotifyCollectionChangedEventHandler? RoutingCollectionChanged; - public event Action? CollectionStateChanged; - - public object SyncRoot { get; } = new object(); - - public ISynchronizedViewFilter CurrentFilter - { - get { lock (SyncRoot) return filter; } - } - - public SortedViewViewComparer(IObservableCollection source, Func identitySelector, Func transform, IComparer comparer) - { - this.source = source; - this.identitySelector = identitySelector; - this.transform = transform; - this.filter = SynchronizedViewFilter.Null; - lock (source.SyncRoot) - { - var dict = new Dictionary<(TView, TKey), (T, TView)>(source.Count); - this.viewMap = new Dictionary(); - foreach (var value in source) - { - var view = transform(value); - var id = identitySelector(value); - dict.Add((view, id), (value, view)); - viewMap.Add(id, view); - } - this.list = new SortedList<(TView View, TKey Key), (T Value, TView View)>(dict, new Comparer(comparer)); - this.source.CollectionChanged += SourceCollectionChanged; - } - } - - public int Count - { - get - { - lock (SyncRoot) - { - return list.Count; - } - } - } - - public void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForCurrentElements = false) - { - lock (SyncRoot) - { - this.filter = filter; - var i = 0; - foreach (var (_, (value, view)) in list) - { - if (invokeAddEventForCurrentElements) - { - filter.InvokeOnAdd(value, view, i++); - } - else - { - filter.InvokeOnAttach(value, view); - } - } - } - } - - public void ResetFilter(Action? resetAction) - { - lock (SyncRoot) - { - this.filter = SynchronizedViewFilter.Null; - if (resetAction != null) - { - foreach (var (_, (value, view)) in list) - { - resetAction(value, view); - } - } - } - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged() - { - lock (SyncRoot) - { - return new NotifyCollectionChangedSynchronizedView(this, null); - } - } - - public INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher) - { - lock (SyncRoot) - { - return new NotifyCollectionChangedSynchronizedView(this, collectionEventDispatcher); - } - } - - public IEnumerator<(T, TView)> GetEnumerator() - { - - lock (SyncRoot) - { - foreach (var item in list) - { - if (filter.IsMatch(item.Value.Value, item.Value.View)) - { - yield return item.Value; - } - } - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public void Dispose() - { - this.source.CollectionChanged -= SourceCollectionChanged; - } - - private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs e) - { - lock (SyncRoot) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - { - // Add, Insert - if (e.IsSingleItem) - { - var value = e.NewItem; - var view = transform(value); - var id = identitySelector(value); - list.Add((view, id), (value, view)); - viewMap.Add(id, view); - var index = list.IndexOfKey((view, id)); - filter.InvokeOnAdd(value, view, index); - } - else - { - foreach (var value in e.NewItems) - { - var view = transform(value); - var id = identitySelector(value); - list.Add((view, id), (value, view)); - viewMap.Add(id, view); - var index = list.IndexOfKey((view, id)); - filter.InvokeOnAdd(value, view, index); - } - } - break; - } - case NotifyCollectionChangedAction.Remove: - { - if (e.IsSingleItem) - { - var value = e.OldItem; - var id = identitySelector(value); - if (viewMap.Remove(id, out var view)) - { - var key = (view, id); - if (list.TryGetValue(key, out var v)) - { - var index = list.IndexOfKey(key); - list.RemoveAt(index); - filter.InvokeOnRemove(v, index); - } - } - } - else - { - foreach (var value in e.OldItems) - { - var id = identitySelector(value); - if (viewMap.Remove(id, out var view)) - { - var key = (view, id); - if (list.TryGetValue(key, out var v)) - { - var index = list.IndexOfKey((view, id)); - list.RemoveAt(index); - filter.InvokeOnRemove(v, index); - } - } - } - } - break; - } - case NotifyCollectionChangedAction.Replace: - // Replace is remove old item and insert new item. - { - var oldValue = e.OldItem; - var oldId = identitySelector(oldValue); - var oldIndex = -1; - if (viewMap.Remove(oldId, out var oldView)) - { - var oldKey = (oldView, oldId); - if (list.TryGetValue(oldKey, out var v)) - { - oldIndex = list.IndexOfKey(oldKey); - list.RemoveAt(oldIndex); - } - } - - var value = e.NewItem; - var view = transform(value); - var id = identitySelector(value); - list.Add((view, id), (value, view)); - viewMap.Add(id, view); - - var index = list.IndexOfKey((view, id)); - filter.InvokeOnReplace(value, view, oldValue, oldView!, index, oldIndex); - break; - } - case NotifyCollectionChangedAction.Move: - // Move(index change) does not affect soreted dict. - { - var value = e.OldItem; - var id = identitySelector(value); - if (viewMap.TryGetValue(id, out var view)) - { - var index = list.IndexOfKey((view, id)); - filter.InvokeOnMove(value, view, index, index); - } - break; - } - case NotifyCollectionChangedAction.Reset: - list.Clear(); - viewMap.Clear(); - filter.InvokeOnReset(); - break; - default: - break; - } - - RoutingCollectionChanged?.Invoke(e); - CollectionStateChanged?.Invoke(e.Action); - } - } - - sealed class Comparer : IComparer<(TView view, TKey id)> - { - readonly IComparer comparer; - - public Comparer(IComparer comparer) - { - this.comparer = comparer; - } - - public int Compare((TView view, TKey id) x, (TView view, TKey id) y) - { - var compare = comparer.Compare(x.view, y.view); - if (compare == 0) - { - compare = Comparer.Default.Compare(x.id, y.id); - } - - return compare; - } - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/ObservableDictionary.Views.cs b/src/ObservableCollections/ObservableDictionary.Views.cs index 4bf347f..4703d84 100644 --- a/src/ObservableCollections/ObservableDictionary.Views.cs +++ b/src/ObservableCollections/ObservableDictionary.Views.cs @@ -38,7 +38,7 @@ namespace ObservableCollections } public object SyncRoot { get; } - public event Action, TView>>? ViewChanged; + public event NotifyViewChangedEventHandler, TView>? ViewChanged; public event Action? CollectionStateChanged; public ISynchronizedViewFilter> Filter @@ -94,7 +94,7 @@ namespace ObservableCollections } } - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs, TView>(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs, TView>(NotifyCollectionChangedAction.Reset)); } } @@ -104,7 +104,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter>.Null; this.filteredCount = dict.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs, TView>(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs, TView>(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs b/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs index 358397d..658a69c 100644 --- a/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs +++ b/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs @@ -320,9 +320,9 @@ namespace ObservableCollections return GetEnumerator(); } - public ISynchronizedView CreateView(Func transform, bool reverse = false) + public ISynchronizedView CreateView(Func transform) { - return new ObservableRingBuffer.View(this, transform, reverse); + return new ObservableRingBuffer.View(this, transform); } } } diff --git a/src/ObservableCollections/ObservableHashSet.Views.cs b/src/ObservableCollections/ObservableHashSet.Views.cs index ea846f2..95d604c 100644 --- a/src/ObservableCollections/ObservableHashSet.Views.cs +++ b/src/ObservableCollections/ObservableHashSet.Views.cs @@ -29,7 +29,7 @@ namespace ObservableCollections ISynchronizedViewFilter filter; - public event Action>? ViewChanged; + public event NotifyViewChangedEventHandler? ViewChanged; public event Action? CollectionStateChanged; public object SyncRoot { get; } @@ -89,6 +89,7 @@ namespace ObservableCollections filteredCount++; } } + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -98,7 +99,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter.Null; this.filteredCount = dict.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/ObservableCollections/ObservableList.Views.cs b/src/ObservableCollections/ObservableList.Views.cs index 6048a27..f1a8669 100644 --- a/src/ObservableCollections/ObservableList.Views.cs +++ b/src/ObservableCollections/ObservableList.Views.cs @@ -46,7 +46,7 @@ namespace ObservableCollections ISynchronizedViewFilter filter; - public event Action>? ViewChanged; + public event NotifyViewChangedEventHandler? ViewChanged; public event Action? CollectionStateChanged; public object SyncRoot { get; } @@ -107,7 +107,7 @@ namespace ObservableCollections } } - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -117,7 +117,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter.Null; this.filteredCount = list.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -245,11 +245,12 @@ namespace ObservableCollections } else { + list.RemoveRange(e.OldStartingIndex, e.OldItems.Length); // remove from list first + var len = e.OldStartingIndex + e.OldItems.Length; for (var i = e.OldStartingIndex; i < len; i++) { var v = list[i]; - list.RemoveAt(e.OldStartingIndex + i); // should we use RemoveRange? this.InvokeOnRemove(ref filteredCount, ViewChanged, v, e.OldStartingIndex + i); } } diff --git a/src/ObservableCollections/ObservableQueue.Views.cs b/src/ObservableCollections/ObservableQueue.Views.cs index b6d9601..d09e89c 100644 --- a/src/ObservableCollections/ObservableQueue.Views.cs +++ b/src/ObservableCollections/ObservableQueue.Views.cs @@ -19,13 +19,12 @@ namespace ObservableCollections { readonly ObservableQueue source; readonly Func selector; - readonly bool reverse; protected readonly Queue<(T, TView)> queue; int filteredCount; ISynchronizedViewFilter filter; - public event Action>? ViewChanged; + public event NotifyViewChangedEventHandler? ViewChanged; public event Action? CollectionStateChanged; public object SyncRoot { get; } @@ -90,7 +89,7 @@ namespace ObservableCollections filteredCount++; } } - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -100,7 +99,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter.Null; this.filteredCount = queue.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/ObservableCollections/ObservableRingBuffer.Views.cs b/src/ObservableCollections/ObservableRingBuffer.Views.cs index 95a1b78..f4df53b 100644 --- a/src/ObservableCollections/ObservableRingBuffer.Views.cs +++ b/src/ObservableCollections/ObservableRingBuffer.Views.cs @@ -30,7 +30,7 @@ namespace ObservableCollections ISynchronizedViewFilter filter; - public event Action>? ViewChanged; + public event NotifyViewChangedEventHandler? ViewChanged; public event Action? CollectionStateChanged; public object SyncRoot { get; } @@ -91,6 +91,7 @@ namespace ObservableCollections filteredCount++; } } + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -100,7 +101,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter.Null; this.filteredCount = ringBuffer.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/ObservableCollections/ObservableStack.Views.cs b/src/ObservableCollections/ObservableStack.Views.cs index 2bfa68a..ee8ee2c 100644 --- a/src/ObservableCollections/ObservableStack.Views.cs +++ b/src/ObservableCollections/ObservableStack.Views.cs @@ -23,7 +23,7 @@ namespace ObservableCollections ISynchronizedViewFilter filter; - public event Action>? ViewChanged; + public event NotifyViewChangedEventHandler? ViewChanged; public event Action? CollectionStateChanged; public object SyncRoot { get; } @@ -88,7 +88,7 @@ namespace ObservableCollections filteredCount++; } } - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } @@ -98,7 +98,7 @@ namespace ObservableCollections { this.filter = SynchronizedViewFilter.Null; this.filteredCount = stack.Count; - ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs b/src/ObservableCollections/SynchronizedViewList.cs similarity index 90% rename from src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs rename to src/ObservableCollections/SynchronizedViewList.cs index f5e45c5..d722adb 100644 --- a/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs +++ b/src/ObservableCollections/SynchronizedViewList.cs @@ -5,7 +5,7 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Linq; -namespace ObservableCollections.Internal +namespace ObservableCollections { internal class SynchronizedViewList : ISynchronizedViewList { @@ -18,18 +18,18 @@ namespace ObservableCollections.Internal this.parent = parent; lock (parent.SyncRoot) { - this.listView = parent.ToList(); + listView = parent.ToList(); parent.ViewChanged += Parent_ViewChanged; } } - private void Parent_ViewChanged(SynchronizedViewChangedEventArgs e) + private void Parent_ViewChanged(in SynchronizedViewChangedEventArgs e) { lock (gate) { switch (e.Action) { - case NotifyViewChangedAction.Add: // Add or Insert + case NotifyCollectionChangedAction.Add: // Add or Insert if (e.NewViewIndex == -1) { listView.Add(e.NewView); @@ -39,7 +39,7 @@ namespace ObservableCollections.Internal listView.Insert(e.NewViewIndex, e.NewView); } break; - case NotifyViewChangedAction.Remove: // Remove + case NotifyCollectionChangedAction.Remove: // Remove if (e.OldViewIndex == -1) // can't gurantee correct remove if index is not provided { listView.Remove(e.OldView); @@ -49,7 +49,7 @@ namespace ObservableCollections.Internal listView.RemoveAt(e.OldViewIndex); } break; - case NotifyViewChangedAction.Replace: // Indexer + case NotifyCollectionChangedAction.Replace: // Indexer if (e.NewViewIndex == -1) { var index = listView.IndexOf(e.OldView); @@ -61,7 +61,7 @@ namespace ObservableCollections.Internal } break; - case NotifyViewChangedAction.Move: //Remove and Insert + case NotifyCollectionChangedAction.Move: //Remove and Insert if (e.NewViewIndex == -1) { // do nothing @@ -72,12 +72,9 @@ namespace ObservableCollections.Internal listView.Insert(e.NewViewIndex, e.NewView); } break; - case NotifyViewChangedAction.Reset: // Clear + case NotifyCollectionChangedAction.Reset: // Clear or drastic changes listView.Clear(); - break; - case NotifyViewChangedAction.FilterReset: - listView.Clear(); - foreach (var item in parent) + foreach (var item in parent) // refresh { listView.Add(item); } @@ -163,7 +160,7 @@ namespace ObservableCollections.Internal switch (args.Action) { - case NotifyViewChangedAction.Add: + case NotifyCollectionChangedAction.Add: eventDispatcher.Post(new CollectionEventDispatcherEventArgs(NotifyCollectionChangedAction.Add, args.NewView, args.NewViewIndex) { Collection = this, @@ -172,7 +169,7 @@ namespace ObservableCollections.Internal IsInvokePropertyChanged = true }); break; - case NotifyViewChangedAction.Remove: + case NotifyCollectionChangedAction.Remove: eventDispatcher.Post(new CollectionEventDispatcherEventArgs(NotifyCollectionChangedAction.Remove, args.OldView, args.OldViewIndex) { Collection = this, @@ -181,7 +178,7 @@ namespace ObservableCollections.Internal IsInvokePropertyChanged = true }); break; - case NotifyViewChangedAction.Reset: + case NotifyCollectionChangedAction.Reset: eventDispatcher.Post(new CollectionEventDispatcherEventArgs(NotifyCollectionChangedAction.Reset) { Collection = this, @@ -190,7 +187,7 @@ namespace ObservableCollections.Internal IsInvokePropertyChanged = true }); break; - case NotifyViewChangedAction.Replace: + case NotifyCollectionChangedAction.Replace: eventDispatcher.Post(new CollectionEventDispatcherEventArgs(NotifyCollectionChangedAction.Replace, args.NewView, args.OldView, args.NewViewIndex) { Collection = this, @@ -199,7 +196,7 @@ namespace ObservableCollections.Internal IsInvokePropertyChanged = false }); break; - case NotifyViewChangedAction.Move: + case NotifyCollectionChangedAction.Move: eventDispatcher.Post(new CollectionEventDispatcherEventArgs(NotifyCollectionChangedAction.Move, args.NewView, args.NewViewIndex, args.OldViewIndex) { Collection = this, @@ -245,7 +242,7 @@ namespace ObservableCollections.Internal static bool IsCompatibleObject(object? value) { - return (value is T) || (value == null && default(T) == null); + return value is T || value == null && default(T) == null; } public bool IsReadOnly => true; diff --git a/tests/ObservableCollections.Tests/ObservableDictionaryTest.cs b/tests/ObservableCollections.Tests/ObservableDictionaryTest.cs index fa6a633..0bca54c 100644 --- a/tests/ObservableCollections.Tests/ObservableDictionaryTest.cs +++ b/tests/ObservableCollections.Tests/ObservableDictionaryTest.cs @@ -24,7 +24,6 @@ namespace ObservableCollections.Tests void Equal(params int[] expected) { dict.Select(x => x.Value).OrderByDescending(x => x).Should().Equal(expected); - view.Select(x => x.Value.Value).OrderByDescending(x => x).Should().Equal(expected); } Equal(-10, -20, -30, -40, -50); @@ -42,146 +41,6 @@ namespace ObservableCollections.Tests Equal(new int[0]); } - [Fact] - public void ViewSorted() - { - var dict = new ObservableDictionary(); - var view1 = dict.CreateSortedView(x => x.Key, x => new ViewContainer(x.Value), x => x.Value, true); - var view2 = dict.CreateSortedView(x => x.Key, x => new ViewContainer(x.Value), x => x.Value, false); - - dict.Add(10, 10); // 0 - dict.Add(50, 50); // 1 - dict.Add(30, 30); // 2 - dict.Add(20, 20); // 3 - dict.Add(40, 40); // 4 - - void Equal(params int[] expected) - { - dict.Select(x => x.Value).OrderBy(x => x).Should().Equal(expected); - view1.Select(x => x.Value.Value).Should().Equal(expected); - view2.Select(x => x.Value.Value).Should().Equal(expected.OrderByDescending(x => x)); - } - - Equal(10, 20, 30, 40, 50); - - dict[99] = 100; - Equal(10, 20, 30, 40, 50, 100); - - dict[10] = -5; - Equal(-5, 20, 30, 40, 50, 100); - - dict.Remove(20); - Equal(-5, 30, 40, 50, 100); - - dict.Clear(); - Equal(new int[0]); - } - - [Fact] - public void Freezed() - { - var dict = new FreezedDictionary(new Dictionary - { - [10] = 10, - [50] = 50, - [30] = 30, - [20] = 20, - [40] = 40, - [60] = 60 - }); - - var view = dict.CreateSortableView(x => new ViewContainer(x.Value)); - - view.Sort(x => x.Key, true); - view.Select(x => x.Value.Value).Should().Equal(10, 20, 30, 40, 50, 60); - view.Select(x => x.View).Should().Equal(10, 20, 30, 40, 50, 60); - - view.Sort(x => x.Key, false); - view.Select(x => x.Value.Value).Should().Equal(60, 50, 40, 30, 20, 10); - view.Select(x => x.View).Should().Equal(60, 50, 40, 30, 20, 10); - } - - [Fact] - public void FilterTest() - { - var dict = new ObservableDictionary(); - var view1 = dict.CreateView(x => new ViewContainer(x.Value)); - var view2 = dict.CreateSortedView(x => x.Key, x => new ViewContainer(x.Value), x => x.Value, true); - var view3 = dict.CreateSortedView(x => new ViewContainer(x.Value), x => x.Value, viewComparer: Comparer>.Default); - var filter1 = new TestFilter2((x, v) => x.Value % 2 == 0); - var filter2 = new TestFilter2((x, v) => x.Value % 2 == 0); - var filter3 = new TestFilter2((x, v) => x.Value % 2 == 0); - - dict.Add(10, -12); // 0 - dict.Add(50, -53); // 1 - dict.Add(30, -34); // 2 - dict.Add(20, -25); // 3 - dict.Add(40, -40); // 4 - - view1.AttachFilter(filter1); - view2.AttachFilter(filter2); - view3.AttachFilter(filter3); - - filter1.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-12, -34, -40); - filter2.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-40, -34, -12); - filter3.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-40, -34, -12); - - dict.Add(99, -100); - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - dict[10] = -1090; - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - dict.Remove(20); - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - dict.Clear(); - filter1.CalledOnCollectionChanged.Select(x => x.Action) - .Should().Equal(NotifyCollectionChangedAction.Reset); - filter2.CalledOnCollectionChanged.Select(x => x.Action) - .Should().Equal(NotifyCollectionChangedAction.Reset); - filter3.CalledOnCollectionChanged.Select(x => x.Action) - .Should().Equal(NotifyCollectionChangedAction.Reset); - } - [Fact] - public void FilterAndInvokeAddEvent() - { - var dict = new ObservableDictionary(); - var view1 = dict.CreateView(x => new ViewContainer(x.Value)); - var filter1 = new TestFilter2((x, v) => x.Value % 2 == 0); - - dict.Add(10, -12); // 0 - dict.Add(50, -53); // 1 - dict.Add(30, -34); // 2 - dict.Add(20, -25); // 3 - dict.Add(40, -40); // 4 - - view1.AttachFilter(filter1, true); - - filter1.CalledOnCollectionChanged.Count.Should().Be(5); - filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[0].NewValue.Key.Should().Be(10); - filter1.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[1].NewValue.Key.Should().Be(50); - filter1.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[2].NewValue.Key.Should().Be(30); - filter1.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[3].NewValue.Key.Should().Be(20); - filter1.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[4].NewValue.Key.Should().Be(40); - - filter1.CalledWhenTrue.Count.Should().Be(3); - filter1.CalledWhenFalse.Count.Should().Be(2); - } } } diff --git a/tests/ObservableCollections.Tests/ObservableHashSetTest.cs b/tests/ObservableCollections.Tests/ObservableHashSetTest.cs index 3ef24d6..65b6ff4 100644 --- a/tests/ObservableCollections.Tests/ObservableHashSetTest.cs +++ b/tests/ObservableCollections.Tests/ObservableHashSetTest.cs @@ -27,7 +27,6 @@ namespace ObservableCollections.Tests { set.Should().BeEquivalentTo(expected); view.Select(x => x.Value).Should().BeEquivalentTo(expected); - view.Select(x => x.View.Value).Should().BeEquivalentTo(expected); } Equal(10, 50, 30, 20, 40); @@ -46,68 +45,7 @@ namespace ObservableCollections.Tests Equal(); } - [Fact] - public void Filter() - { - var set = new ObservableHashSet(); - var view = set.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); - - set.Add(10); - set.Add(50); - set.Add(30); - set.Add(20); - set.Add(40); - - view.AttachFilter(filter); - filter.CalledWhenTrue.Select(x => x.Item1).Should().Equal(30); - filter.CalledWhenFalse.Select(x => x.Item1).Should().Equal(10, 50, 20, 40); - - view.Select(x => x.Value).Should().Equal(30); - - filter.Clear(); - - set.Add(33); - set.AddRange(new[] { 98 }); - - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue)).Should().Equal((NotifyCollectionChangedAction.Add, 33), (NotifyCollectionChangedAction.Add, 98)); - filter.Clear(); - - set.Remove(10); - set.RemoveRange(new[] { 50, 30 }); - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue)).Should().Equal((NotifyCollectionChangedAction.Remove, 10), (NotifyCollectionChangedAction.Remove, 50), (NotifyCollectionChangedAction.Remove, 30)); - } - [Fact] - public void FilterAndInvokeAddEvent() - { - var set = new ObservableHashSet(); - var view = set.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); - - set.Add(10); - set.Add(50); - set.Add(30); - set.Add(20); - set.Add(40); - - view.AttachFilter(filter, true); - filter.CalledOnCollectionChanged.Count.Should().Be(5); - filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[0].NewValue.Should().Be(10); - filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[1].NewValue.Should().Be(50); - filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30); - filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[3].NewValue.Should().Be(20); - filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[4].NewValue.Should().Be(40); - - filter.CalledWhenTrue.Count.Should().Be(1); - filter.CalledWhenFalse.Count.Should().Be(4); - } - [Fact] public void IndexOutOfRange() { diff --git a/tests/ObservableCollections.Tests/ObservableListTest.cs b/tests/ObservableCollections.Tests/ObservableListTest.cs index c2888dd..77e5b1a 100644 --- a/tests/ObservableCollections.Tests/ObservableListTest.cs +++ b/tests/ObservableCollections.Tests/ObservableListTest.cs @@ -27,14 +27,14 @@ namespace ObservableCollections.Tests reference.Should().Equal(expected); list.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); + view.Filtered.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } void Equal2(params int[] expected) { list.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); + view.Filtered.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } Equal(10, 50, 30, 20, 40); @@ -69,178 +69,107 @@ namespace ObservableCollections.Tests Equal2(100, 400, 200, 300); } - [Fact] - public void ViewSorted() - { - var list = new ObservableList(); - var view1 = list.CreateSortedView(x => x, x => new ViewContainer(x), comparer: Comparer.Default); - var view2 = list.CreateSortedView(x => x, x => new ViewContainer(x), viewComparer: Comparer>.Default); - var view3 = list.CreateSortedView(x => x, x => new ViewContainer(x), x => x, ascending: true); - var view4 = list.CreateSortedView(x => x, x => new ViewContainer(x), x => x, ascending: false); + //[Fact] + //public void FilterTest() + //{ + // var list = new ObservableList(); + // var view1 = list.CreateView(x => new ViewContainer(x)); + // list.AddRange(new[] { 10, 21, 30, 44, 45, 66, 90 }); - list.Add(10); // 0 - list.Add(50); // 1 - list.Add(30); // 2 - list.Add(20); // 3 - list.Add(40); // 4 + // var filter1 = new TestFilter((x, v) => x % 2 == 0); + // var filter2 = new TestFilter((x, v) => x % 2 == 0); + // var filter3 = new TestFilter((x, v) => x % 2 == 0); + // view1.AttachFilter(filter1); + // view2.AttachFilter(filter2); + // view3.AttachFilter(filter3); - void Equal(params int[] expected) - { - list.Should().Equal(expected); + // filter1.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); + // filter2.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); + // filter3.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); - var sorted = expected.OrderBy(x => x).ToArray(); - view1.Select(x => x.Value).Should().Equal(sorted); - view2.Select(x => x.View).Should().Equal(sorted.Select(x => new ViewContainer(x))); - view3.Select(x => x.Value).Should().Equal(sorted); - view4.Select(x => x.Value).Should().Equal(expected.OrderByDescending(x => x).ToArray()); - } + // filter1.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); + // filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); + // filter3.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); - Equal(10, 50, 30, 20, 40); + // view1.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); + // view2.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); + // view3.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); - list.Move(3, 1); - Equal(10, 20, 50, 30, 40); + // filter1.Clear(); + // filter2.Clear(); + // filter3.Clear(); - list.Insert(2, 99); - Equal(10, 20, 99, 50, 30, 40); + // list.Add(100); + // list.AddRange(new[] { 101 }); + // filter1.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); + // filter2.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); + // filter3.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); + // filter1.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); + // filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); + // filter3.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); - list.RemoveAt(2); - Equal(10, 20, 50, 30, 40); + // filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); + // filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); + // filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); - list[3] = 88; - Equal(10, 20, 50, 88, 40); + // foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - list.Clear(); - Equal(new int[0]); + // list.Insert(0, 1000); + // list.InsertRange(0, new[] { 999 }); - list.AddRange(new[] { 100, 200, 300 }); - Equal(100, 200, 300); + // filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 0), (NotifyCollectionChangedAction.Add, 999, 0)); + // filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index + // filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index + // foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - list.InsertRange(1, new[] { 400, 500, 600 }); - Equal(100, 400, 500, 600, 200, 300); + // list.RemoveAt(0); + // list.RemoveRange(0, 1); - list.RemoveRange(2, 2); - Equal(100, 400, 200, 300); - } + // filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 0), (NotifyCollectionChangedAction.Remove, 1000, 0)); + // filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9)); + // filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9)); + // foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - [Fact] - public void Freezed() - { - var list = new FreezedList(new[] { 10, 20, 50, 30, 40, 60 }); + // list[0] = 9999; - var view = list.CreateSortableView(x => new ViewContainer(x)); + // filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 0, 0)); + // filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0)); + // filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0)); + // foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - view.Sort(x => x, true); - view.Select(x => x.Value).Should().Equal(10, 20, 30, 40, 50, 60); - view.Select(x => x.View).Should().Equal(10, 20, 30, 40, 50, 60); + // list.Move(3, 0); + // filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 0, 3)); + // filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2)); + // filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2)); + // foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - view.Sort(x => x, false); - view.Select(x => x.Value).Should().Equal(60, 50, 40, 30, 20, 10); - view.Select(x => x.View).Should().Equal(60, 50, 40, 30, 20, 10); - } + // list.Clear(); + // filter1.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); + // filter2.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); + // filter3.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); + //} - [Fact] - public void FilterTest() - { - var list = new ObservableList(); - var view1 = list.CreateView(x => new ViewContainer(x)); - var view2 = list.CreateSortedView(x => x, x => new ViewContainer(x), comparer: Comparer.Default); - var view3 = list.CreateSortedView(x => x, x => new ViewContainer(x), viewComparer: Comparer>.Default); - list.AddRange(new[] { 10, 21, 30, 44, 45, 66, 90 }); + //[Fact] + //public void FilterAndInvokeAddEvent() + //{ + // var list = new ObservableList(); + // var view1 = list.CreateView(x => new ViewContainer(x)); + // list.AddRange(new[] { 10, 21, 30, 44 }); - var filter1 = new TestFilter((x, v) => x % 2 == 0); - var filter2 = new TestFilter((x, v) => x % 2 == 0); - var filter3 = new TestFilter((x, v) => x % 2 == 0); - view1.AttachFilter(filter1); - view2.AttachFilter(filter2); - view3.AttachFilter(filter3); - - filter1.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); - filter2.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); - filter3.CalledWhenTrue.Select(x => x.Item1).Should().Equal(10, 30, 44, 66, 90); - - filter1.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); - filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); - filter3.CalledWhenFalse.Select(x => x.Item1).Should().Equal(21, 45); - - view1.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); - view2.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); - view3.Select(x => x.Value).Should().Equal(10, 30, 44, 66, 90); - - filter1.Clear(); - filter2.Clear(); - filter3.Clear(); - - list.Add(100); - list.AddRange(new[] { 101 }); - filter1.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); - filter2.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); - filter3.CalledWhenTrue.Select(x => x.Item1).Should().Equal(100); - filter1.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); - filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); - filter3.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); - - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8)); - - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - list.Insert(0, 1000); - list.InsertRange(0, new[] { 999 }); - - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 0), (NotifyCollectionChangedAction.Add, 999, 0)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - list.RemoveAt(0); - list.RemoveRange(0, 1); - - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 0), (NotifyCollectionChangedAction.Remove, 1000, 0)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - list[0] = 9999; - - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 0, 0)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - list.Move(3, 0); - filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 0, 3)); - filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2)); - filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2)); - foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); - - list.Clear(); - filter1.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); - filter2.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); - filter3.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset); - } - - [Fact] - public void FilterAndInvokeAddEvent() - { - var list = new ObservableList(); - var view1 = list.CreateView(x => new ViewContainer(x)); - list.AddRange(new[] { 10, 21, 30, 44 }); - - var filter1 = new TestFilter((x, v) => x % 2 == 0); - view1.AttachFilter(filter1, true); + // var filter1 = new TestFilter((x, v) => x % 2 == 0); + // view1.AttachFilter(filter1); - filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[0].NewValue.Should().Be(10); - filter1.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[1].NewValue.Should().Be(21); - filter1.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[2].NewValue.Should().Be(30); - filter1.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter1.CalledOnCollectionChanged[3].NewValue.Should().Be(44); + // filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter1.CalledOnCollectionChanged[0].NewValue.Should().Be(10); + // filter1.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter1.CalledOnCollectionChanged[1].NewValue.Should().Be(21); + // filter1.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter1.CalledOnCollectionChanged[2].NewValue.Should().Be(30); + // filter1.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter1.CalledOnCollectionChanged[3].NewValue.Should().Be(44); - filter1.CalledWhenTrue.Count.Should().Be(3); - filter1.CalledWhenFalse.Count.Should().Be(1); - } + // filter1.CalledWhenTrue.Count.Should().Be(3); + // filter1.CalledWhenFalse.Count.Should().Be(1); + //} } } \ No newline at end of file diff --git a/tests/ObservableCollections.Tests/ObservableQueueTest.cs b/tests/ObservableCollections.Tests/ObservableQueueTest.cs index 69a6601..6ed0ff3 100644 --- a/tests/ObservableCollections.Tests/ObservableQueueTest.cs +++ b/tests/ObservableCollections.Tests/ObservableQueueTest.cs @@ -27,7 +27,6 @@ namespace ObservableCollections.Tests { queue.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } Equal(10, 50, 30, 20, 40); @@ -50,72 +49,72 @@ namespace ObservableCollections.Tests Equal(); } - [Fact] - public void Filter() - { - var queue = new ObservableQueue(); - var view = queue.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); + //[Fact] + //public void Filter() + //{ + // var queue = new ObservableQueue(); + // var view = queue.CreateView(x => new ViewContainer(x)); + // var filter = new TestFilter((x, v) => x % 3 == 0); - queue.Enqueue(10); - queue.Enqueue(50); - queue.Enqueue(30); - queue.Enqueue(20); - queue.Enqueue(40); + // queue.Enqueue(10); + // queue.Enqueue(50); + // queue.Enqueue(30); + // queue.Enqueue(20); + // queue.Enqueue(40); - view.AttachFilter(filter); - filter.CalledWhenTrue.Select(x => x.Item1).Should().Equal(30); - filter.CalledWhenFalse.Select(x => x.Item1).Should().Equal(10, 50, 20, 40); + // view.AttachFilter(filter); + // filter.CalledWhenTrue.Select(x => x.Item1).Should().Equal(30); + // filter.CalledWhenFalse.Select(x => x.Item1).Should().Equal(10, 50, 20, 40); - view.Select(x => x.Value).Should().Equal(30); + // view.Select(x => x.Value).Should().Equal(30); - filter.Clear(); + // filter.Clear(); - queue.Enqueue(33); - queue.EnqueueRange(new[] { 98 }); + // queue.Enqueue(33); + // queue.EnqueueRange(new[] { 98 }); - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 33, 5), (NotifyCollectionChangedAction.Add, 98, 6)); - filter.Clear(); + // filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 33, 5), (NotifyCollectionChangedAction.Add, 98, 6)); + // filter.Clear(); - queue.Dequeue(); - queue.DequeueRange(2); - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 10, 0), (NotifyCollectionChangedAction.Remove, 50, 0), (NotifyCollectionChangedAction.Remove, 30, 0)); - } + // queue.Dequeue(); + // queue.DequeueRange(2); + // filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 10, 0), (NotifyCollectionChangedAction.Remove, 50, 0), (NotifyCollectionChangedAction.Remove, 30, 0)); + //} - [Fact] - public void FilterAndInvokeAddEvent() - { - var queue = new ObservableQueue(); - var view = queue.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); + //[Fact] + //public void FilterAndInvokeAddEvent() + //{ + // var queue = new ObservableQueue(); + // var view = queue.CreateView(x => new ViewContainer(x)); + // var filter = new TestFilter((x, v) => x % 3 == 0); - queue.Enqueue(10); - queue.Enqueue(50); - queue.Enqueue(30); - queue.Enqueue(20); - queue.Enqueue(40); + // queue.Enqueue(10); + // queue.Enqueue(50); + // queue.Enqueue(30); + // queue.Enqueue(20); + // queue.Enqueue(40); - view.AttachFilter(filter, true); + // view.AttachFilter(filter, true); - filter.CalledOnCollectionChanged.Count.Should().Be(5); - filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[0].NewValue.Should().Be(10); - filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(0); - filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[1].NewValue.Should().Be(50); - filter.CalledOnCollectionChanged[1].NewViewIndex.Should().Be(1); - filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30); - filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(2); - filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[3].NewValue.Should().Be(20); - filter.CalledOnCollectionChanged[3].NewViewIndex.Should().Be(3); - filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[4].NewValue.Should().Be(40); - filter.CalledOnCollectionChanged[4].NewViewIndex.Should().Be(4); + // filter.CalledOnCollectionChanged.Count.Should().Be(5); + // filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter.CalledOnCollectionChanged[0].NewValue.Should().Be(10); + // filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(0); + // filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter.CalledOnCollectionChanged[1].NewValue.Should().Be(50); + // filter.CalledOnCollectionChanged[1].NewViewIndex.Should().Be(1); + // filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30); + // filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(2); + // filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter.CalledOnCollectionChanged[3].NewValue.Should().Be(20); + // filter.CalledOnCollectionChanged[3].NewViewIndex.Should().Be(3); + // filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add); + // filter.CalledOnCollectionChanged[4].NewValue.Should().Be(40); + // filter.CalledOnCollectionChanged[4].NewViewIndex.Should().Be(4); - filter.CalledWhenTrue.Count.Should().Be(1); - filter.CalledWhenFalse.Count.Should().Be(4); - } + // filter.CalledWhenTrue.Count.Should().Be(1); + // filter.CalledWhenFalse.Count.Should().Be(4); + //} } } diff --git a/tests/ObservableCollections.Tests/ObservableRingBufferTest.cs b/tests/ObservableCollections.Tests/ObservableRingBufferTest.cs index d2fa603..f3dad10 100644 --- a/tests/ObservableCollections.Tests/ObservableRingBufferTest.cs +++ b/tests/ObservableCollections.Tests/ObservableRingBufferTest.cs @@ -24,7 +24,6 @@ namespace ObservableCollections.Tests { buf.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } Equal(10, 50, 30, 20, 40); @@ -65,7 +64,6 @@ namespace ObservableCollections.Tests { buf.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } buf.AddLast(10); diff --git a/tests/ObservableCollections.Tests/ObservableStackTest.cs b/tests/ObservableCollections.Tests/ObservableStackTest.cs index 85e93dd..710f2ff 100644 --- a/tests/ObservableCollections.Tests/ObservableStackTest.cs +++ b/tests/ObservableCollections.Tests/ObservableStackTest.cs @@ -27,7 +27,6 @@ namespace ObservableCollections.Tests { stack.Should().Equal(expected); view.Select(x => x.Value).Should().Equal(expected); - view.Select(x => x.View).Should().Equal(expected.Select(x => new ViewContainer(x))); } Equal(40, 20, 30, 50, 10); @@ -50,72 +49,6 @@ namespace ObservableCollections.Tests Equal(); } - [Fact] - public void Filter() - { - var stack = new ObservableStack(); - var view = stack.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); - - stack.Push(10); - stack.Push(50); - stack.Push(30); - stack.Push(20); - stack.Push(40); - - view.AttachFilter(filter); - filter.CalledWhenTrue.Select(x => x.Item1).Should().Equal(30); - filter.CalledWhenFalse.Select(x => x.Item1).Should().Equal(40, 20, 50, 10); - - view.Select(x => x.Value).Should().Equal(30); - - filter.Clear(); - - stack.Push(33); - stack.PushRange(new[] { 98 }); - - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 33, 0), (NotifyCollectionChangedAction.Add, 98, 0)); - filter.Clear(); - - stack.Pop(); - stack.PopRange(2); - filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 98, 0), (NotifyCollectionChangedAction.Remove, 33, 0), (NotifyCollectionChangedAction.Remove, 40, 0)); - } - - [Fact] - public void FilterAndInvokeAddEvent() - { - var stack = new ObservableStack(); - var view = stack.CreateView(x => new ViewContainer(x)); - var filter = new TestFilter((x, v) => x % 3 == 0); - - stack.Push(10); - stack.Push(50); - stack.Push(30); - stack.Push(20); - stack.Push(40); - - view.AttachFilter(filter, true); - filter.CalledOnCollectionChanged.Count.Should().Be(5); - filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[4].NewValue.Should().Be(10); - filter.CalledOnCollectionChanged[4].NewViewIndex.Should().Be(0); - filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[3].NewValue.Should().Be(50); - filter.CalledOnCollectionChanged[3].NewViewIndex.Should().Be(0); - filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30); - filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(0); - filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[1].NewValue.Should().Be(20); - filter.CalledOnCollectionChanged[1].NewViewIndex.Should().Be(0); - filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[0].NewValue.Should().Be(40); - filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(0); - - filter.CalledWhenTrue.Count.Should().Be(1); - filter.CalledWhenFalse.Count.Should().Be(4); - } } } diff --git a/tests/ObservableCollections.Tests/SortedViewTest.cs b/tests/ObservableCollections.Tests/SortedViewTest.cs deleted file mode 100644 index fe15c73..0000000 --- a/tests/ObservableCollections.Tests/SortedViewTest.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace ObservableCollections.Tests; - -public class SortedViewTest -{ - [Fact] - public void Sort() - { - var list = new ObservableList(); - var sortedView = list.CreateSortedView( - x => x, - x => new ViewContainer(x), - Comparer.Default); - - list.Add(10); - list.Add(50); - list.Add(30); - list.Add(20); - list.Add(40); - - using var e = sortedView.GetEnumerator(); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(10); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(20); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(30); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(40); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(50); - e.MoveNext().Should().BeFalse(); - } - - [Fact] - public void ObserveIndex() - { - var list = new ObservableList(); - var sortedView = list.CreateSortedView( - x => x, - x => new ViewContainer(x), - Comparer.Default); - - var filter = new TestFilter((value, view) => value % 2 == 0); - list.Add(50); - list.Add(10); - - sortedView.AttachFilter(filter); - - list.Add(20); - filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[0].NewValue.Should().Be(20); - filter.CalledOnCollectionChanged[0].NewView.Should().Be(new ViewContainer(20)); - filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(1); - - list.Remove(20); - filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Remove); - filter.CalledOnCollectionChanged[1].OldValue.Should().Be(20); - filter.CalledOnCollectionChanged[1].OldView.Should().Be(new ViewContainer(20)); - filter.CalledOnCollectionChanged[1].OldViewIndex.Should().Be(1); - - list[1] = 999; // from 10(at 0 in original) to 999 - filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Replace); - filter.CalledOnCollectionChanged[2].NewValue.Should().Be(999); - filter.CalledOnCollectionChanged[2].OldValue.Should().Be(10); - filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(1); - } -} \ No newline at end of file diff --git a/tests/ObservableCollections.Tests/SortedViewViewComparerTest.cs b/tests/ObservableCollections.Tests/SortedViewViewComparerTest.cs deleted file mode 100644 index 071f382..0000000 --- a/tests/ObservableCollections.Tests/SortedViewViewComparerTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace ObservableCollections.Tests; - -public class SortedViewViewComparerTest -{ - [Fact] - public void Sort() - { - var list = new ObservableList(); - var sortedView = list.CreateSortedView( - x => x, - x => new ViewContainer(x), - Comparer>.Default); - - list.Add(10); - list.Add(50); - list.Add(30); - list.Add(20); - list.Add(40); - - using var e = sortedView.GetEnumerator(); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(10); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(20); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(30); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(40); - e.MoveNext().Should().BeTrue(); - e.Current.Value.Should().Be(50); - e.MoveNext().Should().BeFalse(); - } - - [Fact] - public void ObserveIndex() - { - var list = new ObservableList(); - var sortedView = list.CreateSortedView( - x => x, - x => new ViewContainer(x), - Comparer>.Default); - - var filter = new TestFilter((value, view) => value % 2 == 0); - list.Add(50); - list.Add(10); - - sortedView.AttachFilter(filter); - - list.Add(20); - filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); - filter.CalledOnCollectionChanged[0].NewValue.Should().Be(20); - filter.CalledOnCollectionChanged[0].NewView.Should().Be(new ViewContainer(20)); - filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(1); - - list.Remove(20); - filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Remove); - filter.CalledOnCollectionChanged[1].OldValue.Should().Be(20); - filter.CalledOnCollectionChanged[1].OldView.Should().Be(new ViewContainer(20)); - filter.CalledOnCollectionChanged[1].OldViewIndex.Should().Be(1); - - list[1] = 999; // from 10(at 0 in original) to 999 - filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Replace); - filter.CalledOnCollectionChanged[2].NewValue.Should().Be(999); - filter.CalledOnCollectionChanged[2].OldValue.Should().Be(10); - filter.CalledOnCollectionChanged[2].NewView.Should().Be(new ViewContainer(999)); - filter.CalledOnCollectionChanged[2].OldView.Should().Be(new ViewContainer(10)); - filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(1); - filter.CalledOnCollectionChanged[2].OldViewIndex.Should().Be(0); - } -} \ No newline at end of file diff --git a/tests/ObservableCollections.Tests/ToNotifyCollectionChangedTest.cs b/tests/ObservableCollections.Tests/ToNotifyCollectionChangedTest.cs index 106b6ec..e8f4fa0 100644 --- a/tests/ObservableCollections.Tests/ToNotifyCollectionChangedTest.cs +++ b/tests/ObservableCollections.Tests/ToNotifyCollectionChangedTest.cs @@ -1,3 +1,5 @@ +using ObservableCollections; + namespace ObservableCollections.Tests; public class ToNotifyCollectionChangedTest @@ -43,7 +45,7 @@ public class ToNotifyCollectionChangedTest var view = list.CreateView(x => $"${x}"); var notify = view.ToNotifyCollectionChanged(); - view.AttachFilter((value, view) => value % 2 == 0); + view.AttachFilter((value) => value % 2 == 0); list.Add(4); diff --git a/tests/ObservableCollections.Tests/ViewContainer.cs b/tests/ObservableCollections.Tests/ViewContainer.cs index b9dcb34..4a02766 100644 --- a/tests/ObservableCollections.Tests/ViewContainer.cs +++ b/tests/ObservableCollections.Tests/ViewContainer.cs @@ -31,83 +31,81 @@ namespace ObservableCollections.Tests } } - public class TestFilter : ISynchronizedViewFilter> - { - readonly Func, bool> filter; - public List<(T, ViewContainer)> CalledWhenTrue = new(); - public List<(T, ViewContainer)> CalledWhenFalse = new(); - public List>> CalledOnCollectionChanged = new(); + //public class TestFilter : ISynchronizedViewFilter + //{ + // readonly Func filter; + // public List>> CalledOnCollectionChanged = new(); - public TestFilter(Func, bool> filter) - { - this.filter = filter; - } + // public TestFilter(Func filter) + // { + // this.filter = filter; + // } - public void Clear() - { - CalledWhenTrue.Clear(); - CalledWhenFalse.Clear(); - CalledOnCollectionChanged.Clear(); - } + // public void Clear() + // { + // CalledWhenTrue.Clear(); + // CalledWhenFalse.Clear(); + // CalledOnCollectionChanged.Clear(); + // } - public bool IsMatch(T value, ViewContainer view) - { - return this.filter.Invoke(value, view); - } + // public bool IsMatch(T value) + // { + // return this.filter.Invoke(value); + // } - public void OnCollectionChanged(in SynchronizedViewChangedEventArgs> args) - { - CalledOnCollectionChanged.Add(args); - } + // public void OnCollectionChanged(in SynchronizedViewChangedEventArgs> args) + // { + // CalledOnCollectionChanged.Add(args); + // } - public void WhenTrue(T value, ViewContainer view) - { - CalledWhenTrue.Add((value, view)); - } + // public void WhenTrue(T value, ViewContainer view) + // { + // CalledWhenTrue.Add((value, view)); + // } - public void WhenFalse(T value, ViewContainer view) - { - CalledWhenFalse.Add((value, view)); - } - } + // public void WhenFalse(T value, ViewContainer view) + // { + // CalledWhenFalse.Add((value, view)); + // } + //} - public class TestFilter2 : ISynchronizedViewFilter, ViewContainer> - { - readonly Func, ViewContainer, bool> filter; - public List<(KeyValuePair, ViewContainer)> CalledWhenTrue = new(); - public List<(KeyValuePair, ViewContainer)> CalledWhenFalse = new(); - public List, ViewContainer>> CalledOnCollectionChanged = new(); + //public class TestFilter2 : ISynchronizedViewFilter, ViewContainer> + //{ + // readonly Func, ViewContainer, bool> filter; + // public List<(KeyValuePair, ViewContainer)> CalledWhenTrue = new(); + // public List<(KeyValuePair, ViewContainer)> CalledWhenFalse = new(); + // public List, ViewContainer>> CalledOnCollectionChanged = new(); - public TestFilter2(Func, ViewContainer, bool> filter) - { - this.filter = filter; - } + // public TestFilter2(Func, ViewContainer, bool> filter) + // { + // this.filter = filter; + // } - public void Clear() - { - CalledWhenTrue.Clear(); - CalledWhenFalse.Clear(); - CalledOnCollectionChanged.Clear(); - } + // public void Clear() + // { + // CalledWhenTrue.Clear(); + // CalledWhenFalse.Clear(); + // CalledOnCollectionChanged.Clear(); + // } - public bool IsMatch(KeyValuePair value, ViewContainer view) - { - return this.filter.Invoke(value, view); - } + // public bool IsMatch(KeyValuePair value, ViewContainer view) + // { + // return this.filter.Invoke(value, view); + // } - public void OnCollectionChanged(in SynchronizedViewChangedEventArgs, ViewContainer> args) - { - CalledOnCollectionChanged.Add(args); - } + // public void OnCollectionChanged(in SynchronizedViewChangedEventArgs, ViewContainer> args) + // { + // CalledOnCollectionChanged.Add(args); + // } - public void WhenTrue(KeyValuePair value, ViewContainer view) - { - CalledWhenTrue.Add((value, view)); - } + // public void WhenTrue(KeyValuePair value, ViewContainer view) + // { + // CalledWhenTrue.Add((value, view)); + // } - public void WhenFalse(KeyValuePair value, ViewContainer view) - { - CalledWhenFalse.Add((value, view)); - } - } + // public void WhenFalse(KeyValuePair value, ViewContainer view) + // { + // CalledWhenFalse.Add((value, view)); + // } + //} }