public async Task ScopedStateMonadShouldDisposeVariablesThatItRemoves() { var repo = new MockRepository(MockBehavior.Strict); var sd = repo.Create <IDoubleDisposable>(); var monad1 = CreateMonad(repo); var scopedMonad = new ScopedStateMonad( monad1, ImmutableDictionary <VariableName, object> .Empty ); sd.Setup(x => x.DisposeAsync(scopedMonad)).Returns(Task.CompletedTask); sd.Setup(x => x.Dispose()); await scopedMonad.SetVariableAsync(new VariableName("V"), sd.Object, false, null); await scopedMonad.RemoveVariableAsync(new VariableName("V"), true, null); repo.VerifyAll(); }
/// <inheritdoc /> protected override async Task <Result <Unit, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var sclResult = await SCL.Run(stateMonad, cancellationToken).Map(x => x.GetStringAsync()); if (sclResult.IsFailure) { return(sclResult.ConvertFailure <Unit>()); } List <VariableName> variablesToExport; if (Export is null) { variablesToExport = new List <VariableName>(); } else { var exportResult = await Export.Run(stateMonad, cancellationToken) .Bind(x => x.GetElementsAsync(cancellationToken)); if (exportResult.IsFailure) { return(exportResult.ConvertFailure <Unit>()); } variablesToExport = exportResult.Value.Select(x => x.GetString()) .Select(x => new VariableName(x)) .ToList(); } var stepResult = SCLParsing.TryParseStep(sclResult.Value) .Bind(x => x.TryFreeze(TypeReference.Unit.Instance, stateMonad.StepFactoryStore)); if (stepResult.IsFailure) { return(stepResult.ConvertFailure <Unit>()); } await using var monad2 = new ScopedStateMonad( stateMonad, ImmutableDictionary <VariableName, object> .Empty ); await stepResult.Value.Run <Unit>(monad2, cancellationToken); foreach (var variable in variablesToExport) { var value = monad2.GetVariable <object>(variable); var valueV = value.IsSuccess ? value.Value : null; await monad2.RemoveVariableAsync( variable, false, this ); //Remove the variable to prevent it being disposed await stateMonad.SetVariableAsync(variable, valueV, true, this); } return(Unit.Default); }