refactor(project): replace mechanical constructors with Lombok
This commit is contained in:
@@ -0,0 +1,115 @@
|
|||||||
|
# Test Evidence: Targeted Project Lombok boilerplate
|
||||||
|
|
||||||
|
- **Test type:** Unit
|
||||||
|
- **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`
|
||||||
|
- **Implementation commit:** `pending`
|
||||||
|
|
||||||
|
## Protected behavior
|
||||||
|
|
||||||
|
Project Spring components use targeted required-argument constructor generation only when their
|
||||||
|
constructors assign required final dependencies. Project JPA entities use only protected no-arg
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Hand-derived expected result
|
||||||
|
|
||||||
|
Seven handwritten constructors are mechanical and eligible for removal: three dependency-assignment
|
||||||
|
constructors, one empty advice constructor, and three empty protected JPA constructors. The three
|
||||||
|
entity domain constructors, all aggregate mutation methods, defensive-copy accessors, derived
|
||||||
|
membership/leadership accessors, validation constructors, exception constructors, and all thirteen
|
||||||
|
records must remain explicit or remain records because they carry behavior or preserve the existing
|
||||||
|
API shape.
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
**Command**
|
||||||
|
|
||||||
|
```text
|
||||||
|
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||||
|
export PATH="/opt/homebrew/opt/node@24/bin:$JAVA_HOME/bin:$PATH"
|
||||||
|
./mvnw -Dtest=ProjectLombokBoilerplateTest test
|
||||||
|
```
|
||||||
|
|
||||||
|
**Observed result**
|
||||||
|
|
||||||
|
```text
|
||||||
|
[INFO] Running com.lab.labtimesheet.feature.project.repository.ProjectLombokBoilerplateTest
|
||||||
|
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
|
||||||
|
ProjectLombokBoilerplateTest.eligibleConstructorsUseTargetedLombokWithoutChangingDomainApis
|
||||||
|
expected ProjectController.java to contain import lombok.RequiredArgsConstructor; and
|
||||||
|
@RequiredArgsConstructor, but neither was present and the handwritten assignment-only constructor
|
||||||
|
remained.
|
||||||
|
[INFO] BUILD FAILURE
|
||||||
|
```
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
**Command**
|
||||||
|
|
||||||
|
```text
|
||||||
|
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||||
|
export PATH="/opt/homebrew/opt/node@24/bin:$JAVA_HOME/bin:$PATH"
|
||||||
|
./mvnw -Dtest=ProjectLombokBoilerplateTest test
|
||||||
|
```
|
||||||
|
|
||||||
|
**Observed result**
|
||||||
|
|
||||||
|
```text
|
||||||
|
[INFO] Running com.lab.labtimesheet.feature.project.repository.ProjectLombokBoilerplateTest
|
||||||
|
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Affected suite
|
||||||
|
|
||||||
|
**Command and result**
|
||||||
|
|
||||||
|
```text
|
||||||
|
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||||
|
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
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
|
||||||
|
./mvnw -Dtest=ProjectControllerTest test
|
||||||
|
[INFO] Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
|
||||||
|
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
|
||||||
|
./mvnw -Dtest=ProjectServiceIntegrationTest test
|
||||||
|
[INFO] Tests run: 7, Failures: 0, Errors: 0, Skipped: 0
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
|
||||||
|
./mvnw -Dtest='Project*Test' test
|
||||||
|
[INFO] Tests run: 45, Failures: 0, Errors: 0, Skipped: 0
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
|
||||||
|
./mvnw -DskipTests -Dmaven.javadoc.failOnWarnings=true -Ddoclint=all \
|
||||||
|
-Dsubpackages=com.lab.labtimesheet.feature.project javadoc:javadoc
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
(no output; exit 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
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.
|
||||||
+2
-11
@@ -8,6 +8,7 @@ import com.lab.labtimesheet.feature.project.service.ProjectQueryService;
|
|||||||
import com.lab.labtimesheet.feature.project.service.ProjectService;
|
import com.lab.labtimesheet.feature.project.service.ProjectService;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
@@ -27,22 +28,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/projects")
|
@RequestMapping("/projects")
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ProjectController {
|
public class ProjectController {
|
||||||
|
|
||||||
private final ProjectQueryService pages;
|
private final ProjectQueryService pages;
|
||||||
private final ProjectService projects;
|
private final ProjectService projects;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the MVC adapter for Project queries and mutations.
|
|
||||||
*
|
|
||||||
* @param pages authorized Project read operations
|
|
||||||
* @param projects transactional Project mutation operations
|
|
||||||
*/
|
|
||||||
public ProjectController(ProjectQueryService pages, ProjectService projects) {
|
|
||||||
this.pages = pages;
|
|
||||||
this.projects = projects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists only Projects visible to the authenticated actor and exposes Project creation only
|
* Lists only Projects visible to the authenticated actor and exposes Project creation only
|
||||||
* to Mentors.
|
* to Mentors.
|
||||||
|
|||||||
-4
@@ -17,10 +17,6 @@ import org.springframework.web.servlet.ModelAndView;
|
|||||||
@ControllerAdvice(assignableTypes = ProjectController.class)
|
@ControllerAdvice(assignableTypes = ProjectController.class)
|
||||||
public class ProjectControllerAdvice {
|
public class ProjectControllerAdvice {
|
||||||
|
|
||||||
/** Creates the stateless Project exception-to-view adapter. */
|
|
||||||
public ProjectControllerAdvice() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides whether a requested Project or nested resource exists.
|
* Hides whether a requested Project or nested resource exists.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA aggregate root for Project lifecycle, membership intervals, and leadership intervals.
|
* JPA aggregate root for Project lifecycle, membership intervals, and leadership intervals.
|
||||||
@@ -32,6 +34,7 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "projects")
|
@Table(name = "projects")
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class ProjectEntity {
|
public class ProjectEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@@ -75,10 +78,6 @@ public class ProjectEntity {
|
|||||||
@Version
|
@Version
|
||||||
private long version;
|
private long version;
|
||||||
|
|
||||||
/** Constructor reserved for JPA materialization. */
|
|
||||||
protected ProjectEntity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProjectEntity(
|
private ProjectEntity(
|
||||||
long mentorUserId,
|
long mentorUserId,
|
||||||
String name,
|
String name,
|
||||||
|
|||||||
+3
-4
@@ -11,6 +11,8 @@ import jakarta.persistence.JoinColumn;
|
|||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA leadership interval attached to an active same-Project membership.
|
* JPA leadership interval attached to an active same-Project membership.
|
||||||
@@ -20,6 +22,7 @@ import java.time.Instant;
|
|||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "project_leadership_terms")
|
@Table(name = "project_leadership_terms")
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class ProjectLeadershipTermEntity {
|
public class ProjectLeadershipTermEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@@ -46,10 +49,6 @@ public class ProjectLeadershipTermEntity {
|
|||||||
@Column(name = "ended_by_mentor_user_id")
|
@Column(name = "ended_by_mentor_user_id")
|
||||||
private Long endedByMentorUserId;
|
private Long endedByMentorUserId;
|
||||||
|
|
||||||
/** Constructor reserved for JPA materialization. */
|
|
||||||
protected ProjectLeadershipTermEntity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ProjectLeadershipTermEntity(
|
ProjectLeadershipTermEntity(
|
||||||
ProjectEntity project,
|
ProjectEntity project,
|
||||||
ProjectMembershipEntity membership,
|
ProjectMembershipEntity membership,
|
||||||
|
|||||||
+3
-4
@@ -11,6 +11,8 @@ import jakarta.persistence.ManyToOne;
|
|||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.persistence.Version;
|
import jakarta.persistence.Version;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA membership interval linking one Intern to one Project.
|
* JPA membership interval linking one Intern to one Project.
|
||||||
@@ -20,6 +22,7 @@ import java.time.Instant;
|
|||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "project_memberships")
|
@Table(name = "project_memberships")
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class ProjectMembershipEntity {
|
public class ProjectMembershipEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@@ -48,10 +51,6 @@ public class ProjectMembershipEntity {
|
|||||||
@Version
|
@Version
|
||||||
private long version;
|
private long version;
|
||||||
|
|
||||||
/** Constructor reserved for JPA materialization. */
|
|
||||||
protected ProjectMembershipEntity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ProjectMembershipEntity(ProjectEntity project, long internUserId, Instant joinedAt, long addedByUserId) {
|
ProjectMembershipEntity(ProjectEntity project, long internUserId, Instant joinedAt, long addedByUserId) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.internUserId = internUserId;
|
this.internUserId = internUserId;
|
||||||
|
|||||||
+2
-11
@@ -15,6 +15,7 @@ import com.lab.labtimesheet.feature.project.model.dto.ProjectTaskMemberView;
|
|||||||
import com.lab.labtimesheet.feature.project.model.entity.ProjectEntity;
|
import com.lab.labtimesheet.feature.project.model.entity.ProjectEntity;
|
||||||
import com.lab.labtimesheet.feature.project.repository.ProjectRepository;
|
import com.lab.labtimesheet.feature.project.repository.ProjectRepository;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -26,22 +27,12 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
* members but expose no current Leader or active-member context.
|
* members but expose no current Leader or active-member context.
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ProjectQueryService {
|
public class ProjectQueryService {
|
||||||
|
|
||||||
private final ProjectRepository projects;
|
private final ProjectRepository projects;
|
||||||
private final AccountService accounts;
|
private final AccountService accounts;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the Project read service.
|
|
||||||
*
|
|
||||||
* @param projects Project aggregate repository
|
|
||||||
* @param accounts public Account identity and internship-eligibility boundary
|
|
||||||
*/
|
|
||||||
public ProjectQueryService(ProjectRepository projects, AccountService accounts) {
|
|
||||||
this.projects = projects;
|
|
||||||
this.accounts = accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves an active authenticated account to its stable user identifier.
|
* Resolves an active authenticated account to its stable user identifier.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.lab.labtimesheet.feature.task.service.TaskQueryService;
|
|||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
* imports their repositories or entities.
|
* imports their repositories or entities.
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ProjectService {
|
public class ProjectService {
|
||||||
|
|
||||||
private final ProjectRepository projects;
|
private final ProjectRepository projects;
|
||||||
@@ -30,28 +32,6 @@ public class ProjectService {
|
|||||||
private final TaskQueryService taskQueries;
|
private final TaskQueryService taskQueries;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the Project mutation service.
|
|
||||||
*
|
|
||||||
* @param projects Project aggregate repository
|
|
||||||
* @param accounts public Account identity and eligibility boundary
|
|
||||||
* @param queries DTO-only Project query boundary reused for locked Task context
|
|
||||||
* @param taskQueries public Task activation-guard boundary
|
|
||||||
* @param clock server clock supplying persisted mutation instants
|
|
||||||
*/
|
|
||||||
public ProjectService(
|
|
||||||
ProjectRepository projects,
|
|
||||||
AccountService accounts,
|
|
||||||
ProjectQueryService queries,
|
|
||||||
TaskQueryService taskQueries,
|
|
||||||
Clock clock) {
|
|
||||||
this.projects = projects;
|
|
||||||
this.accounts = accounts;
|
|
||||||
this.queries = queries;
|
|
||||||
this.taskQueries = taskQueries;
|
|
||||||
this.clock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically creates a planned Mentor-owned Project, eligible initial membership, and first
|
* Atomically creates a planned Mentor-owned Project, eligible initial membership, and first
|
||||||
* leadership term. {@code saveAndFlush} exposes database invariant violations before commit.
|
* leadership term. {@code saveAndFlush} exposes database invariant violations before commit.
|
||||||
|
|||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user