• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alunacjones / LSL.VariableReplacer / 23

03 Apr 2025 10:18PM UTC coverage: 99.0% (-1.0%) from 100.0%
23

push

appveyor

Alun Jones
more changes

198 of 200 relevant lines covered (99.0%)

48.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.44
/LSL.VariableReplacer/CanAddVariablesExtensions.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Reflection;
5

6
namespace LSL.VariableReplacer;
7

8
/// <summary>
9
/// Extensions for ICanAddVariables
10
/// </summary>
11
public static class CanAddVariablesExtensions
12
{
13
    /// <summary>
14
    /// Adds a dictionary of variables
15
    /// to the configuration
16
    /// </summary>
17
    /// <typeparam name="TSelf"></typeparam>
18
    /// <param name="source"></param>
19
    /// <param name="variableDictionary"></param>
20
    /// <returns></returns>
21
    /// <exception cref="ArgumentException"></exception>
22
    public static TSelf AddVariables<TSelf>(this TSelf source, IDictionary<string, object> variableDictionary)
23
        where TSelf : ICanAddVariables<TSelf> => 
24
            Guard.IsNotNull(variableDictionary, nameof(variableDictionary))
11✔
25
                .Aggregate(source, (agg, i) => agg.AddVariable(i.Key, i.Value));
41✔
26

27
    /// <summary>
28
    /// Adds environment variables to the variables
29
    /// </summary>
30
    /// <typeparam name="TSelf"></typeparam>
31
    /// <param name="source"></param>
32
    /// <param name="environmentVariableFilter">
33
    /// An optional filter that is given the envionment variable
34
    /// key and returns <c>true</c> if it should be included
35
    /// </param>
36
    /// <param name="prefix">
37
    /// A prefix to apply to each variable's key. 
38
    /// The resultant key is <c>Prefix + Environment Variable Key</c>
39
    /// </param>
40
    /// <returns></returns>
41
    public static TSelf AddEnvironmentVariables<TSelf>(this TSelf source, Func<string, bool> environmentVariableFilter = null, string prefix = "ENV_")
42
        where TSelf : ICanAddVariables<TSelf>
43
    {
44
        environmentVariableFilter ??= key => true;
105✔
45
        var environmentVariables = Environment.GetEnvironmentVariables();
2✔
46
        var transformer = (source as IHaveATransformer)?.Transformer;
2✔
47
        var validateVariableName = transformer is null 
2✔
48
            ? new Func<string, VariableNameValidationResult>(key => VariableNameValidationResult.Success()) 
×
49
            : transformer.IsAValidVariableName;
2✔
50

51
        return environmentVariables
2✔
52
            .Keys
2✔
53
            .OfType<object>()
2✔
54
            .Select(k => k.ToString())
212✔
55
            .Where(k => validateVariableName(k).Succeeded)
212✔
56
            .Where(environmentVariableFilter)
2✔
57
            .Select(key => new { key, value = environmentVariables[key].ToString() })
106✔
58
            .Aggregate(source, (agg, i) => agg.AddVariable($"{prefix}{i.key}", i.value));
106✔
59
    }
60

61
    /// <summary>
62
    /// Adds all properties from an object
63
    /// </summary>
64
    /// <remarks>
65
    /// Any object properties will be recursively traversed
66
    /// </remarks>
67
    /// <typeparam name="TSelf"></typeparam>
68
    /// <param name="source"></param>
69
    /// <param name="value"></param>
70
    /// <param name="configurator"></param>
71
    /// <returns></returns>
72
    public static TSelf AddVariablesFromObject<TSelf>(this TSelf source, object value, Action<VariablesFromObjectConfiguration> configurator = null)
73
        where TSelf : ICanAddVariables<TSelf>
74
    {        
75
        var configuration = new VariablesFromObjectConfiguration();
4✔
76
        configurator?.Invoke(configuration);
4✔
77

78
        return AddProperties(Guard.IsNotNull(value, nameof(value)), string.Empty);
4✔
79

80
        TSelf AddProperties(object value, string path) => 
81
            value.GetType()
10✔
82
                .GetProperties()
10✔
83
                .Aggregate(source, (agg, property) =>
10✔
84
                {
10✔
85
                    if (IsAPrimitiveType(property.PropertyType))
30✔
86
                    {
10✔
87
                        if (IncludeProperty()) source.AddVariable(MakePath(), property.GetValue(value));
36✔
88
                        return agg;
24✔
89
                    }
10✔
90

10✔
91
                    AddProperties(property.GetValue(value), MakePath());
16✔
92
                    return agg;
16✔
93

10✔
94
                    string MakePath() => 
10✔
95
                        path.Length == 0 ? $"{property.Name}" : $"{path}{configuration.PropertyPathSeparator}{property.Name}";
28✔
96

10✔
97
                    bool IncludeProperty() => 
10✔
98
                        configuration.PropertyFilter == null || configuration.PropertyFilter(new PropertyFilterContext(property, path));
24✔
99
                });
10✔
100

101
        static bool IsAPrimitiveType(Type type) => type.IsPrimitive || type == typeof(string);
20✔
102
    }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc