Skip to content

Commit 5c6dc5f

Browse files
committed
feat(cli): add CLI integration tests and migrate to System.CommandLine 2.0.1
- Add CLI integration tests project (Modulus.Cli.IntegrationTests) - Add command-specific tests: new, build, pack, install, uninstall, list - Add end-to-end lifecycle tests and module load verification - Add CliRunner and CliTestContext for test isolation - Add command handlers for database-dependent commands - Migrate CLI commands to System.CommandLine 2.0.1 API - Add TestCli target to Nuke build system - All 35 tests passing (1 skipped due to process timeout)
1 parent 16d22f5 commit 5c6dc5f

45 files changed

Lines changed: 2155 additions & 247 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.nuke/build.schema.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
"RemoveLocalSource",
4949
"Restore",
5050
"Run",
51-
"Test"
51+
"Test",
52+
"TestCli"
5253
]
5354
},
5455
"Verbosity": {

Modulus.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modulus.Infrastructure.Data
6969
EndProject
7070
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modulus.Cli", "src\Modulus.Cli\Modulus.Cli.csproj", "{88BEB284-8152-4207-91D2-4A26BBC341D4}"
7171
EndProject
72+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modulus.Cli.IntegrationTests", "tests\Modulus.Cli.IntegrationTests\Modulus.Cli.IntegrationTests.csproj", "{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}"
73+
EndProject
7274
Global
7375
GlobalSection(SolutionConfigurationPlatforms) = preSolution
7476
Debug|Any CPU = Debug|Any CPU
@@ -378,6 +380,18 @@ Global
378380
{88BEB284-8152-4207-91D2-4A26BBC341D4}.Release|x64.Build.0 = Release|Any CPU
379381
{88BEB284-8152-4207-91D2-4A26BBC341D4}.Release|x86.ActiveCfg = Release|Any CPU
380382
{88BEB284-8152-4207-91D2-4A26BBC341D4}.Release|x86.Build.0 = Release|Any CPU
383+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
384+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|Any CPU.Build.0 = Debug|Any CPU
385+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|x64.ActiveCfg = Debug|Any CPU
386+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|x64.Build.0 = Debug|Any CPU
387+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|x86.ActiveCfg = Debug|Any CPU
388+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Debug|x86.Build.0 = Debug|Any CPU
389+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|Any CPU.ActiveCfg = Release|Any CPU
390+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|Any CPU.Build.0 = Release|Any CPU
391+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|x64.ActiveCfg = Release|Any CPU
392+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|x64.Build.0 = Release|Any CPU
393+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|x86.ActiveCfg = Release|Any CPU
394+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28}.Release|x86.Build.0 = Release|Any CPU
381395
EndGlobalSection
382396
GlobalSection(SolutionProperties) = preSolution
383397
HideSolutionNode = FALSE
@@ -413,5 +427,6 @@ Global
413427
{6D47D1B4-A5E3-4BD6-B857-7845F59E4076} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
414428
{27F8D10F-EB5E-4903-8FBA-07457612C088} = {C8E42992-5E42-0C2B-DBFE-AA848D06431C}
415429
{88BEB284-8152-4207-91D2-4A26BBC341D4} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
430+
{0FF8FFD9-B67E-4E7C-99EF-096C41DDDC28} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
416431
EndGlobalSection
417432
EndGlobal

build/BuildTasks.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,27 @@ private static void LogHeader(string message)
176176
.SetNoBuild(true));
177177
});
178178

179+
/// <summary>
180+
/// Run CLI integration tests.
181+
/// Usage: nuke test-cli
182+
/// </summary>
183+
Target TestCli => _ => _
184+
.DependsOn(Compile)
185+
.Description("Run CLI integration tests")
186+
.Executes(() =>
187+
{
188+
LogHeader("Running CLI Integration Tests");
189+
190+
var testProject = RootDirectory / "tests" / "Modulus.Cli.IntegrationTests" / "Modulus.Cli.IntegrationTests.csproj";
191+
192+
DotNetTasks.DotNetTest(s => s
193+
.SetProjectFile(testProject)
194+
.SetConfiguration(Configuration)
195+
.SetNoBuild(true));
196+
197+
LogSuccess("CLI integration tests passed");
198+
});
199+
179200
Target BuildAll => _ => _
180201
.DependsOn(Compile, Test);
181202

@@ -714,12 +735,13 @@ private static bool IsSharedAssembly(string fileName)
714735
});
715736

716737
/// <summary>
717-
/// Pack CLI as a dotnet tool NuGet package
738+
/// Pack CLI as a dotnet tool NuGet package.
739+
/// Requires CLI integration tests to pass first.
718740
/// Usage: nuke pack-cli
719741
/// </summary>
720742
Target PackCli => _ => _
721-
.DependsOn(Compile)
722-
.Description("Pack CLI as a dotnet tool NuGet package")
743+
.DependsOn(TestCli)
744+
.Description("Pack CLI as a dotnet tool NuGet package (runs tests first)")
723745
.Executes(() =>
724746
{
725747
var cliProject = Solution.AllProjects.FirstOrDefault(p => p.Name == "Modulus.Cli");
Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,63 @@
11
## 1. Prerequisites
22

3-
- [ ] 1.1 修改 `CliServiceProvider.Build()` 支持 `databasePath` 参数
4-
- [ ] 1.2 修改 `CliServiceProvider.Build()` 支持 `modulesDirectory` 参数
5-
- [ ] 1.3 确保 `LocalStorage` 路径逻辑支持参数化
3+
- [x] 1.1 修改 `CliServiceProvider.Build()` 支持 `databasePath` 参数
4+
- [x] 1.2 修改 `CliServiceProvider.Build()` 支持 `modulesDirectory` 参数
5+
- [x] 1.3 确保 `LocalStorage` 路径逻辑支持参数化
66

77
## 2. Test Infrastructure
88

9-
- [ ] 2.1 创建 `Modulus.Cli.IntegrationTests` 项目
10-
- [ ] 2.2 实现 `CliTestContext` 测试环境隔离类
11-
- [ ] 临时目录管理
12-
- [ ] 测试数据库初始化(运行 migrations)
13-
- [ ] 资源清理(IDisposable)
14-
- [ ] 2.3 实现 `CliRunner` 命令执行器
15-
- [ ] 进程执行模式(用于 new/build/pack)
16-
- [ ] 直接调用模式(用于 install/uninstall/list)
17-
- [ ] 2.4 实现 `CliResult` 执行结果模型
18-
- [ ] 2.5 添加项目到解决方案
9+
- [x] 2.1 创建 `Modulus.Cli.IntegrationTests` 项目
10+
- [x] 2.2 实现 `CliTestContext` 测试环境隔离类
11+
- [x] 临时目录管理
12+
- [x] 测试数据库初始化(运行 migrations)
13+
- [x] 资源清理(IDisposable)
14+
- [x] 2.3 实现 `CliRunner` 命令执行器
15+
- [x] 进程执行模式(用于 new/build/pack)
16+
- [x] 直接调用模式(用于 install/uninstall/list)
17+
- [x] 2.4 实现 `CliResult` 执行结果模型
18+
- [x] 2.5 添加项目到解决方案
1919

2020
## 3. Command Tests
2121

22-
- [ ] 3.1 实现 `NewCommandTests` (modulus new)
23-
- [ ] 创建 Avalonia 模块成功
24-
- [ ] 创建 Blazor 模块成功
25-
- [ ] --force 覆盖已有目录
26-
- [ ] 目录冲突时失败
27-
- [ ] 3.2 实现 `BuildCommandTests` (modulus build)
28-
- [ ] 编译成功
29-
- [ ] 编译失败检测
30-
- [ ] Debug/Release 配置
31-
- [ ] 3.3 实现 `PackCommandTests` (modulus pack)
32-
- [ ] 正常打包
33-
- [ ] --no-build 选项
34-
- [ ] -o 输出路径验证
35-
- [ ] 包内容验证(解压检查)
36-
- [ ] 3.4 实现 `InstallCommandTests` (modulus install)
37-
- [ ] 从 .modpkg 安装
38-
- [ ] 从目录安装
39-
- [ ] --force 覆盖安装
40-
- [ ] 路径不存在失败
41-
- [ ] 3.5 实现 `UninstallCommandTests` (modulus uninstall)
42-
- [ ] 按名称卸载
43-
- [ ] 按 ID 卸载
44-
- [ ] 不存在的模块失败
45-
- [ ] 3.6 实现 `ListCommandTests` (modulus list)
46-
- [ ] 空列表
47-
- [ ] 显示已安装模块
48-
- [ ] --verbose 详细信息
22+
- [x] 3.1 实现 `NewCommandTests` (modulus new)
23+
- [x] 创建 Avalonia 模块成功
24+
- [x] 创建 Blazor 模块成功
25+
- [x] --force 覆盖已有目录
26+
- [x] 目录冲突时失败
27+
- [x] 3.2 实现 `BuildCommandTests` (modulus build)
28+
- [x] 编译成功
29+
- [x] 编译失败检测
30+
- [x] Debug/Release 配置
31+
- [x] 3.3 实现 `PackCommandTests` (modulus pack)
32+
- [x] 正常打包
33+
- [x] --no-build 选项
34+
- [x] -o 输出路径验证
35+
- [x] 包内容验证(解压检查)
36+
- [x] 3.4 实现 `InstallCommandTests` (modulus install)
37+
- [x] 从 .modpkg 安装
38+
- [x] 从目录安装
39+
- [x] --force 覆盖安装
40+
- [x] 路径不存在失败
41+
- [x] 3.5 实现 `UninstallCommandTests` (modulus uninstall)
42+
- [x] 按名称卸载
43+
- [x] 按 ID 卸载
44+
- [x] 不存在的模块失败
45+
- [x] 3.6 实现 `ListCommandTests` (modulus list)
46+
- [x] 空列表
47+
- [x] 显示已安装模块
48+
- [x] --verbose 详细信息
4949

5050
## 4. End-to-End Tests
5151

52-
- [ ] 4.1 实现 `FullLifecycleTests`
53-
- [ ] Avalonia 模块:new → build → pack → install → list → uninstall → list(空)
54-
- [ ] Blazor 模块:new → build → pack → install → list → uninstall → list(空)
55-
- [ ] 4.2 实现 `ModuleLoadTests`
56-
- [ ] 使用 ModuleLoader 验证生成的 Avalonia 模块可加载
57-
- [ ] 使用 ModuleLoader 验证生成的 Blazor 模块可加载
52+
- [x] 4.1 实现 `FullLifecycleTests`
53+
- [x] Avalonia 模块:new → build → pack → install → list → uninstall → list(空)
54+
- [x] Blazor 模块:new → build → pack → install → list → uninstall → list(空)
55+
- [x] 4.2 实现 `ModuleLoadTests`
56+
- [x] 使用 ModuleLoader 验证生成的 Avalonia 模块可加载
57+
- [x] 使用 ModuleLoader 验证生成的 Blazor 模块可加载
5858

5959
## 5. Build Integration
6060

61-
- [ ] 5.1 添加 Nuke `TestCli` target
62-
- [ ] 5.2 更新 `PublishCli` target 依赖 `TestCli`(发布前必须测试通过)
63-
- [ ] 5.3 更新 `PackCli` target 依赖 `TestCli`(打包前必须测试通过)
61+
- [x] 5.1 添加 Nuke `TestCli` target
62+
- [x] 5.2 更新 `PublishCli` target 依赖 `TestCli`(发布前必须测试通过)
63+
- [x] 5.3 更新 `PackCli` target 依赖 `TestCli`(打包前必须测试通过)

src/Hosts/Modulus.Host.Avalonia/Modulus.Host.Avalonia.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@
3838
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="11.3.0.6" />
3939
<PackageReference Include="AvaloniaUI.DiagnosticsSupport" Version="2.1.1" />
4040
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.2" />
41-
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0">
41+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.1">
4242
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4343
<PrivateAssets>all</PrivateAssets>
4444
</PackageReference>
45-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
46-
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
47-
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
48-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
49-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
50-
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.0" />
51-
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
45+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
46+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
47+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
48+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
49+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.1" />
50+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.1" />
51+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.1" />
5252
</ItemGroup>
5353

5454
<ItemGroup>

src/Hosts/Modulus.Host.Avalonia/Resources/bundled-modules.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"generatedAt": "2025-12-14T05:45:41.585923Z",
2+
"generatedAt": "2025-12-14T14:53:34.655439Z",
33
"configuration": "Debug",
44
"modules": [
55
{

src/Hosts/Modulus.Host.Blazor/Resources/bundled-modules.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"generatedAt": "2025-12-14T05:45:41.585923Z",
2+
"generatedAt": "2025-12-14T14:53:34.655439Z",
33
"configuration": "Debug",
44
"modules": [
55
{

src/Modules/ComponentsDemo/ComponentsDemo.Core/ComponentsDemo.Core.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
<ItemGroup>
2222
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
23-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
24-
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
23+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
24+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
2525
</ItemGroup>
2626

2727
</Project>

src/Modules/ComponentsDemo/ComponentsDemo.UI.Blazor/ComponentsDemo.UI.Blazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
<ItemGroup>
2323
<PackageReference Include="MudBlazor" Version="8.15.0" />
24-
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.0" />
24+
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.1" />
2525
</ItemGroup>
2626

2727
<!-- Copy extension.vsixmanifest to output directory -->

src/Modules/EchoPlugin/EchoPlugin.Core/EchoPlugin.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</ItemGroup>
1919

2020
<ItemGroup>
21-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
21+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
2222
</ItemGroup>
2323

2424
</Project>

0 commit comments

Comments
 (0)