public void ReplaceAllNotifiesOfChangesMade()
        {
            IEnumerable <int> loadedInts = new int[] { 1, 2, 3, 4 };
            var replacements             = new int[] { 5, 6 };

            var expectedChanges = loadedInts.Select(i => new ItemChange <int>(ChangeType.Removed, i))
                                  .Concat(replacements.Select(i => new ItemChange <int>(ChangeType.Added, i)));

            var loader = new ThreadSafeAsyncLoader <int>(
                Seq.ListBased,
                loadDataAsync: tok => Task.FromResult(loadedInts),
                eventContext: new RunInlineSynchronizationContext());

            loader.LoadAsync();  // load initial values

            var listener = Substitute.For <CollectionChangedHandler <int> >();

            loader.CollectionChanged += listener;


            loader.Should().Equal(loadedInts);   // sanity check
            loader.ReplaceAll(replacements);     // --- Perform ---
            loader.Should().Equal(replacements); // sanity check


            listener.Received().Invoke(loader, Fluent.Match <IntChangesAlias>(
                                           changes => changes.Should().BeEquivalentTo(expectedChanges)));
        }
        public void Replace_WithPredicate_WorksForEmptyLoader()
        {
            var loader = new ThreadSafeAsyncLoader <int>(Seq.ListBased);

            loader.Replace(i => i == 1, 2);  // --- Perform ---
            loader.Should().BeEmpty();
        }
        public void ReplaceCanReplaceWhenLoaderHasMultipleItems()
        {
            IEnumerable <int> loadedInts = new[] { 1, 2, 3 };
            var loader = new ThreadSafeAsyncLoader <int>(Seq.ListBased, tok => Task.FromResult(loadedInts));

            loader.LoadAsync();

            loader.Replace(2, 4);  // --- Perform ---

            loader.Should().BeEquivalentTo(new[] { 1, 4, 3 });
        }
        public void Replace_WithPredicate_OnSingleton_DoesNothing_WhenNotMatched()
        {
            IEnumerable <int> loadedInts = new[] { 1 };
            var loader = new ThreadSafeAsyncLoader <int>(Seq.ListBased, tok => Task.FromResult(loadedInts));

            loader.LoadAsync();

            loader.Replace(i => i == 2, 3);  // --- Perform ---

            loader.Should().BeEquivalentTo(new[] { 1 });
        }
        public void Replace_WithPredicate_CanReplaceSingleton()
        {
            IEnumerable <int> loadedInts = new[] { 1 };
            var loader = new ThreadSafeAsyncLoader <int>(Seq.ListBased, tok => Task.FromResult(loadedInts));

            loader.LoadAsync();

            loader.Replace(i => i == 1, 2); // --- Perform ---

            loader.Should().BeEquivalentTo(new[] { 2 });
        }
        public void Replace_WithPredicate_OnTimestampedValues_Updates_IfNewer()
        {
            IEnumerable <TimestampedInt> originalItems = new[]
            {
                new TimestampedInt(1, new DateTime(2017, 09, 08, 18, 56, 00, DateTimeKind.Utc)),
                new TimestampedInt(2, new DateTime(2016, 01, 01, 10, 00, 00, DateTimeKind.Utc))
            };

            // A newer replacement
            TimestampedInt replacement = new TimestampedInt(3, new DateTime(2018, 01, 01, 01, 08, 00, DateTimeKind.Utc));

            var loader = new ThreadSafeAsyncLoader <TimestampedInt>(seqFactory: Seq.ListBased, loadDataAsync: _ => Task.FromResult(originalItems));

            loader.LoadAsync();

            // --- Perform ---
            loader.Replace(i => i.Value == 1, replacement);

            loader.Should().BeEquivalentTo(new[] { replacement, originalItems.ElementAt(1) });
        }
        public void Replace_OnTimestampedValues_DoesNotUpdate_IfOlder()
        {
            IEnumerable <TimestampedInt> originalItems = new[]
            {
                new TimestampedInt(1, new DateTime(2017, 09, 08, 18, 56, 00, DateTimeKind.Utc)),
                new TimestampedInt(2, new DateTime(2016, 01, 01, 10, 00, 00, DateTimeKind.Utc))
            };

            // An older replacement
            TimestampedInt replacement = new TimestampedInt(3, new DateTime(2017, 01, 01, 01, 08, 00, DateTimeKind.Utc));

            var loader = new ThreadSafeAsyncLoader <TimestampedInt>(
                seqFactory: Seq.ListBased,
                loadDataAsync: _ => Task.FromResult(originalItems),
                identityComparer: new TimestampedIntValueComparer());

            loader.LoadAsync();

            // --- Perform ---
            loader.Replace(originalItems.ElementAt(0), replacement);

            loader.Should().BeEquivalentTo(originalItems);
        }