Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
coenm committed Oct 11, 2024
1 parent e99887b commit dae60b5
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace RepoM.ActionMenu.Core.Abstractions;

using System;
using System.Collections.Generic;

internal sealed class EnvironmentsCacheDecorator: IEnvironment
{
private readonly IEnvironment _decoratee;
private Dictionary<string, string>? _cachedValue;

public EnvironmentsCacheDecorator(IEnvironment decoratee)
{
_decoratee = decoratee ?? throw new ArgumentNullException(nameof(decoratee));
}

public Dictionary<string, string> GetEnvironmentVariables()
{
return _cachedValue ??= _decoratee.GetEnvironmentVariables();
}
}
8 changes: 8 additions & 0 deletions src/RepoM.ActionMenu.Core/Abstractions/IEnvironment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace RepoM.ActionMenu.Core.Abstractions;

using System.Collections.Generic;

internal interface IEnvironment
{
Dictionary<string, string> GetEnvironmentVariables();
}
36 changes: 36 additions & 0 deletions src/RepoM.ActionMenu.Core/Abstractions/SystemEnvironments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace RepoM.ActionMenu.Core.Abstractions;

using System;
using System.Collections;
using System.Collections.Generic;

internal sealed class SystemEnvironments : IEnvironment
{
private SystemEnvironments()
{
}

public static SystemEnvironments Instance { get; } = new ();

public Dictionary<string, string> GetEnvironmentVariables()
{
var env = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

foreach (DictionaryEntry item in Environment.GetEnvironmentVariables())
{
if (item.Key is not string key || string.IsNullOrEmpty(key))
{
continue;
}

if (item.Value is not string value)
{
continue;
}

env.Add(key.Trim(), value);
}

return env;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ internal sealed class EnvSetScriptObject : IScriptObject, IDisposable
{
private FastStack<EnvScriptObject> _stack = new(10);

public EnvSetScriptObject(IDictionary<string, string> envVars) : this(new EnvScriptObject(envVars))
{
}

public EnvSetScriptObject(EnvScriptObject @base)
{
_ = @base ?? throw new ArgumentNullException(nameof(@base));
Expand Down
4 changes: 4 additions & 0 deletions src/RepoM.ActionMenu.Core/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace RepoM.ActionMenu.Core;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using RepoM.ActionMenu.Core.Abstractions;
using RepoM.ActionMenu.Core.ConfigReader;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Core.Model;
Expand Down Expand Up @@ -55,6 +56,9 @@ private static void RegisterPrivateTypes(Container container)

container.RegisterSingleton<IFileReader, FileReader>();
container.RegisterDecorator<IFileReader, CacheFileReaderDecorator>(Lifestyle.Singleton);

container.RegisterInstance<IEnvironment>(SystemEnvironments.Instance);
container.RegisterDecorator<IEnvironment, EnvironmentsCacheDecorator>(Lifestyle.Singleton);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace RepoM.ActionMenu.Core.Model;
using System.IO.Abstractions;
using System.Linq;
using System.Threading.Tasks;
using RepoM.ActionMenu.Core.Abstractions;
using RepoM.ActionMenu.Core.ActionMenu.Context;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Core.Yaml.Model.ActionContext;
Expand All @@ -23,6 +24,7 @@ namespace RepoM.ActionMenu.Core.Model;
internal class ActionMenuGenerationContext : TemplateContext, IActionMenuGenerationContext, IContextMenuActionMenuGenerationContext
{
private readonly ITemplateParser _templateParser;
private readonly IEnvironment _environment;
private readonly ITemplateContextRegistration[] _functionsArray;
private readonly IActionMenuDeserializer _deserializer;
private readonly IActionToRepositoryActionMapper[] _repositoryActionMappers;
Expand All @@ -35,12 +37,14 @@ internal class ActionMenuGenerationContext : TemplateContext, IActionMenuGenerat
public ActionMenuGenerationContext(
ITemplateParser templateParser,
IFileSystem fileSystem,
IEnvironment environment,
ITemplateContextRegistration[] functionsArray,
IActionToRepositoryActionMapper[] repositoryActionMappers,
IActionMenuDeserializer deserializer,
IContextActionProcessor[] contextActionMappers)
{
_templateParser = templateParser ?? throw new ArgumentNullException(nameof(templateParser));
_environment = environment ?? throw new ArgumentNullException(nameof(environment));
_functionsArray = functionsArray ?? throw new ArgumentNullException(nameof(functionsArray));
FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_repositoryActionMappers = repositoryActionMappers ?? throw new ArgumentNullException(nameof(repositoryActionMappers));
Expand Down Expand Up @@ -102,6 +106,7 @@ public IActionMenuGenerationContext Clone()
var result = new ActionMenuGenerationContext(
_templateParser,
FileSystem,
_environment,
_functionsArray,
_repositoryActionMappers,
_deserializer,
Expand All @@ -115,8 +120,7 @@ internal void Initialize(IRepository repository)
{
Repository = repository ?? throw new ArgumentNullException(nameof(repository));

_rootScriptObject = CreateAndInitRepoMScriptObject(
new EnvSetScriptObject(EnvScriptObject.Instance));
_rootScriptObject = CreateAndInitRepoMScriptObject(new EnvSetScriptObject(_environment.GetEnvironmentVariables()));

foreach (ITemplateContextRegistration contextRegistration in _functionsArray)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace RepoM.ActionMenu.Core.Services;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RepoM.ActionMenu.Core;
using RepoM.ActionMenu.Core.Abstractions;
using RepoM.ActionMenu.Core.ConfigReader;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Core.Model;
Expand All @@ -25,6 +26,7 @@ namespace RepoM.ActionMenu.Core.Services;
internal class UserInterfaceActionMenuFactory : IUserInterfaceActionMenuFactory
{
private readonly IFileSystem _fileSystem;
private readonly IEnvironment _environment;
private readonly ITemplateParser _templateParser;
private readonly ITemplateContextRegistration[] _plugins;
private readonly IActionToRepositoryActionMapper[] _mappers;
Expand All @@ -34,7 +36,8 @@ internal class UserInterfaceActionMenuFactory : IUserInterfaceActionMenuFactory
private readonly IContextActionProcessor[] _contextActionMappers;

public UserInterfaceActionMenuFactory(
IFileSystem fileSystem,
IFileSystem fileSystem,
IEnvironment environment,
ITemplateParser templateParser,
IEnumerable<ITemplateContextRegistration> plugins,
IEnumerable<IActionToRepositoryActionMapper> mappers,
Expand All @@ -43,6 +46,7 @@ public UserInterfaceActionMenuFactory(
ILogger logger)
{
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_environment = environment ?? throw new ArgumentNullException(nameof(environment));
_templateParser = templateParser ?? throw new ArgumentNullException(nameof(templateParser));
_plugins = plugins.ToArray();
_mappers = mappers.ToArray();
Expand Down Expand Up @@ -101,7 +105,7 @@ private async Task<ActionMenuGenerationContext> CreateActionMenuGenerationContex
await Task.Yield();

_logger.LogTrace("CreateActionMenuGenerationContext ActionMenuGenerationContext ctor");
var actionMenuGenerationContext = new ActionMenuGenerationContext(_templateParser, _fileSystem, _plugins, _mappers, _deserializer, _contextActionMappers);
var actionMenuGenerationContext = new ActionMenuGenerationContext(_templateParser, _fileSystem, _environment, _plugins, _mappers, _deserializer, _contextActionMappers);
actionMenuGenerationContext.Initialize(repository);
return actionMenuGenerationContext;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace RepoM.ActionMenu.Core.Tests.Model;
using System.Threading.Tasks;
using FakeItEasy;
using FluentAssertions;
using RepoM.ActionMenu.Core.ActionMenu.Context;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Core.Model;
using RepoM.ActionMenu.Core.Yaml.Model.ActionContext;
Expand All @@ -17,6 +16,7 @@ namespace RepoM.ActionMenu.Core.Tests.Model;
using RepoM.ActionMenu.Interface.YamlModel.Templating;
using RepoM.Core.Plugin.Repository;
using Xunit;
using IEnvironment = RepoM.ActionMenu.Core.Abstractions.IEnvironment;

public class DisposableContextScriptObjectTests
{
Expand All @@ -26,21 +26,25 @@ public class DisposableContextScriptObjectTests
private readonly ITemplateContextRegistration[] _functionsArray = [];
private readonly IActionToRepositoryActionMapper[] _mapper = [];
private readonly IActionMenuDeserializer _deserializer = A.Fake<IActionMenuDeserializer>();
private readonly ActionMenuGenerationContext _context;
private ActionMenuGenerationContext _context;
private readonly IContextActionProcessor[] _mappers;
private readonly DisposableContextScriptObject _sut;
private readonly IEnvironment _environment = A.Fake<IEnvironment>();

public DisposableContextScriptObjectTests()
{
A.CallTo(() => _environment.GetEnvironmentVariables()).Returns(new Dictionary<string, string>()
{
{ "x", "y" },
});

_mappers =
[
A.Fake<IContextActionProcessor>(),
A.Fake<IContextActionProcessor>(),
];
_context = new ActionMenuGenerationContext(_templateParser, _fileSystem, _functionsArray, _mapper, _deserializer, _mappers);
_context.Initialize(_repository);
_sut = new DisposableContextScriptObject(_context, _mappers);
_context = CreateContext();
_sut = CreateSut();
}
[Fact]
Expand Down Expand Up @@ -129,16 +133,17 @@ public async Task AddContextActionAsync_ShouldUseMapperForProcessing_WhenMapperF
public void PushEnvironmentVariable_ShouldAddVariables()
{
// arrange
var env = new EnvScriptObject(
new Dictionary<string, string>
A.CallTo(() => _environment.GetEnvironmentVariables())
.Returns(new Dictionary<string, string>
{
{ "x", "y" },
});
_context.Env.Push(env);
IScope sut = new DisposableContextScriptObject(_context, _mappers);

_context = CreateContext();
IScope sut = CreateSut();

// assume
env.Count.Should().Be(1);
_context.Env.Count.Should().Be(1);

// act
sut.PushEnvironmentVariable(
Expand All @@ -149,24 +154,25 @@ public void PushEnvironmentVariable_ShouldAddVariables()
});

// assert
env.Count.Should().Be(3);
env.GetMembers().Should().BeEquivalentTo("x", "x1", "x2");
_context.Env.Count.Should().Be(3);
_context.Env.GetMembers().Should().BeEquivalentTo("x", "x1", "x2");
}

[Fact]
public void PushEnvironmentVariable_ShouldAddVariables_Distinct()
{
// arrange
var env = new EnvScriptObject(
new Dictionary<string, string>
{
{ "x", "y" },
});
_context.Env.Push(env);
IScope sut = new DisposableContextScriptObject(_context, _mappers);
A.CallTo(() => _environment.GetEnvironmentVariables())
.Returns(new Dictionary<string, string>
{
{ "x", "y" },
});

_context = CreateContext();
IScope sut = CreateSut();

// assume
env.Count.Should().Be(1);
_context.Env.Count.Should().Be(1);

// act
sut.PushEnvironmentVariable(
Expand All @@ -177,22 +183,24 @@ public void PushEnvironmentVariable_ShouldAddVariables_Distinct()
});

// assert
env.Count.Should().Be(2);
env.GetMembers().Should().BeEquivalentTo("x", "x1");
_context.Env.Count.Should().Be(2);
_context.Env.GetMembers().Should().BeEquivalentTo("x", "x1");
}

[Fact]
public void Dispose_ShouldPopAllPushedEnvironmentVariables()
{
// arrange
var env = new EnvScriptObject(
new Dictionary<string, string>
{
{ "x1", "y" },
{ "x2", "yy" },
});
_context.Env.Push(env);
IScope sut = new DisposableContextScriptObject(_context, _mappers);
A.CallTo(() => _environment.GetEnvironmentVariables())
.Returns(new Dictionary<string, string>
{
{ "x1", "y" },
{ "x2", "yy" },
});

_context = CreateContext();
IScope sut = CreateSut();

sut.PushEnvironmentVariable(
new Dictionary<string, string>
{
Expand All @@ -207,13 +215,25 @@ public void Dispose_ShouldPopAllPushedEnvironmentVariables()
});

// assume
env.Count.Should().Be(5);
_context.Env.Count.Should().Be(5);

// act
sut.Dispose();

// assert
env.Count.Should().Be(2);
_context.Env.Count.Should().Be(2);
}

private ActionMenuGenerationContext CreateContext()
{
var context = new ActionMenuGenerationContext(_templateParser, _fileSystem, _environment, _functionsArray, _mapper, _deserializer, _mappers);
context.Initialize(_repository);
return context;
}

private DisposableContextScriptObject CreateSut()
{
return new DisposableContextScriptObject(_context, _mappers);
}
}

Expand Down

0 comments on commit dae60b5

Please sign in to comment.