< Summary

Information
Class: NGql.Core.Abstractions.QueryBlock
Assembly: NGql.Core
File(s): /home/runner/work/NGql/NGql/src/Core/Abstractions/QueryBlock.cs
Line coverage
100%
Covered lines: 61
Uncovered lines: 0
Coverable lines: 61
Total lines: 202
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_FieldsList()100%11100%
get_Arguments()100%11100%
get_Variables()100%11100%
get_Name()100%11100%
get_Alias()100%11100%
AddVariable(...)100%11100%
AddVariable(...)100%11100%
AddField(...)100%11100%
AddField(...)100%11100%
AddField(...)100%11100%
AddArgument(...)100%11100%
AddArgument(...)100%22100%
.ctor(...)100%44100%
ToString()100%11100%
HandleAddField(...)100%66100%
AddSubQuery(...)100%22100%
AddStringField(...)100%22100%
AddListItems(...)100%66100%
HandleAddVariable(...)100%11100%
HandleAddArgument(...)100%11100%

File(s)

/home/runner/work/NGql/NGql/src/Core/Abstractions/QueryBlock.cs

#LineLine coverage
 1using System.Collections;
 2using NGql.Core.Builders;
 3using NGql.Core.Extensions;
 4
 5namespace NGql.Core.Abstractions;
 6
 7/// <summary>
 8/// Represents a GraphQL Query Block.
 9/// </summary>
 10public sealed class QueryBlock
 11{
 12    private readonly string _prefix;
 13    private readonly SortedDictionary<string, object> _arguments;
 14    private readonly SortedSet<Variable> _variables;
 15    private readonly List<object> _fieldsList;
 16
 17    /// <summary>
 18    /// The list of fields to retrieve from GraphQL.
 19    /// </summary>
 46220    public IReadOnlyList<object> FieldsList => _fieldsList;
 21
 22    /// <summary>
 23    /// The collection of arguments related to <see cref="FieldsList"/>.
 24    /// </summary>
 48325    public IReadOnlyDictionary<string, object> Arguments => _arguments;
 26
 27    /// <summary>
 28    /// The collection of variables related to <see cref="FieldsList"/> or <see cref="Arguments"/>.
 29    /// </summary>
 54630    public IReadOnlyCollection<Variable> Variables => _variables;
 31
 32    /// <summary>
 33    /// The Query name.
 34    /// </summary>
 58835    public string Name { get; }
 36
 37    /// <summary>
 38    /// The Query alias.
 39    /// </summary>
 79240    public string? Alias { get; }
 41
 42    /// <summary>
 43    /// Indicates if the query is empty.
 44    /// </summary>
 45    internal bool IsEmpty = false;
 46
 47    /// <summary>
 48    /// Adds the variable with give name into <see cref="Variables"/> part of the query.
 49    /// </summary>
 50    /// <param name="variable">The variable</param>
 51    public void AddVariable(Variable variable)
 3052        => HandleAddVariable(variable);
 53
 54    /// <summary>
 55    /// Adds the variable with give name into <see cref="Variables"/> part of the query.
 56    /// </summary>
 57    /// <param name="name">The variable name</param>
 58    /// <param name="type">The value of the variable</param>
 59    public void AddVariable(string name, string type)
 3060        => HandleAddVariable(new Variable(name, type));
 61
 62    /// <summary>
 63    /// Adds the given generic list to the <see cref="FieldsList"/> part of the query.
 64    /// </summary>
 65    /// <remarks>
 66    /// Accepts any type of list, but must contain one of supported types of data.
 67    /// </remarks>
 68    /// <param name="selectList">Generic list of select fields.</param>
 69    public void AddField(IEnumerable<object> selectList)
 2770        => HandleAddField(selectList);
 71
 72    /// <summary>
 73    /// Adds the given list of strings to the <see cref="FieldsList"/> part of the query.
 74    /// </summary>
 75    /// <param name="selects">List of strings.</param>
 76    /// <returns>Query</returns>
 77    public void AddField(params string[] selects)
 19578        => HandleAddField(selects);
 79
 80    /// <summary>
 81    /// Adds the given sub query to the <see cref="FieldsList"/> part of the query.
 82    /// </summary>
 83    /// <param name="subQuery">A sub-query.</param>
 84    /// <returns>Query</returns>
 85    public void AddField(QueryBlock subQuery)
 21686        => HandleAddField(subQuery);
 87
 88    /// <summary>
 89    /// Adds the given key into <see cref="Arguments"/> part of the query.
 90    /// </summary>
 91    /// <param name="key">The Parameter Name</param>
 92    /// <param name="where">The value of the parameter, primitive or object</param>
 93    /// <returns></returns>
 94    public void AddArgument(string key, object where)
 10895        => HandleAddArgument(key, where);
 96
 97    /// <summary>
 98    /// Add a dict of key value pairs &lt;string, object&gt; into <see cref="Arguments"/> part of the query.
 99    /// </summary>
 100    /// <param name="dict">An existing Dictionary that takes &lt;string, object&gt;</param>
 101    /// <returns>Query</returns>
 102    /// <throws>DuplicateKeyException and others</throws>
 103    public void AddArgument(IReadOnlyDictionary<string, object> dict)
 104    {
 216105        foreach (var (key, value) in dict)
 81106            HandleAddArgument(key, value);
 27107    }
 108
 109    /// <summary>
 110    /// Initializes a new instance of the <see cref="QueryBlock"/> class.
 111    /// </summary>
 522112    public QueryBlock(string name, string prefix = "", string? alias = null, params Variable[]? variables)
 113    {
 522114        _prefix = prefix;
 522115        Name = name;
 522116        Alias = alias;
 117
 522118        _fieldsList = new List<object>();
 624119        _variables = variables is null ? [] : [.. variables.DistinctBy(x => x.Name)];
 522120        _arguments = new SortedDictionary<string, object>(StringComparer.OrdinalIgnoreCase);
 522121    }
 122
 123    public override string ToString()
 124    {
 207125        var builder = QueryTextBuilder.GetFromPool();
 126        try
 127        {
 207128            return builder.Build(this, prefix: _prefix);
 129        }
 130        finally
 131        {
 207132            QueryTextBuilder.ReturnToPool(builder);
 207133        }
 207134    }
 135
 136    private void HandleAddField(object value)
 137    {
 138        switch (value)
 139        {
 140            case QueryBlock subQuery:
 222141                AddSubQuery(subQuery);
 222142                return;
 143            case string field:
 303144                AddStringField(field);
 303145                return;
 146            case IList list:
 222147                AddListItems(list);
 219148                return;
 149            default:
 3150                throw new InvalidOperationException("Unsupported Field type found, must be a `string` or `QueryBlock`");
 151        }
 152    }
 153
 154    private void AddSubQuery(QueryBlock subQuery)
 155    {
 558156        foreach (var variable in subQuery.Variables)
 157        {
 57158            _variables.Add(variable);
 159        }
 222160        _fieldsList.Add(subQuery);
 222161    }
 162
 163    private void AddStringField(string field)
 164    {
 321165        if (string.IsNullOrWhiteSpace(field)) return;
 166
 285167        var insertIndex = _fieldsList.OfType<string>()
 120168            .TakeWhile(existing => string.Compare(existing, field, StringComparison.OrdinalIgnoreCase) < 0)
 285169            .Count();
 285170        _fieldsList.Insert(insertIndex, field);
 285171    }
 172
 173    private void AddListItems(IList list)
 174    {
 222175        var sortedItems = list.Cast<object>()
 171176            .OrderBy(x => x switch
 171177            {
 159178                string s => s,
 6179                QueryBlock q => q.Name,
 6180                _ => x.ToString()
 171181            })
 222182            .ToList();
 183
 1065184        foreach (var item in sortedItems)
 185        {
 312186            HandleAddField(item);
 187        }
 219188    }
 189
 190    private void HandleAddVariable(Variable variable)
 191    {
 60192        _variables.Add(variable);
 60193    }
 194
 195    private void HandleAddArgument(string key, object value)
 196    {
 189197        Helpers.ExtractVariablesFromValue(value, _variables);
 189198        var sortedValue = Helpers.SortArgumentValue(value);
 199
 189200        _arguments[key] = sortedValue!; // SortArgumentValue preserves non-null input
 189201    }
 202}