diff --git a/docs/tests/unit/lombok-project-boilerplate.md b/docs/tests/unit/lombok-project-boilerplate.md index 75c5454..6fd7bef 100644 --- a/docs/tests/unit/lombok-project-boilerplate.md +++ b/docs/tests/unit/lombok-project-boilerplate.md @@ -1,9 +1,9 @@ # Test Evidence: Targeted Project Lombok boilerplate -- **Test type:** Unit +- **Test type:** Temporary source audit (removed after GREEN) - **Requirement IDs:** `ARC-002`, `ARC-005`, `ARC-006`, `TST-001` - **Scenario IDs:** `AC-TST-001` -- **Test class/method:** `com.lab.labtimesheet.feature.project.repository.ProjectLombokBoilerplateTest#eligibleConstructorsUseTargetedLombokWithoutChangingDomainApis` +- **Test class/method:** N/A; the temporary source audit was removed after its RED/GREEN cycle - **Implementation commit:** `e5639c1` ## Protected behavior @@ -13,13 +13,15 @@ constructors assign required final dependencies. Project JPA entities use only p constructor generation. Records remain records, and entity identity, lazy associations, explicit domain accessors, aggregate constructors, and mutation methods do not gain broad generated APIs. -## Test method +## Temporary RED/GREEN method -The source-contract test inspects only `feature.project` production sources. It requires -`@RequiredArgsConstructor` on the three injection-only components, removes the stateless advice's -handwritten no-arg constructor, and requires protected `@NoArgsConstructor` on the three JPA -entities. It also rejects broad entity Lombok annotations, confirms representative explicit domain -APIs remain, and verifies every Project immutable DTO/value type remains a Java record. +The temporary source-contract test inspected only `feature.project` production sources. It required +`@RequiredArgsConstructor` on the three injection-only components, removal of the stateless advice's +handwritten no-arg constructor, and protected `@NoArgsConstructor` on the three JPA entities. It also +rejected broad entity Lombok annotations, confirmed representative explicit domain APIs remained, +and verified every Project immutable DTO/value type remained a Java record. It was deleted after +preserving the historical RED/GREEN below because exact imports, annotation spelling, and source +substrings are implementation details rather than a durable public contract. ## Hand-derived expected result @@ -80,8 +82,8 @@ export PATH="/opt/homebrew/opt/node@24/bin:$JAVA_HOME/bin:$PATH" ./mvnw -DskipTests compile [INFO] BUILD SUCCESS -./mvnw -Dtest=ProjectLombokBoilerplateTest,ProjectEntityTest,ProjectPersistenceStructureTest,ProjectTaskMutationContextTest test -[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0 +./mvnw -Dtest=ProjectEntityTest,ProjectPersistenceStructureTest,ProjectTaskMutationContextTest test +[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS ./mvnw -Dtest=ProjectControllerTest test @@ -94,7 +96,7 @@ export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock [INFO] BUILD SUCCESS ./mvnw -Dtest='Project*Test' test -[INFO] Tests run: 45, Failures: 0, Errors: 0, Skipped: 0 +[INFO] Tests run: 44, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS ./mvnw -DskipTests -Dmaven.javadoc.failOnWarnings=true -Ddoclint=all \ @@ -107,9 +109,9 @@ git diff --check ## External-test boundaries -The source audit does not by itself prove Lombok annotation processing, Spring constructor -injection, Hibernate materialization, PostgreSQL mappings, Thymeleaf behavior, Project authorization, -locking, or aggregate lifecycle rules. Those boundaries are covered by the compile, scoped +The removed source audit did not prove Lombok annotation processing, Spring constructor injection, +Hibernate materialization, PostgreSQL mappings, Thymeleaf behavior, Project authorization, locking, +or aggregate lifecycle rules. Those durable boundaries are covered by the compile, scoped Javadoc/doclint, Project unit/web, and PostgreSQL 18.4 integration gates above. The first sandboxed unit-suite attempt could not attach Mockito's Byte Buddy agent; the unchanged command passed after approved execution outside that sandbox. Browser E2E behavior remains outside this unit milestone. diff --git a/src/test/java/com/lab/labtimesheet/feature/project/repository/ProjectLombokBoilerplateTest.java b/src/test/java/com/lab/labtimesheet/feature/project/repository/ProjectLombokBoilerplateTest.java deleted file mode 100644 index c5e5c7d..0000000 --- a/src/test/java/com/lab/labtimesheet/feature/project/repository/ProjectLombokBoilerplateTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.lab.labtimesheet.feature.project.repository; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import org.junit.jupiter.api.Test; - -class ProjectLombokBoilerplateTest { - - private static final Path PROJECT_SOURCE = - Path.of("src/main/java/com/lab/labtimesheet/feature/project"); - - @Test - void eligibleConstructorsUseTargetedLombokWithoutChangingDomainApis() throws IOException { - assertRequiredArgsConstructor("controller/ProjectController.java", "ProjectController"); - assertRequiredArgsConstructor("service/ProjectService.java", "ProjectService"); - assertRequiredArgsConstructor("service/ProjectQueryService.java", "ProjectQueryService"); - - String advice = source("exception/ProjectControllerAdvice.java"); - assertThat(advice).doesNotContain("public ProjectControllerAdvice()"); - - assertProtectedJpaConstructor("model/entity/ProjectEntity.java", "ProjectEntity"); - assertProtectedJpaConstructor( - "model/entity/ProjectLeadershipTermEntity.java", "ProjectLeadershipTermEntity"); - assertProtectedJpaConstructor( - "model/entity/ProjectMembershipEntity.java", "ProjectMembershipEntity"); - - assertThat(source("model/entity/ProjectEntity.java")) - .contains("public static ProjectEntity plan(", "public ProjectMembershipEntity addMember(") - .doesNotContain("@Getter", "@Setter", "@Data", "@EqualsAndHashCode", "@ToString"); - assertThat(source("model/entity/ProjectLeadershipTermEntity.java")) - .contains("public long internUserId()", "Instant end(Instant at, long mentorUserId)") - .doesNotContain("@Getter", "@Setter", "@Data", "@EqualsAndHashCode", "@ToString"); - assertThat(source("model/entity/ProjectMembershipEntity.java")) - .contains("public long internUserId()", "public boolean isCurrent()") - .doesNotContain("@Getter", "@Setter", "@Data", "@EqualsAndHashCode", "@ToString"); - - for (String recordSource : List.of( - "model/ProjectInternEligibility.java", - "model/ProjectLeaderChange.java", - "model/dto/ProjectActorView.java", - "model/dto/ProjectCreateCommand.java", - "model/dto/ProjectCreateForm.java", - "model/dto/ProjectDashboardSummary.java", - "model/dto/ProjectDetail.java", - "model/dto/ProjectLeadershipTermView.java", - "model/dto/ProjectMemberForm.java", - "model/dto/ProjectMemberView.java", - "model/dto/ProjectSummary.java", - "model/dto/ProjectTaskContext.java", - "model/dto/ProjectTaskMemberView.java")) { - assertThat(source(recordSource)).contains(" record "); - } - } - - private static void assertRequiredArgsConstructor(String relativePath, String typeName) throws IOException { - assertThat(source(relativePath)) - .contains("import lombok.RequiredArgsConstructor;", "@RequiredArgsConstructor") - .doesNotContain("public " + typeName + "("); - } - - private static void assertProtectedJpaConstructor(String relativePath, String typeName) throws IOException { - assertThat(source(relativePath)) - .contains( - "import lombok.AccessLevel;", - "import lombok.NoArgsConstructor;", - "@NoArgsConstructor(access = AccessLevel.PROTECTED)") - .doesNotContain("protected " + typeName + "()"); - } - - private static String source(String relativePath) throws IOException { - return Files.readString(PROJECT_SOURCE.resolve(relativePath)); - } -}