public void MultipleSortingAndFiltering() { var expectedTotal = 20; var rnd = new Random(214748364); var titles1 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('a' + x)).ToString()).ToList(); var dates1 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList(); var idstack1 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next)); var datestack1 = new Stack<DateTimeOffset>(dates1); var titlestack1 = new Stack<string>(titles1.OrderBy(_ => rnd.Next())); var titles2 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('c' + x)).ToString()).ToList(); var dates2 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList(); var dates2mixed = new List<DateTimeOffset>() { dates2[2], dates2[0], dates2[1], dates2[3], dates2[5], dates2[9], dates2[15], dates2[6], dates2[7], dates2[8], dates2[13], dates2[10], dates2[16], dates2[11], dates2[12], dates2[14], dates2[17], dates2[18], dates2[19], dates2[4], }; var idstack2 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next)); var datestack2 = new Stack<DateTimeOffset>(dates2mixed); var titlestack2 = new Stack<string>(titles2.OrderBy(_ => rnd.Next())); var datestack3 = new Stack<DateTimeOffset>(); for (int i = 0; i < datestack1.Count; i++) datestack3.Push(new DateTimeOffset(Math.Max(dates1[i].Ticks, dates2mixed[i].Ticks), TimeSpan.Zero)); var list1 = Observable.Defer(() => Enumerable.Range(1, expectedTotal) .OrderBy(rnd.Next) .Select(x => new Thing(idstack1.Pop(), titlestack1.Pop(), datestack1.Pop())) .ToObservable()) .Replay() .RefCount(); var list2 = Observable.Defer(() => Enumerable.Range(1, expectedTotal) .OrderBy(rnd.Next) .Select(x => new Thing(idstack2.Pop(), titlestack2.Pop(), datestack2.Pop())) .ToObservable()) .Replay() .RefCount(); ITrackingCollection<Thing> col = new TrackingCollection<Thing>( list1.Concat(list2), OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare, (item, idx, list) => idx < 5 ); col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare; col.ProcessingDelay = TimeSpan.Zero; var evt = new ManualResetEvent(false); col.OriginalCompleted.Subscribe(_ => evt.Set()); col.Subscribe(); //col.Subscribe(t => //{ // if (++count == expectedTotal * 2) // evt.Set(); //}, () => { }); evt.WaitOne(); evt.Reset(); // it's initially sorted by date, so id list should not match CollectionAssert.AreNotEqual(list1.Select(x => x.Number).ToEnumerable(), list2.Select(x => x.Number).ToEnumerable()); var sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Number).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Title).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Dispose(); }
public async Task MultipleSortingAndFiltering() { var expectedTotal = 20; var rnd = new Random(214748364); var updatedAtMinutesStack = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next)); var list1 = Observable.Defer(() => Enumerable.Range(1, expectedTotal) .OrderBy(rnd.Next) .Select(x => GetThing(x, x, x, ((char)('a' + x)).ToString())) .ToObservable()) .Replay() .RefCount(); var list2 = Observable.Defer(() => Enumerable.Range(1, expectedTotal) .OrderBy(rnd.Next) .Select(x => GetThing(x, x, updatedAtMinutesStack.Pop(), ((char)('c' + x)).ToString())) .ToObservable()) .Replay() .RefCount(); ITrackingCollection<Thing> col = new TrackingCollection<Thing>( list1.Concat(list2), OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare, (item, idx, list) => idx < 5 ); col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare; col.Subscribe(); await col.OriginalCompleted; // it's initially sorted by date, so id list should not match CollectionAssert.AreNotEqual(list1.Select(x => x.Number).ToEnumerable(), list2.Select(x => x.Number).ToEnumerable()); var sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing> .OrderByDescending(x => x.UpdatedAt) .ThenByDescending(x => x.CreatedAt).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Number).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing> .OrderBy(x => x.UpdatedAt) .ThenBy(x => x.CreatedAt).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Title).Compare; sortlist = col.ToArray(); Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare)); CollectionAssert.AreEqual(sortlist.Take(5), col); col.Dispose(); }