Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve message when Scriban cannot execute predicate for context menu #201

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace RepoM.ActionMenu.Core.Yaml.Model.Templating;

using System;
using System.Threading.Tasks;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Interface.ActionMenuFactory;
Expand Down Expand Up @@ -35,8 +36,15 @@ public override async Task<bool> EvaluateAsync(ITemplateEvaluator instance)

if (instance is TemplateContext tc && _template != null)
{
var result = await _template.EvaluateAsync(tc).ConfigureAwait(false);
return ToBool(result);
try
{
var result = await _template.EvaluateAsync(tc).ConfigureAwait(false);
return ToBool(result);
}
catch (Exception e)
{
throw new PredicateEvaluationException(Value, e);
}
}

return await base.EvaluateAsync(instance).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public override string ToString()
return $"{nameof(Predicate)} {base.ToString()} : {DefaultValue}";
}

/// <exception cref="PredicateEvaluationException"></exception>
public virtual async Task<bool> EvaluateAsync(ITemplateEvaluator instance)
{
if (StaticValue.HasValue)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace RepoM.ActionMenu.Interface.YamlModel.Templating;

using System;

public sealed class PredicateEvaluationException : Exception
{
public PredicateEvaluationException(string predicate, Exception innerException)
: base(CreateMessage(predicate, innerException), innerException)
{
PredicateText = predicate;
}

public string PredicateText { get; }

private static string CreateMessage(string predicateText, Exception exception)
{
return $"Could not evaluate predicate '{predicateText}' because {exception.Message}";
}
}
4 changes: 4 additions & 0 deletions src/RepoM.App/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
},
"RepoM.App": {
"commandName": "Project"
},
"RepoM.App appdata": {
"commandName": "Project",
"commandLineArgs": "--App:AppSettingsPath \"%appdata%\\RepoM\""
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace RepoM.ActionMenu.Core.Tests.Yaml.Model;

using System;
using System.Threading.Tasks;
using FluentAssertions;
using RepoM.ActionMenu.Core.Misc;
using RepoM.ActionMenu.Core.Yaml.Model.Templating;
using RepoM.ActionMenu.Interface.ActionMenuFactory;
using RepoM.ActionMenu.Interface.YamlModel.Templating;
using Scriban;
using Xunit;

public class ScribanPredicateTests
{
[Fact]
public async Task EvaluateAsync_ShouldThrowPredicateEvaluationException_WhenPredicateIsWrong()
{
// arrange
var sut = new ScribanPredicate
{
Value = "file.exists x",
};
var realTemplateParser = new FixedTemplateParser();
((ICreateTemplate)sut).CreateTemplate(realTemplateParser);
ITemplateEvaluator templateEvaluator = new FakeTemplateContext(realTemplateParser);

// act
Func<Task<bool>> act = async () => await sut.EvaluateAsync(templateEvaluator);

// assert
(await act.Should().ThrowAsync<PredicateEvaluationException>())
.WithMessage("Could not evaluate predicate 'file.exists x' because <input>(1,6) : error : Cannot get the member file.exists for a null object.")
.And.PredicateText.Should().Be("file.exists x");

}
}

file class FakeTemplateContext : TemplateContext, ITemplateEvaluator
{
private readonly ITemplateParser _templateParser;

public FakeTemplateContext(ITemplateParser templateParser)
{
_templateParser = templateParser;
}
public Task<string> RenderStringAsync(string text)
{
throw new NotImplementedException();
}

public async Task<object> EvaluateAsync(string text)
{
Template template = _templateParser.ParseScriptOnly(text);
return await template.EvaluateAsync(this).ConfigureAwait(false);
}
}
Loading