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(); }
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."); }
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."); }
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."); }
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."); }
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."); }
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."); }
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(); }
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(); }
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 }); }
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 } }); }
/// <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 }, }); }