Skip to content

Commit

Permalink
Refactor CSharp version 12 (#21)
Browse files Browse the repository at this point in the history
* Refactor CS12
  • Loading branch information
thohng authored May 31, 2024
1 parent 964d6e1 commit 3a0dda6
Show file tree
Hide file tree
Showing 26 changed files with 108 additions and 125 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# All files
[*]
indent_style = space
spelling_languages = en-us
spelling_exclusion_path = .\exclusion.dic

# Xml files
[{*.xml,*.csproj,*.props,*.targets}]
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<!-- Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>

<LangVersion>11.0</LangVersion>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions NetLah.SpaServices.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Build.targets = Directory.Build.targets
docker-build.ps1 = docker-build.ps1
docker-compose.yml = docker-compose.yml
exclusion.dic = exclusion.dic
README.md = README.md
EndProjectSection
EndProject
Expand Down
13 changes: 13 additions & 0 deletions exclusion.dic
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
buildtime
ffff
fffff
ffffff
fffffff
fffzzz
healthz
hsts
subpath
testhost
urls
yaml
yyyy
16 changes: 11 additions & 5 deletions src/Hosting/AppFileVersionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@

namespace NetLah.Extensions.SpaServices.Hosting;

internal class AppFileVersionParser
internal partial class AppFileVersionParser
{
private static readonly Regex KeyValueRegex = new("^\\s*(?<key>app|version|buildTime|description)\\s*:(?<value>.{1,100})$",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
#if NET7_0_OR_GREATER
private static readonly Regex KeyValueRegex = KeyValueRegexClass();

[GeneratedRegex("^\\s*(?<key>app|version|buildTime|description)\\s*:(?<value>.{1,100})$", RegexOptions.IgnoreCase | RegexOptions.Compiled, "en-US")]
private static partial Regex KeyValueRegexClass();
#else
private static readonly Regex KeyValueRegex = new("^\\s*(?<key>app|version|buildTime|description)\\s*:(?<value>.{1,100})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
#endif

#pragma warning disable CA1822 // Mark members as static
public AppFileVersionInfo? Parse(TextReader reader)
Expand All @@ -22,8 +28,8 @@ internal class AppFileVersionParser
{
if (!string.IsNullOrWhiteSpace(line))
{
if (line.IndexOf(":") is { } index &&
index > 0 &&
var index = line.IndexOf(':');
if (index > 0 &&
KeyValueRegex.Match(line) is { } m &&
m.Success)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace NetLah.Extensions.SpaServices.Hosting;

internal static class AppFileVersionParserExentions
internal static class AppFileVersionParserExtensions
{
public static AppFileVersionInfo? ParseFolder(this AppFileVersionParser parser, string folderName)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Hosting/ApplicationInsightsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ public static class ApplicationInsightsExtensions

public static WebApplicationBuilder CustomApplicationInsightsTelemetry(this WebApplicationBuilder builder, Func<TokenCredential> tokenCredentialFactory, ILogger? logger = null)
{
bool isDisabled = builder.Configuration.GetValue<bool>("ApplicationInsights:IsDisabled");
var isDisabled = builder.Configuration.GetValue<bool>("ApplicationInsights:IsDisabled");
if (!isDisabled)
{
logger ??= _loggerLazy.Value!;
logger?.LogDebug("ApplicationInsights configured");
builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);

string? apiKey = builder.Configuration["ApplicationInsights:AuthenticationApiKey"];
var apiKey = builder.Configuration["ApplicationInsights:AuthenticationApiKey"];
if (!string.IsNullOrEmpty(apiKey))
{
logger?.LogDebug("ApplicationInsights Live Metrics with AuthenticationApiKey");
builder.Services.ConfigureTelemetryModule<QuickPulseTelemetryModule>((module, opt) => module.AuthenticationApiKey = apiKey);
}
else
{
bool isEnabledLiveMetrics = builder.Configuration.GetValue<bool>("ApplicationInsights:IsEnabledLiveMetrics");
var isEnabledLiveMetrics = builder.Configuration.GetValue<bool>("ApplicationInsights:IsEnabledLiveMetrics");
if (isEnabledLiveMetrics)
{
logger?.LogDebug("ApplicationInsights Live Metrics with Azure AD");
Expand Down
4 changes: 2 additions & 2 deletions src/Hosting/BuildTimeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal static class BuildTimeHelper
public static DateTimeOffset? ParseBuildTime(string? value)
=> !string.IsNullOrEmpty(value) &&
DateTimeOffset.TryParseExact(value,
new string[] {
[
"yyyy-MM-ddTHH:mm:ss.fffffff", "yyyy-MM-ddTHH:mm:ss.fffffffZ",
"yyyy-MM-ddTHH:mm:ss.fff", "yyyy-MM-ddTHH:mm:ss.fffZ",

Expand All @@ -18,7 +18,7 @@ internal static class BuildTimeHelper
"yyyy-MM-ddTHH:mm:ss.ffff", "yyyy-MM-ddTHH:mm:ss.ffffZ",
"yyyy-MM-ddTHH:mm:ss.fffff", "yyyy-MM-ddTHH:mm:ss.fffffZ",
"yyyy-MM-ddTHH:mm:ss.ffffff", "yyyy-MM-ddTHH:mm:ss.ffffffZ"
},
],
CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var result) ?
result :
null;
Expand Down
9 changes: 2 additions & 7 deletions src/Hosting/Controllers/GeneralController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ namespace NetLah.Extensions.SpaServices.Hosting.Controllers;
//[Route("api/v1/[controller]/[action]")]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[ApiExplorerSettings(IgnoreApi = true)]
public class GeneralController : ControllerBase
public class GeneralController(IAppInfo appInfo) : ControllerBase
{
private readonly IAppInfo _appInfo;

public GeneralController(IAppInfo appInfo)
{
_appInfo = appInfo;
}
private readonly IAppInfo _appInfo = appInfo;

public string Version() => _appInfo.Version;

Expand Down
20 changes: 5 additions & 15 deletions src/Hosting/DecoratorAndExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,26 @@ public interface IDecorator<out TService>
TService Instance { get; }
}

internal class Decorator<TService> : IDecorator<TService>
internal class Decorator<TService>(TService instance) : IDecorator<TService>
{
public TService Instance { get; }

public Decorator(TService instance)
{
Instance = instance;
}
public TService Instance { get; } = instance;
}

internal class Decorator<TService, TImplementation> : Decorator<TService>
internal class Decorator<TService, TImplementation>(TImplementation instance) : Decorator<TService>(instance)
where TImplementation : class, TService
{
public Decorator(TImplementation instance) : base(instance) { }
}

internal sealed class DisposableDecorator<TService> : Decorator<TService>, IDisposable
internal sealed class DisposableDecorator<TService>(TService instance) : Decorator<TService>(instance), IDisposable
{
public DisposableDecorator(TService instance) : base(instance) { }

public void Dispose()
{
(Instance as IDisposable)?.Dispose();
}
}

internal sealed class AsyncDisposableDecorator<TService> : Decorator<TService>, IAsyncDisposable
internal sealed class AsyncDisposableDecorator<TService>(TService instance) : Decorator<TService>(instance), IAsyncDisposable
{
public AsyncDisposableDecorator(TService instance) : base(instance) { }

public ValueTask DisposeAsync()
{
return Instance is IAsyncDisposable asyncDisposable ? asyncDisposable.DisposeAsync() : ValueTask.CompletedTask;
Expand Down
6 changes: 3 additions & 3 deletions src/Hosting/InfoCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace NetLah.Extensions.SpaServices.Hosting;

public class InfoCollector : IInfoCollector
{
public List<string> Logs { get; } = new List<string>();
public List<string> Logs { get; } = [];

public IInfoCollector Add<T>(string key, T value)
{
Expand All @@ -24,8 +24,8 @@ public static IInfoCollector CreateInstance(IWebHostEnvironment env, IAppInfo ap
.Add("HostFramework", appInfo.HostFrameworkName)
.Add("HostBuildTime", appInfo.HostBuildTimestampLocal)
.Add("Environment", env.EnvironmentName)
.Add("Timezone", TimeZoneInfo.Local)
.Add("TimezoneSG", TimeZoneLocalHelper.GetSingaporeOrCustomTimeZone())
.Add("TimeZone", TimeZoneInfo.Local)
.Add("TimeZoneSG", TimeZoneLocalHelper.GetSingaporeOrCustomTimeZone())
.Add("ContentRootPath", env.ContentRootPath)
.Add("RootPath (PWD)", Directory.GetCurrentDirectory())
.Add("BaseDirectory", AppDomain.CurrentDomain.BaseDirectory)
Expand Down
13 changes: 4 additions & 9 deletions src/Hosting/MountSpaStaticFileProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

namespace NetLah.Extensions.SpaServices.Hosting;

internal class MountSpaStaticFileProvider : ISpaStaticFileProvider
internal class MountSpaStaticFileProvider(IDecorator<ISpaStaticFileProvider> decorator, MountFileProviderOptions options) : ISpaStaticFileProvider
{
public MountSpaStaticFileProvider(IDecorator<ISpaStaticFileProvider> decorator, MountFileProviderOptions options)
{
FileProvider = decorator.Instance.FileProvider == null
? decorator.Instance.FileProvider
: new MountFileProvider(decorator.Instance.FileProvider, options);
}

public IFileProvider? FileProvider { get; }
public IFileProvider? FileProvider { get; } = decorator.Instance.FileProvider == null
? decorator.Instance.FileProvider
: new MountFileProvider(decorator.Instance.FileProvider, options);
}
8 changes: 4 additions & 4 deletions src/Hosting/ResponseHeadersHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ResponseHeadersHandler(ILogger logger, ResponseHeadersOptions responseHea
.Select(kv => new KeyValuePair<string, StringValues>(kv.Key, new StringValues(kv.Value)))
.ToList();

if (!responseHeaders.IsEnabled || !_headers.Any())
if (!responseHeaders.IsEnabled || _headers.Count == 0)
{
_matchStatusCode = _ => false;
_matchContentType = _ => false;
Expand All @@ -30,9 +30,9 @@ public ResponseHeadersHandler(ILogger logger, ResponseHeadersOptions responseHea
else
{
if (responseHeaders.FilterHttpStatusCode is { } listHttpStatusCode
&& listHttpStatusCode.Any())
&& listHttpStatusCode.Count != 0)
{
_statusCodes = listHttpStatusCode.ToHashSet();
_statusCodes = [.. listHttpStatusCode];
_matchStatusCode = statusCode => _statusCodes.Contains(statusCode);
logger.LogInformation("ResponseHeadersHandler StatusCode in list");
}
Expand All @@ -51,7 +51,7 @@ public ResponseHeadersHandler(ILogger logger, ResponseHeadersOptions responseHea
else
{
_contentTypeHashSet = listContentType.ToHashSet(StringComparer.InvariantCultureIgnoreCase);
_contentTypeList = _contentTypeHashSet.ToList();
_contentTypeList = [.. _contentTypeHashSet];

if (responseHeaders.IsContentTypeContainsMatch)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Hosting/ResponseHeadersOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class ResponseHeadersOptions

public bool IsAnyContentType { get; set; } = false;

public Dictionary<string, string?> Headers { get; set; } = new Dictionary<string, string?>();
public Dictionary<string, string?> Headers { get; set; } = [];

public List<string?>? FilterContentType { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/Hosting/WebApplicationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Builder;

public static class WebApplicationExtensions
{
private static readonly string[] DefaultHttpMethods = new[] { "GET" };
private static readonly string[] DefaultHttpMethods = ["GET"];

public static WebApplication UseSpaApp(this WebApplication app, ILogger? logger = null, Action<WebApplication>? action = null)
{
Expand Down
8 changes: 1 addition & 7 deletions test/Hosting.Test/AppFileVersionParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ public void ParseStreamSuccess()
{
var stream = TestHelper.GetEmbeddedResourceStream("public1..version");

#pragma warning disable CS8604 // Possible null reference argument.
var appFileVersionInfo = new AppFileVersionParser().ParseStream(stream);
#pragma warning restore CS8604 // Possible null reference argument.
var appFileVersionInfo = new AppFileVersionParser().ParseStream(stream!);

TestHelper.AssertPublic1_Version(appFileVersionInfo);
}
Expand All @@ -34,11 +32,7 @@ public void ParseStreamSuccess()
public void ParseSuccess2()
{
var fileContent = TestHelper.GetEmbeddedTemplateContent("public1..version");

#pragma warning disable CS8604 // Possible null reference argument.
var appFileVersionInfo = new AppFileVersionParser().Parse(fileContent);
#pragma warning restore CS8604 // Possible null reference argument.

TestHelper.AssertPublic1_Version(appFileVersionInfo);
}

Expand Down
70 changes: 36 additions & 34 deletions test/Hosting.Test/BuildTimeHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,45 @@

public class BuildTimeHelperTest
{
public static IEnumerable<object?[]> DateTimeFormats =>
new List<object?[]>
public class TestData : TheoryData<string, DateTimeOffset?>
{
public TestData()
{
new object?[] { "2021-05-08T05:25:59", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.1", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 100, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.1Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 100, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.12", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 120, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.12Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 120, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.123", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 123, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.123Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 123, TimeSpan.Zero) },
new object?[] { "2021-05-08T05:25:59.1234", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.4D)) },
new object?[] { "2021-05-08T05:25:59.1234Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.4D)) },
new object?[] { "2021-05-08T05:25:59.12345", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.45D)) },
new object?[] { "2021-05-08T05:25:59.12345Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.45D)) },
new object?[] { "2021-05-08T05:25:59.123456", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.456D)) },
new object?[] { "2021-05-08T05:25:59.123456Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.456D)) },
new object?[] { "2021-05-08T05:25:59.1234567", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.4567D)) },
new object?[] { "2021-05-08T05:25:59.1234567Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds( 123.4567D)) },
new object?[] { "2021-05-08T05:25:59:1", null },
new object?[] { "2021-05-08T05:25:59:1Z", null },
new object?[] { "2021-05-08T05:25:59:12", null },
new object?[] { "2021-05-08T05:25:59:12Z", null },
new object?[] { "2021-05-08T05:25:59:123", null },
new object?[] { "2021-05-08T05:25:59:123Z", null },
new object?[] { "2021-05-08T05:25:59:1234", null },
new object?[] { "2021-05-08T05:25:59:1234Z", null },
new object?[] { "2021-05-08T05:25:59:12345", null },
new object?[] { "2021-05-08T05:25:59:12345Z", null },
new object?[] { "2021-05-08T05:25:59:123456", null },
new object?[] { "2021-05-08T05:25:59:123456Z", null },
new object?[] { "2021-05-08T05:25:59:1234567", null },
new object?[] { "2021-05-08T05:25:59:1234567Z", null },
};
Add("2021-05-08T05:25:59", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero));
Add("2021-05-08T05:25:59Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero));
Add("2021-05-08T05:25:59.1", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 100, TimeSpan.Zero));
Add("2021-05-08T05:25:59.1Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 100, TimeSpan.Zero));
Add("2021-05-08T05:25:59.12", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 120, TimeSpan.Zero));
Add("2021-05-08T05:25:59.12Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 120, TimeSpan.Zero));
Add("2021-05-08T05:25:59.123", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 123, TimeSpan.Zero));
Add("2021-05-08T05:25:59.123Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, 123, TimeSpan.Zero));
Add("2021-05-08T05:25:59.1234", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.4D)));
Add("2021-05-08T05:25:59.1234Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.4D)));
Add("2021-05-08T05:25:59.12345", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.45D)));
Add("2021-05-08T05:25:59.12345Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.45D)));
Add("2021-05-08T05:25:59.123456", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.456D)));
Add("2021-05-08T05:25:59.123456Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.456D)));
Add("2021-05-08T05:25:59.1234567", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.4567D)));
Add("2021-05-08T05:25:59.1234567Z", new DateTimeOffset(2021, 5, 8, 5, 25, 59, TimeSpan.Zero).Add(TimeSpan.FromMilliseconds(123.4567D)));
Add("2021-05-08T05:25:59:1", null);
Add("2021-05-08T05:25:59:1Z", null);
Add("2021-05-08T05:25:59:12", null);
Add("2021-05-08T05:25:59:12Z", null);
Add("2021-05-08T05:25:59:123", null);
Add("2021-05-08T05:25:59:123Z", null);
Add("2021-05-08T05:25:59:1234", null);
Add("2021-05-08T05:25:59:1234Z", null);
Add("2021-05-08T05:25:59:12345", null);
Add("2021-05-08T05:25:59:12345Z", null);
Add("2021-05-08T05:25:59:123456", null);
Add("2021-05-08T05:25:59:123456Z", null);
Add("2021-05-08T05:25:59:1234567", null);
Add("2021-05-08T05:25:59:1234567Z", null);
}
}

[Theory]
[MemberData(nameof(DateTimeFormats))]
[ClassData(typeof(TestData))]
public void ParseDateTimeUtcToDateTimeOffsetSuccess(string value, DateTimeOffset? expected)
{
var buildTime = BuildTimeHelper.ParseBuildTime(value);
Expand Down
7 changes: 2 additions & 5 deletions test/WebApp.Test/BasePagesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

namespace WebApp.Test;

public abstract class BasePagesTest<TEntryPoint> where TEntryPoint : class
public abstract class BasePagesTest<TEntryPoint>(WebApplicationFactory<TEntryPoint> factory) where TEntryPoint : class
{
protected readonly HttpClient _client;

protected BasePagesTest(WebApplicationFactory<TEntryPoint> factory)
=> _client = factory.CreateClientNoAutoRedirect();
protected readonly HttpClient _client = factory.CreateClientNoAutoRedirect();

protected Task AssertIndexHtmlNotFoundAsync(string url) => TestHelper.AssertIndexHtmlNotFoundAsync(_client, url);

Expand Down
4 changes: 2 additions & 2 deletions test/WebApp.Test/GeneralControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ public async Task GeneralSysUrl()
Assert.Contains("HostFramework: ", content);
Assert.Contains("HostBuildTime: ", content);
Assert.Contains("Environment: Testing", content);
Assert.Contains("Timezone: ", content);
Assert.Contains("TimezoneSG: ", content);
Assert.Contains("TimeZone: ", content);
Assert.Contains("TimeZoneSG: ", content);
Assert.Contains("ContentRootPath: ", content);
Assert.Contains("RootPath (PWD): ", content);
Assert.Contains("BaseDirectory: ", content);
Expand Down
Loading

0 comments on commit 3a0dda6

Please sign in to comment.