Last active
January 7, 2022 16:08
-
-
Save RolandPheasant/5b0e44cab6e59dc52a03f33a17996c2a to your computer and use it in GitHub Desktop.
RightJoin / AutoRefresh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reactive; | |
using System.Reactive.Concurrency; | |
using System.Collections.Generic; | |
using DynamicData.Binding; | |
using DynamicData.Kernel; | |
using FluentAssertions; | |
using Microsoft.Reactive.Testing; | |
using Xunit; | |
namespace DynamicData.Tests.Cache | |
{ | |
public record ProjectModel(Guid Id, string Title, Guid OwnerId); | |
public record UserModel(Guid Id, string Name); | |
public class RightJoinWithDeferredLoadFixture | |
{ | |
private readonly SourceCache<ProjectModel, Guid> _projectsCache = new(static x => x.Id); | |
private readonly SourceCache<UserModel, Guid> _usersCache = new(static x => x.Id); | |
private readonly ObservableCollectionExtended<ProjectViewModel> _projects = new(); | |
private readonly ObservableCollectionExtended<ProjectViewModel> _selectedProjects = new(); | |
private readonly TestScheduler _scheduler = new(); | |
public RightJoinWithDeferredLoadFixture() | |
{ | |
var shared = _usersCache.Connect() | |
.RightJoin( | |
_projectsCache.Connect(), | |
static project => project.OwnerId, | |
static (user, project) => new ProjectViewModel(project, user)) | |
.RefCount(); | |
_ = shared | |
.Bind(_projects) | |
.Subscribe(); | |
_ = shared | |
.AutoRefresh(static x => x.IsSelected, TimeSpan.FromMilliseconds(10), scheduler: _scheduler) | |
.Filter(static x => x.IsEnabled && x.IsSelected) | |
.Bind(_selectedProjects) | |
.Subscribe(); | |
} | |
[Fact] | |
public void ThisWillNotFail() | |
{ | |
_scheduler.Schedule(TimeSpan.FromSeconds(10), () => _projectsCache.AddOrUpdate(Api.Projects)); | |
_scheduler.Schedule(TimeSpan.FromSeconds(2), () => _usersCache.AddOrUpdate(Api.Users)); | |
_scheduler.AdvanceBy(TimeSpan.FromSeconds(2).Ticks); | |
_scheduler.AdvanceBy(TimeSpan.FromSeconds(8).Ticks); | |
_projects[0].IsSelected = true; | |
_projects[2].IsSelected = true; | |
_projects[3].IsSelected = true; | |
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks); | |
_selectedProjects.Count.Should().Be(3); | |
_projects[2].IsSelected = false; | |
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(10).Ticks); | |
_selectedProjects.Count.Should().Be(2); | |
} | |
} | |
public class ProjectViewModel : AbstractNotifyPropertyChanged | |
{ | |
private bool _isSelected; | |
public bool IsSelected | |
{ | |
get => _isSelected; | |
set => SetAndRaise(ref _isSelected, value); | |
} | |
public bool IsEnabled { get; set; } = true; | |
public ProjectModel Model { get; } | |
public Guid Id { get; set; } = Guid.Empty; | |
public string Title { get; set; } = string.Empty; | |
public Guid OwnerId { get; set; } = Guid.Empty; | |
public string Username { get; set; } = string.Empty; | |
public ProjectViewModel() | |
{ | |
Model = new(Guid.Empty, string.Empty, Guid.Empty); | |
} | |
public ProjectViewModel(ProjectModel model, Optional<UserModel> optionalUser = default) | |
{ | |
model = model ?? throw new ArgumentNullException(nameof(model)); | |
Model = model; | |
Id = model.Id; | |
Title = model.Title ?? string.Empty; | |
OwnerId = model.OwnerId; | |
Username = optionalUser.ValueOrDefault()?.Name ?? string.Empty; | |
} | |
} | |
public static class Api | |
{ | |
public static IReadOnlyCollection<ProjectModel> Projects { get; } = new[] | |
{ | |
new ProjectModel(Guid.NewGuid(), "Project1", new Guid("243578cd-0739-4ddd-81d9-f43fccece753")), | |
new ProjectModel(Guid.NewGuid(), "Project2", new Guid("243578cd-0739-4ddd-81d9-f43fccece753")), | |
new ProjectModel(Guid.NewGuid(), "Project3", new Guid("243578cd-0739-4ddd-81d9-f43fccece753")), | |
new ProjectModel(Guid.NewGuid(), "Project4", new Guid("243578cd-0739-4ddd-81d9-f43fccece753")), | |
new ProjectModel(Guid.NewGuid(), "Project5", new Guid("3faef27b-7e0e-49a2-aa6c-29532411dc70")), | |
new ProjectModel(Guid.NewGuid(), "Project6", new Guid("3faef27b-7e0e-49a2-aa6c-29532411dc70")), | |
new ProjectModel(Guid.NewGuid(), "Project7", new Guid("3faef27b-7e0e-49a2-aa6c-29532411dc70")), | |
new ProjectModel(Guid.NewGuid(), "Project8", new Guid("3faef27b-7e0e-49a2-aa6c-29532411dc70")), | |
}; | |
public static IReadOnlyCollection<UserModel> Users { get; } = new[] | |
{ | |
new UserModel(new Guid("243578cd-0739-4ddd-81d9-f43fccece753"), "User1"), | |
new UserModel(new Guid("3faef27b-7e0e-49a2-aa6c-29532411dc70"), "User2"), | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment