< Summary

Information
Class: NGql.Tool.SnippetResult
Assembly: NGql.Tool
File(s): /home/runner/work/NGql/NGql/tools/Tool/SnippetRunner.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 61
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Ok()100%11100%
Rendered(...)100%11100%
Failed(...)100%11100%

File(s)

/home/runner/work/NGql/NGql/tools/Tool/SnippetRunner.cs

#LineLine coverage
 1using Microsoft.CodeAnalysis.CSharp.Scripting;
 2using Microsoft.CodeAnalysis.Scripting;
 3
 4using NGql.Core;
 5using NGql.Core.Builders;
 6
 7namespace NGql.Tool;
 8
 9/// <summary>
 10/// Compiles + evaluates a C# script snippet against the bundled NGql.Core, returning the
 11/// ToString() of the final expression's value.
 12/// </summary>
 13internal static class SnippetRunner
 14{
 15    private static readonly ScriptOptions Options = ScriptOptions.Default
 16        .WithReferences(
 17            typeof(QueryBuilder).Assembly,
 18            typeof(EnumValue).Assembly,
 19            typeof(Dictionary<,>).Assembly,
 20            typeof(System.Linq.Enumerable).Assembly,
 21            typeof(object).Assembly)
 22        .WithImports(
 23            "System",
 24            "System.Collections.Generic",
 25            "System.Linq",
 26            "NGql.Core",
 27            "NGql.Core.Builders");
 28
 29    public static async Task<SnippetResult> CompileAndRun(string snippet)
 30    {
 31        try
 32        {
 33            var result = await CSharpScript.EvaluateAsync<object?>(snippet, Options);
 34            return result is null
 35                ? SnippetResult.Failed("snippet produced null — its final expression must yield a builder/object with To
 36                : SnippetResult.Rendered(result.ToString() ?? string.Empty);
 37        }
 38        catch (CompilationErrorException ex)
 39        {
 40            return SnippetResult.Failed("compile error:\n" + string.Join('\n', ex.Diagnostics));
 41        }
 42        catch (Exception ex)
 43        {
 44            return SnippetResult.Failed($"runtime error: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}");
 45        }
 46    }
 47
 48    public static bool IsMutation(string rendered) =>
 49        rendered.TrimStart().StartsWith("mutation ", StringComparison.Ordinal);
 50}
 51
 52/// <summary>
 53/// Outcome of compiling and evaluating a snippet: exactly one of <see cref="Output"/> (when
 54/// <see cref="Ok"/>) or <see cref="Error"/> carries text, so callers never need a null fallback.
 55/// </summary>
 70856internal sealed record SnippetResult(bool Ok, string Output, string Error)
 57{
 21958    public static SnippetResult Rendered(string output) => new(true, output, string.Empty);
 59
 1560    public static SnippetResult Failed(string error) => new(false, string.Empty, error);
 61}