Skip to content

Commit

Permalink
Merge pull request #3 from Nexus-Mods/flow-design
Browse files Browse the repository at this point in the history
Switch to tUnit, work on rewriting the tests
  • Loading branch information
halgari authored Jan 10, 2025
2 parents 5e1dc0a + a181d0f commit 58a423e
Show file tree
Hide file tree
Showing 18 changed files with 199 additions and 240 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageVersion Include="NexusMods.Paths" Version="0.15.0" />
<PackageVersion Include="TransparentValueObjects" Version="1.0.2" />
<PackageVersion Include="TUnit" Version="0.6.59" />
</ItemGroup>
</Project>
13 changes: 6 additions & 7 deletions NexusMods.Cascade.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6ED01F9D
ProjectSection(SolutionItems) = preProject
tests\Directory.Build.props = tests\Directory.Build.props
tests\Directory.Build.targets = tests\Directory.Build.targets
tests\SharedAssemblyAttributes.cs = tests\SharedAssemblyAttributes.cs
tests\SharedUsings.cs = tests\SharedUsings.cs
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Cascade", "src\NexusMods.Cascade\NexusMods.Cascade.csproj", "{A92DED3D-BC67-4E04-9A06-9A1B302B3070}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Cascade.Tests", "tests\NexusMods.Cascade.Tests\NexusMods.Cascade.Tests.csproj", "{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Cascade.Tests", "tests\NexusMods.Cascade.Tests\NexusMods.Cascade.Tests.csproj", "{CD2CC009-1A10-4DA3-BBD0-E17217B22152}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -35,16 +34,16 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A92DED3D-BC67-4E04-9A06-9A1B302B3070} = {0377EBE6-F147-4233-86AD-32C821B9567E}
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89} = {6ED01F9D-5E12-4EB2-9601-64A2ADC719DE}
{CD2CC009-1A10-4DA3-BBD0-E17217B22152} = {6ED01F9D-5E12-4EB2-9601-64A2ADC719DE}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A92DED3D-BC67-4E04-9A06-9A1B302B3070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A92DED3D-BC67-4E04-9A06-9A1B302B3070}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A92DED3D-BC67-4E04-9A06-9A1B302B3070}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A92DED3D-BC67-4E04-9A06-9A1B302B3070}.Release|Any CPU.Build.0 = Release|Any CPU
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89}.Release|Any CPU.Build.0 = Release|Any CPU
{CD2CC009-1A10-4DA3-BBD0-E17217B22152}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD2CC009-1A10-4DA3-BBD0-E17217B22152}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD2CC009-1A10-4DA3-BBD0-E17217B22152}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD2CC009-1A10-4DA3-BBD0-E17217B22152}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
19 changes: 19 additions & 0 deletions src/NexusMods.Cascade/Flow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using NexusMods.Cascade.Abstractions;
using NexusMods.Cascade.Implementation;

Expand Down Expand Up @@ -39,6 +40,15 @@ public void Update<T1>(Action<FlowOps, T1> updateFn, T1 state)
updateFn(new FlowOps(_impl), state);
}

/// <summary>
/// Update synchronously, with one state value passed in, and a return value
/// </summary>
public TRet Update<T1, TRet>(Func<FlowOps, T1, TRet> updateFn, T1 state)
{
using var _ = _lock.Lock();
return updateFn(new FlowOps(_impl), state);
}

/// <summary>
/// Update synchronously, and return a value
/// </summary>
Expand All @@ -47,4 +57,13 @@ public T Update<T>(Func<FlowOps, T> updateFn)
using var _ = _lock.Lock();
return updateFn(new FlowOps(_impl));
}

/// <summary>
/// Runs a query and returns the results
/// </summary>
public IReadOnlyCollection<T> Query<T>(IQuery<T> query)
where T : notnull
{
return Update(static (ops, q) => ops.GetAllResults(q), query);
}
}
44 changes: 30 additions & 14 deletions src/NexusMods.Cascade/Implementation/FlowImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class FlowImpl : IFlowImpl
/// </summary>
private readonly Dictionary<IStageDefinition, IStage> _stages = [];

private readonly Dictionary<IStageDefinition, IOutletDefinition> _implicitOutlets = [];
private readonly Dictionary<IStageDefinition, IOutlet> _implicitOutlets = [];

/// <summary>
/// Mapping of stage outputs to stages that require that output
Expand All @@ -24,40 +24,55 @@ internal class FlowImpl : IFlowImpl
/// </summary>
private readonly Dictionary<(IStage InputStage, int InputIndex), List<(IStage OutputStage, int OutputIndex)>> _backConnections = new();

private IStage AddStage(IStageDefinition definition)
private IStage AddStage(IStageDefinition definition, out bool wasCreated)
{
// Deduplicate the stage
if (_stages.TryGetValue(definition, out var found))
{
wasCreated = false;
return found;
}

wasCreated = true;

// Create the stage if it doesn't exist
var instance = definition.CreateInstance(this);
_stages.Add(definition, instance);
var idx = 0;
foreach (var outlet in definition.UpstreamInputs)
{
var upstream = AddStage(outlet.Stage);
var upstream = AddStage(outlet.Stage, out _);
Connect(upstream, outlet.Index, instance, idx);
idx++;
}
return instance;
}

private IOutlet<T> GetOutlet<T>(IQuery<T> stageDefinition)
private IOutlet<T> GetOutlet<T>(IQuery<T> stageDefinition, out bool wasCreated)
where T : notnull
{
if (stageDefinition is IOutletDefinition<T> outlet)
return (IOutlet<T>)AddStage(outlet);
if (stageDefinition is IOutletDefinition<T> castedOutletDefinition)
{
return (IOutlet<T>)AddStage(castedOutletDefinition, out wasCreated);
}

if (_implicitOutlets.TryGetValue(stageDefinition, out var found))
{
wasCreated = false;
return (IOutlet<T>)found;
}

var newOutlet = new Outlet<T>(stageDefinition.Output);
_implicitOutlets.Add(stageDefinition, newOutlet);
return (IOutlet<T>)AddStage(newOutlet);
wasCreated = true;
var newOutletDefinition = new Outlet<T>(stageDefinition.Output);
var outlet = (IOutlet)AddStage(newOutletDefinition, out _);
_implicitOutlets.Add(stageDefinition, outlet);
return (IOutlet<T>)outlet;
}

internal void AddData<T>(IInletDefinition<T> definition, ReadOnlySpan<T> input, int delta = 1)
where T : notnull
{
var stage = AddStage(definition);
var stage = AddStage(definition, out _);

var inlet = (Inlet<T>.Stage)stage;
inlet.OutputSets[0].Reset();
Expand All @@ -69,7 +84,7 @@ internal void AddData<T>(IInletDefinition<T> definition, ReadOnlySpan<T> input,
internal void AddData<T>(IInletDefinition<T> definition, ReadOnlySpan<(T Item, int delta)> input)
where T : notnull
{
var stage = AddStage(definition);
var stage = AddStage(definition, out _);

var inlet = (Inlet<T>.Stage)stage;
inlet.OutputSets[0].Reset();
Expand Down Expand Up @@ -99,14 +114,15 @@ private void FlowDataFrom(IStage stage)
internal IReadOnlyCollection<T> GetAllResults<T>(IQuery<T> stageDefinition) where T : notnull
{

var stage = GetOutlet(stageDefinition);
var stage = GetOutlet(stageDefinition, out var wasCreated);

if (stage is not Outlet<T>.Stage outlet)
{
throw new ArgumentException("Stage is not an Outlet", nameof(stage));
}

BackPropagate(outlet);
if (wasCreated)
BackPropagate(outlet);

return outlet.Results;

Expand All @@ -130,7 +146,7 @@ private void BackPropagate(IStage stage)
{
foreach (var upstream in stage.Definition.UpstreamInputs)
{
var upstreamStage = AddStage(upstream.Stage);
var upstreamStage = AddStage(upstream.Stage, out _);
BackPropagate(upstreamStage);
stage.AddData(upstreamStage.OutputSets[upstream.Index], idx);
idx++;
Expand Down
2 changes: 1 addition & 1 deletion src/NexusMods.Cascade/Inlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void Add(ReadOnlySpan<T> input, int delta = 1)
var inputSet = (IOutputSet<T>)OutputSets[0];
foreach (var item in input)
{
var pair = new KeyValuePair<T, int>(item, 1);
var pair = new KeyValuePair<T, int>(item, delta);
inputSet.Add(in pair);

ref var existingDelta = ref CollectionsMarshal.GetValueRefOrAddDefault(_results, item, out _);
Expand Down
4 changes: 2 additions & 2 deletions src/NexusMods.Cascade/StageExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ public static HashJoin<TLeft, TRight, TKey, TOut> Join<TLeft, TRight, TKey, TOut
return new HashJoin<TLeft, TRight, TKey, TOut>(left.Output, right.Output, leftKeySelector, rightKeySelector, resultSelector);
}

public static Select<TIn, TOut> Select<TIn, TOut>(this IQuery<TIn> upstream, Expression<Func<TIn, TOut>> selector)
public static Select<TIn, TOut> Select<TIn, TOut>(this IQuery<TIn> upstream, Func<TIn, TOut> selector)
where TIn : notnull
where TOut : notnull
{
return new Select<TIn, TOut>(upstream.Output, selector.Compile());
return new Select<TIn, TOut>(upstream.Output, selector);
}

public static IQuery<TResult> SelectMany<TSource, TCollection, TResult>(this IQuery<TSource> input, Func<TSource, IEnumerable<TCollection>> collectionSelector,
Expand Down
47 changes: 0 additions & 47 deletions tests/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,51 +1,4 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Moq" Version="4.*" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.*" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.*" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.*" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.*" />
<PackageReference Include="FluentAssertions.OneOf" Version="0.0.5" />
<PackageReference Include="FluentAssertions.Analyzers" Version="0.18.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<PackageReference Include="xunit" Version="2.4.*" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Xunit.SkippableFact" Version="1.4.*" />
<PackageReference Include="Xunit.DependencyInjection" Version="8.*" />
<PackageReference Include="Xunit.DependencyInjection.Logging" Version="8.*" />
<PackageReference Include="Xunit.DependencyInjection.SkippableFact" Version="8.*" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.*" />
<PackageReference Include="coverlet.collector" Version="6.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
66 changes: 0 additions & 66 deletions tests/NexusMods.Cascade.Tests/BasicOperatorTests.cs

This file was deleted.

10 changes: 10 additions & 0 deletions tests/NexusMods.Cascade.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace NexusMods.Cascade.Tests;

public class BasicTests
{
[Test]
public async Task Test1()
{
await Assert.That(1 + 1).IsEqualTo(2);
}
}
9 changes: 0 additions & 9 deletions tests/NexusMods.Cascade.Tests/ModlistTests.cs

This file was deleted.

16 changes: 0 additions & 16 deletions tests/NexusMods.Cascade.Tests/ModlistUtils/Inlets.cs

This file was deleted.

17 changes: 0 additions & 17 deletions tests/NexusMods.Cascade.Tests/ModlistUtils/Loader.cs

This file was deleted.

Loading

0 comments on commit 58a423e

Please sign in to comment.