diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index a90296d..242ebf3 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,10 +3,11 @@ "isRoot": true, "tools": { "dotnet-validate": { - "version": "0.0.1-preview.304", + "version": "0.0.1-preview.537", "commands": [ "dotnet-validate" - ] + ], + "rollForward": true } } } \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7bce0a2..af85bc1 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -7,25 +7,14 @@ env: ContinuousIntegrationBuild: true DOTNET_CLI_TELEMETRY_OPTOUT: true DOTNET_NOLOGO: true + DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true + TERM: xterm-256color jobs: package: strategy: matrix: os: [ macos-latest, ubuntu-latest, windows-latest ] - dotnet-version: ['481', '6.0', '8.0'] - framework-version: ['netstandard2.0', 'net6.0'] - exclude: - - os: macos-latest - dotnet-version: 481 - - os: ubuntu-latest - dotnet-version: 481 - - dotnet-version: 481 - framework-version: net6.0 - - dotnet-version: 6.0 - framework-version: netstandard2.0 - - dotnet-version: 8.0 - framework-version: netstandard2.0 fail-fast: false runs-on: ${{ matrix.os }} name: Build and run tests @@ -36,85 +25,53 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ matrix.dotnet-version }} - if: matrix.dotnet-version != '481' + dotnet-version: | + 6.x + 8.x - - name: Restore NuGet packages for CoreTest - run: dotnet restore --no-dependencies -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal CoreTest - - name: Restore library Core - run: dotnet restore --verbosity normal Core - - name: Build library Core - run: dotnet build --configuration Release --no-restore --verbosity normal Core - - name: Build test project CoreTest - run: dotnet build --configuration Release --no-restore -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal CoreTest - - name: Run tests CoreTest - run: dotnet test --configuration Release --no-build -P:TargetFramework=net${{ matrix.dotnet-version }} --logger:"html;LogFileName=../../TestResults-CoreTest-${{ matrix.os }}-dotnet_${{ matrix.dotnet-version }}.html" --verbosity normal CoreTest + - name: Restore NuGet packages + run: dotnet restore - - name: Restore NuGet packages for PixelCanvasTest - run: dotnet restore --no-dependencies -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal PixelCanvasTest - - name: Restore library PixelCanvas - run: dotnet restore --verbosity normal PixelCanvas - - name: Build library PixelCanvas - run: dotnet build --configuration Release --no-restore --verbosity normal PixelCanvas - - name: Build test project PixelCanvasTest - run: dotnet build --configuration Release --no-restore -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal PixelCanvasTest - - name: Run tests PixelCanvasTest - run: dotnet test --configuration Release --no-build -P:TargetFramework=net${{ matrix.dotnet-version }} --logger:"html;LogFileName=../../TestResults-PixelCanvasTest-${{ matrix.os }}-dotnet_${{ matrix.dotnet-version }}.html" --verbosity normal PixelCanvasTest + - name: Build solution + run: dotnet build --no-restore --verbosity normal - - name: Restore NuGet packages for WindowsTest - run: dotnet restore --no-dependencies -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal WindowsTest - if: startsWith(matrix.os,'windows') - - name: Restore library Windows - run: dotnet restore --verbosity normal Windows - if: startsWith(matrix.os,'windows') - - name: Build library Windows - run: dotnet build --configuration Release --no-restore --verbosity normal Windows - if: startsWith(matrix.os,'windows') - - name: Build test project WindowsTest - run: dotnet build --configuration Release --no-restore -p:TargetFramework=net${{ matrix.dotnet-version }} --verbosity normal WindowsTest - if: startsWith(matrix.os,'windows') - - name: Run tests WindowsTest - run: dotnet test --configuration Release --no-build -P:TargetFramework=net${{ matrix.dotnet-version }} --logger:"html;LogFileName=../../TestResults-WindowsTest-${{ matrix.os }}-dotnet_${{ matrix.dotnet-version }}.html" --verbosity normal WindowsTest - if: startsWith(matrix.os,'windows') + - name: Run tests + run: dotnet test --no-build --verbosity normal - name: Upload received files from failing tests uses: actions/upload-artifact@v4 if: failure() with: - name: Received-${{ runner.os }}-${{ matrix.dotnet-version }} + name: Received-${{ runner.os }} path: "**/*.received.*" - name: Upload test results uses: actions/upload-artifact@v4 if: always() with: - name: TestResults-${{ runner.os }}-${{ matrix.dotnet-version }} + name: TestResults-${{ runner.os }} path: TestResults-*.html - - name: Create and validate NuGet package for Core - run: dotnet pack --no-build --verbosity normal Core/Core.csproj - if: startsWith(matrix.os,'windows') - - name: Create and validate NuGet package for PixelCanvas - run: dotnet pack --no-build --verbosity normal PixelCanvas/PixelCanvas.csproj - if: startsWith(matrix.os,'windows') - - name: Create and validate NuGet package for Windows - run: dotnet pack --no-build --verbosity normal WindowsTest/WindowsTest.csproj + - name: Create and validate NuGet packages + run: | + dotnet tool restore + dotnet pack --no-build --verbosity normal if: startsWith(matrix.os,'windows') - name: Set up JDK 17 (for SonarQube) - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' + if: startsWith(matrix.os,'windows') uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' - name: Cache SonarCloud packages - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' + if: startsWith(matrix.os,'windows') uses: actions/cache@v4 with: path: ~\.sonar\cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache SonarCloud scanner - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' + if: startsWith(matrix.os,'windows') id: cache-sonar-scanner uses: actions/cache@v4 with: @@ -122,13 +79,13 @@ jobs: key: ${{ runner.os }}-sonar-scanner restore-keys: ${{ runner.os }}-sonar-scanner - name: Install SonarCloud scanner - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' && steps.cache-sonar-scanner.outputs.cache-hit != 'true' + if: startsWith(matrix.os,'windows') && steps.cache-sonar-scanner.outputs.cache-hit != 'true' shell: powershell run: | New-Item -Path .\.sonar\scanner -ItemType Directory dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner - name: Cache dotnet-coverage - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' + if: startsWith(matrix.os,'windows') id: cache-dotnet-coverage uses: actions/cache@v4 with: @@ -136,16 +93,16 @@ jobs: key: ${{ runner.os }}-dotnet-coverage restore-keys: ${{ runner.os }}-dotnet-coverage - name: Install dotnet-coverage - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' && steps.cache-dotnet-coverage.outputs.cache-hit != 'true' + if: startsWith(matrix.os,'windows') && steps.cache-dotnet-coverage.outputs.cache-hit != 'true' shell: powershell run: | New-Item -Path .\.dotnet-coverage -ItemType Directory dotnet tool update dotnet-coverage --tool-path .\.dotnet-coverage - name: Build and analyze - if: startsWith(matrix.os,'windows') && matrix.dotnet-version == '8.0' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + if: startsWith(matrix.os,'windows') && env.SONAR_TOKEN != '' shell: powershell run: | dotnet clean diff --git a/.gitignore b/.gitignore index bc40a97..681a193 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,9 @@ bld/ *.VisualState.xml TestResult.xml +# xUnit.net +TestResults-* + # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ diff --git a/Core/Core.csproj b/Core/Core.csproj index 9ff88fc..0030796 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -1,7 +1,5 @@ - - Codecrete.SwissQRBill.Core Codecrete.SwissQRBill.Generator @@ -42,7 +40,7 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other True true 3.3.0 - 3.0.0 + 3.3.0 True @@ -58,7 +56,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other - @@ -67,7 +64,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other - diff --git a/CoreTest/CoreTest.csproj b/CoreTest/CoreTest.csproj index f5ff91b..a3ac532 100644 --- a/CoreTest/CoreTest.csproj +++ b/CoreTest/CoreTest.csproj @@ -1,54 +1,30 @@ - net7.0 - - false - - Codecrete.SwissQRBill.CoreTest - + net6.0;net8.0 + net481;$(TargetFrameworks) Codecrete.SwissQRBill.CoreTest - - Manuel Bleichenbacher - - Codecrete - - Swiss QR Bill - - Open source published under MIT license - - - - 3.3.0 - - MIT - - 7.3 + true + $([System.IO.Path]::Combine($(MSBuildThisFileDirectory),'..','TestResults-$(MSBuildProjectName)-$(TargetFramework).html')) - - $(ProjectExt.Replace('proj', '')) - $([System.String]::Copy('%(FileName)').Split('.')[0]) - %(ParentFile)%(ParentExtension) - - - $(ProjectExt.Replace('proj', '')) - $([System.String]::Copy('%(FileName)').Split('.')[0]) - %(ParentFile)%(ParentExtension) - + + + @(VSTestLogger) + + - - - - - - - - - + + + + + + + + diff --git a/CoreTest/VerifyImages.cs b/CoreTest/VerifyImages.cs index 1135fda..a47fe14 100644 --- a/CoreTest/VerifyImages.cs +++ b/CoreTest/VerifyImages.cs @@ -25,7 +25,7 @@ public class VerifyImages static VerifyImages() { - VerifierSettings.RegisterFileConverter("pdf", ConvertPdfToPng); + VerifierSettings.RegisterStreamConverter("pdf", ConvertPdfToPng); VerifyImageMagick.RegisterComparers(threshold: 0.1, ImageMagick.ErrorMetric.PerceptualHash); Settings.UseDirectory("ReferenceFiles"); @@ -33,7 +33,7 @@ static VerifyImages() protected VerifyImages() { } - private static ConversionResult ConvertPdfToPng(Stream stream, IReadOnlyDictionary context) + private static ConversionResult ConvertPdfToPng(string name, Stream stream, IReadOnlyDictionary context) { var pngStreams = new List(); @@ -76,11 +76,6 @@ public static SettingsTask VerifySvg(byte[] svg, [CallerFilePath] string sourceF return Verifier.Verify(svg, settings: Settings, extension: "svg", sourceFile: sourceFile); } - public static SettingsTask VerifyPng(byte[] png, [CallerFilePath] string sourceFile = "") - { - return Verifier.Verify(png, settings: Settings, extension: "png", sourceFile: sourceFile); - } - public static SettingsTask VerifyPdf(byte[] pdf, [CallerFilePath] string sourceFile = "") { return Verifier.Verify(pdf, settings: Settings, extension: "pdf", sourceFile: sourceFile); diff --git a/PixelCanvas/PixelCanvas.csproj b/PixelCanvas/PixelCanvas.csproj index 589ddef..f2fe836 100644 --- a/PixelCanvas/PixelCanvas.csproj +++ b/PixelCanvas/PixelCanvas.csproj @@ -1,7 +1,5 @@ - - Codecrete.SwissQRBill.Generator Codecrete.SwissQRBill.PixelCanvas @@ -43,7 +41,7 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other True true 3.3.0 - 3.0.0 + 3.3.0 True @@ -59,7 +57,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other - @@ -72,7 +69,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and other - diff --git a/PixelCanvasTest/PixelCanvasTest.csproj b/PixelCanvasTest/PixelCanvasTest.csproj index f12eb11..cfe2756 100644 --- a/PixelCanvasTest/PixelCanvasTest.csproj +++ b/PixelCanvasTest/PixelCanvasTest.csproj @@ -1,58 +1,32 @@ - net7.0 - - false - + net6.0;net8.0 + net481;$(TargetFrameworks) Codecrete.SwissQRBill.PixelCanvasTest - - 7.3 + true + $([System.IO.Path]::Combine($(MSBuildThisFileDirectory),'..','TestResults-$(MSBuildProjectName)-$(TargetFramework).html')) - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + @(VSTestLogger) + + - + + + + + + - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - + diff --git a/Windows/Windows.csproj b/Windows/Windows.csproj index 6214fac..7cbe72d 100644 --- a/Windows/Windows.csproj +++ b/Windows/Windows.csproj @@ -1,7 +1,5 @@ - - Codecrete.SwissQRBill.Windows Codecrete.SwissQRBill.Windows @@ -42,7 +40,7 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and platf True true 3.3.0 - 3.0.3 + 3.3.0 True @@ -57,7 +55,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and platf - @@ -71,7 +68,6 @@ See home page https://github.com/manuelbl/SwissQRBill.NET for examples and platf - diff --git a/WindowsTest/A4BillTest.cs b/WindowsTest/A4BillTest.cs index b10cba2..e86d012 100644 --- a/WindowsTest/A4BillTest.cs +++ b/WindowsTest/A4BillTest.cs @@ -14,7 +14,7 @@ namespace Codecrete.SwissQRBill.WindowsTest { public class A4BillTest { - [Fact] + [WindowsFact] public Task CreateA4PngBill1() { return GenerateAndCompareBill(SampleData.CreateExample1(), OutputSize.A4PortraitSheet, GraphicsFormat.PNG); diff --git a/WindowsTest/CleanupTest.cs b/WindowsTest/CleanupTest.cs index 58245fc..97391d6 100644 --- a/WindowsTest/CleanupTest.cs +++ b/WindowsTest/CleanupTest.cs @@ -15,7 +15,7 @@ namespace Codecrete.SwissQRBill.WindowsTest { public class CleanupTest { - [Fact] + [WindowsFact] public void ClosePngFreesResources() { Type type = typeof(BitmapCanvas); diff --git a/WindowsTest/EmfCanvasTest.cs b/WindowsTest/EmfCanvasTest.cs index ad6a338..bda2b01 100644 --- a/WindowsTest/EmfCanvasTest.cs +++ b/WindowsTest/EmfCanvasTest.cs @@ -24,7 +24,7 @@ public EmfCanvasTest() SetProcessDPIAware(); } - [Fact] + [WindowsFact] public Task QrBillExtraSpace_ComparePng() { Bill bill = SampleData.CreateExample5(); @@ -40,7 +40,7 @@ public Task QrBillExtraSpace_ComparePng() return VerifyImages.VerifyEmf(emf); } - [Fact] + [WindowsFact] public Task QrBillA4_ComparePng() { Bill bill = SampleData.CreateExample3(); @@ -56,7 +56,7 @@ public Task QrBillA4_ComparePng() return VerifyImages.VerifyEmf(png); } - [Fact] + [WindowsFact] public void ToStream_RunsSuccessfully() { Bill bill = SampleData.CreateExample5(); @@ -71,7 +71,7 @@ public void ToStream_RunsSuccessfully() Assert.True(true); } - [Fact] + [WindowsFact] public void ToByteArray_CorrectFrame() { Bill bill = SampleData.CreateExample4(); @@ -97,7 +97,7 @@ public void ToByteArray_CorrectFrame() Assert.InRange(frame.Bottom, expectedHeight - 2, expectedHeight + 2); } - [Fact] + [WindowsFact] public void ToMetafile_CorrectFrame() { Bill bill = SampleData.CreateExample6(); diff --git a/WindowsTest/LineStyleTest.cs b/WindowsTest/LineStyleTest.cs index 09f79cf..d092bd0 100644 --- a/WindowsTest/LineStyleTest.cs +++ b/WindowsTest/LineStyleTest.cs @@ -15,14 +15,14 @@ namespace Codecrete.SwissQRBill.WindowsTest { public class LineStyleTest { - [Fact] + [WindowsFact] public Task PngWithDashedLines() { Bill bill = SampleData.CreateExample1(); return GenerateAndComparePngBill(bill, SeparatorType.DashedLine); } - [Fact] + [WindowsFact] public Task PngWithDottedLines() { Bill bill = SampleData.CreateExample2(); diff --git a/WindowsTest/PNGCanvasTest.cs b/WindowsTest/PNGCanvasTest.cs index 2620d6f..b0b3ba5 100644 --- a/WindowsTest/PNGCanvasTest.cs +++ b/WindowsTest/PNGCanvasTest.cs @@ -16,7 +16,7 @@ namespace Codecrete.SwissQRBill.WindowsTest { public class PNGCanvasTest { - [Fact] + [WindowsFact] public Task PngBillQrBill() { Bill bill = SampleData.CreateExample1(); @@ -32,7 +32,7 @@ public Task PngBillQrBill() return VerifyImages.VerifyPng(png); } - [Fact] + [WindowsFact] public Task PngBillA4() { Bill bill = SampleData.CreateExample3(); @@ -48,7 +48,7 @@ public Task PngBillA4() return VerifyImages.VerifyPng(png); } - [Fact] + [WindowsFact] public void PngWriteTo() { Bill bill = SampleData.CreateExample5(); @@ -63,7 +63,7 @@ public void PngWriteTo() Assert.True(true); } - [Fact] + [WindowsFact] public void PngSaveAs() { Bill bill = SampleData.CreateExample6(); diff --git a/WindowsTest/VerifyImages.cs b/WindowsTest/VerifyImages.cs index 0fc660f..9828d4e 100644 --- a/WindowsTest/VerifyImages.cs +++ b/WindowsTest/VerifyImages.cs @@ -22,7 +22,7 @@ protected VerifyImages() { } static VerifyImages() { - VerifierSettings.RegisterFileConverter("emf", Convert); + VerifierSettings.RegisterStreamConverter("emf", Convert); VerifyImageMagick.RegisterComparers(threshold: 0.35, ImageMagick.ErrorMetric.PerceptualHash); Settings.UseDirectory("ReferenceFiles"); @@ -40,7 +40,7 @@ public static SettingsTask VerifyEmf(byte[] emf, [CallerFilePath] string sourceF return Verifier.Verify(emf, settings: Settings, extension: "emf", sourceFile: sourceFile); } - private static ConversionResult Convert(Stream stream, IReadOnlyDictionary context) + private static ConversionResult Convert(string name, Stream stream, IReadOnlyDictionary context) { MemoryStream result; diff --git a/WindowsTest/WindowsFactAttribute.cs b/WindowsTest/WindowsFactAttribute.cs new file mode 100644 index 0000000..0a2c0d7 --- /dev/null +++ b/WindowsTest/WindowsFactAttribute.cs @@ -0,0 +1,18 @@ +using System.Runtime.InteropServices; +using Xunit; + +namespace Codecrete.SwissQRBill.WindowsTest +{ + public sealed class WindowsFactAttribute : FactAttribute + { + private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + + public WindowsFactAttribute() + { + if (!IsWindows) + { + Skip = "Only supported on Windows"; + } + } + } +} diff --git a/WindowsTest/WindowsTest.csproj b/WindowsTest/WindowsTest.csproj index 98525db..902ad59 100644 --- a/WindowsTest/WindowsTest.csproj +++ b/WindowsTest/WindowsTest.csproj @@ -1,55 +1,31 @@ - net7.0 - false + net6.0;net8.0 + net481;$(TargetFrameworks) Codecrete.SwissQRBill.WindowsTest - true - 7.3 + true + $([System.IO.Path]::Combine($(MSBuildThisFileDirectory),'..','TestResults-$(MSBuildProjectName)-$(TargetFramework).html')) - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + @(VSTestLogger) + + - + + + + + - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - - - $([System.String]::Copy('%(FileName)').Split('.')[0]) - $(MSBuildProjectExtension.Replace('proj', '')) - %(ParentFile)%(ParentExtension) - +