public async Task Sync_None_Int_WithEmptyLists()
        {
            List <int> source = new List <int>()
            , destination     = new List <int>();

            await SyncAgent <int> .Create()
            .Configure((c) => c.SyncMode.SyncModePreset = SyncModePreset.None)
            .SetComparerAgent(ComparerAgent <int> .Create())
            .SetSourceProvider(source)
            .SetDestinationProvider(destination)
            .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            source.Should().BeEmpty();
            destination.Should().BeEmpty();
        }
Пример #2
0
        public void Sync_List_SourceSyncProviderIsSetToNullableList()
        {
            List <int> source = null
            , destination     = new List <int> {
                6, 10, 5
            };

            Func <Task> act = async() => await SyncAgent <int> .Create()
                              .SetComparerAgent(ComparerAgent <int> .Create())
                              .SetSourceProvider(source)
                              .SetDestinationProvider(destination)
                              .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().ThrowAsync <NullReferenceException>().WithMessage("The source items cannot be null.");
        }
Пример #3
0
        public void Sync_DestinationSyncProviderNotSet()
        {
            List <int> source = new List <int> {
                5, 4, 9
            }
            , destination = new List <int> {
                6, 10, 5
            };

            Func <Task> act = async() => await SyncAgent <int> .Create()
                              .SetComparerAgent(ComparerAgent <int> .Create())
                              .SetSourceProvider(source)
                              .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().Throw <NullReferenceException>().WithMessage($"The {nameof(SyncAgent<int>.DestinationProvider)} cannot be null.");
        }
Пример #4
0
        public void Compare_Int_NullableCompareItemFunc()
        {
            List <int> source = new List <int>()
            , destination     = new List <int>();

            var comparerAgent = ComparerAgent <int> .Create()
                                .SetSourceProvider(source)
                                .SetDestinationProvider(destination);

            comparerAgent.CompareItemFunc = null;

            Func <Task> act = async() => await comparerAgent
                              .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().Throw <NullReferenceException>().WithMessage($"The {nameof(ComparerAgent<int>.CompareItemFunc)} cannot be null.");
        }
Пример #5
0
        public void Compare_ClassWithNullableKey_PreventNegativeIdsInDestination()
        {
            List <Person> source = new List <Person> {
                new Person {
                    Id = 3, FirstName = "Joe", LastName = "Jim", DOB = null
                },
                new Person {
                    Id = 1, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                },
                new Person {
                    Id = 2, FirstName = "Tom", LastName = "Tim", DOB = null
                }
            }
            , destination = new List <Person> {
                new Person {
                    Id = -1, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                },
                new Person {
                    Id = -2, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                }
            };

            Func <Task> act = async() => await ComparerAgent <int?, Person> .Create()
                              .SetValidateItemsAction((s, d) =>
            {
                int count = s.Count(x => x.Id < 0);
                if (count > 0)
                {
                    throw new ArgumentException(string.Format("Negative Ids are invalid in the source list, {0} item{1} {2} found."
                                                              , count, count == 1 ? "" : "s", count == 1 ? "was" : "were"));
                }

                count = d.Count(x => x.Id < 0);
                if (count > 0)
                {
                    throw new ArgumentException(string.Format("Negative Ids are invalid in the destination list, {0} item{1} {2} found."
                                                              , count, count == 1 ? "" : "s", count == 1 ? "was" : "were"));
                }
            })
                              .SetKeySelector(person => person.Id)
                              .SetCompareItemFunc((s, d) => (s.Id == d.Id && s.FirstName == d.FirstName && s.LastName == d.LastName && s.DOB == d.DOB) ? MatchComparisonResultType.Same : MatchComparisonResultType.Conflict)
                              .SetSourceProvider(source)
                              .SetDestinationProvider(destination)
                              .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().Throw <ArgumentException>().WithMessage("Negative Ids are invalid in the destination list, 2 items were found.");
        }
Пример #6
0
        public void Sync_SortedSet_DestinationSyncProviderMustBeSetAfterSettingComparerAgent()
        {
            SortedSet <int> source = new SortedSet <int> {
                5, 4, 9
            }
            , destination = new SortedSet <int> {
                6, 10, 5
            };

            Func <Task> act = async() => await SyncAgent <int> .Create()
                              .SetDestinationProvider(destination)
                              .SetComparerAgent(ComparerAgent <int> .Create())
                              .SetSourceProvider(source)
                              .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().Throw <NullReferenceException>().WithMessage($"The {nameof(SyncAgent<int>.ComparerAgent)} must be set first.");
        }
        public void Compare_Int_PreventDuplicatesInSource()
        {
            List <int> source = new List <int> {
                10, 10
            }
            , destination = new List <int> {
                20, 20
            };

            Func <Task> act = async() => await ComparerAgent <int> .Create()
                              .Configure((c) => c.AllowDuplicateKeys = RuleAllowanceType.Destination)
                              .SetSourceProvider(source)
                              .SetDestinationProvider(destination)
                              .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().ThrowAsync <ArgumentException>().WithMessage("Duplicated items are not allowed in the source list, 1 item was found.");
        }
        public void Compare_Int_PreventNullableItemsInDestination()
        {
            List <int?> source = new List <int?> {
                10, null
            }
            , destination = new List <int?> {
                20, null
            };

            Func <Task> act = async() => await ComparerAgent <int?> .Create()
                              .Configure((c) => c.AllowNullableItems = RuleAllowanceType.Source)
                              .SetSourceProvider(source)
                              .SetDestinationProvider(destination)
                              .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().ThrowAsync <ArgumentException>().WithMessage("Null-able items are not allowed in the destination list, 1 item was found.");
        }
Пример #9
0
        public void Compare_ClassWithNullableKey_PreventDuplicatesInDestinationUsingItemComparer()
        {
            List <Person> source = new List <Person> {
                new Person {
                    Id = 3, FirstName = "Joe", LastName = "Jim", DOB = null
                },
                new Person {
                    Id = 1, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                },
                new Person {
                    Id = 2, FirstName = "Tom", LastName = "Tim", DOB = null
                }
            }
            , destination = new List <Person> {
                new Person {
                    Id = 1, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                },
                new Person {
                    Id = 1, FirstName = "Tom", LastName = "Smith", DOB = new DateTime(2000, 1, 1)
                },
                new Person {
                    Id = null, FirstName = "Abby", LastName = "Smith", DOB = null
                },
                new Person {
                    Id = null, FirstName = "Abby", LastName = "Smith", DOB = null
                },
                new Person(),
                new Person(),
                new Person {
                    Id = 3, FirstName = "Joe", LastName = "jim", DOB = null
                },
                new Person {
                    Id = 3, FirstName = "Joe", LastName = "jim", DOB = null
                }
            };

            Func <Task> act = async() => await ComparerAgent <int?, Person> .Create()
                              .Configure((c) => c.AllowDuplicateKeys = RuleAllowanceType.None)
                              .SetKeySelector(person => person.Id)
                              .SetCompareItemFunc((s, d) => (s.Id == d.Id && s.FirstName == d.FirstName && s.LastName == d.LastName && s.DOB == d.DOB) ? MatchComparisonResultType.Same : MatchComparisonResultType.Conflict)
                              .SetSourceProvider(source)
                              .SetDestinationProvider(destination)
                              .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            act.Should().Throw <ArgumentException>().WithMessage("Duplicated items are not allowed in the destination list, 5 items were found.");
        }
Пример #10
0
        public async Task Compare_Int_EmptySourceList()
        {
            List <int> source = new List <int>()
            , destination     = new List <int> {
                1
            };

            var comparisonResult = await ComparerAgent <int> .Create()
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEmpty();
            comparisonResult.ItemsInDestinationOnly.Should().BeEquivalentTo(new List <int> {
                1
            });
            comparisonResult.Matches.Should().BeEmpty();
        }
Пример #11
0
        public async Task ComparerAgentShouldHaveComparerProviders()
        {
            ComparerProvider <int> source = new ComparerProvider <int> {
                Items = new List <int>()
            }
            , destination = new ComparerProvider <int> {
                Items = new List <int>()
            };

            var comparisonResult = await ComparerAgent <int> .Create()
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEmpty();
            comparisonResult.ItemsInDestinationOnly.Should().BeEmpty();
            comparisonResult.Matches.Should().BeEmpty();
        }
Пример #12
0
        public async Task Sync_MirrorToSource_Int_WithEmptySourceList()
        {
            List <int> source = new List <int>()
            , destination     = new List <int> {
                6, 10, 5
            };

            await SyncAgent <int> .Create()
            .Configure((c) => c.SyncMode.SyncModePreset = SyncModePreset.MirrorToSource)
            .SetComparerAgent(ComparerAgent <int> .Create())
            .SetSourceProvider(source)
            .SetDestinationProvider(destination)
            .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            source.Should().BeEquivalentTo(new List <int> {
                6, 10, 5
            });
            destination.Should().BeEquivalentTo(new List <int> {
                6, 10, 5
            });
        }
        public async Task Sync_TwoWay_Int_WithEmptyDestination()
        {
            List <int> source = new List <int> {
                5, 4, 9
            }
            , destination = new List <int>();

            await SyncAgent <int> .Create()
            .Configure((c) => c.SyncMode.SyncModePreset = SyncModePreset.TwoWay)
            .SetComparerAgent(ComparerAgent <int> .Create())
            .SetSourceProvider(source)
            .SetDestinationProvider(destination)
            .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            source.Should().BeEquivalentTo(new List <int> {
                5, 4, 9
            });
            destination.Should().BeEquivalentTo(new List <int> {
                5, 4, 9
            });
        }
        public async Task Compare_String_WithCaseSensitiveComparer_AndNullableItemsInDestination()
        {
            List <string> source = new List <string> {
                "Tom"
            }
            , destination = new List <string> {
                null
            };

            var comparisonResult = await ComparerAgent <string> .Create()
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEquivalentTo(new List <string> {
                "Tom"
            });
            comparisonResult.ItemsInDestinationOnly.Should().BeEquivalentTo(new List <string> {
                null
            });
            comparisonResult.Matches.Should().BeEmpty();
        }
        public async Task Sync_UpdateSource_Int_NonEmptyLists()
        {
            List <int> source = new List <int> {
                5, 4, 9
            }
            , destination = new List <int> {
                6, 10, 5
            };

            await SyncAgent <int> .Create()
            .Configure((c) => c.SyncMode.SyncModePreset = SyncModePreset.UpdateSource)
            .SetComparerAgent(ComparerAgent <int> .Create())
            .SetSourceProvider(source)
            .SetDestinationProvider(destination)
            .SyncAsync(CancellationToken.None).ConfigureAwait(false);

            source.Should().BeEquivalentTo(new List <int> {
                5, 4, 9, 6, 10
            });
            destination.Should().BeEquivalentTo(new List <int> {
                6, 10, 5
            });
        }
Пример #16
0
        public async Task Compare_String_WithCaseInsensitiveCompareItemFunc_AndNullableItemsInDestination()
        {
            List <string> source = new List <string> {
                "Tom"
            }
            , destination = new List <string> {
                null
            };

            var comparisonResult = await ComparerAgent <string> .Create()
                                   .SetCompareItemFunc((s, d) => string.Equals(s, d, StringComparison.OrdinalIgnoreCase) ? MatchComparisonResultType.Same : MatchComparisonResultType.Conflict)
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEquivalentTo(new List <string> {
                "Tom"
            });
            comparisonResult.ItemsInDestinationOnly.Should().BeEquivalentTo(new List <string> {
                null
            });
            comparisonResult.Matches.Should().BeEmpty();
        }
        public async Task Compare_Int_EquivalentListsWithOneItem()
        {
            List <int> source = new List <int> {
                10
            }
            , destination = new List <int> {
                10
            };

            var comparisonResult = await ComparerAgent <int> .Create()
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEmpty();
            comparisonResult.ItemsInDestinationOnly.Should().BeEmpty();

            comparisonResult.Matches.Should().BeEquivalentTo(new List <MatchComparisonResult <int> >
            {
                new MatchComparisonResult <int> {
                    Source = 10, Destination = 10, ComparisonResult = MatchComparisonResultType.Same
                }
            });
        }
Пример #18
0
        /// <summary>
        /// Synchronizes the items that exist in the source and destination.
        /// </summary>
        /// <param name="batchKeys">The keys of the items.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
        /// <returns></returns>
        private async Task SyncMatchesBatchAsync(List <TKey> batchKeys, CancellationToken cancellationToken)
        {
            var srcTask = SourceProvider.GetAsync(batchKeys, cancellationToken);
            var dstTask = DestinationProvider.GetAsync(batchKeys, cancellationToken);

            await Task.WhenAll(srcTask, dstTask);

            // Compare
            var comparisonResult = await ComparerAgent <TKey, TItem> .Create()
                                   .Configure((c) =>
            {
                c.AllowDuplicateItems = RuleAllowanceType.None;
                c.AllowDuplicateKeys  = RuleAllowanceType.None;
                c.AllowNullableItems  = RuleAllowanceType.None;
            })
                                   .SetKeySelector(KeySelector)
                                   .SetCompareItemFunc(CompareItemFunc)
                                   .SetSourceProvider(srcTask.Result)
                                   .SetDestinationProvider(dstTask.Result)
                                   .CompareAsync(cancellationToken).ConfigureAwait(false);

            // Sync
            await SyncAsync(comparisonResult, cancellationToken).ConfigureAwait(false);
        }
        public async Task Compare_ClassWithNullableKey_Updated()
        {
            List <Event> source = new List <Event> {
                new Event {
                    Id = 2, Title = "Birthday", ModifiedDate = new DateTime(2000, 1, 1)
                },
                new Event {
                    Id = 1, Title = "soccer match", ModifiedDate = new DateTime(2000, 1, 2)
                },
                new Event {
                    Id = null, Title = "Private", ModifiedDate = null
                },
                new Event(),
                new Event {
                    Id = 4, Title = "Hang-out", ModifiedDate = new DateTime(2000, 1, 2)
                },
                new Event {
                    Id = 5, Title = "bad", ModifiedDate = new DateTime(2000, 1, 8)
                }
            }
            , destination = new List <Event> {
                new Event {
                    Id = 1, Title = "Soccer Match", ModifiedDate = new DateTime(2000, 1, 3)
                },
                new Event {
                    Id = 2, Title = "Birthday", ModifiedDate = new DateTime(2000, 1, 1)
                },
                new Event {
                    Id = 3, Title = "Free-time", ModifiedDate = null
                },
                new Event {
                    Id = 4, Title = "hang-out", ModifiedDate = new DateTime(2000, 1, 1)
                },
                new Event {
                    Id = 5, Title = "Bad", ModifiedDate = new DateTime(2000, 1, 8)
                }
            };

            var comparisonResult = await ComparerAgent <int?, Event> .Create()
                                   .SetKeySelector(e => e.Id)
                                   .SetCompareItemFunc((s, d) =>
            {
                if (s.Title == d.Title && s.ModifiedDate == d.ModifiedDate)
                {
                    return(MatchComparisonResultType.Same);
                }
                else if (s.ModifiedDate < d.ModifiedDate)
                {
                    return(MatchComparisonResultType.NewerDestination);
                }
                else if (s.ModifiedDate > d.ModifiedDate)
                {
                    return(MatchComparisonResultType.NewerSource);
                }
                else
                {
                    return(MatchComparisonResultType.Conflict);
                }
            })
                                   .SetSourceProvider(source)
                                   .SetDestinationProvider(destination)
                                   .CompareAsync(CancellationToken.None).ConfigureAwait(false);

            comparisonResult.ItemsInSourceOnly.Should().BeEquivalentTo(new List <Event> {
                source[2], source[3]
            });
            comparisonResult.ItemsInDestinationOnly.Should().BeEquivalentTo(new List <Event> {
                destination[2]
            });

            comparisonResult.Matches.Should().BeEquivalentTo(new List <MatchComparisonResult <Event> >
            {
                new MatchComparisonResult <Event> {
                    Source = source[1], Destination = destination[0], ComparisonResult = MatchComparisonResultType.NewerDestination
                },
                new MatchComparisonResult <Event> {
                    Source = source[0], Destination = destination[1], ComparisonResult = MatchComparisonResultType.Same
                },
                new MatchComparisonResult <Event> {
                    Source = source[4], Destination = destination[3], ComparisonResult = MatchComparisonResultType.NewerSource
                },
                new MatchComparisonResult <Event> {
                    Source = source[5], Destination = destination[4], ComparisonResult = MatchComparisonResultType.Conflict
                },
            });
        }