Skip to content

Instantly share code, notes, and snippets.

@RolandPheasant
Last active January 7, 2022 16:08
Show Gist options
  • Save RolandPheasant/5b0e44cab6e59dc52a03f33a17996c2a to your computer and use it in GitHub Desktop.
Save RolandPheasant/5b0e44cab6e59dc52a03f33a17996c2a to your computer and use it in GitHub Desktop.
RightJoin / AutoRefresh
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