< Summary - Helper.Tests

Information
Class: Configuration.Helper.SettingsStoreBase
Assembly: Configuration.Helper
File(s): D:\a\NuGetPackages\NuGetPackages\src\Helper\Configuration.Helper\SettingsStore\SettingsStoreBase.cs
Tag: 3_8508158812
Line coverage
100%
Covered lines: 93
Uncovered lines: 0
Coverable lines: 93
Total lines: 198
Line coverage: 100%
Branch coverage
87%
Covered branches: 35
Total branches: 40
Branch coverage: 87.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Location()100%11100%
get_Sections()100%11100%
get_IsInitialized()100%11100%
get_AppSettings()100%11100%
get_ConnectionStrings()100%11100%
get_Source()100%11100%
AddSetting(...)100%11100%
GetSection(...)100%66100%
GetSetting(...)100%11100%
.ctor()100%11100%
ProcessSetting(...)83.33%66100%
ProcessSetting(...)71.42%1414100%
AddSetting(...)100%44100%
LoadFromStream(...)100%1010100%

File(s)

D:\a\NuGetPackages\NuGetPackages\src\Helper\Configuration.Helper\SettingsStore\SettingsStoreBase.cs

#LineLine coverage
 1using System.Xml.Linq;
 2using System.Text.Json;
 3
 4namespace Configuration.Helper;
 5
 6/// <summary>Base class for Settings Store implementations.</summary>
 7public abstract class SettingsStoreBase : ISettingsStore
 8{
 9  #region ISettingsStore Implementation
 10
 11  #region Properties
 12
 13  /// <inheritdoc />
 6114  public string Location { get; protected set; }
 15
 16  /// <inheritdoc />
 12817  public IDictionary<string, SettingsSection> Sections { get; }
 18
 19  /// <inheritdoc />
 4020  public bool IsInitialized { get; protected set; }
 21
 22  /// <inheritdoc />
 623  public ISettingsSection AppSettings => GetSection( cAppSettings );
 24
 25  /// <inheritdoc />
 126  public ISettingsSection ConnectionStrings => GetSection( cConnections );
 27
 28  /// <inheritdoc />
 2429  public IOHelper.PathType Source { get; protected set; }
 30
 31  #endregion
 32
 33  #region Methods
 34
 35  /// <inheritdoc />
 36  public bool AddSetting( string settingKey, string settingValue )
 337  {
 38    // Add the setting value to the AppSettings section
 339    string section = cAppSettings;
 340    AddSetting( ref section, settingKey, settingValue );
 341    return true;
 342  }
 43
 44  /// <inheritdoc />
 45  public ISettingsSection GetSection( string? sectionName )
 1346  {
 47    // Check the required parameter is supplied
 48    const string cMethod = @"SettingsStoreBase.GetSection";
 1549    if( null == sectionName ) { throw new ArgumentNullException( nameof( sectionName ), cMethod ); }
 1250    sectionName = sectionName.Trim();
 1451    if( sectionName.Length == 0 ) { throw new ArgumentException( cMethod, nameof( sectionName ) ); }
 52
 53    // Return the section if it exists
 2754    if( Sections.TryGetValue( sectionName, out SettingsSection? value ) ) { return value; }
 55
 56    // Return a new section if not found
 357    SettingsSection retValue = new( _comparer );
 358    Sections.Add( sectionName, retValue );
 359    return retValue;
 1160  }
 61
 62  /// <inheritdoc />
 63  public string GetSetting( string settingKey )
 164  {
 165    return AppSettings.GetSetting( settingKey );
 166  }
 67
 68  #endregion
 69
 70  #endregion
 71
 72  /// <summary>Configuration settings file extension.</summary>
 4073  protected string fileExtension = string.Empty;
 74
 75  #region Constants and Protected Constructor
 76
 77  private const string cAppSettings = @"appSettings"; // Application settings section name
 78  private const string cAppSettingKey = @"key"; // Application setting key name
 79  private const string cConnections = @"connectionStrings"; // Connection strings section name
 80  private const string cConnectionKey = @"name"; // Connection string key name
 4081  private readonly StringComparer _comparer = StringComparer.CurrentCultureIgnoreCase;
 82
 83  /// <summary>Default constructor.</summary>
 4084  protected SettingsStoreBase()
 4085  {
 4086    Location = string.Empty;
 4087    Sections = new Dictionary<string, SettingsSection>( _comparer )
 4088    {
 4089      // Add the standard sections
 4090      {cAppSettings, new SettingsSection( _comparer )},
 4091      {cConnections, new SettingsSection( _comparer )}
 4092    };
 4093  }
 94
 95  #endregion
 96
 97  #region Private Methods
 98
 99  private void ProcessSetting( JsonElement element, string sectionName )
 6100  {
 6101    if( element.ValueKind != JsonValueKind.Object ) return;
 102
 38103    foreach( JsonProperty item in element.EnumerateObject() )
 10104    {
 10105      string? val = item.Value.GetString();
 10106      AddSetting( ref sectionName, item.Name, val ?? string.Empty );
 10107    }
 6108  }
 109
 110  private void ProcessSetting( XElement elem )
 83111  {
 112    // The element must have a parent section
 83113    if( null == elem || null == elem.Parent ) { return; }
 83114    string sectionName = elem.Parent.Name.LocalName;
 115
 116    // Check for application setting
 83117    XAttribute? settingKey = elem.Attribute( cAppSettingKey ) ?? elem.Attribute( cConnectionKey );
 118
 119    // Get the setting value
 83120    XAttribute? settingVal = ( settingKey?.Name.LocalName ) switch
 83121    {
 19122      cConnectionKey => elem.Attribute( @"connectionString" ),
 64123      _ => elem.Attribute( @"value" ),
 83124    };
 125
 83126    if( null != settingVal && null != settingKey )
 83127    {
 128      // Add the value to the section
 83129      AddSetting( ref sectionName, settingKey.Value, settingVal.Value );
 83130    }
 83131  }
 132
 133  private void AddSetting( ref string sectionName, string settingKey, string settingVal )
 96134  {
 135    // Try getting existing section
 96136    SettingsSection? section = Sections.TryGetValue( sectionName, out SettingsSection? value ) ? value : null;
 137
 96138    if( null == section )
 18139    {
 140      // Create a new section
 18141      section = new SettingsSection( _comparer );
 18142      Sections.Add( sectionName, section );
 18143    }
 144
 145    // Add the setting
 96146    section.AddSetting( settingKey, settingVal );
 96147  }
 148
 149  #endregion
 150
 151  #region Protected Methods
 152
 153  /// <summary>Initializes the Setting Store object.</summary>
 154  /// <param name="config">String containing the configuration file contents.</param>
 155  /// <exception cref="ArgumentException">Thrown if the parameter is null or empty.</exception>
 156  /// <exception cref="JsonException">The JSON text to parse does not represent a valid single JSON value.</exception>
 157  protected void LoadFromStream( ref string config )
 24158  {
 159    // Check the required parameter is supplied
 160    const string cMethod = @"SettingsStoreBase.LoadFromStream";
 161
 162    // Check the required parameter has a value
 26163    if( string.IsNullOrWhiteSpace( config ) ) { throw new ArgumentException( cMethod, nameof( config ) ); }
 23164    config = config.Trim();
 165
 23166    if( ConfigFileHelper.cJsonExtension.Equals( fileExtension, StringComparison.CurrentCultureIgnoreCase ) )
 4167    {
 168      // Convert the string to JSON
 4169      using JsonDocument doc = JsonDocument.Parse( config, new JsonDocumentOptions
 4170        { AllowTrailingCommas = true, MaxDepth = 2 } );
 2171      {
 2172        JsonElement root = doc.RootElement;
 2173        if( root.ValueKind == JsonValueKind.Object )
 2174        {
 175          // find name of section
 18176          foreach( JsonProperty element in root.EnumerateObject() )
 6177          {
 6178            string section = element.Name;
 6179            ProcessSetting( element.Value, section );
 6180          }
 2181        }
 2182      }
 2183    }
 184    else
 19185    {
 186      // Convert the string to XML
 19187      XElement xml = XElement.Parse( config );
 188
 189      // Process each configuration settings
 223190      foreach( XElement elem in xml.Descendants( @"add" ) )
 83191      {
 83192        ProcessSetting( elem );
 83193      }
 19194    }
 21195  }
 196
 197  #endregion
 198}