diff --git a/src/main/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentation.java b/src/main/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentation.java new file mode 100644 index 0000000..c39627e --- /dev/null +++ b/src/main/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentation.java @@ -0,0 +1,24 @@ +package com.example.workutils.biz.aitest.project; + +import java.util.Optional; + +public record ModuleLoadPresentation(int moduleCount, Optional selectedModule, + String message) { + + public static ModuleLoadPresentation from(MavenProjectModel model, String preferredArtifactId) { + Optional selected = Optional.empty(); + if (preferredArtifactId != null && !preferredArtifactId.isBlank()) { + selected = model.moduleByArtifactId(preferredArtifactId); + } + if (selected.isEmpty()) { + selected = new StartModuleSelector().autoSelect(model); + } + int count = model.modules().size(); + String message = selected + .map(module -> "已检出 " + count + " 个 Maven 模块,已选择 " + module.artifactId()) + .orElseGet(() -> count == 0 + ? "未检出 Maven 模块,请检查项目 pom.xml" + : "已检出 " + count + " 个 Maven 模块,请选择生成模块"); + return new ModuleLoadPresentation(count, selected, message); + } +} diff --git a/src/main/java/com/example/workutils/biz/aitest/ui/TaskProgressState.java b/src/main/java/com/example/workutils/biz/aitest/ui/TaskProgressState.java new file mode 100644 index 0000000..3ca6678 --- /dev/null +++ b/src/main/java/com/example/workutils/biz/aitest/ui/TaskProgressState.java @@ -0,0 +1,30 @@ +package com.example.workutils.biz.aitest.ui; + +public final class TaskProgressState { + public static final double INDETERMINATE = -1.0; + + private boolean visible; + private double progress; + + public void start() { + visible = true; + progress = INDETERMINATE; + } + + public void update(double value) { + progress = Math.max(0.0, Math.min(1.0, value)); + } + + public void finish() { + visible = false; + progress = 0.0; + } + + public boolean visible() { + return visible; + } + + public double progress() { + return progress; + } +} diff --git a/src/test/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentationTest.java b/src/test/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentationTest.java new file mode 100644 index 0000000..c8a8458 --- /dev/null +++ b/src/test/java/com/example/workutils/biz/aitest/project/ModuleLoadPresentationTest.java @@ -0,0 +1,47 @@ +package com.example.workutils.biz.aitest.project; + +import org.junit.jupiter.api.Test; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ModuleLoadPresentationTest { + + @Test + void uniqueStartModuleIsSelectedAndCountIsReported() { + ModuleLoadPresentation view = ModuleLoadPresentation.from(model("core", "app-start"), ""); + + assertEquals(2, view.moduleCount()); + assertEquals("app-start", view.selectedModule().orElseThrow().artifactId()); + assertEquals("已检出 2 个 Maven 模块,已选择 app-start", view.message()); + } + + @Test + void preferredModuleWinsOverAutomaticSelection() { + ModuleLoadPresentation view = ModuleLoadPresentation.from(model("core", "app-start"), "core"); + + assertEquals("core", view.selectedModule().orElseThrow().artifactId()); + assertEquals("已检出 2 个 Maven 模块,已选择 core", view.message()); + } + + @Test + void multipleStartModulesRequireManualSelection() { + ModuleLoadPresentation view = ModuleLoadPresentation.from(model("a-start", "b-start"), ""); + + assertTrue(view.selectedModule().isEmpty()); + assertEquals("已检出 2 个 Maven 模块,请选择生成模块", view.message()); + } + + private static MavenProjectModel model(String... artifactIds) { + Path root = Path.of("project").toAbsolutePath(); + List modules = Arrays.stream(artifactIds) + .map(id -> new MavenModule(root.resolve(id), Path.of(id), "com.example", id, "1", Set.of())) + .toList(); + return new MavenProjectModel(root, modules); + } +} diff --git a/src/test/java/com/example/workutils/biz/aitest/ui/TaskProgressStateTest.java b/src/test/java/com/example/workutils/biz/aitest/ui/TaskProgressStateTest.java new file mode 100644 index 0000000..544fb16 --- /dev/null +++ b/src/test/java/com/example/workutils/biz/aitest/ui/TaskProgressStateTest.java @@ -0,0 +1,40 @@ +package com.example.workutils.biz.aitest.ui; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TaskProgressStateTest { + + @Test + void taskProgressIsHiddenUntilStartedAndResetsWhenFinished() { + TaskProgressState state = new TaskProgressState(); + + assertFalse(state.visible()); + assertEquals(0.0, state.progress()); + + state.start(); + assertTrue(state.visible()); + assertEquals(TaskProgressState.INDETERMINATE, state.progress()); + + state.update(0.5); + assertEquals(0.5, state.progress()); + + state.finish(); + assertFalse(state.visible()); + assertEquals(0.0, state.progress()); + } + + @Test + void progressIsClampedToUnitRange() { + TaskProgressState state = new TaskProgressState(); + state.start(); + + state.update(2.0); + assertEquals(1.0, state.progress()); + state.update(-2.0); + assertEquals(0.0, state.progress()); + } +}