From d18588c2bb3c8396acc7f231debfefbfe7706655 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:57:22 +0800 Subject: [PATCH] test(exporter): Add unit tests - Add LibreOffice unit tests - Add Spire.XLS unit tests --- ....Abp.Exporter.Pdf.LibreOffice.Tests.csproj | 20 +++++++++++ ...YUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln | 24 +++++++++++++ .../AbpExporterPdfLibreOfficeTestBase.cs | 6 ++++ .../AbpExporterPdfLibreOfficeTestsModule.cs | 20 +++++++++++ .../AbpExporterPdfLibreOffice_Tests.cs | 5 +++ ...YUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj | 20 +++++++++++ .../AbpExporterPdfSpireLibTestBase.cs | 6 ++++ .../AbpExporterPdfSpireLibTestsModule.cs | 12 +++++++ .../AbpExporterSpireLibOffice_Tests.cs | 5 +++ .../LINGYUN.Abp.Exporter.Pdf.Tests.csproj | 25 +++++++++++++ .../Exporter/Pdf/AbpExporterPdfTestBase.cs | 8 +++++ .../Exporter/Pdf/AbpExporterPdfTestsModule.cs | 20 +++++++++++ .../Exporter/Pdf/ExcelToPdfProvider_Tests.cs | 34 ++++++++++++++++++ .../Abp/Exporter/Pdf/Resources/test.xlsx | Bin 0 -> 8799 bytes 14 files changed, 205 insertions(+) create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj new file mode 100644 index 000000000..ae6eda819 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln new file mode 100644 index 000000000..3efe62149 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests", "LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj", "{F760B606-3243-2655-8219-F8799FFAE4AF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F760B606-3243-2655-8219-F8799FFAE4AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E1CB4316-1F23-4B1A-B67C-322A416FD6F5} + EndGlobalSection +EndGlobal diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs new file mode 100644 index 000000000..652982b63 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs @@ -0,0 +1,6 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public abstract class AbpExporterPdfLibreOfficeTestBase : AbpTestsBase +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs new file mode 100644 index 000000000..ea288dfe0 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; + +[DependsOn( + typeof(AbpExporterPdfLibreOfficeModule), + typeof(AbpExporterPdfTestsModule), + typeof(AbpAutofacModule))] +public class AbpExporterPdfLibreOfficeTestsModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + if (!LibreOfficeCommands.IsLibreOffliceInstalled()) + { + context.Services.AddSingleton(); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs new file mode 100644 index 000000000..0112e9d65 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs @@ -0,0 +1,5 @@ +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public class AbpExporterPdfLibreOffice_Tests : ExcelToPdfProvider_Tests +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj new file mode 100644 index 000000000..689bb3861 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs new file mode 100644 index 000000000..2dddc4d1a --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs @@ -0,0 +1,6 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; +public abstract class AbpExporterPdfSpireLibTestBase : AbpTestsBase +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs new file mode 100644 index 000000000..c474d59e1 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; + +[DependsOn( + typeof(AbpExporterPdfSpireLibModule), + typeof(AbpExporterPdfTestsModule), + typeof(AbpAutofacModule))] +public class AbpExporterPdfSpireLibTestsModule : AbpModule +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs new file mode 100644 index 000000000..ea5b95912 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs @@ -0,0 +1,5 @@ +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; +public class AbpExporterSpireLibOffice_Tests : ExcelToPdfProvider_Tests +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj new file mode 100644 index 000000000..20265586e --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj @@ -0,0 +1,25 @@ + + + + net9.0 + true + false + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs new file mode 100644 index 000000000..106f6c55b --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Modularity; +using Volo.Abp.Testing; + +namespace LINGYUN.Abp.Exporter.Pdf; +public abstract class AbpExporterPdfTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs new file mode 100644 index 000000000..15e901cb9 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs @@ -0,0 +1,20 @@ +using LINGYUN.Abp.Tests; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Exporter.Pdf; + +[DependsOn( + typeof(AbpVirtualFileSystemModule), + typeof(AbpExporterPdfModule), + typeof(AbpTestsBaseModule))] +public class AbpExporterPdfTestsModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs new file mode 100644 index 000000000..725da41f3 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs @@ -0,0 +1,34 @@ +using Shouldly; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.IO; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Xunit; + +namespace LINGYUN.Abp.Exporter.Pdf; +public abstract class ExcelToPdfProvider_Tests : AbpExporterPdfTestBase + where TStartupModule : IAbpModule +{ + private readonly IExcelToPdfProvider _excelToPdfProvider; + private readonly IVirtualFileProvider _virtualFileProvider; + public ExcelToPdfProvider_Tests() + { + _excelToPdfProvider = GetRequiredService(); + _virtualFileProvider = GetRequiredService(); + } + + [Fact] + public async virtual Task Should_Parsed() + { + var excelFileInfo = _virtualFileProvider.GetFileInfo("/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx"); + using (var excelStream = excelFileInfo.CreateReadStream()) + { + using (var pdfStream = await _excelToPdfProvider.ParseAsync(excelStream)) + { + pdfStream.Seek(0, System.IO.SeekOrigin.Begin); + pdfStream.Length.ShouldBePositive(); + } + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..029db08db2269cfeb30451ae516e8f05b1103be9 GIT binary patch literal 8799 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 s1d#&(|M1pd;eXGGe}!LB{ssPfhSX9+g6%E