Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 42 additions & 41 deletions .github/workflows/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,11 @@ on:
- Release

jobs:
prepare:
name: 🧰 Prepare
strategy:
matrix:
os: [ubuntu-22.04, windows-2022] # had to add this due to caching issue
runs-on: ${{ matrix.os }}
prepare_linux:
name: ✨ Prepare Linux Runner
runs-on: ubuntu-22.04
outputs:
restoreCacheKey: ${{ steps.dotnet-restore.outputs.restoreCacheKey }}
testProjects: ${{ steps.test-projects.outputs.result }}
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1
Expand All @@ -50,11 +46,23 @@ jobs:
with:
useRestoreCache: true

- id: test-projects
name: Generate matrix for test projects
uses: codebeltnet/shell-globbing@v1
prepare_windows:
name: ✨ Prepare Windows Runner
runs-on: windows-2022
outputs:
restoreCacheKey: ${{ steps.dotnet-restore.outputs.restoreCacheKey }}
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1

- name: Install .NET
uses: codebeltnet/install-dotnet@v1

- id: dotnet-restore
name: Restore Dependencies
uses: codebeltnet/dotnet-restore@v2
with:
pattern: test/**/*.csproj
useRestoreCache: true

build:
name: 🛠️ Build
Expand All @@ -63,9 +71,10 @@ jobs:
matrix:
configuration: [Debug, Release]
framework: [net8.0, net6.0, netstandard2.1, netstandard2.0]
needs: [prepare]
needs: [prepare_linux]
outputs:
version: ${{ steps.minver-calculate.outputs.version }}
testProjects: ${{ steps.test-projects.outputs.result }}
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1
Expand Down Expand Up @@ -139,15 +148,21 @@ jobs:
projects: ${{ env.PROJECTS }}
configuration: ${{ matrix.configuration }}
framework: ${{ matrix.framework }}
restoreCacheKey: ${{ needs.prepare.outputs.restoreCacheKey }}
restoreCacheKey: ${{ needs.prepare_linux.outputs.restoreCacheKey }}

- id: test-projects
name: Generate matrix for test projects
uses: codebeltnet/shell-globbing@v1
with:
pattern: test/**/*.csproj

pack:
name: 📦 Pack
runs-on: ubuntu-22.04
strategy:
matrix:
configuration: [Debug, Release]
needs: [prepare, build]
needs: [prepare_linux, build]
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1
Expand All @@ -158,18 +173,18 @@ jobs:
configuration: ${{ matrix.configuration }}
uploadPackedArtifact: true
version: ${{ needs.build.outputs.version }}
restoreCacheKey: ${{ needs.prepare.outputs.restoreCacheKey }}
restoreCacheKey: ${{ needs.prepare_linux.outputs.restoreCacheKey }}
downloadBuildArtifact: true

test:
name: 🧪 Test
needs: [prepare, build]
needs: [build, prepare_linux, prepare_windows]
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, windows-2022]
configuration: [Debug, Release]
project: ${{ fromJson(needs.prepare.outputs.testProjects) }}
project: ${{ fromJson(needs.build.outputs.testProjects) }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
Expand Down Expand Up @@ -201,9 +216,9 @@ jobs:
with:
projects: ${{ matrix.project }}
configuration: ${{ matrix.configuration }}
restoreCacheKey: ${{ needs.prepare.outputs.restoreCacheKey }}
restoreCacheKey: ${{ runner.os == 'Linux' && needs.prepare_linux.outputs.restoreCacheKey || needs.prepare_windows.outputs.restoreCacheKey }}
buildSwitches: -p:SkipSignAssembly=true
downloadBuildArtifact: true
level: normal
env:
CONNECTIONSTRINGS__ADVENTUREWORKS: ${{ secrets.DB_ADVENTUREWORKS }}

Expand All @@ -215,7 +230,7 @@ jobs:

sonarcloud:
name: 🔬 Code Quality Analysis
needs: [prepare, build, test]
needs: [prepare_linux, build, test]
runs-on: ubuntu-22.04
steps:
- name: Checkout
Expand All @@ -228,17 +243,10 @@ jobs:
uses: codebeltnet/dotnet-tool-install-sonarscanner@v1

- name: Restore Dependencies
uses: actions/cache/restore@v4
uses: codebeltnet/dotnet-restore@v2
with:
path: |
${{ github.workspace }}/src
${{ github.workspace }}/test
~/.nuget/packages
key: ${{ needs.prepare.outputs.restoreCacheKey }}
restore-keys: |
dotnet-restore-
enableCrossOsArchive: true
fail-on-cache-miss: true
useRestoreCache: true
restoreCacheKey: ${{ needs.prepare_linux.outputs.restoreCacheKey }}

- name: Run SonarCloud Analysis
uses: codebeltnet/sonarcloud-scan@v1
Expand Down Expand Up @@ -275,7 +283,7 @@ jobs:

codeql:
name: 🛡️ Security Analysis
needs: [prepare, build, test]
needs: [prepare_linux, build, test]
runs-on: ubuntu-22.04
steps:
- name: Checkout
Expand All @@ -285,17 +293,10 @@ jobs:
uses: codebeltnet/install-dotnet@v1

- name: Restore Dependencies
uses: actions/cache/restore@v4
uses: codebeltnet/dotnet-restore@v2
with:
path: |
${{ github.workspace }}/src
${{ github.workspace }}/test
~/.nuget/packages
key: ${{ needs.prepare.outputs.restoreCacheKey }}
restore-keys: |
dotnet-restore-
enableCrossOsArchive: true
fail-on-cache-miss: true
useRestoreCache: true
restoreCacheKey: ${{ needs.prepare_linux.outputs.restoreCacheKey }}

- name: Prepare CodeQL SAST Analysis
uses: codebeltnet/codeql-scan@v1
Expand Down
3 changes: 3 additions & 0 deletions .nuget/Cuemon.Extensions.YamlDotNet/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Availability: .NET 8, .NET 6 and .NET Standard 2.0
- REMOVED Support for TFM .NET 7 (STS)
- CHANGED Dependencies to latest and greatest with respect to TFMs

# Bug Fixes
- FIXED YamlFormatter class in the Cuemon.Extensions.YamlDotNet.Formatters namespace to use WithCaseInsensitivePropertyMatching (https://github.com/aaubry/YamlDotNet/discussions/946)

Version 8.3.1
Availability: .NET 8, .NET 7, .NET 6 and .NET Standard 2.0

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ This release was primarily focused on adapting a more modern way of performing C
- Cuemon.Extensions.Xunit.Hosting.AspNetCore.Mvc updated to latest and greatest with respect to TFMs
- Cuemon.Extensions.YamlDotNet updated to latest and greatest with respect to TFMs

### Fixed

- YamlFormatter class in the Cuemon.Extensions.YamlDotNet.Formatters namespace to use WithCaseInsensitivePropertyMatching (https://github.com/aaubry/YamlDotNet/discussions/946)
- Although v16.0.0 of YamlDotNet has breaking changes, this is not reflected in the API from Cuemon.Extensions.YamlDotNet until next major release

### Added

- IWebHostTest interface in the Cuemon.Extensions.Xunit.Hosting.AspNetCore namespace that represents the members needed for ASP.NET Core (including but not limited to MVC, Razor and related) testing
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
# Cuemon for .NET

An open-source project (MIT license) that targets and complements the Microsoft .NET platform. It provides vast ways of possibilities for all breeds of coders, programmers, developers and the likes thereof.
Your ideal companion for .NET 8, .NET 7, .NET 6, .NET Standard 2 and .NET Framework 4.6.2 and newer.
Your ideal companion for .NET 8, .NET 6, .NET Standard 2 and .NET Framework 4.6.2 and newer.

It is, by heart, free, flexible and built to extend and boost your agile codebelt.

## State of the Union

Cuemon for .NET (formerly Cuemon .NET Standard) has been completely refactored and updated to support .NET 8 (LTS), .NET 7 (STS) and .NET 6 (LTS).
Cuemon for .NET (formerly Cuemon .NET Standard) has been completely refactored and updated to support .NET 8 (LTS) and .NET 6 (LTS).

Support for .NET Core 3.0, .NET Core 3.1, .NET 5 and .NET 7 has been deprecated as these are out of [support](https://endoflife.date/dotnet).

Expand Down
16 changes: 8 additions & 8 deletions src/Cuemon.Extensions.YamlDotNet/Converters/YamlConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Cuemon.Extensions.YamlDotNet.Converters
/// </summary>
public abstract class YamlConverter : IYamlTypeConverter
{
internal abstract void WriteYamlCore(IEmitter writer, object value);
internal abstract void WriteYamlCore(IEmitter writer, object value, ObjectSerializer serializer);

internal abstract object ReadYamlCore(IParser reader, Type typeToConvert);
internal abstract object ReadYamlCore(IParser reader, Type typeToConvert, ObjectDeserializer deserializer);

/// <summary>
/// Determines whether this instance can convert the specified object type.
Expand Down Expand Up @@ -43,14 +43,14 @@ bool IYamlTypeConverter.Accepts(Type type)
return CanConvert(type);
}

object IYamlTypeConverter.ReadYaml(IParser parser, Type type)
object IYamlTypeConverter.ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
{
return ReadYamlCore(parser, type);
return ReadYamlCore(parser, type, rootDeserializer);
}

void IYamlTypeConverter.WriteYaml(IEmitter emitter, object value, Type type) // odd decision with type parameter
void IYamlTypeConverter.WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer)
{
WriteYamlCore(emitter, value);
WriteYamlCore(emitter, value, serializer);
}
}

Expand All @@ -76,12 +76,12 @@ public abstract class YamlConverter<T> : YamlConverter
/// <returns>The converted value.</returns>
public abstract T ReadYaml(IParser reader, Type typeToConvert);

internal override object ReadYamlCore(IParser reader, Type typeToConvert)
internal override object ReadYamlCore(IParser reader, Type typeToConvert, ObjectDeserializer deserializer)
{
return ReadYaml(reader, typeToConvert);
}

internal override void WriteYamlCore(IEmitter writer, object value)
internal override void WriteYamlCore(IEmitter writer, object value, ObjectSerializer serializer)
{
WriteYaml(writer, (T)value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="YamlDotNet" Version="15.3.0" />
<PackageReference Include="YamlDotNet" Version="16.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion src/Cuemon.Extensions.YamlDotNet/Formatters/YamlFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ public override object Deserialize(Stream value, Type objectType)
var builder = new DeserializerBuilder()
.WithNamingConvention(Options.Settings.NamingConvention)
.WithEnumNamingConvention(Options.Settings.EnumNamingConvention)
.WithYamlFormatter(Options.Settings.Formatter);
.WithYamlFormatter(Options.Settings.Formatter)
.WithCaseInsensitivePropertyMatching();
if (Options.Settings.ReflectionRules.Flags.HasFlag(BindingFlags.NonPublic))
{
builder.IncludeNonPublicProperties();
Expand Down
5 changes: 3 additions & 2 deletions src/Cuemon.Extensions.YamlDotNet/YamlConverterFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Cuemon.Extensions.YamlDotNet.Converters;
using YamlDotNet.Core;
using YamlDotNet.Serialization;

namespace Cuemon.Extensions.YamlDotNet
{
Expand Down Expand Up @@ -74,13 +75,13 @@ internal DynamicConvertFactory(Func<Type, bool> predicate, Action<IEmitter, obje

private Func<IParser, Type, object> Reader { get; }

internal override void WriteYamlCore(IEmitter writer, object value)
internal override void WriteYamlCore(IEmitter writer, object value, ObjectSerializer serializer)
{
if (Writer == null) { throw new NotImplementedException("Delegate writer is null."); }
Writer.Invoke(writer, value);
}

internal override object ReadYamlCore(IParser reader, Type typeToConvert)
internal override object ReadYamlCore(IParser reader, Type typeToConvert, ObjectDeserializer deserializer)
{
if (Reader == null) { throw new NotImplementedException("Function delegate reader is null."); }
return Reader.Invoke(reader, typeToConvert);
Expand Down
4 changes: 2 additions & 2 deletions test/Cuemon.Data.SqlClient.Tests/SqlDatabaseDependencyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task StartAsync_ShouldReceiveTwoSignalsFromDatabaseWatcher()
command.CommandText = "SELECT * FROM [Person].[ContactType]";
return command.ExecuteReader();

}, o => o.Period = TimeSpan.FromMilliseconds(500)));
}, o => o.Period = TimeSpan.FromMilliseconds(750)));
var sut3 = new DatabaseDependency(sut2);
var sut4 = DateTime.UtcNow;
var sut5 = new List<DateTime>();
Expand Down Expand Up @@ -85,7 +85,7 @@ public async Task StartAsync_ShouldReceiveOnlyOneSignalFromDatabaseWatcher()
command.CommandText = "SELECT * FROM [Person].[ContactType]";
return command.ExecuteReader();

}, o => o.Period = TimeSpan.FromMilliseconds(500)));
}, o => o.Period = TimeSpan.FromMilliseconds(550)));
var sut3 = new DatabaseDependency(sut2, true);
var sut4 = DateTime.UtcNow;
var sut5 = new List<DateTime>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public async void AuthorizationResponseHandler_BasicScheme_ShouldRenderResponseU
TestOutput.WriteLine(content);

Assert.Equal(HttpStatusCode.NotFound, result.StatusCode);

if (sensitivityDetails == FaultSensitivityDetails.All)
{
Assert.Equal("""
Expand Down Expand Up @@ -1090,7 +1090,7 @@ public async void AuthorizationResponseHandler_BasicScheme_VerifyAsyncOptions_Sh
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, bb.Build().ToString());
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "text/plain");

for (var i = 0; i < 14; i++)
for (var i = 0; i < 12; i++)
{
var result = await client.GetAsync("/");
var content = await result.Content.ReadAsStringAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ public void YamlFormatter_ShouldSerializeBookToYaml()
""".ReplaceLineEndings(), yamlString.ReplaceLineEndings());
}

[Fact]
public void YamlFormatter_ShouldDeserializeFromYamlToBook()
{


var book = YamlFormatter.DeserializeObject<Book>("""
title: A
summary: 0
""".ToStream());

Assert.Equal("A", book.Title);
Assert.Equal("0", book.Summary);
}

[Fact]
public void YamlFormatter_ShouldSerializeArgumentOutOfRangeExceptionToYaml()
{
Expand Down Expand Up @@ -110,7 +124,7 @@ Specified arguments x is greater than y.
Actual value was 5 > 1.
stack:
- at Cuemon.Validator.ThrowIfGreaterThan[T](T x, T y, String paramName, String message) *
- at Cuemon.Extensions.YamlDotNet.Formatters.YamlFormatterTest.<>c.<YamlFormatter_ShouldSerializeArgumentOutOfRangeExceptionToYaml>b__3_0() *
- at Cuemon.Extensions.YamlDotNet.Formatters.YamlFormatterTest.<>c.<YamlFormatter_ShouldSerializeArgumentOutOfRangeExceptionToYaml>*
- at Xunit.Assert.RecordException(Action testCode) *
rangeMessage: Specified argument was out of the range of valid values.
paramName: argument
Expand Down Expand Up @@ -141,7 +155,7 @@ Specified arguments x is greater than y. (Parameter 'argument')
Actual value was 5 > 1.
stack:
- at Cuemon.Validator.ThrowIfGreaterThan[T](T x, T y, String paramName, String message) *
- at Cuemon.Extensions.YamlDotNet.Formatters.YamlFormatterTest.<>c.<YamlFormatter_ShouldSerializeArgumentOutOfRangeExceptionToYaml>b__3_0() *
- at Cuemon.Extensions.YamlDotNet.Formatters.YamlFormatterTest.<>c.<YamlFormatter_ShouldSerializeArgumentOutOfRangeExceptionToYaml>*
- at Xunit.Assert.RecordException(Action testCode) *
paramName: argument

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static Task<string> TriggerTransientFaultExceptionAsync(Guid id, Concurre

public static Task<string> TriggerLatencyExceptionAsync(Guid id, ConcurrentDictionary<Guid, int> retryTracker, CancellationToken ct)
{
Thread.Sleep(250);
Thread.Sleep(350);
retryTracker[id] += 1;
throw new HttpRequestException();
}
Expand Down
2 changes: 1 addition & 1 deletion test/Cuemon.Resilience.Tests/TransientOperationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class TransientOperationTest : Test

private const string ExpectedResult = "OK";
private const int ExpectedRetryAttempts = 2;
private static readonly TimeSpan Jitter = TimeSpan.FromMilliseconds(1000);
private static readonly TimeSpan Jitter = TimeSpan.FromSeconds(Generate.RandomNumber(7, 15));
private const int NormalRunIncrement = 1;
private const int DescriptiveExceptionCauseIncrement = 1;
private static readonly TimeSpan ExpectedRecoveryWaitTime = TimeSpan.FromSeconds(1);
Expand Down
Loading