From fe8f57e2a99545bd913cb97c1743d8c00468b594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Sat, 11 May 2024 12:40:17 +0200 Subject: [PATCH 01/15] feat: Created Solution File --- .github/template-sync.yml | 34 -------------------- .github/workflows/cicd.yml | 2 +- .github/workflows/template-sync.yml | 24 -------------- Extensions.Logging.XUnit.sln | 32 ++++++++++++++++++ new-project.ps1 | 2 +- new-solution.ps1 | 19 ----------- src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs | 21 ++++++++++++ 7 files changed, 55 insertions(+), 79 deletions(-) delete mode 100644 .github/template-sync.yml delete mode 100644 .github/workflows/template-sync.yml create mode 100644 Extensions.Logging.XUnit.sln delete mode 100644 new-solution.ps1 create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs diff --git a/.github/template-sync.yml b/.github/template-sync.yml deleted file mode 100644 index 982577b..0000000 --- a/.github/template-sync.yml +++ /dev/null @@ -1,34 +0,0 @@ -additional: - - analyzer - - arguments - - article.benchmarks - - editorconfig - - equaduct - - extensions.hosting.winforms - - extensions.logging.measurement - - extensions.logging.xunit - - extensions.strings - - extensions.tasks - - extensions.test - - guard - - healthchecks - - http.correlation - - sequentialguid - -files: - - "!**/*" - - ".editorconfig" - - ".gitattributes" - - ".gitignore" - - ".github/CODEOWNERS" - - ".github/dependabot.yml" - - ".github/FUNDING.yml" - - ".github/release-drafter.yml" - - ".github/ISSUE_TEMPLATE/**/*" - - ".github/PULL_REQUEST_TEMPLATE/**/*" - - ".github/workflows/update-license.yml" - - # you probably want to exclude these files: - - "!.github/workflows/dependabot-merge.yml" - - "!.github/workflows/template-sync.yml" - - "!.github/template-sync.yml" diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 39026ab..233dff7 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -28,5 +28,5 @@ jobs: dotnet-logging: ${{ inputs.dotnet-logging }} dotnet-version: | 8.x - solution: ###SOLUTION### + solution: ./Extensions.Logging.XUnit.sln secrets: inherit diff --git a/.github/workflows/template-sync.yml b/.github/workflows/template-sync.yml deleted file mode 100644 index 3d0acf1..0000000 --- a/.github/workflows/template-sync.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Update template files - -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_dispatch: - -jobs: - template-sync: - if: github.actor != 'dependabot[bot]' && github.repository == 'dailydevops/dotnet-template' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: ahmadnassri/action-template-repository-sync@v2.6.0 - with: - github-token: ${{ secrets.TEMPLATE_SYNC }} - dry-run: false - skip-ci: true diff --git a/Extensions.Logging.XUnit.sln b/Extensions.Logging.XUnit.sln new file mode 100644 index 0000000..2d58042 --- /dev/null +++ b/Extensions.Logging.XUnit.sln @@ -0,0 +1,32 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D9954CB8-DB50-4331-A461-36A4AD4DA06E}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .filenesting.json = .filenesting.json + .gitattributes = .gitattributes + .gitignore = .gitignore + .gitmodules = .gitmodules + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + Directory.Packages.props = Directory.Packages.props + Directory.Solution.props = Directory.Solution.props + GitVersion.yml = GitVersion.yml + LICENSE = LICENSE + new-project.ps1 = new-project.ps1 + nuget.config = nuget.config + README.md = README.md + update-solution.ps1 = update-solution.ps1 + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/new-project.ps1 b/new-project.ps1 index fe28792..e3b7884 100644 --- a/new-project.ps1 +++ b/new-project.ps1 @@ -49,7 +49,7 @@ New-Project ` -DisableTests $DisableTests ` -DisableUnitTests $DisableUnitTests ` -DisableIntegrationTests $DisableIntegrationTests ` - -SolutionFile "###SOLUTION###" ` + -SolutionFile "./Extensions.Logging.XUnit.sln" ` -OutputDirectory (Get-Location) ` -EnableProjectGrouping $EnableProjectGrouping ` -DisableArchitectureTests $DisableArchitectureTests diff --git a/new-solution.ps1 b/new-solution.ps1 deleted file mode 100644 index d517277..0000000 --- a/new-solution.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -[CmdletBinding()] -param ( - # Name of the solution to be created. - [Parameter(Mandatory = $true)] - [string] - $SolutionName -) - -Write-Output "Updating submodules ..." -git submodule update --init --recursive --remote | Out-Null - -Write-Output "Creating $SolutionName.sln ..." -$location = Get-Location -. .\eng\scripts\new-solution.ps1 - -New-Solution -SolutionName $SolutionName -Output $location -Remove-Item -Path "$location\new-solution.ps1" -Force -Remove-Item -Path "$location\.github\template-sync.yml" -Force -Remove-Item -Path "$location\.github\workflows\template-sync.yml" -Force diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs new file mode 100644 index 0000000..3c1f9be --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs @@ -0,0 +1,21 @@ +namespace NetEvolve.Logging.XUnit; + +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +public sealed class XUnitLogger : XUnitLogger, ILogger +{ + internal XUnitLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider, + XUnitLoggerOptions? options + ) + : base(testOutputHelper, scopeProvider, typeof(T).FullName, options) { } + + internal XUnitLogger( + IMessageSink messageSink, + IExternalScopeProvider? scopeProvider, + XUnitLoggerOptions? options + ) + : base(messageSink, scopeProvider, typeof(T).FullName, options) { } +} From 4a300b517d3268fd0df276fa4f7cf34221c42037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Sat, 11 May 2024 12:47:02 +0200 Subject: [PATCH 02/15] chore: Created projects --- Directory.Packages.props | 16 ++++++---- Extensions.Logging.XUnit.sln | 31 ++++++++++++++++++- .../Class1.cs | 3 ++ .../NetEvolve.Extensions.Logging.XUni.csproj | 7 +++++ .../README.md | 1 + ...ions.Logging.XUni.Tests.Integration.csproj | 28 +++++++++++++++++ .../UnitTest1.cs | 6 ++++ ....Extensions.Logging.XUni.Tests.Unit.csproj | 28 +++++++++++++++++ .../UnitTest1.cs | 6 ++++ 9 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 src/NetEvolve.Extensions.Logging.XUni/Class1.cs create mode 100644 src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj create mode 100644 src/NetEvolve.Extensions.Logging.XUni/README.md create mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj create mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs create mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj create mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 78f453b..478d49a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,18 +1,22 @@ - true true - - + - - + + + + + + + + + - diff --git a/Extensions.Logging.XUnit.sln b/Extensions.Logging.XUnit.sln index 2d58042..9c8724e 100644 --- a/Extensions.Logging.XUnit.sln +++ b/Extensions.Logging.XUnit.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 @@ -21,6 +21,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution update-solution.ps1 = update-solution.ps1 EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EFE8181B-6FAB-4E04-BD9B-557C1286B858}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni", "src\NetEvolve.Extensions.Logging.XUni\NetEvolve.Extensions.Logging.XUni.csproj", "{20C3A39A-E7BA-4189-8064-11F2555A0ABF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BD750CCE-0318-424D-89B4-9C66EF329E96}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni.Tests.Unit", "tests\NetEvolve.Extensions.Logging.XUni.Tests.Unit\NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj", "{6211ACA9-9A91-4218-8B4B-E94F91796B58}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni.Tests.Integration", "tests\NetEvolve.Extensions.Logging.XUni.Tests.Integration\NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj", "{FFF70EC4-D0FD-4D73-8599-7FF442133436}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -29,4 +39,23 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Release|Any CPU.Build.0 = Release|Any CPU + {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Release|Any CPU.Build.0 = Release|Any CPU + {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {20C3A39A-E7BA-4189-8064-11F2555A0ABF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} + {6211ACA9-9A91-4218-8B4B-E94F91796B58} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + {FFF70EC4-D0FD-4D73-8599-7FF442133436} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + EndGlobalSection EndGlobal diff --git a/src/NetEvolve.Extensions.Logging.XUni/Class1.cs b/src/NetEvolve.Extensions.Logging.XUni/Class1.cs new file mode 100644 index 0000000..2c15727 --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUni/Class1.cs @@ -0,0 +1,3 @@ +namespace NetEvolve.Extensions.Logging.XUni; + +public class Class1 { } diff --git a/src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj b/src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj new file mode 100644 index 0000000..8268829 --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj @@ -0,0 +1,7 @@ + + + + net7.0 + + + diff --git a/src/NetEvolve.Extensions.Logging.XUni/README.md b/src/NetEvolve.Extensions.Logging.XUni/README.md new file mode 100644 index 0000000..570f4e7 --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUni/README.md @@ -0,0 +1 @@ +Please give the customer a brief introduction about this library, and how to use it. diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj new file mode 100644 index 0000000..7d823c0 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj @@ -0,0 +1,28 @@ + + + + net7.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs new file mode 100644 index 0000000..e7294b7 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs @@ -0,0 +1,6 @@ +namespace NetEvolve.Extensions.Logging.XUni.Tests.Integration; + +public class UnitTest1 +{ + public void Test1() { } +} diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj new file mode 100644 index 0000000..7d823c0 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj @@ -0,0 +1,28 @@ + + + + net7.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs new file mode 100644 index 0000000..d77f42a --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs @@ -0,0 +1,6 @@ +namespace NetEvolve.Extensions.Logging.XUni.Tests.Unit; + +public class UnitTest1 +{ + public void Test1() { } +} From 6abedf87b7aa711fcf083a209704ba026f873387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Sat, 11 May 2024 12:48:46 +0200 Subject: [PATCH 03/15] fix: Renamed project typo --- Extensions.Logging.XUnit.sln | 52 ++++++++++++++----- .../Class1.cs | 3 -- .../Class1.cs | 3 ++ ...NetEvolve.Extensions.Logging.XUnit.csproj} | 2 + .../README.md | 0 .../UnitTest1.cs | 6 --- .../UnitTest1.cs | 6 --- .../GlobalUsings.cs | 1 + ...ns.Logging.XUnit.Tests.Integration.csproj} | 2 +- .../UnitTest1.cs | 7 +++ .../GlobalUsings.cs | 1 + ...xtensions.Logging.XUnit.Tests.Unit.csproj} | 2 +- .../UnitTest1.cs | 7 +++ 13 files changed, 63 insertions(+), 29 deletions(-) delete mode 100644 src/NetEvolve.Extensions.Logging.XUni/Class1.cs create mode 100644 src/NetEvolve.Extensions.Logging.XUnit/Class1.cs rename src/{NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj => NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj} (63%) rename src/{NetEvolve.Extensions.Logging.XUni => NetEvolve.Extensions.Logging.XUnit}/README.md (100%) delete mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs delete mode 100644 tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs create mode 100644 tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs rename tests/{NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj => NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj} (94%) create mode 100644 tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs create mode 100644 tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs rename tests/{NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj => NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj} (94%) create mode 100644 tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs diff --git a/Extensions.Logging.XUnit.sln b/Extensions.Logging.XUnit.sln index 9c8724e..dbec575 100644 --- a/Extensions.Logging.XUnit.sln +++ b/Extensions.Logging.XUnit.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 @@ -23,13 +23,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EFE8181B-6FAB-4E04-BD9B-557C1286B858}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni", "src\NetEvolve.Extensions.Logging.XUni\NetEvolve.Extensions.Logging.XUni.csproj", "{20C3A39A-E7BA-4189-8064-11F2555A0ABF}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BD750CCE-0318-424D-89B4-9C66EF329E96}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni.Tests.Unit", "tests\NetEvolve.Extensions.Logging.XUni.Tests.Unit\NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj", "{6211ACA9-9A91-4218-8B4B-E94F91796B58}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit", "src\NetEvolve.Extensions.Logging.XUnit\NetEvolve.Extensions.Logging.XUnit.csproj", "{3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit.Tests.Unit", "tests\NetEvolve.Extensions.Logging.XUnit.Tests.Unit\NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj", "{EAAD2C22-48F4-4E37-9A46-0350C6B84388}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.Logging.XUni.Tests.Integration", "tests\NetEvolve.Extensions.Logging.XUni.Tests.Integration\NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj", "{FFF70EC4-D0FD-4D73-8599-7FF442133436}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit.Tests.Integration", "tests\NetEvolve.Extensions.Logging.XUnit.Tests.Integration\NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj", "{F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -40,22 +40,50 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20C3A39A-E7BA-4189-8064-11F2555A0ABF}.Release|Any CPU.Build.0 = Release|Any CPU - {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Release|Any CPU.Build.0 = Release|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Release|Any CPU.Build.0 = Release|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} + {EAAD2C22-48F4-4E37-9A46-0350C6B84388} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + EndGlobalSection +EndGlobal +Any CPU {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Release|Any CPU.Build.0 = Release|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.Build.0 = Debug|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.ActiveCfg = Release|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.Build.0 = Release|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Release|Any CPU.Build.0 = Release|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAAD2C22-48F4-4E37-9A46-0350C6B84388}.Release|Any CPU.Build.0 = Release|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {20C3A39A-E7BA-4189-8064-11F2555A0ABF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} {6211ACA9-9A91-4218-8B4B-E94F91796B58} = {BD750CCE-0318-424D-89B4-9C66EF329E96} {FFF70EC4-D0FD-4D73-8599-7FF442133436} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} + {EAAD2C22-48F4-4E37-9A46-0350C6B84388} = {BD750CCE-0318-424D-89B4-9C66EF329E96} + {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12} = {BD750CCE-0318-424D-89B4-9C66EF329E96} EndGlobalSection EndGlobal diff --git a/src/NetEvolve.Extensions.Logging.XUni/Class1.cs b/src/NetEvolve.Extensions.Logging.XUni/Class1.cs deleted file mode 100644 index 2c15727..0000000 --- a/src/NetEvolve.Extensions.Logging.XUni/Class1.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUni; - -public class Class1 { } diff --git a/src/NetEvolve.Extensions.Logging.XUnit/Class1.cs b/src/NetEvolve.Extensions.Logging.XUnit/Class1.cs new file mode 100644 index 0000000..f388cad --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUnit/Class1.cs @@ -0,0 +1,3 @@ +namespace NetEvolve.Extensions.Logging.XUnit; + +public class Class1 { } diff --git a/src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj b/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj similarity index 63% rename from src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj rename to src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj index 8268829..cfadb03 100644 --- a/src/NetEvolve.Extensions.Logging.XUni/NetEvolve.Extensions.Logging.XUni.csproj +++ b/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj @@ -2,6 +2,8 @@ net7.0 + enable + enable diff --git a/src/NetEvolve.Extensions.Logging.XUni/README.md b/src/NetEvolve.Extensions.Logging.XUnit/README.md similarity index 100% rename from src/NetEvolve.Extensions.Logging.XUni/README.md rename to src/NetEvolve.Extensions.Logging.XUnit/README.md diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs deleted file mode 100644 index e7294b7..0000000 --- a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/UnitTest1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUni.Tests.Integration; - -public class UnitTest1 -{ - public void Test1() { } -} diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs deleted file mode 100644 index d77f42a..0000000 --- a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/UnitTest1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUni.Tests.Unit; - -public class UnitTest1 -{ - public void Test1() { } -} diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs new file mode 100644 index 0000000..c802f44 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj similarity index 94% rename from tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj rename to tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj index 7d823c0..62b4eec 100644 --- a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Unit/NetEvolve.Extensions.Logging.XUni.Tests.Unit.csproj +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj @@ -22,7 +22,7 @@ - + diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs new file mode 100644 index 0000000..e5cd8f0 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs @@ -0,0 +1,7 @@ +namespace NetEvolve.Extensions.Logging.XUnit.Tests.Integration; + +public class UnitTest1 +{ + [Fact] + public void Test1() { } +} diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs new file mode 100644 index 0000000..c802f44 --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; diff --git a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj similarity index 94% rename from tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj rename to tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj index 7d823c0..62b4eec 100644 --- a/tests/NetEvolve.Extensions.Logging.XUni.Tests.Integration/NetEvolve.Extensions.Logging.XUni.Tests.Integration.csproj +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj @@ -22,7 +22,7 @@ - + diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs new file mode 100644 index 0000000..ed6a7fe --- /dev/null +++ b/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs @@ -0,0 +1,7 @@ +namespace NetEvolve.Extensions.Logging.XUnit.Tests.Unit; + +public class UnitTest1 +{ + [Fact] + public void Test1() { } +} From 5afe166b352e8c2f8c78840c87c993caa86420f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Sat, 11 May 2024 16:29:40 +0200 Subject: [PATCH 04/15] chore: Initial implementation --- Directory.Packages.props | 4 +- .../NetEvolve.Extensions.Logging.XUnit.csproj | 5 ++ .../XUnitLogger.cs | 89 +++++++++++++++++++ .../XUnitLoggerOfT.cs | 15 ++++ .../{Class1.cs => XUnitLoggerOptions.cs} | 2 +- 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs create mode 100644 src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs rename src/NetEvolve.Extensions.Logging.XUnit/{Class1.cs => XUnitLoggerOptions.cs} (58%) diff --git a/Directory.Packages.props b/Directory.Packages.props index 478d49a..998a072 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,8 +15,10 @@ + + - + \ No newline at end of file diff --git a/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj b/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj index cfadb03..4bcb180 100644 --- a/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj +++ b/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj @@ -6,4 +6,9 @@ enable + + + + + diff --git a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs new file mode 100644 index 0000000..c584490 --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs @@ -0,0 +1,89 @@ +namespace NetEvolve.Extensions.Logging.XUnit; + +using System; +using System.Text; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +public class XUnitLogger : ILogger +{ + private readonly ITestOutputHelper _testOutputHelper; + private readonly IExternalScopeProvider _scopeProvider; + private readonly string? _categoryName; + private readonly XUnitLoggerOptions? _options; + + public static ILogger CreateLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider = null, + string? categoryName = null, + XUnitLoggerOptions? options = null + ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); + + public static ILogger CreateLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider = null, + string? categoryName = null, + XUnitLoggerOptions? options = null + ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); + + internal XUnitLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider, + string? categoryName, + XUnitLoggerOptions? options + ) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + + _testOutputHelper = testOutputHelper; + _scopeProvider = scopeProvider ?? new LoggerExternalScopeProvider(); + _categoryName = categoryName; + _options = options ?? new XUnitLoggerOptions(); + } + + /// + public IDisposable? BeginScope(TState state) + where TState : notnull => _scopeProvider.Push(state); + + /// + public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; + + /// + public void Log( + LogLevel logLevel, + EventId eventId, + TState state, + Exception? exception, + Func formatter + ) + { + ArgumentNullException.ThrowIfNull(formatter); + + var sb = new StringBuilder(500); + + _ = sb.Append('[').Append(LogLevelToString(logLevel)).Append("] "); + + _ = sb.Append(formatter(state, exception)); + + try + { + _testOutputHelper.WriteLine(sb.ToString()); + } + catch + { + // Unfortunately, this can happen if the process is terminated before the end of the test. + } + } + + private static string LogLevelToString(LogLevel logLevel) => logLevel switch + { + LogLevel.Trace => "trce", + LogLevel.Debug => "dbug", + LogLevel.Information => "info", + LogLevel.Warning => "warn", + LogLevel.Error => "fail", + LogLevel.Critical => "crit", + LogLevel.None => "none", + _ => throw new ArgumentOutOfRangeException(nameof(logLevel)) + }; +} diff --git a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs new file mode 100644 index 0000000..0159822 --- /dev/null +++ b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs @@ -0,0 +1,15 @@ +namespace NetEvolve.Extensions.Logging.XUnit; + +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +public sealed class XUnitLogger : XUnitLogger, ILogger +{ + internal XUnitLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider, + string? categoryName, + XUnitLoggerOptions? options + ) + : base(testOutputHelper, scopeProvider, categoryName, options) { } +} diff --git a/src/NetEvolve.Extensions.Logging.XUnit/Class1.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs similarity index 58% rename from src/NetEvolve.Extensions.Logging.XUnit/Class1.cs rename to src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs index f388cad..9ce14c5 100644 --- a/src/NetEvolve.Extensions.Logging.XUnit/Class1.cs +++ b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs @@ -1,3 +1,3 @@ namespace NetEvolve.Extensions.Logging.XUnit; -public class Class1 { } +public class XUnitLoggerOptions { } From 1c63aea8311e65d84f9a3ac8e7e00e0ca0877199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Fri, 17 May 2024 09:23:12 +0200 Subject: [PATCH 05/15] chore: Extended implementation --- Directory.Build.props | 7 + Directory.Packages.props | 3 + ...ons.Logging.XUnit.sln => Logging.XUnit.sln | 9 +- .../XUnitLogger.cs | 89 ------- .../XUnitLoggerOfT.cs | 15 -- .../XUnitLoggerOptions.cs | 3 - src/NetEvolve.Logging.XUnit/LoggedMessage.cs | 22 ++ .../NetEvolve.Logging.XUnit.csproj} | 5 +- .../README.md | 0 src/NetEvolve.Logging.XUnit/XUnitLogger.cs | 233 ++++++++++++++++++ .../XUnitLoggerExtensions.cs | 29 +++ src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs | 21 ++ .../XUnitLoggerOptions.cs | 75 ++++++ .../XUnitLoggerProvider.cs | 96 ++++++++ .../GlobalUsings.cs | 0 ...ve.Logging.XUnit.Tests.Integration.csproj} | 2 +- .../UnitTest1.cs | 2 +- .../GlobalUsings.cs | 0 ...NetEvolve.Logging.XUnit.Tests.Unit.csproj} | 2 +- .../UnitTest1.cs | 2 +- 20 files changed, 498 insertions(+), 117 deletions(-) rename Extensions.Logging.XUnit.sln => Logging.XUnit.sln (85%) delete mode 100644 src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs delete mode 100644 src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs delete mode 100644 src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs create mode 100644 src/NetEvolve.Logging.XUnit/LoggedMessage.cs rename src/{NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj => NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj} (55%) rename src/{NetEvolve.Extensions.Logging.XUnit => NetEvolve.Logging.XUnit}/README.md (100%) create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLogger.cs create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs create mode 100644 src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Integration => NetEvolve.Logging.XUnit.Tests.Integration}/GlobalUsings.cs (100%) rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj => NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj} (88%) rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Unit => NetEvolve.Logging.XUnit.Tests.Integration}/UnitTest1.cs (54%) rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Unit => NetEvolve.Logging.XUnit.Tests.Unit}/GlobalUsings.cs (100%) rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj => NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj} (88%) rename tests/{NetEvolve.Extensions.Logging.XUnit.Tests.Integration => NetEvolve.Logging.XUnit.Tests.Unit}/UnitTest1.cs (51%) diff --git a/Directory.Build.props b/Directory.Build.props index 2958b68..b3f0ce0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,4 +9,11 @@ + + net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0 + + true + + diff --git a/Directory.Packages.props b/Directory.Packages.props index 998a072..11cd075 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,9 +16,12 @@ + + + \ No newline at end of file diff --git a/Extensions.Logging.XUnit.sln b/Logging.XUnit.sln similarity index 85% rename from Extensions.Logging.XUnit.sln rename to Logging.XUnit.sln index dbec575..70a8721 100644 --- a/Extensions.Logging.XUnit.sln +++ b/Logging.XUnit.sln @@ -25,11 +25,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EFE8181B-6FA EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BD750CCE-0318-424D-89B4-9C66EF329E96}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit", "src\NetEvolve.Extensions.Logging.XUnit\NetEvolve.Extensions.Logging.XUnit.csproj", "{3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Logging.XUnit", "src\NetEvolve.Logging.XUnit\NetEvolve.Logging.XUnit.csproj", "{3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit.Tests.Unit", "tests\NetEvolve.Extensions.Logging.XUnit.Tests.Unit\NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj", "{EAAD2C22-48F4-4E37-9A46-0350C6B84388}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Logging.XUnit.Tests.Unit", "tests\NetEvolve.Logging.XUnit.Tests.Unit\NetEvolve.Logging.XUnit.Tests.Unit.csproj", "{EAAD2C22-48F4-4E37-9A46-0350C6B84388}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.Logging.XUnit.Tests.Integration", "tests\NetEvolve.Extensions.Logging.XUnit.Tests.Integration\NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj", "{F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Logging.XUnit.Tests.Integration", "tests\NetEvolve.Logging.XUnit.Tests.Integration\NetEvolve.Logging.XUnit.Tests.Integration.csproj", "{F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,8 +59,7 @@ Global {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12} = {BD750CCE-0318-424D-89B4-9C66EF329E96} EndGlobalSection EndGlobal -Any CPU - {6211ACA9-9A91-4218-8B4B-E94F91796B58}.Release|Any CPU.Build.0 = Release|Any CPU +CPU.Build.0 = Release|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.Build.0 = Debug|Any CPU {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs deleted file mode 100644 index c584490..0000000 --- a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLogger.cs +++ /dev/null @@ -1,89 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUnit; - -using System; -using System.Text; -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -public class XUnitLogger : ILogger -{ - private readonly ITestOutputHelper _testOutputHelper; - private readonly IExternalScopeProvider _scopeProvider; - private readonly string? _categoryName; - private readonly XUnitLoggerOptions? _options; - - public static ILogger CreateLogger( - ITestOutputHelper testOutputHelper, - IExternalScopeProvider? scopeProvider = null, - string? categoryName = null, - XUnitLoggerOptions? options = null - ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); - - public static ILogger CreateLogger( - ITestOutputHelper testOutputHelper, - IExternalScopeProvider? scopeProvider = null, - string? categoryName = null, - XUnitLoggerOptions? options = null - ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); - - internal XUnitLogger( - ITestOutputHelper testOutputHelper, - IExternalScopeProvider? scopeProvider, - string? categoryName, - XUnitLoggerOptions? options - ) - { - ArgumentNullException.ThrowIfNull(testOutputHelper); - - _testOutputHelper = testOutputHelper; - _scopeProvider = scopeProvider ?? new LoggerExternalScopeProvider(); - _categoryName = categoryName; - _options = options ?? new XUnitLoggerOptions(); - } - - /// - public IDisposable? BeginScope(TState state) - where TState : notnull => _scopeProvider.Push(state); - - /// - public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; - - /// - public void Log( - LogLevel logLevel, - EventId eventId, - TState state, - Exception? exception, - Func formatter - ) - { - ArgumentNullException.ThrowIfNull(formatter); - - var sb = new StringBuilder(500); - - _ = sb.Append('[').Append(LogLevelToString(logLevel)).Append("] "); - - _ = sb.Append(formatter(state, exception)); - - try - { - _testOutputHelper.WriteLine(sb.ToString()); - } - catch - { - // Unfortunately, this can happen if the process is terminated before the end of the test. - } - } - - private static string LogLevelToString(LogLevel logLevel) => logLevel switch - { - LogLevel.Trace => "trce", - LogLevel.Debug => "dbug", - LogLevel.Information => "info", - LogLevel.Warning => "warn", - LogLevel.Error => "fail", - LogLevel.Critical => "crit", - LogLevel.None => "none", - _ => throw new ArgumentOutOfRangeException(nameof(logLevel)) - }; -} diff --git a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs deleted file mode 100644 index 0159822..0000000 --- a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOfT.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUnit; - -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -public sealed class XUnitLogger : XUnitLogger, ILogger -{ - internal XUnitLogger( - ITestOutputHelper testOutputHelper, - IExternalScopeProvider? scopeProvider, - string? categoryName, - XUnitLoggerOptions? options - ) - : base(testOutputHelper, scopeProvider, categoryName, options) { } -} diff --git a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs b/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs deleted file mode 100644 index 9ce14c5..0000000 --- a/src/NetEvolve.Extensions.Logging.XUnit/XUnitLoggerOptions.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace NetEvolve.Extensions.Logging.XUnit; - -public class XUnitLoggerOptions { } diff --git a/src/NetEvolve.Logging.XUnit/LoggedMessage.cs b/src/NetEvolve.Logging.XUnit/LoggedMessage.cs new file mode 100644 index 0000000..a55b0ea --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/LoggedMessage.cs @@ -0,0 +1,22 @@ +namespace NetEvolve.Logging.XUnit; + +using System; +using Microsoft.Extensions.Logging; + +/// +/// Represents a logged message, including the timestamp, log level, event ID, message, exception, and scopes. +/// +/// Timestamp of the logged message. +/// LogLevel of the logged message. +/// EventId of the logged message. +/// Logged message. +/// Logged exception. (optional) +/// Logged scopes. +public record struct LoggedMessage( + DateTimeOffset Timestamp, + LogLevel LogLevel, + EventId EventId, + string Message, + Exception? Exception, + IReadOnlyCollection Scopes +); diff --git a/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj similarity index 55% rename from src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj rename to src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj index 4bcb180..878e607 100644 --- a/src/NetEvolve.Extensions.Logging.XUnit/NetEvolve.Extensions.Logging.XUnit.csproj +++ b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj @@ -1,14 +1,17 @@ - net7.0 + $(ProjectTargetFrameworks) enable enable + + + diff --git a/src/NetEvolve.Extensions.Logging.XUnit/README.md b/src/NetEvolve.Logging.XUnit/README.md similarity index 100% rename from src/NetEvolve.Extensions.Logging.XUnit/README.md rename to src/NetEvolve.Logging.XUnit/README.md diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs new file mode 100644 index 0000000..7dd0063 --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs @@ -0,0 +1,233 @@ +namespace NetEvolve.Logging.XUnit; + +using System; +using System.Globalization; +using System.Text; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; +using Xunit.Sdk; + +public class XUnitLogger : ILogger +{ + private readonly string? _categoryName; + private readonly XUnitLoggerOptions _options; + private readonly Action? _writeToLogger; + + private readonly List _loggedMessages; + + private const int DefaultCapacity = 1024; + + [ThreadStatic] + private static StringBuilder? _builder; + + public IReadOnlyList LoggedMessages => _loggedMessages.AsReadOnly(); + + internal IExternalScopeProvider? ScopeProvider { get; set; } + + public static XUnitLogger CreateLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider = null, + string? categoryName = null, + XUnitLoggerOptions? options = null + ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); + + public static XUnitLogger CreateLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider = null, + XUnitLoggerOptions? options = null + ) => new XUnitLogger(testOutputHelper, scopeProvider, options); + + internal XUnitLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider, + string? categoryName, + XUnitLoggerOptions? options + ) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + + _writeToLogger = testOutputHelper.WriteLine; + ScopeProvider = scopeProvider; + _categoryName = categoryName; + _options = options ?? XUnitLoggerOptions.Default; + + _loggedMessages = []; + } + + internal XUnitLogger( + IMessageSink messageSink, + IExternalScopeProvider? scopeProvider, + string? categoryName, + XUnitLoggerOptions? options + ) + { + ArgumentNullException.ThrowIfNull(messageSink); + + _writeToLogger = message => messageSink.OnMessage(new DiagnosticMessage(message)); + ScopeProvider = scopeProvider; + _categoryName = categoryName; + _options = options ?? XUnitLoggerOptions.Default; + + _loggedMessages = []; + } + + /// + public IDisposable? BeginScope(TState state) + where TState : notnull => ScopeProvider?.Push(state); + + /// + public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; + + /// + public void Log( + LogLevel logLevel, + EventId eventId, + TState state, + Exception? exception, + Func formatter + ) + { + ArgumentNullException.ThrowIfNull(formatter); + + if (!IsEnabled(logLevel)) + { + return; + } + + var builder = _builder; + _builder = null; + builder ??= new StringBuilder(DefaultCapacity); + + var message = formatter(state, exception); + var now = DateTimeOffset.Now; + (builder, var scopes) = CreateMessage(logLevel, state, exception, builder, message, now); + + try + { + _loggedMessages.Add( + new LoggedMessage(now, logLevel, eventId, message, exception, scopes) + ); + _writeToLogger?.Invoke(builder.ToString()); + } + catch + { + // Ignore exception. + // Unfortunately, this can happen if the process is terminated before the end of the test. + } + + _ = builder.Clear(); + if (builder.Capacity > DefaultCapacity) + { + builder.Capacity = DefaultCapacity; + } + _builder = builder; + } + + private (StringBuilder, List) CreateMessage( + LogLevel logLevel, + TState state, + Exception? exception, + StringBuilder builder, + string message, + DateTimeOffset now + ) + { + var scopes = new List(); + if (!_options.DisableTimestamp) + { + _ = builder + .Append(now.ToString(_options.TimestampFormat, CultureInfo.InvariantCulture)) + .Append(' '); + } + + if (!_options.DisableLogLevel) + { + _ = builder.Append('[').Append(LogLevelToString(logLevel)).Append("] "); + } + + if (!_options.DisableCategory) + { + _ = builder.Append('[').Append(_categoryName).Append("] "); + } + + _ = builder.Append(message); + + if (exception is not null) + { + _ = builder.Append('\n').Append(exception); + } + + if ( + !_options.DisableAdditionalInformation + && state is IReadOnlyList> additionalInformation + ) + { + var level = 1; + _ = builder.Append('\n').Append('\t').Append("Additional Information"); + foreach (var info in additionalInformation) + { + AddAdditionalInformation(builder, info, level); + } + } + + ScopeProvider?.ForEachScope( + (scope, state) => + { + scopes.Add(scope); + + if (!_options.DisableScopes) + { + _ = state.Append("\n=>\t").Append(scope); + } + }, + builder + ); + + return (builder, scopes); + } + + private static void AddAdditionalInformation( + StringBuilder builder, + KeyValuePair info, + int level + ) + { + _ = builder + .Append('\n') + .Append('\t', level) + .Append(CultureInfo.InvariantCulture, $"`{info.Key}`:"); + + if (info.Value is null) + { + _ = builder.Append(" `null`"); + } + else if (info.Value is IConvertible convertible) + { + _ = builder.Append(CultureInfo.InvariantCulture, $" `{convertible.ToString()}`"); + } + else if (info.Value is KeyValuePair kvp) + { + AddAdditionalInformation(builder, kvp, level + 1); + } + else if (info.Value is IEnumerable> enumerable) + { + foreach (var item in enumerable) + { + AddAdditionalInformation(builder, item, level + 1); + } + } + } + + private static string LogLevelToString(LogLevel logLevel) => + logLevel switch + { + LogLevel.Trace => "TRCE", + LogLevel.Debug => "DBUG", + LogLevel.Information => "INFO", + LogLevel.Warning => "WARN", + LogLevel.Error => "FAIL", + LogLevel.Critical => "CRIT", + LogLevel.None => "NONE", + _ => throw new ArgumentOutOfRangeException(nameof(logLevel)) + }; +} diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs new file mode 100644 index 0000000..24e9c6e --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs @@ -0,0 +1,29 @@ +namespace NetEvolve.Logging.XUnit; + +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Configuration; +using Xunit.Abstractions; + +public static class XUnitLoggerExtensions +{ + public static ILoggingBuilder AddXUnit( + this ILoggingBuilder builder, + ITestOutputHelper testOutputHelper + ) + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(testOutputHelper); + + builder.AddConfiguration(); + + _ = builder.Services.AddSingleton(testOutputHelper); + builder.Services.TryAddEnumerable( + ServiceDescriptor.Singleton() + ); + + return builder; + } +} diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs new file mode 100644 index 0000000..3c1f9be --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs @@ -0,0 +1,21 @@ +namespace NetEvolve.Logging.XUnit; + +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +public sealed class XUnitLogger : XUnitLogger, ILogger +{ + internal XUnitLogger( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider, + XUnitLoggerOptions? options + ) + : base(testOutputHelper, scopeProvider, typeof(T).FullName, options) { } + + internal XUnitLogger( + IMessageSink messageSink, + IExternalScopeProvider? scopeProvider, + XUnitLoggerOptions? options + ) + : base(messageSink, scopeProvider, typeof(T).FullName, options) { } +} diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs new file mode 100644 index 0000000..f6f20a3 --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs @@ -0,0 +1,75 @@ +namespace NetEvolve.Logging.XUnit; + +/// +/// Options for the . +/// +public class XUnitLoggerOptions +{ + public static XUnitLoggerOptions Default { get; } = + new XUnitLoggerOptions { DisableAdditionalInformation = true, DisableScopes = true }; + + public static XUnitLoggerOptions DisableAllFeatures { get; } = + new XUnitLoggerOptions + { + DisableAdditionalInformation = true, + DisableCategory = true, + DisableLogLevel = true, + DisableScopes = true, + DisableTimestamp = true + }; + + public static XUnitLoggerOptions EnableAllFeatures { get; } = + new XUnitLoggerOptions + { + DisableAdditionalInformation = false, + DisableCategory = false, + DisableLogLevel = false, + DisableScopes = false, + DisableTimestamp = false + }; + + /// + /// Disables the output of the additional information in the log output. Default . + /// + public bool DisableAdditionalInformation { get; set; } + + /// + /// Disable the category name in the log output. Default . + /// + public bool DisableCategory { get; set; } + + /// + /// Disable the log level in the log output. Default . + /// + public bool DisableLogLevel { get; set; } + + /// + /// Disable the scopes in the log output. Default . + /// + public bool DisableScopes { get; set; } + + /// + /// Disables the timestamps in the log output. Default . + /// + public bool DisableTimestamp { get; set; } + + private string? _timestampFormat; + +#if NET7_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.StringSyntax( + System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.DateTimeFormat + )] +#endif + public string TimestampFormat + { + get + { + if (string.IsNullOrWhiteSpace(_timestampFormat)) + { + return "o"; + } + return _timestampFormat; + } + set => _timestampFormat = value; + } +} diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs new file mode 100644 index 0000000..7690af2 --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs @@ -0,0 +1,96 @@ +namespace NetEvolve.Logging.XUnit; + +using System; +using System.Collections.Concurrent; +using Microsoft.Extensions.Logging; +using NetEvolve.Arguments; +using Xunit.Abstractions; + +internal sealed class XUnitLoggerProvider : ILoggerProvider, ISupportExternalScope +{ + private readonly ITestOutputHelper? _testOutputHelper; + private readonly IMessageSink? _messageSink; + private readonly IExternalScopeProvider _scopeProvider; // = NullExternalScopeProvider.Instance; + private readonly XUnitLoggerOptions _options; + private readonly ConcurrentDictionary _loggers; + + public XUnitLoggerProvider( + ITestOutputHelper testOutputHelper, + IExternalScopeProvider? scopeProvider = null, + XUnitLoggerOptions? options = null + ) + : this(scopeProvider, options) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + + _testOutputHelper = testOutputHelper; + } + + public XUnitLoggerProvider( + IMessageSink messageSink, + IExternalScopeProvider? scopeProvider = null, + XUnitLoggerOptions? options = null + ) + : this(scopeProvider, options) + { + ArgumentNullException.ThrowIfNull(messageSink); + + _messageSink = messageSink; + } + + private XUnitLoggerProvider( + IExternalScopeProvider? scopeProvider = null, + XUnitLoggerOptions? options = null + ) + { + _scopeProvider = scopeProvider ?? new LoggerExternalScopeProvider(); + _options = options ?? new XUnitLoggerOptions(); + + _loggers = new ConcurrentDictionary(StringComparer.Ordinal); + } + + /// + public ILogger CreateLogger(string categoryName) + { + Argument.ThrowIfNullOrWhiteSpace(categoryName); + + return _loggers.GetOrAdd(categoryName, CreateLoggerInternal); + } + + /// + public ILogger CreateLogger() + where T : notnull => _loggers.GetOrAdd(typeof(T).FullName!, CreateLoggerInternal); + + private XUnitLogger CreateLoggerInternal(string name) + { + if (_testOutputHelper is not null) + { + return new XUnitLogger(_testOutputHelper, _scopeProvider, name, _options); + } + else if (_messageSink is not null) + { + return new XUnitLogger(_messageSink, _scopeProvider, name, _options); + } + + throw new InvalidOperationException("No output destination was provided."); + } + + /// + public void SetScopeProvider(IExternalScopeProvider scopeProvider) + { + ArgumentNullException.ThrowIfNull(scopeProvider); + + if (_scopeProvider == scopeProvider) + { + return; + } + + foreach (var logger in _loggers.Values) + { + logger.ScopeProvider = scopeProvider; + } + } + + /// + public void Dispose() { } +} diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs similarity index 100% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/GlobalUsings.cs rename to tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj b/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj similarity index 88% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj rename to tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj index 62b4eec..655d983 100644 --- a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/NetEvolve.Extensions.Logging.XUnit.Tests.Integration.csproj +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj @@ -22,7 +22,7 @@ - + diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs similarity index 54% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs rename to tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs index ed6a7fe..4ddc983 100644 --- a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/UnitTest1.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs @@ -1,4 +1,4 @@ -namespace NetEvolve.Extensions.Logging.XUnit.Tests.Unit; +namespace NetEvolve.Logging.XUnit.Tests.Integration; public class UnitTest1 { diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs similarity index 100% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/GlobalUsings.cs rename to tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj b/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj similarity index 88% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj rename to tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj index 62b4eec..655d983 100644 --- a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Unit/NetEvolve.Extensions.Logging.XUnit.Tests.Unit.csproj +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj @@ -22,7 +22,7 @@ - + diff --git a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs similarity index 51% rename from tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs rename to tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs index e5cd8f0..6ec4be9 100644 --- a/tests/NetEvolve.Extensions.Logging.XUnit.Tests.Integration/UnitTest1.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs @@ -1,4 +1,4 @@ -namespace NetEvolve.Extensions.Logging.XUnit.Tests.Integration; +namespace NetEvolve.Logging.XUnit.Tests.Unit; public class UnitTest1 { From 360a7da22cfec2eb053388eff057a1038cda5976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Sun, 19 May 2024 10:34:26 +0200 Subject: [PATCH 06/15] chore: Added first tests --- src/NetEvolve.Logging.XUnit/LoggedMessage.cs | 22 ----- .../NetEvolve.Logging.XUnit.csproj | 2 +- src/NetEvolve.Logging.XUnit/XUnitLogger.cs | 44 ++++------ src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs | 21 ----- .../XUnitLoggerProvider.cs | 58 ++++-------- src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs | 7 -- .../GlobalUsings.cs | 1 - .../UnitTest1.cs | 4 +- .../GlobalUsings.cs | 1 - .../UnitTest1.cs | 7 -- .../XUnitLoggerProviderTests.cs | 88 +++++++++++++++++++ 11 files changed, 127 insertions(+), 128 deletions(-) delete mode 100644 src/NetEvolve.Logging.XUnit/LoggedMessage.cs delete mode 100644 src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs delete mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs delete mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs delete mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs diff --git a/src/NetEvolve.Logging.XUnit/LoggedMessage.cs b/src/NetEvolve.Logging.XUnit/LoggedMessage.cs deleted file mode 100644 index a55b0ea..0000000 --- a/src/NetEvolve.Logging.XUnit/LoggedMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace NetEvolve.Logging.XUnit; - -using System; -using Microsoft.Extensions.Logging; - -/// -/// Represents a logged message, including the timestamp, log level, event ID, message, exception, and scopes. -/// -/// Timestamp of the logged message. -/// LogLevel of the logged message. -/// EventId of the logged message. -/// Logged message. -/// Logged exception. (optional) -/// Logged scopes. -public record struct LoggedMessage( - DateTimeOffset Timestamp, - LogLevel LogLevel, - EventId EventId, - string Message, - Exception? Exception, - IReadOnlyCollection Scopes -); diff --git a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj index 878e607..1e402c7 100644 --- a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj +++ b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj @@ -10,8 +10,8 @@ + - diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs index 7dd0063..2a6dbbf 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs @@ -4,10 +4,10 @@ using System.Globalization; using System.Text; using Microsoft.Extensions.Logging; +using NetEvolve.Logging.Abstractions; using Xunit.Abstractions; -using Xunit.Sdk; -public class XUnitLogger : ILogger +public class XUnitLogger : ILogger, ISupportExternalScope { private readonly string? _categoryName; private readonly XUnitLoggerOptions _options; @@ -20,9 +20,9 @@ public class XUnitLogger : ILogger [ThreadStatic] private static StringBuilder? _builder; - public IReadOnlyList LoggedMessages => _loggedMessages.AsReadOnly(); + public IExternalScopeProvider ScopeProvider { get; private set; } - internal IExternalScopeProvider? ScopeProvider { get; set; } + public IReadOnlyList LoggedMessages => _loggedMessages.AsReadOnly(); public static XUnitLogger CreateLogger( ITestOutputHelper testOutputHelper, @@ -40,32 +40,16 @@ public static XUnitLogger CreateLogger( internal XUnitLogger( ITestOutputHelper testOutputHelper, IExternalScopeProvider? scopeProvider, - string? categoryName, + string? name, XUnitLoggerOptions? options ) { ArgumentNullException.ThrowIfNull(testOutputHelper); + ArgumentNullException.ThrowIfNull(name); _writeToLogger = testOutputHelper.WriteLine; - ScopeProvider = scopeProvider; - _categoryName = categoryName; - _options = options ?? XUnitLoggerOptions.Default; - - _loggedMessages = []; - } - - internal XUnitLogger( - IMessageSink messageSink, - IExternalScopeProvider? scopeProvider, - string? categoryName, - XUnitLoggerOptions? options - ) - { - ArgumentNullException.ThrowIfNull(messageSink); - - _writeToLogger = message => messageSink.OnMessage(new DiagnosticMessage(message)); - ScopeProvider = scopeProvider; - _categoryName = categoryName; + ScopeProvider = scopeProvider ?? NullExternalScopeProvider.Instance; + _categoryName = name; _options = options ?? XUnitLoggerOptions.Default; _loggedMessages = []; @@ -73,7 +57,7 @@ internal XUnitLogger( /// public IDisposable? BeginScope(TState state) - where TState : notnull => ScopeProvider?.Push(state); + where TState : notnull => ScopeProvider.Push(state); /// public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; @@ -170,7 +154,7 @@ DateTimeOffset now } } - ScopeProvider?.ForEachScope( + ScopeProvider.ForEachScope( (scope, state) => { scopes.Add(scope); @@ -230,4 +214,12 @@ private static string LogLevelToString(LogLevel logLevel) => LogLevel.None => "NONE", _ => throw new ArgumentOutOfRangeException(nameof(logLevel)) }; + + /// + public void SetScopeProvider(IExternalScopeProvider scopeProvider) + { + ArgumentNullException.ThrowIfNull(scopeProvider); + + ScopeProvider = scopeProvider; + } } diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs deleted file mode 100644 index 3c1f9be..0000000 --- a/src/NetEvolve.Logging.XUnit/XUnitLoggerOfT.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace NetEvolve.Logging.XUnit; - -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -public sealed class XUnitLogger : XUnitLogger, ILogger -{ - internal XUnitLogger( - ITestOutputHelper testOutputHelper, - IExternalScopeProvider? scopeProvider, - XUnitLoggerOptions? options - ) - : base(testOutputHelper, scopeProvider, typeof(T).FullName, options) { } - - internal XUnitLogger( - IMessageSink messageSink, - IExternalScopeProvider? scopeProvider, - XUnitLoggerOptions? options - ) - : base(messageSink, scopeProvider, typeof(T).FullName, options) { } -} diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs index 7690af2..1b83cf3 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs @@ -2,51 +2,34 @@ using System; using System.Collections.Concurrent; +using System.Collections.Immutable; using Microsoft.Extensions.Logging; using NetEvolve.Arguments; +using NetEvolve.Logging.Abstractions; using Xunit.Abstractions; internal sealed class XUnitLoggerProvider : ILoggerProvider, ISupportExternalScope { - private readonly ITestOutputHelper? _testOutputHelper; - private readonly IMessageSink? _messageSink; - private readonly IExternalScopeProvider _scopeProvider; // = NullExternalScopeProvider.Instance; + private readonly ITestOutputHelper _testOutputHelper; + private readonly IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance; private readonly XUnitLoggerOptions _options; private readonly ConcurrentDictionary _loggers; + internal ImmutableList Loggers => _loggers.Values.ToImmutableList(); + public XUnitLoggerProvider( ITestOutputHelper testOutputHelper, IExternalScopeProvider? scopeProvider = null, XUnitLoggerOptions? options = null ) - : this(scopeProvider, options) { ArgumentNullException.ThrowIfNull(testOutputHelper); - _testOutputHelper = testOutputHelper; - } - - public XUnitLoggerProvider( - IMessageSink messageSink, - IExternalScopeProvider? scopeProvider = null, - XUnitLoggerOptions? options = null - ) - : this(scopeProvider, options) - { - ArgumentNullException.ThrowIfNull(messageSink); - - _messageSink = messageSink; - } - - private XUnitLoggerProvider( - IExternalScopeProvider? scopeProvider = null, - XUnitLoggerOptions? options = null - ) - { _scopeProvider = scopeProvider ?? new LoggerExternalScopeProvider(); _options = options ?? new XUnitLoggerOptions(); _loggers = new ConcurrentDictionary(StringComparer.Ordinal); + _testOutputHelper = testOutputHelper; } /// @@ -54,26 +37,19 @@ public ILogger CreateLogger(string categoryName) { Argument.ThrowIfNullOrWhiteSpace(categoryName); - return _loggers.GetOrAdd(categoryName, CreateLoggerInternal); + return _loggers.GetOrAdd( + categoryName, + name => new XUnitLogger(_testOutputHelper, _scopeProvider, name, _options) + ); } /// public ILogger CreateLogger() - where T : notnull => _loggers.GetOrAdd(typeof(T).FullName!, CreateLoggerInternal); - - private XUnitLogger CreateLoggerInternal(string name) - { - if (_testOutputHelper is not null) - { - return new XUnitLogger(_testOutputHelper, _scopeProvider, name, _options); - } - else if (_messageSink is not null) - { - return new XUnitLogger(_messageSink, _scopeProvider, name, _options); - } - - throw new InvalidOperationException("No output destination was provided."); - } + where T : notnull => + _loggers.GetOrAdd( + typeof(T).FullName!, + _ => new XUnitLogger(_testOutputHelper, _scopeProvider, _options) + ); /// public void SetScopeProvider(IExternalScopeProvider scopeProvider) @@ -87,7 +63,7 @@ public void SetScopeProvider(IExternalScopeProvider scopeProvider) foreach (var logger in _loggers.Values) { - logger.ScopeProvider = scopeProvider; + logger.SetScopeProvider(scopeProvider); } } diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs index 3c1f9be..f46852b 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs @@ -11,11 +11,4 @@ internal XUnitLogger( XUnitLoggerOptions? options ) : base(testOutputHelper, scopeProvider, typeof(T).FullName, options) { } - - internal XUnitLogger( - IMessageSink messageSink, - IExternalScopeProvider? scopeProvider, - XUnitLoggerOptions? options - ) - : base(messageSink, scopeProvider, typeof(T).FullName, options) { } } diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs deleted file mode 100644 index c802f44..0000000 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs index 4ddc983..a8e0562 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs @@ -1,4 +1,6 @@ -namespace NetEvolve.Logging.XUnit.Tests.Integration; +namespace NetEvolve.Logging.XUnit.Tests.Integration; + +using Xunit; public class UnitTest1 { diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs deleted file mode 100644 index c802f44..0000000 --- a/tests/NetEvolve.Logging.XUnit.Tests.Unit/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs deleted file mode 100644 index 6ec4be9..0000000 --- a/tests/NetEvolve.Logging.XUnit.Tests.Unit/UnitTest1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NetEvolve.Logging.XUnit.Tests.Unit; - -public class UnitTest1 -{ - [Fact] - public void Test1() { } -} diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs new file mode 100644 index 0000000..6bcf292 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs @@ -0,0 +1,88 @@ +namespace NetEvolve.Logging.XUnit.Tests.Unit; + +using System; +using Microsoft.Extensions.Logging; +using NetEvolve.Logging.Abstractions; +using Xunit; +using Xunit.Abstractions; + +public class XUnitLoggerProviderTests +{ + private readonly ITestOutputHelper _testOutputHelper; + + public XUnitLoggerProviderTests(ITestOutputHelper testOutputHelper) => + _testOutputHelper = testOutputHelper; + + [Fact] + public void CreateLogger_WithTestOutputHelper() + { + // Arrange + using var provider = new XUnitLoggerProvider(_testOutputHelper); + + // Act + var logger = provider.CreateLogger(nameof(XUnitLoggerProviderTests)); + + // Assert + Assert.NotNull(logger); + _ = Assert.IsType(logger); + } + + [Fact] + public void CreateLoggerGeneric_WithTestOutputHelper() + { + // Arrange + using var provider = new XUnitLoggerProvider(_testOutputHelper); + + // Act + var logger = provider.CreateLogger(); + + // Assert + Assert.NotNull(logger); + _ = Assert.IsType>(logger); + } + + [Fact] + public void SetScopeProvider_Null_ThrowArgumentNullException() + { + // Arrange + using var provider = new XUnitLoggerProvider(_testOutputHelper); + + // Act + void Act() => provider.SetScopeProvider(null!); + + // Assert + _ = Assert.Throws("scopeProvider", Act); + } + + [Fact] + public void SetScopeProvider_WithNullScopeProvider_NoExceptionThrown() + { + // Arrange + using var provider = new XUnitLoggerProvider(_testOutputHelper); + + // Act + var ex = Record.Exception( + () => provider.SetScopeProvider(NullExternalScopeProvider.Instance) + ); + + // Assert + Assert.Null(ex); + } + + [Fact] + public void SetScopeProvider_WithScopeProvider_Expected() + { + // Arrange + using var provider = new XUnitLoggerProvider(_testOutputHelper); + var scopeProvider = new LoggerExternalScopeProvider(); + + // Act + provider.SetScopeProvider(scopeProvider); + + // Assert + foreach (var logger in provider.Loggers) + { + Assert.Same(scopeProvider, logger.ScopeProvider); + } + } +} From a5f7c86e204f09f08747972312f9eb43f5af6655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Tue, 21 May 2024 19:44:36 +0200 Subject: [PATCH 07/15] chore: Activated SonarQube --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 233dff7..7498989 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -24,7 +24,7 @@ jobs: name: Build & Tests uses: dailydevops/pipelines/.github/workflows/cicd-dotnet.yml@0.9.3 with: - disablePublish: true + enableSonarQube: true dotnet-logging: ${{ inputs.dotnet-logging }} dotnet-version: | 8.x From 40c9ccb3c770e49df9c5c7f6e9ab62a4dbd4ae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Tue, 21 May 2024 20:22:16 +0200 Subject: [PATCH 08/15] chore: Updated `.gitmodules` [skip ci] --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 33c81aa..a898072 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "eng"] path = eng url = https://github.com/dailydevops/dotnet-engineering.git - update = merge + update = rebase From d341d062dd71a386e0e1d21148bc5bb446134ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:11:00 +0200 Subject: [PATCH 09/15] chore: Finished implementation, added tests --- Directory.Packages.props | 4 + README.md | 5 +- .../IXUnitLoggerOptions.cs | 32 +++ .../NetEvolve.Logging.XUnit.csproj | 10 + src/NetEvolve.Logging.XUnit/README.md | 68 ++++- src/NetEvolve.Logging.XUnit/XUnitLogger.cs | 233 ++++++++++++------ .../XUnitLoggerExtensions.cs | 33 ++- .../XUnitLoggerOptions.cs | 35 ++- .../XUnitLoggerProvider.cs | 38 ++- src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs | 8 +- ...lve.Logging.XUnit.Tests.Integration.csproj | 4 +- .../UnitTest1.cs | 9 - .../XUnitLoggerExtensionsTests.cs | 142 +++++++++++ .../XUnitLoggerTests.cs | 147 +++++++++++ ...ory_Expected_239eb6e5afbe5154.verified.txt | 77 ++++++ ...ory_Expected_45a9a7d9ce8ebe1d.verified.txt | 77 ++++++ ...ory_Expected_56be48173312786d.verified.txt | 77 ++++++ ...ory_Expected_70ab237ef6d4482a.verified.txt | 77 ++++++ ...ory_Expected_7c4961359b3868c7.verified.txt | 77 ++++++ ...ory_Expected_d7bac2eb9436e03b.verified.txt | 77 ++++++ ...ory_Expected_239eb6e5afbe5154.verified.txt | 9 + ...ory_Expected_45a9a7d9ce8ebe1d.verified.txt | 9 + ...ory_Expected_56be48173312786d.verified.txt | 9 + ...ory_Expected_70ab237ef6d4482a.verified.txt | 9 + ...ory_Expected_7c4961359b3868c7.verified.txt | 9 + ...ory_Expected_d7bac2eb9436e03b.verified.txt | 9 + .../NetEvolve.Logging.XUnit.Tests.Unit.csproj | 2 +- .../XUnitLoggerExtensionsTests.cs | 47 ++++ .../XUnitLoggerProviderTests.cs | 16 +- .../XUnitLoggerTests.cs | 31 +++ 30 files changed, 1249 insertions(+), 131 deletions(-) create mode 100644 src/NetEvolve.Logging.XUnit/IXUnitLoggerOptions.cs delete mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerExtensionsTests.cs create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_239eb6e5afbe5154.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_56be48173312786d.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_70ab237ef6d4482a.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_7c4961359b3868c7.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_d7bac2eb9436e03b.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerExtensionsTests.cs create mode 100644 tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerTests.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 11cd075..7ad1b69 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,10 +15,14 @@ + + + + diff --git a/README.md b/README.md index 0e844c8..dbc0860 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# template-dotnet -.NET template for repositories +# NetEvolve.Logging.XUnit + +This library provides a logging implementation for [XUnit](https://xunit.net/). When using this library, you have the ability to access the logs generated while executing your tests. This can be useful for debugging purposes. \ No newline at end of file diff --git a/src/NetEvolve.Logging.XUnit/IXUnitLoggerOptions.cs b/src/NetEvolve.Logging.XUnit/IXUnitLoggerOptions.cs new file mode 100644 index 0000000..5fe98ed --- /dev/null +++ b/src/NetEvolve.Logging.XUnit/IXUnitLoggerOptions.cs @@ -0,0 +1,32 @@ +namespace NetEvolve.Logging.XUnit; + +/// +/// Accessor for the options of the . +/// +public interface IXUnitLoggerOptions +{ + /// + /// Disables the output of the additional information in the log output. Default . + /// + bool DisableAdditionalInformation { get; } + + /// + /// Disable the log level in the log output. Default . + /// + bool DisableLogLevel { get; } + + /// + /// Disable the scopes in the log output. Default . + /// + bool DisableScopes { get; } + + /// + /// Disables the timestamps in the log output. Default . + /// + bool DisableTimestamp { get; } + + /// + /// The format of the timestamp in the log output. Default "o". + /// + string TimestampFormat { get; } +} diff --git a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj index 1e402c7..4cf8750 100644 --- a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj +++ b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj @@ -6,7 +6,17 @@ enable + + $(MSBuildProjectName) + Extensions for `ILogger` implementations to log messages to xUnit test output. + https://github.com/dailydevops/extensions.logging.xunit.git + https://github.com/dailydevops/extensions.logging.xunit.git + logging;provider;xunit + 2024 + + + diff --git a/src/NetEvolve.Logging.XUnit/README.md b/src/NetEvolve.Logging.XUnit/README.md index 570f4e7..54f5861 100644 --- a/src/NetEvolve.Logging.XUnit/README.md +++ b/src/NetEvolve.Logging.XUnit/README.md @@ -1 +1,67 @@ -Please give the customer a brief introduction about this library, and how to use it. +# NetEvolve.Logging.XUnit + +This library provides a logging implementation for [XUnit](https://xunit.net/). When using this library, you have the ability to access the logs generated while executing your tests. This can be useful for debugging purposes. + +## Installation +```bash +dotnet add package NetEvolve.Logging.XUnit +``` + +## Usage + +You can choose to use the `XUnitLogger` class directly or use the `AddXUnit` extension method on the `ILoggingBuilder` instance. + +### Direct usage + +```csharp +using Microsoft.Extensions.Logging; +using NetEvolve.Logging.XUnit; +using XUnit; + +public class ExampleTests +{ + private readonly ITestOutputHelper _output; + + public ExampleTests(ITestOutputHelper output) + { + _output = output; + } + + [Fact] + public void Test() + { + var logger = XUnitLogger.CreateLogger(_output); + + // Arrange + ... + // Act + ... + // Assert + ... + + Assert.NotEmpty(logger.LoggedMessages); + } +} +``` + +### Usage with `ILoggingBuilder.AddXUnit` + +Or you can use the `AddXUnit` extension method on the `ILoggingBuilder` instance. + +```csharp +using Microsoft.Extensions.Logging; +using NetEvolve.Logging.XUnit; + +var services = new ServiceCollection(); +services.AddLogging(builder => +{ + // Add the XUnit logging implementation + builder.AddXUnit(); + + // Or alternatively with options + builder.AddXUnit(options => + { + options.TimestampFormat = "HH:mm:ss.fff"; + }); +}); +``` \ No newline at end of file diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs index 2a6dbbf..e6546a9 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs @@ -4,14 +4,19 @@ using System.Globalization; using System.Text; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; +using NetEvolve.Arguments; using NetEvolve.Logging.Abstractions; using Xunit.Abstractions; +/// +/// Represents a logger that writes messages to xunit output. +/// public class XUnitLogger : ILogger, ISupportExternalScope { - private readonly string? _categoryName; - private readonly XUnitLoggerOptions _options; - private readonly Action? _writeToLogger; + private readonly IXUnitLoggerOptions _options; + private readonly ITestOutputHelper _testOutputHelper; + private readonly TimeProvider _timeProvider; private readonly List _loggedMessages; @@ -20,36 +25,65 @@ public class XUnitLogger : ILogger, ISupportExternalScope [ThreadStatic] private static StringBuilder? _builder; + /// + /// Gets the external scope provider. + /// public IExternalScopeProvider ScopeProvider { get; private set; } + /// public IReadOnlyList LoggedMessages => _loggedMessages.AsReadOnly(); + /// + /// Creates a new instance of . + /// + /// The to write the log messages to. + /// The to use to get the current time. + /// The to use to get the current scope. + /// The options to control the behavior of the logger. + /// A cached or new instance of . public static XUnitLogger CreateLogger( ITestOutputHelper testOutputHelper, + TimeProvider timeProvider, IExternalScopeProvider? scopeProvider = null, - string? categoryName = null, - XUnitLoggerOptions? options = null - ) => new XUnitLogger(testOutputHelper, scopeProvider, categoryName, options); + IXUnitLoggerOptions? options = null + ) + { + Argument.ThrowIfNull(testOutputHelper); + return new XUnitLogger(testOutputHelper, timeProvider, scopeProvider, options); + } + + /// + /// Creates a new instance of . + /// + /// The type who's fullname is used as the category name for messages produced by the logger. + /// The to write the log messages to. + /// The to use to get the current time. + /// The to use to get the current scope. + /// The options to control the behavior of the logger. + /// A cached or new instance of . public static XUnitLogger CreateLogger( ITestOutputHelper testOutputHelper, + TimeProvider timeProvider, IExternalScopeProvider? scopeProvider = null, - XUnitLoggerOptions? options = null - ) => new XUnitLogger(testOutputHelper, scopeProvider, options); + IXUnitLoggerOptions? options = null + ) + where T : notnull => + new XUnitLogger(testOutputHelper, timeProvider, scopeProvider, options); - internal XUnitLogger( + private protected XUnitLogger( ITestOutputHelper testOutputHelper, + TimeProvider timeProvider, IExternalScopeProvider? scopeProvider, - string? name, - XUnitLoggerOptions? options + IXUnitLoggerOptions? options ) { - ArgumentNullException.ThrowIfNull(testOutputHelper); - ArgumentNullException.ThrowIfNull(name); + Argument.ThrowIfNull(testOutputHelper); + Argument.ThrowIfNull(timeProvider); - _writeToLogger = testOutputHelper.WriteLine; ScopeProvider = scopeProvider ?? NullExternalScopeProvider.Instance; - _categoryName = name; + _testOutputHelper = testOutputHelper; + _timeProvider = timeProvider; _options = options ?? XUnitLoggerOptions.Default; _loggedMessages = []; @@ -71,7 +105,7 @@ public void Log( Func formatter ) { - ArgumentNullException.ThrowIfNull(formatter); + Argument.ThrowIfNull(formatter); if (!IsEnabled(logLevel)) { @@ -82,29 +116,38 @@ public void Log( _builder = null; builder ??= new StringBuilder(DefaultCapacity); - var message = formatter(state, exception); - var now = DateTimeOffset.Now; - (builder, var scopes) = CreateMessage(logLevel, state, exception, builder, message, now); - try { + var message = formatter(state, exception); + var now = _timeProvider.GetLocalNow(); + (builder, var scopes) = CreateMessage( + logLevel, + state, + exception, + builder, + message, + now + ); + _loggedMessages.Add( new LoggedMessage(now, logLevel, eventId, message, exception, scopes) ); - _writeToLogger?.Invoke(builder.ToString()); + _testOutputHelper.WriteLine(builder.ToString()); } catch { // Ignore exception. // Unfortunately, this can happen if the process is terminated before the end of the test. } - - _ = builder.Clear(); - if (builder.Capacity > DefaultCapacity) + finally { - builder.Capacity = DefaultCapacity; + _ = builder.Clear(); + if (builder.Capacity > DefaultCapacity) + { + builder.Capacity = DefaultCapacity; + } + _builder = builder; } - _builder = builder; } private (StringBuilder, List) CreateMessage( @@ -129,11 +172,6 @@ DateTimeOffset now _ = builder.Append('[').Append(LogLevelToString(logLevel)).Append("] "); } - if (!_options.DisableCategory) - { - _ = builder.Append('[').Append(_categoryName).Append("] "); - } - _ = builder.Append(message); if (exception is not null) @@ -146,63 +184,63 @@ DateTimeOffset now && state is IReadOnlyList> additionalInformation ) { - var level = 1; _ = builder.Append('\n').Append('\t').Append("Additional Information"); foreach (var info in additionalInformation) { - AddAdditionalInformation(builder, info, level); + AddAdditionalInformation(builder, info); } } - ScopeProvider.ForEachScope( - (scope, state) => + ScopeProvider.ForEachScope(IterateScopes, builder); + + return (builder, scopes); + + void IterateScopes(object? scope, StringBuilder state) + { + if (scope is null) + { + return; + } + + scopes.Add(scope); + + if (!_options.DisableScopes) { - scopes.Add(scope); + PrintScope(scope, state); + } + } - if (!_options.DisableScopes) + void PrintScope(object? scope, StringBuilder state) + { + if (scope is IEnumerable> scopeList) + { + foreach (var info in scopeList) { - _ = state.Append("\n=>\t").Append(scope); + PrintScope(info, state); } - }, - builder - ); - return (builder, scopes); - } + return; + } - private static void AddAdditionalInformation( - StringBuilder builder, - KeyValuePair info, - int level - ) - { - _ = builder - .Append('\n') - .Append('\t', level) - .Append(CultureInfo.InvariantCulture, $"`{info.Key}`:"); + _ = state.Append('\n').Append(' ', 4).Append("=>").Append(' '); - if (info.Value is null) - { - _ = builder.Append(" `null`"); - } - else if (info.Value is IConvertible convertible) - { - _ = builder.Append(CultureInfo.InvariantCulture, $" `{convertible.ToString()}`"); - } - else if (info.Value is KeyValuePair kvp) - { - AddAdditionalInformation(builder, kvp, level + 1); - } - else if (info.Value is IEnumerable> enumerable) - { - foreach (var item in enumerable) + if (scope is string stringScope) { - AddAdditionalInformation(builder, item, level + 1); + _ = state.Append(stringScope); + } + else if (scope is KeyValuePair info) + { + _ = state.Append(info.Key).Append(": ").Append(info.Value); } } } - private static string LogLevelToString(LogLevel logLevel) => + private static void AddAdditionalInformation( + StringBuilder builder, + KeyValuePair info + ) => _ = builder.Append('\n').Append(' ', 4).Append(info.Key).Append(": ").Append(info.Value); + + internal static string LogLevelToString(LogLevel logLevel) => logLevel switch { LogLevel.Trace => "TRCE", @@ -211,15 +249,64 @@ private static string LogLevelToString(LogLevel logLevel) => LogLevel.Warning => "WARN", LogLevel.Error => "FAIL", LogLevel.Critical => "CRIT", - LogLevel.None => "NONE", - _ => throw new ArgumentOutOfRangeException(nameof(logLevel)) + _ => "NONE" }; /// public void SetScopeProvider(IExternalScopeProvider scopeProvider) { - ArgumentNullException.ThrowIfNull(scopeProvider); + Argument.ThrowIfNull(scopeProvider); ScopeProvider = scopeProvider; } + + /// + public override string ToString() + { + var builder = _builder; + _builder = null; + builder ??= new StringBuilder(DefaultCapacity); + + try + { + foreach (var lmsg in LoggedMessages) + { + if (!_options.DisableTimestamp) + { + _ = builder + .Append( + lmsg.Timestamp.ToString( + _options.TimestampFormat, + CultureInfo.InvariantCulture + ) + ) + .Append(' '); + } + + if (!_options.DisableLogLevel) + { + _ = builder.Append('[').Append(LogLevelToString(lmsg.LogLevel)).Append("] "); + } + + _ = builder.Append(lmsg.Message); + _ = builder.AppendLine(); + + if (lmsg.Exception is not null) + { + _ = builder.Append(lmsg.Exception).AppendLine(); + } + } + + return builder.ToString().Trim(); + } + finally + { + _ = builder.Clear(); + if (builder.Capacity > DefaultCapacity) + { + builder.Capacity = DefaultCapacity; + } + _builder = builder; + } + } } diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs index 24e9c6e..51356c9 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerExtensions.cs @@ -1,27 +1,40 @@ namespace NetEvolve.Logging.XUnit; -using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Configuration; +using NetEvolve.Arguments; using Xunit.Abstractions; +/// +/// Extensions for to add a xunit logger. +/// public static class XUnitLoggerExtensions { + /// + /// Adds a xunit logger named `xunit` to the factory. + /// public static ILoggingBuilder AddXUnit( this ILoggingBuilder builder, - ITestOutputHelper testOutputHelper + ITestOutputHelper testOutputHelper, + XUnitLoggerOptions? options = null ) { - ArgumentNullException.ThrowIfNull(builder); - ArgumentNullException.ThrowIfNull(testOutputHelper); + Argument.ThrowIfNull(builder); + Argument.ThrowIfNull(testOutputHelper); - builder.AddConfiguration(); - - _ = builder.Services.AddSingleton(testOutputHelper); - builder.Services.TryAddEnumerable( - ServiceDescriptor.Singleton() + var services = builder.Services.AddSingleton(testOutputHelper); + services.TryAddSingleton(_ => TimeProvider.System); + services.TryAddScoped(); + services.TryAddEnumerable( + ServiceDescriptor.Singleton( + sp => new XUnitLoggerProvider( + sp.GetRequiredService(), + sp.GetRequiredService(), + sp.GetRequiredService(), + options ?? XUnitLoggerOptions.Default + ) + ) ); return builder; diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs index f6f20a3..14accbe 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerOptions.cs @@ -3,58 +3,53 @@ /// /// Options for the . /// -public class XUnitLoggerOptions +public class XUnitLoggerOptions : IXUnitLoggerOptions { + /// + /// Default options, which disables the category name, additional information and scopes in the log output. + /// public static XUnitLoggerOptions Default { get; } = new XUnitLoggerOptions { DisableAdditionalInformation = true, DisableScopes = true }; + /// + /// Disables all features in the log output. + /// public static XUnitLoggerOptions DisableAllFeatures { get; } = new XUnitLoggerOptions { DisableAdditionalInformation = true, - DisableCategory = true, DisableLogLevel = true, DisableScopes = true, DisableTimestamp = true }; + /// + /// Enables all features in the log output. + /// public static XUnitLoggerOptions EnableAllFeatures { get; } = new XUnitLoggerOptions { DisableAdditionalInformation = false, - DisableCategory = false, DisableLogLevel = false, DisableScopes = false, DisableTimestamp = false }; - /// - /// Disables the output of the additional information in the log output. Default . - /// + /// public bool DisableAdditionalInformation { get; set; } - /// - /// Disable the category name in the log output. Default . - /// - public bool DisableCategory { get; set; } - - /// - /// Disable the log level in the log output. Default . - /// + /// public bool DisableLogLevel { get; set; } - /// - /// Disable the scopes in the log output. Default . - /// + /// public bool DisableScopes { get; set; } - /// - /// Disables the timestamps in the log output. Default . - /// + /// public bool DisableTimestamp { get; set; } private string? _timestampFormat; + /// #if NET7_0_OR_GREATER [System.Diagnostics.CodeAnalysis.StringSyntax( System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.DateTimeFormat diff --git a/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs index 1b83cf3..b920693 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLoggerProvider.cs @@ -8,25 +8,49 @@ using NetEvolve.Logging.Abstractions; using Xunit.Abstractions; -internal sealed class XUnitLoggerProvider : ILoggerProvider, ISupportExternalScope +[ProviderAlias("XUnit")] +internal sealed class XUnitLoggerProvider + : ILoggerProvider, + ISupportExternalScope, + IXUnitLoggerOptions { private readonly ITestOutputHelper _testOutputHelper; private readonly IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance; private readonly XUnitLoggerOptions _options; private readonly ConcurrentDictionary _loggers; + private readonly TimeProvider _timeProvider; internal ImmutableList Loggers => _loggers.Values.ToImmutableList(); + /// + public bool DisableAdditionalInformation => _options.DisableAdditionalInformation; + + /// + public bool DisableLogLevel => _options.DisableLogLevel; + + /// + public bool DisableScopes => _options.DisableScopes; + + /// + public bool DisableTimestamp => _options.DisableTimestamp; + + /// + public string TimestampFormat => _options.TimestampFormat; + public XUnitLoggerProvider( ITestOutputHelper testOutputHelper, + TimeProvider timeProvider, IExternalScopeProvider? scopeProvider = null, XUnitLoggerOptions? options = null ) { - ArgumentNullException.ThrowIfNull(testOutputHelper); + Argument.ThrowIfNull(testOutputHelper); + Argument.ThrowIfNull(timeProvider); _scopeProvider = scopeProvider ?? new LoggerExternalScopeProvider(); - _options = options ?? new XUnitLoggerOptions(); + _options = options ?? XUnitLoggerOptions.Default; + + _timeProvider = timeProvider; _loggers = new ConcurrentDictionary(StringComparer.Ordinal); _testOutputHelper = testOutputHelper; @@ -39,7 +63,7 @@ public ILogger CreateLogger(string categoryName) return _loggers.GetOrAdd( categoryName, - name => new XUnitLogger(_testOutputHelper, _scopeProvider, name, _options) + name => XUnitLogger.CreateLogger(_testOutputHelper, _timeProvider, _scopeProvider, this) ); } @@ -48,13 +72,13 @@ public ILogger CreateLogger() where T : notnull => _loggers.GetOrAdd( typeof(T).FullName!, - _ => new XUnitLogger(_testOutputHelper, _scopeProvider, _options) + _ => XUnitLogger.CreateLogger(_testOutputHelper, _timeProvider, _scopeProvider, this) ); /// public void SetScopeProvider(IExternalScopeProvider scopeProvider) { - ArgumentNullException.ThrowIfNull(scopeProvider); + Argument.ThrowIfNull(scopeProvider); if (_scopeProvider == scopeProvider) { @@ -68,5 +92,5 @@ public void SetScopeProvider(IExternalScopeProvider scopeProvider) } /// - public void Dispose() { } + public void Dispose() => _loggers.Clear(); } diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs index f46852b..912608f 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger`T.cs @@ -1,14 +1,18 @@ namespace NetEvolve.Logging.XUnit; +using System; using Microsoft.Extensions.Logging; using Xunit.Abstractions; +/// public sealed class XUnitLogger : XUnitLogger, ILogger + where T : notnull { internal XUnitLogger( ITestOutputHelper testOutputHelper, + TimeProvider timeProvider, IExternalScopeProvider? scopeProvider, - XUnitLoggerOptions? options + IXUnitLoggerOptions? options ) - : base(testOutputHelper, scopeProvider, typeof(T).FullName, options) { } + : base(testOutputHelper, timeProvider, scopeProvider, options) { } } diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj b/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj index 655d983..08b60ce 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/NetEvolve.Logging.XUnit.Tests.Integration.csproj @@ -1,7 +1,7 @@ - net7.0 + $(TestTargetFrameworks) @@ -13,7 +13,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + all diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs deleted file mode 100644 index a8e0562..0000000 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/UnitTest1.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NetEvolve.Logging.XUnit.Tests.Integration; - -using Xunit; - -public class UnitTest1 -{ - [Fact] - public void Test1() { } -} diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerExtensionsTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerExtensionsTests.cs new file mode 100644 index 0000000..89f1bee --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerExtensionsTests.cs @@ -0,0 +1,142 @@ +namespace NetEvolve.Logging.XUnit.Tests.Integration; + +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Xunit; +using Xunit.Abstractions; + +public partial class XUnitLoggerExtensionsTests +{ + private readonly ITestOutputHelper _testOutputHelper; + + public XUnitLoggerExtensionsTests(ITestOutputHelper testOutputHelper) => + _testOutputHelper = testOutputHelper; + + [Theory] + [MemberData(nameof(AddXUnitData))] + public void AddXUnit_TestCase1_Expected(XUnitLoggerOptions? options) + { + // Arrange + var services = new ServiceCollection() + .AddLogging(builder => _ = builder.AddXUnit(_testOutputHelper, options)) + .AddSingleton(); + using var serviceProvider = services.BuildServiceProvider(); + + // Act + var ex = Record.Exception(() => + { + var testCase = serviceProvider.GetRequiredService(); + + testCase.Run(); + }); + + // Assert + Assert.Null(ex); + } + + [Fact] + public void AddXUnit_TestCase2_Expected() + { + // Arrange + var services = new ServiceCollection() + .AddLogging(builder => _ = builder.AddXUnit(_testOutputHelper)) + .AddSingleton(); + using var serviceProvider = services.BuildServiceProvider(); + + // Act + var ex = Record.Exception(() => + { + var testCase = serviceProvider.GetRequiredService(); + + testCase.Run(); + }); + + // Assert + Assert.Null(ex); + } + + public static TheoryData AddXUnitData => + new TheoryData + { + null, + XUnitLoggerOptions.Default, + XUnitLoggerOptions.EnableAllFeatures, + XUnitLoggerOptions.DisableAllFeatures + }; + +#pragma warning disable CA1812 // Avoid uninstantiated internal classes + private sealed partial class TestCase1 + { + private readonly ILogger _logger; + +#pragma warning disable S1144 // Unused private types or members should be removed + public TestCase1(ILogger logger) => _logger = logger; +#pragma warning restore S1144 // Unused private types or members should be removed + + public void Run() + { + using var scope1 = _logger.BeginScope("Scope"); +#pragma warning disable CA1848 // Use the LoggerMessage delegates + using var scope2 = _logger.BeginScope("Execution {Now}", DateTimeOffset.Now); + using var scope3 = _logger.BeginScope( + new Dictionary { { "ExectionTime", DateTimeOffset.Now } } + ); +#pragma warning restore CA1848 // Use the LoggerMessage delegates + LogTrace(); + LogDebug(); + LogInformation(); + LogWarning(); + LogError(); + LogCritical(); + } + + [LoggerMessage(0, LogLevel.Trace, "Trace")] + private partial void LogTrace(); + + [LoggerMessage(1, LogLevel.Debug, "Debug")] + private partial void LogDebug(); + + [LoggerMessage(2, LogLevel.Information, "Information")] + private partial void LogInformation(); + + [LoggerMessage(3, LogLevel.Warning, "Warning")] + private partial void LogWarning(); + + [LoggerMessage(4, LogLevel.Error, "Error")] + private partial void LogError(); + + [LoggerMessage(5, LogLevel.Critical, "Critical")] + private partial void LogCritical(); + } + + private sealed partial class TestCase2 + { + private readonly ILogger _logger; + +#pragma warning disable S1144 // Unused private types or members should be removed + public TestCase2(ILogger logger) => _logger = logger; +#pragma warning restore S1144 // Unused private types or members should be removed + + public void Run() + { + LogBefore(1, null); + try + { + throw new InvalidOperationException(); + } + catch (Exception ex) + { + LogException(ex, "Unknown exception."); + } + } + + [LoggerMessage(0, LogLevel.Information, "Before {Number}: {Name}")] + private partial void LogBefore(int number, string? name); + + [LoggerMessage(1, LogLevel.Error, "Exception: {Message}")] + private partial void LogException(Exception ex, string message); + } +#pragma warning restore CA1812 // Avoid uninstantiated internal classes +} diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs new file mode 100644 index 0000000..849fb79 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs @@ -0,0 +1,147 @@ +namespace NetEvolve.Logging.XUnit.Tests.Integration; + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Time.Testing; +using VerifyXunit; +using Xunit; +using Xunit.Abstractions; + +public partial class XUnitLoggerTests +{ + private readonly ITestOutputHelper _testOutputHelper; + + public XUnitLoggerTests(ITestOutputHelper testOutputHelper) => + _testOutputHelper = testOutputHelper; + + [Theory] + [MemberData(nameof(LoggedMessageOrToStringData))] + public async Task LoggedMessages_Theory_Expected( + bool disableAdditionalInformation, + bool disableLogLevel, + bool disableScopes, + bool disableTimestamp, + string? formatTimestamp + ) + { + var options = new XUnitLoggerOptions + { + DisableAdditionalInformation = disableAdditionalInformation, + DisableLogLevel = disableLogLevel, + DisableScopes = disableScopes, + DisableTimestamp = disableTimestamp, + TimestampFormat = formatTimestamp! + }; + var logger = XUnitLogger.CreateLogger( + _testOutputHelper, + new FakeTimeProvider(new DateTimeOffset(2000, 1, 1, 13, 37, 00, TimeSpan.FromHours(2))), + new LoggerExternalScopeProvider(), + options + ); + var @case = new TestCase(logger); + + // Act + @case.Run(); + + // Assert + _ = await Verifier + .Verify(logger.LoggedMessages) + .UseDirectory("_snapshots") + .UseHashedParameters( + disableAdditionalInformation, + disableLogLevel, + disableScopes, + disableTimestamp, + formatTimestamp + ) + .AutoVerify(); + } + + [Theory] + [MemberData(nameof(LoggedMessageOrToStringData))] + public async Task ToString_Theory_Expected( + bool disableAdditionalInformation, + bool disableLogLevel, + bool disableScopes, + bool disableTimestamp, + string? formatTimestamp + ) + { + var options = new XUnitLoggerOptions + { + DisableAdditionalInformation = disableAdditionalInformation, + DisableLogLevel = disableLogLevel, + DisableScopes = disableScopes, + DisableTimestamp = disableTimestamp, + TimestampFormat = formatTimestamp! + }; + var logger = XUnitLogger.CreateLogger( + _testOutputHelper, + new FakeTimeProvider(new DateTimeOffset(2000, 1, 1, 13, 37, 00, TimeSpan.FromHours(2))), + new LoggerExternalScopeProvider(), + options + ); + var @case = new TestCase(logger); + + // Act + @case.Run(); + + // Assert + _ = await Verifier + .Verify(logger.ToString()) + .UseDirectory("_snapshots") + .UseHashedParameters( + disableAdditionalInformation, + disableLogLevel, + disableScopes, + disableTimestamp, + formatTimestamp + ) + .AutoVerify(); + } + + public static TheoryData LoggedMessageOrToStringData => + new TheoryData + { + { false, false, false, false, null }, + { true, false, false, false, null }, + { false, true, false, false, null }, + { false, false, true, false, null }, + { false, false, false, true, null }, + { false, false, false, false, "yyyy-MM-dd HH:mm:ss" } + }; + + private sealed partial class TestCase + { + private readonly ILogger _logger; + + public TestCase(ILogger logger) => _logger = logger; + + public void Run() + { + using var scopeNull = _logger.BeginScope((string)null!); + using var scopeOne = _logger.BeginScope( + new Dictionary { { "MethodName", nameof(Run) } } + ); +#pragma warning disable CA1848 // Use the LoggerMessage delegates + try + { + _logger.LogTrace("This is a Trace."); + _logger.LogDebug("This is a Debug."); + _logger.LogInformation("This is an Information."); + _logger.LogWarning("This is a Warning."); + _logger.LogError("This is an Error."); + _logger.LogCritical("This is a Critical."); + + throw new NotImplementedException(); + } + catch (Exception ex) + { + _logger.LogCritical(ex, "This is a Critical with exception."); + } +#pragma warning restore CA1848 // Use the LoggerMessage delegates + } + } +} diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_239eb6e5afbe5154.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_239eb6e5afbe5154.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_239eb6e5afbe5154.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_56be48173312786d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_56be48173312786d.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_56be48173312786d.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_70ab237ef6d4482a.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_70ab237ef6d4482a.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_70ab237ef6d4482a.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_7c4961359b3868c7.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_7c4961359b3868c7.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_7c4961359b3868c7.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_d7bac2eb9436e03b.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_d7bac2eb9436e03b.verified.txt new file mode 100644 index 0000000..eadbd50 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.LoggedMessages_Theory_Expected_d7bac2eb9436e03b.verified.txt @@ -0,0 +1,77 @@ +[ + { + Timestamp: DateTimeOffset_1, + Message: This is a Trace., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Debug, + Message: This is a Debug., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Information, + Message: This is an Information., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Warning, + Message: This is a Warning., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Error, + Message: This is an Error., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical., + Scopes: [ + { + MethodName: Run + } + ] + }, + { + Timestamp: DateTimeOffset_1, + LogLevel: Critical, + Message: This is a Critical with exception., + Exception: { + $type: NotImplementedException, + Type: NotImplementedException, + Message: The method or operation is not implemented., + StackTrace: at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() + }, + Scopes: [ + { + MethodName: Run + } + ] + } +] \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt new file mode 100644 index 0000000..249e6bb --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt @@ -0,0 +1,9 @@ +2000-01-01 13:37:00 [TRCE] This is a Trace. +2000-01-01 13:37:00 [DBUG] This is a Debug. +2000-01-01 13:37:00 [INFO] This is an Information. +2000-01-01 13:37:00 [WARN] This is a Warning. +2000-01-01 13:37:00 [FAIL] This is an Error. +2000-01-01 13:37:00 [CRIT] This is a Critical. +2000-01-01 13:37:00 [CRIT] This is a Critical with exception. +2000-01-01 13:37:00 System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt new file mode 100644 index 0000000..1e1b8e5 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt @@ -0,0 +1,9 @@ +2000-01-01T13:37:00.0000000+02:00 [TRCE] This is a Trace. +2000-01-01T13:37:00.0000000+02:00 [DBUG] This is a Debug. +2000-01-01T13:37:00.0000000+02:00 [INFO] This is an Information. +2000-01-01T13:37:00.0000000+02:00 [WARN] This is a Warning. +2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. +2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt new file mode 100644 index 0000000..1e1b8e5 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt @@ -0,0 +1,9 @@ +2000-01-01T13:37:00.0000000+02:00 [TRCE] This is a Trace. +2000-01-01T13:37:00.0000000+02:00 [DBUG] This is a Debug. +2000-01-01T13:37:00.0000000+02:00 [INFO] This is an Information. +2000-01-01T13:37:00.0000000+02:00 [WARN] This is a Warning. +2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. +2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt new file mode 100644 index 0000000..e6eb65b --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt @@ -0,0 +1,9 @@ +[TRCE] This is a Trace. +[DBUG] This is a Debug. +[INFO] This is an Information. +[WARN] This is a Warning. +[FAIL] This is an Error. +[CRIT] This is a Critical. +[CRIT] This is a Critical with exception. +System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt new file mode 100644 index 0000000..cb00e4f --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt @@ -0,0 +1,9 @@ +2000-01-01T13:37:00.0000000+02:00 This is a Trace. +2000-01-01T13:37:00.0000000+02:00 This is a Debug. +2000-01-01T13:37:00.0000000+02:00 This is an Information. +2000-01-01T13:37:00.0000000+02:00 This is a Warning. +2000-01-01T13:37:00.0000000+02:00 This is an Error. +2000-01-01T13:37:00.0000000+02:00 This is a Critical. +2000-01-01T13:37:00.0000000+02:00 This is a Critical with exception. +2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt new file mode 100644 index 0000000..1e1b8e5 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt @@ -0,0 +1,9 @@ +2000-01-01T13:37:00.0000000+02:00 [TRCE] This is a Trace. +2000-01-01T13:37:00.0000000+02:00 [DBUG] This is a Debug. +2000-01-01T13:37:00.0000000+02:00 [INFO] This is an Information. +2000-01-01T13:37:00.0000000+02:00 [WARN] This is a Warning. +2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. +2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. +2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj b/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj index 655d983..aa354f3 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/NetEvolve.Logging.XUnit.Tests.Unit.csproj @@ -1,7 +1,7 @@ - net7.0 + $(TestTargetFrameworks) diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerExtensionsTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerExtensionsTests.cs new file mode 100644 index 0000000..3834398 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerExtensionsTests.cs @@ -0,0 +1,47 @@ +namespace NetEvolve.Logging.XUnit.Tests.Unit; + +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Xunit; +using Xunit.Abstractions; + +public class XUnitLoggerExtensionsTests +{ + private readonly ITestOutputHelper _testOutputHelper; + + public XUnitLoggerExtensionsTests(ITestOutputHelper testOutputHelper) => + _testOutputHelper = testOutputHelper; + + [Fact] + public void AddXUnit_WithNullBuilder_ThrowArgumentNullException() + { + // Arrange + ILoggingBuilder builder = null!; + + // Act + void Act() => builder.AddXUnit(_testOutputHelper); + + // Assert + _ = Assert.Throws("builder", Act); + } + + [Fact] + public void AddXUnit_WithNullTestOutputHelper_ThrowArgumentNullException() + { + // Arrange + var services = new ServiceCollection(); + + // Act & Assert + _ = Assert.Throws( + "testOutputHelper", + () => + { + _ = services.AddLogging(builder => + { + _ = builder.AddXUnit(null!); + }); + } + ); + } +} diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs index 6bcf292..ceee635 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerProviderTests.cs @@ -17,7 +17,7 @@ public XUnitLoggerProviderTests(ITestOutputHelper testOutputHelper) => public void CreateLogger_WithTestOutputHelper() { // Arrange - using var provider = new XUnitLoggerProvider(_testOutputHelper); + using var provider = new XUnitLoggerProvider(_testOutputHelper, TimeProvider.System); // Act var logger = provider.CreateLogger(nameof(XUnitLoggerProviderTests)); @@ -31,7 +31,7 @@ public void CreateLogger_WithTestOutputHelper() public void CreateLoggerGeneric_WithTestOutputHelper() { // Arrange - using var provider = new XUnitLoggerProvider(_testOutputHelper); + using var provider = new XUnitLoggerProvider(_testOutputHelper, TimeProvider.System); // Act var logger = provider.CreateLogger(); @@ -45,7 +45,7 @@ public void CreateLoggerGeneric_WithTestOutputHelper() public void SetScopeProvider_Null_ThrowArgumentNullException() { // Arrange - using var provider = new XUnitLoggerProvider(_testOutputHelper); + using var provider = new XUnitLoggerProvider(_testOutputHelper, TimeProvider.System); // Act void Act() => provider.SetScopeProvider(null!); @@ -58,7 +58,10 @@ public void SetScopeProvider_Null_ThrowArgumentNullException() public void SetScopeProvider_WithNullScopeProvider_NoExceptionThrown() { // Arrange - using var provider = new XUnitLoggerProvider(_testOutputHelper); + using var provider = new XUnitLoggerProvider(_testOutputHelper, TimeProvider.System); + + _ = provider.CreateLogger(nameof(XUnitLoggerProviderTests)); + _ = provider.CreateLogger(); // Act var ex = Record.Exception( @@ -73,9 +76,12 @@ public void SetScopeProvider_WithNullScopeProvider_NoExceptionThrown() public void SetScopeProvider_WithScopeProvider_Expected() { // Arrange - using var provider = new XUnitLoggerProvider(_testOutputHelper); + using var provider = new XUnitLoggerProvider(_testOutputHelper, TimeProvider.System); var scopeProvider = new LoggerExternalScopeProvider(); + _ = provider.CreateLogger(nameof(XUnitLoggerProviderTests)); + _ = provider.CreateLogger(); + // Act provider.SetScopeProvider(scopeProvider); diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerTests.cs new file mode 100644 index 0000000..55b4671 --- /dev/null +++ b/tests/NetEvolve.Logging.XUnit.Tests.Unit/XUnitLoggerTests.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Logging.XUnit.Tests.Unit; + +using Microsoft.Extensions.Logging; +using Xunit; + +public partial class XUnitLoggerTests +{ + [Theory] + [MemberData(nameof(LogLevelToStringData))] + public void LogLevelToString_Theory_Expected(string expected, LogLevel logLevel) + { + // Arrange + // Act + var result = XUnitLogger.LogLevelToString(logLevel); + + // Assert + Assert.Equal(expected, result); + } + + public static TheoryData LogLevelToStringData => + new TheoryData + { + { "TRCE", LogLevel.Trace }, + { "DBUG", LogLevel.Debug }, + { "INFO", LogLevel.Information }, + { "WARN", LogLevel.Warning }, + { "FAIL", LogLevel.Error }, + { "CRIT", LogLevel.Critical }, + { "NONE", LogLevel.None } + }; +} From 5c1d6d7ca7ff198b7178702f0216d13bfba00faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:11:10 +0200 Subject: [PATCH 10/15] fix: Removed timestamp --- ...Tests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt | 2 +- ...Tests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt | 2 +- ...Tests.ToString_Theory_Expected_56be48173312786d.verified.txt | 2 +- ...Tests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt | 2 +- ...Tests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt index 249e6bb..fbcc4e3 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt @@ -5,5 +5,5 @@ 2000-01-01 13:37:00 [FAIL] This is an Error. 2000-01-01 13:37:00 [CRIT] This is a Critical. 2000-01-01 13:37:00 [CRIT] This is a Critical with exception. -2000-01-01 13:37:00 System.NotImplementedException: The method or operation is not implemented. +System.NotImplementedException: The method or operation is not implemented. at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt index 1e1b8e5..5b97f3f 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt @@ -5,5 +5,5 @@ 2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. -2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. +System.NotImplementedException: The method or operation is not implemented. at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt index 1e1b8e5..5b97f3f 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt @@ -5,5 +5,5 @@ 2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. -2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. +System.NotImplementedException: The method or operation is not implemented. at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt index cb00e4f..e00398d 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt @@ -5,5 +5,5 @@ 2000-01-01T13:37:00.0000000+02:00 This is an Error. 2000-01-01T13:37:00.0000000+02:00 This is a Critical. 2000-01-01T13:37:00.0000000+02:00 This is a Critical with exception. -2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. +System.NotImplementedException: The method or operation is not implemented. at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt index 1e1b8e5..5b97f3f 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt @@ -5,5 +5,5 @@ 2000-01-01T13:37:00.0000000+02:00 [FAIL] This is an Error. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. -2000-01-01T13:37:00.0000000+02:00 System.NotImplementedException: The method or operation is not implemented. +System.NotImplementedException: The method or operation is not implemented. at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file From 773adf8ecca8d9828a2192b0620c3aea7e340eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:14:42 +0200 Subject: [PATCH 11/15] fix: Removed `.AutoVerify` --- src/NetEvolve.Logging.XUnit/XUnitLogger.cs | 34 +++++++++---------- .../XUnitLoggerTests.cs | 6 ++-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs index e6546a9..809cf08 100644 --- a/src/NetEvolve.Logging.XUnit/XUnitLogger.cs +++ b/src/NetEvolve.Logging.XUnit/XUnitLogger.cs @@ -209,29 +209,29 @@ void IterateScopes(object? scope, StringBuilder state) PrintScope(scope, state); } } + } - void PrintScope(object? scope, StringBuilder state) + private static void PrintScope(object? scope, StringBuilder state) + { + if (scope is IEnumerable> scopeList) { - if (scope is IEnumerable> scopeList) + foreach (var subScope in scopeList) { - foreach (var info in scopeList) - { - PrintScope(info, state); - } - - return; + PrintScope(subScope, state); } - _ = state.Append('\n').Append(' ', 4).Append("=>").Append(' '); + return; + } + + _ = state.Append('\n').Append(' ', 4).Append("=>").Append(' '); - if (scope is string stringScope) - { - _ = state.Append(stringScope); - } - else if (scope is KeyValuePair info) - { - _ = state.Append(info.Key).Append(": ").Append(info.Value); - } + if (scope is KeyValuePair info) + { + _ = state.Append(info.Key).Append(": ").Append(info.Value); + } + else + { + _ = state.Append(scope); } } diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs index 849fb79..7980e53 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs @@ -55,8 +55,7 @@ public async Task LoggedMessages_Theory_Expected( disableScopes, disableTimestamp, formatTimestamp - ) - .AutoVerify(); + ); } [Theory] @@ -98,8 +97,7 @@ public async Task ToString_Theory_Expected( disableScopes, disableTimestamp, formatTimestamp - ) - .AutoVerify(); + ); } public static TheoryData LoggedMessageOrToStringData => From c45ff9ea5155aff1b802114470aa309d8f52c158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:16:22 +0200 Subject: [PATCH 12/15] fix: Removed unused prefix --- .github/workflows/cicd.yml | 2 +- new-project.ps1 | 2 +- src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 7498989..db637fe 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -28,5 +28,5 @@ jobs: dotnet-logging: ${{ inputs.dotnet-logging }} dotnet-version: | 8.x - solution: ./Extensions.Logging.XUnit.sln + solution: ./Logging.XUnit.sln secrets: inherit diff --git a/new-project.ps1 b/new-project.ps1 index e3b7884..bd80458 100644 --- a/new-project.ps1 +++ b/new-project.ps1 @@ -49,7 +49,7 @@ New-Project ` -DisableTests $DisableTests ` -DisableUnitTests $DisableUnitTests ` -DisableIntegrationTests $DisableIntegrationTests ` - -SolutionFile "./Extensions.Logging.XUnit.sln" ` + -SolutionFile "./Logging.XUnit.sln" ` -OutputDirectory (Get-Location) ` -EnableProjectGrouping $EnableProjectGrouping ` -DisableArchitectureTests $DisableArchitectureTests diff --git a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj index 4cf8750..2c4ae7a 100644 --- a/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj +++ b/src/NetEvolve.Logging.XUnit/NetEvolve.Logging.XUnit.csproj @@ -9,8 +9,8 @@ $(MSBuildProjectName) Extensions for `ILogger` implementations to log messages to xUnit test output. - https://github.com/dailydevops/extensions.logging.xunit.git - https://github.com/dailydevops/extensions.logging.xunit.git + https://github.com/dailydevops/logging.xunit.git + https://github.com/dailydevops/logging.xunit.git logging;provider;xunit 2024 From 07aa0ec0312e3a4579e22c2dafb4b760021891eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:17:59 +0200 Subject: [PATCH 13/15] fix: Solution reference --- Logging.XUnit.sln | 1 - 1 file changed, 1 deletion(-) diff --git a/Logging.XUnit.sln b/Logging.XUnit.sln index 70a8721..688b0b8 100644 --- a/Logging.XUnit.sln +++ b/Logging.XUnit.sln @@ -78,7 +78,6 @@ CPU.Build.0 = Release|Any CPU {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {20C3A39A-E7BA-4189-8064-11F2555A0ABF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} {6211ACA9-9A91-4218-8B4B-E94F91796B58} = {BD750CCE-0318-424D-89B4-9C66EF329E96} {FFF70EC4-D0FD-4D73-8599-7FF442133436} = {BD750CCE-0318-424D-89B4-9C66EF329E96} {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} From bb1bbb420dbfe757f9c86987bc08e8599d1ddae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:19:54 +0200 Subject: [PATCH 14/15] fix: Removed unused solution references --- Logging.XUnit.sln | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Logging.XUnit.sln b/Logging.XUnit.sln index 688b0b8..5214a1e 100644 --- a/Logging.XUnit.sln +++ b/Logging.XUnit.sln @@ -60,10 +60,6 @@ Global EndGlobalSection EndGlobal CPU.Build.0 = Release|Any CPU - {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFF70EC4-D0FD-4D73-8599-7FF442133436}.Release|Any CPU.Build.0 = Release|Any CPU {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -78,8 +74,6 @@ CPU.Build.0 = Release|Any CPU {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {6211ACA9-9A91-4218-8B4B-E94F91796B58} = {BD750CCE-0318-424D-89B4-9C66EF329E96} - {FFF70EC4-D0FD-4D73-8599-7FF442133436} = {BD750CCE-0318-424D-89B4-9C66EF329E96} {3F3CD6EC-4636-4B58-8400-09AC2B9BAFDF} = {EFE8181B-6FAB-4E04-BD9B-557C1286B858} {EAAD2C22-48F4-4E37-9A46-0350C6B84388} = {BD750CCE-0318-424D-89B4-9C66EF329E96} {F2B38EDD-63F9-4027-9EA6-D1E0C6387C12} = {BD750CCE-0318-424D-89B4-9C66EF329E96} From e6ee41dd6b5783be9ee40c07a860a866b3c26cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Wed, 22 May 2024 00:28:26 +0200 Subject: [PATCH 15/15] fix: Verify files --- .../XUnitLoggerTests.cs | 7 +++++-- ....ToString_Theory_Expected_239eb6e5afbe5154.verified.txt | 2 +- ....ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt | 2 +- ....ToString_Theory_Expected_56be48173312786d.verified.txt | 2 +- ....ToString_Theory_Expected_70ab237ef6d4482a.verified.txt | 2 +- ....ToString_Theory_Expected_7c4961359b3868c7.verified.txt | 2 +- ....ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs index 7980e53..ccf6f02 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/XUnitLoggerTests.cs @@ -11,6 +11,9 @@ public partial class XUnitLoggerTests { + private readonly TimeProvider _fakeTimeProvider = new FakeTimeProvider( + new DateTimeOffset(2000, 1, 1, 13, 37, 00, TimeSpan.FromHours(2)) + ); private readonly ITestOutputHelper _testOutputHelper; public XUnitLoggerTests(ITestOutputHelper testOutputHelper) => @@ -36,7 +39,7 @@ public async Task LoggedMessages_Theory_Expected( }; var logger = XUnitLogger.CreateLogger( _testOutputHelper, - new FakeTimeProvider(new DateTimeOffset(2000, 1, 1, 13, 37, 00, TimeSpan.FromHours(2))), + _fakeTimeProvider, new LoggerExternalScopeProvider(), options ); @@ -78,7 +81,7 @@ public async Task ToString_Theory_Expected( }; var logger = XUnitLogger.CreateLogger( _testOutputHelper, - new FakeTimeProvider(new DateTimeOffset(2000, 1, 1, 13, 37, 00, TimeSpan.FromHours(2))), + _fakeTimeProvider, new LoggerExternalScopeProvider(), options ); diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt index fbcc4e3..26e67d2 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_239eb6e5afbe5154.verified.txt @@ -6,4 +6,4 @@ 2000-01-01 13:37:00 [CRIT] This is a Critical. 2000-01-01 13:37:00 [CRIT] This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt index 5b97f3f..8501ba3 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_45a9a7d9ce8ebe1d.verified.txt @@ -6,4 +6,4 @@ 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt index 5b97f3f..8501ba3 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_56be48173312786d.verified.txt @@ -6,4 +6,4 @@ 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt index e6eb65b..1b1bd4c 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_70ab237ef6d4482a.verified.txt @@ -6,4 +6,4 @@ [CRIT] This is a Critical. [CRIT] This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt index e00398d..236ae83 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_7c4961359b3868c7.verified.txt @@ -6,4 +6,4 @@ 2000-01-01T13:37:00.0000000+02:00 This is a Critical. 2000-01-01T13:37:00.0000000+02:00 This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file diff --git a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt index 5b97f3f..8501ba3 100644 --- a/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt +++ b/tests/NetEvolve.Logging.XUnit.Tests.Integration/_snapshots/XUnitLoggerTests.ToString_Theory_Expected_d7bac2eb9436e03b.verified.txt @@ -6,4 +6,4 @@ 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical. 2000-01-01T13:37:00.0000000+02:00 [CRIT] This is a Critical with exception. System.NotImplementedException: The method or operation is not implemented. - at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 138 \ No newline at end of file + at NetEvolve.Logging.XUnit.Tests.Integration.XUnitLoggerTests.TestCase.Run() in {ProjectDirectory}XUnitLoggerTests.cs:line 139 \ No newline at end of file