refactor(attendance): target lombok boilerplate
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# Test Evidence: Attendance targeted Lombok boilerplate retrofit
|
||||
|
||||
- **Test type:** Unit source-contract audit
|
||||
- **Requirement IDs:** `ATT-001`–`ATT-012`, `CAL-001`, `CAL-006`–`CAL-009`
|
||||
- **Scenario IDs:** `AC-ATT-001`–`AC-ATT-005`, `AC-CAL-003`, `AC-CAL-004`
|
||||
- **Test class/method:** `com.lab.labtimesheet.feature.attendance.AttendanceLombokBoilerplateTest`
|
||||
- **Implementation commit:** `pending`
|
||||
|
||||
## Protected behavior
|
||||
|
||||
Attendance uses the installed Lombok processor only for mechanical constructors while preserving package-level
|
||||
Spring injection access, protected JPA construction, immutable records, domain constructors and mutations, raw punch
|
||||
and attached-policy history rules, composite-key identity, and existing public API names.
|
||||
|
||||
## Test method
|
||||
|
||||
The source-contract test inspects only `feature.attendance` production Java. It enumerates the exact injection-only
|
||||
components and JPA/stateless no-argument constructors eligible for Lombok, rejects retained handwritten equivalents
|
||||
and blanket `@Data`, and asserts that records and business-significant methods remain explicit.
|
||||
|
||||
## Hand-derived expected result
|
||||
|
||||
Five injection-only components use package-scoped `@RequiredArgsConstructor`; six JPA/embeddable types use protected
|
||||
`@NoArgsConstructor`; the stateless domain service uses a package-scoped `@NoArgsConstructor`. No record is replaced,
|
||||
and no validated constructor, state mutation, identity method, or stable domain-style accessor is generated away.
|
||||
|
||||
## RED
|
||||
|
||||
**Command**
|
||||
|
||||
```text
|
||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
./mvnw -Dtest=AttendanceLombokBoilerplateTest test
|
||||
```
|
||||
|
||||
**Observed result**
|
||||
|
||||
```text
|
||||
Tests run: 3, Failures: 2, Errors: 0, Skipped: 0
|
||||
The injection-component assertion first failed on AttendanceController because the required package-scoped
|
||||
@RequiredArgsConstructor and Lombok imports were absent. The JPA/stateless assertion first failed on
|
||||
AttendancePolicyEntity because the protected @NoArgsConstructor and Lombok imports were absent. The record and
|
||||
business-method retention guard passed.
|
||||
BUILD FAILURE
|
||||
Process exited 1.
|
||||
```
|
||||
|
||||
## GREEN
|
||||
|
||||
**Command**
|
||||
|
||||
```text
|
||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
./mvnw -Dtest=AttendanceLombokBoilerplateTest test
|
||||
```
|
||||
|
||||
**Observed result**
|
||||
|
||||
```text
|
||||
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
|
||||
BUILD SUCCESS
|
||||
Process exited 0.
|
||||
```
|
||||
|
||||
## Affected suite
|
||||
|
||||
**Command and result**
|
||||
|
||||
```text
|
||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
|
||||
./mvnw -Dtest='*Attendance*Test' test
|
||||
Tests run: 38, Failures: 0, Errors: 0, Skipped: 0
|
||||
PostgreSQL 18.4 started and Flyway applied V1 for the persistence and concurrency contexts.
|
||||
BUILD SUCCESS
|
||||
Process exited 0.
|
||||
```
|
||||
|
||||
## External-test boundaries
|
||||
|
||||
The source audit does not replace compilation, reflection/JPA bootstrapping, MVC property access, PostgreSQL
|
||||
persistence, or Javadoc/doclint. Those checks are required as affected verification after the source contract turns
|
||||
GREEN. No application behavior or public API is intentionally changed by this retrofit.
|
||||
|
||||
Additional verification on the same source tree:
|
||||
|
||||
```text
|
||||
./mvnw -DskipTests compile
|
||||
BUILD SUCCESS
|
||||
|
||||
./mvnw -Dtest=AttendanceLombokBoilerplateTest,AttendanceLayerStructureTest,AttendancePolicyTest,AttendanceServiceTest,AttendanceApplicationServiceTest,AttendanceControllerTest test
|
||||
Tests run: 27, Failures: 0, Errors: 0, Skipped: 0
|
||||
BUILD SUCCESS
|
||||
|
||||
./mvnw -Dtest=AttendancePersistenceIntegrationTest,AttendanceConcurrencyIntegrationTest test
|
||||
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
|
||||
PostgreSQL 18.4; BUILD SUCCESS
|
||||
|
||||
javadoc -quiet -Xdoclint:all -d target/attendance-javadocs -classpath "target/classes:<Maven dependency classpath>" -sourcepath src/main/java -subpackages com.lab.labtimesheet.feature.attendance
|
||||
Process exited 0. The source frontend reported seven generated-constructor missing-comment warnings because it does not
|
||||
expand Lombok constructors; repository policy exempts generated trivial constructors from duplicate Javadoc.
|
||||
```
|
||||
+3
-6
@@ -7,6 +7,8 @@ import com.lab.labtimesheet.feature.attendance.service.AttendanceApplicationServ
|
||||
import com.lab.labtimesheet.feature.attendance.service.AttendanceCurrentUserService;
|
||||
import java.security.Principal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -22,17 +24,12 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/attendance")
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class AttendanceController {
|
||||
|
||||
private final AttendanceApplicationService attendance;
|
||||
private final AttendanceCurrentUserService currentUsers;
|
||||
|
||||
AttendanceController(
|
||||
AttendanceApplicationService attendance, AttendanceCurrentUserService currentUsers) {
|
||||
this.attendance = attendance;
|
||||
this.currentUsers = currentUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the authenticated Intern's inclusive attendance history, defaulting to the current month.
|
||||
*
|
||||
|
||||
+3
-9
@@ -7,6 +7,8 @@ import com.lab.labtimesheet.feature.attendance.service.AttendanceCurrentUserServ
|
||||
import com.lab.labtimesheet.feature.attendance.service.CalendarApplicationService;
|
||||
import java.security.Principal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -23,21 +25,13 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/attendance/calendar")
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class CalendarController {
|
||||
|
||||
private final CalendarApplicationService calendar;
|
||||
private final AttendanceApplicationService attendance;
|
||||
private final AttendanceCurrentUserService currentUsers;
|
||||
|
||||
CalendarController(
|
||||
CalendarApplicationService calendar,
|
||||
AttendanceApplicationService attendance,
|
||||
AttendanceCurrentUserService currentUsers) {
|
||||
this.calendar = calendar;
|
||||
this.attendance = attendance;
|
||||
this.currentUsers = currentUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the next year of locally stored calendar events for an authenticated Admin.
|
||||
*
|
||||
|
||||
+3
-5
@@ -19,12 +19,15 @@ import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* JPA mapping of an immutable-on-effective attendance policy version and its configured workdays.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "attendance_policy_versions")
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class AttendancePolicyEntity {
|
||||
|
||||
@Id
|
||||
@@ -65,11 +68,6 @@ public class AttendancePolicyEntity {
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
/**
|
||||
* Required by JPA; application code resolves existing effective-dated versions instead of constructing them here.
|
||||
*/
|
||||
protected AttendancePolicyEntity() {}
|
||||
|
||||
/**
|
||||
* Converts the persisted version to the immutable policy used for historical boundary calculations.
|
||||
*
|
||||
|
||||
+3
-5
@@ -13,12 +13,15 @@ import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Version;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* JPA persistence model for one Intern/work-date punch row with its permanently attached policy version.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "attendance_records")
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class AttendanceRecordEntity {
|
||||
|
||||
@Id
|
||||
@@ -44,11 +47,6 @@ public class AttendanceRecordEntity {
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
/**
|
||||
* Required by JPA.
|
||||
*/
|
||||
protected AttendanceRecordEntity() {}
|
||||
|
||||
/**
|
||||
* Creates a new persistence row from server-authoritative raw punch values.
|
||||
*
|
||||
|
||||
+3
-5
@@ -10,12 +10,15 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Version;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* JPA model for the locally authoritative global calendar decision.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "global_calendar_events")
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class GlobalCalendarEventEntity {
|
||||
|
||||
@Id
|
||||
@@ -43,11 +46,6 @@ public class GlobalCalendarEventEntity {
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
/**
|
||||
* Required by JPA.
|
||||
*/
|
||||
protected GlobalCalendarEventEntity() {}
|
||||
|
||||
/**
|
||||
* Creates a custom calendar event attributed to the Admin actor.
|
||||
*
|
||||
|
||||
+3
-5
@@ -9,12 +9,15 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* JPA mapping of an immutable leave-day allocation whose exact date, policy, and quota snapshot remain historical.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "leave_request_days")
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class LeaveRequestDayEntity {
|
||||
|
||||
@EmbeddedId
|
||||
@@ -35,11 +38,6 @@ public class LeaveRequestDayEntity {
|
||||
@Column(name = "monthly_quota_snapshot", nullable = false)
|
||||
private int monthlyQuotaSnapshot;
|
||||
|
||||
/**
|
||||
* Required by JPA.
|
||||
*/
|
||||
protected LeaveRequestDayEntity() {}
|
||||
|
||||
LeaveRequestDayEntity(
|
||||
LeaveRequestEntity request,
|
||||
LocalDate leaveDate,
|
||||
|
||||
+3
-5
@@ -5,11 +5,14 @@ import jakarta.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Objects;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Composite identifier of one frozen quota-consuming date within a leave request.
|
||||
*/
|
||||
@Embeddable
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class LeaveRequestDayId implements Serializable {
|
||||
|
||||
/** Parent request identity used by the composite primary key. */
|
||||
@@ -20,11 +23,6 @@ public class LeaveRequestDayId implements Serializable {
|
||||
@Column(name = "leave_date", nullable = false)
|
||||
private LocalDate leaveDate;
|
||||
|
||||
/**
|
||||
* Required by JPA.
|
||||
*/
|
||||
protected LeaveRequestDayId() {}
|
||||
|
||||
/**
|
||||
* Creates the identity for an already-persisted request and its exact allocated date.
|
||||
*
|
||||
|
||||
+3
-5
@@ -9,12 +9,15 @@ import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Version;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Minimal Attendance-owned JPA mapping of leave request state used when evaluating frozen leave-day allocations.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "leave_requests")
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class LeaveRequestEntity {
|
||||
|
||||
@Id
|
||||
@@ -51,11 +54,6 @@ public class LeaveRequestEntity {
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
/**
|
||||
* Required by JPA.
|
||||
*/
|
||||
protected LeaveRequestEntity() {}
|
||||
|
||||
LeaveRequestEntity(
|
||||
long internUserId,
|
||||
LocalDate startDate,
|
||||
|
||||
+4
-18
@@ -20,9 +20,11 @@ import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -31,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* Account eligibility is obtained only through {@link AccountService}; raw rows retain their attached policy.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class AttendanceApplicationService {
|
||||
|
||||
private final Clock clock;
|
||||
@@ -41,23 +44,6 @@ public class AttendanceApplicationService {
|
||||
private final CalendarApplicationService calendar;
|
||||
private final AttendanceService attendance;
|
||||
|
||||
AttendanceApplicationService(
|
||||
Clock clock,
|
||||
AttendancePolicyRepository policyEntities,
|
||||
AttendanceRecordRepository recordEntities,
|
||||
AttendanceQueryRepository queries,
|
||||
AccountService accounts,
|
||||
CalendarApplicationService calendar,
|
||||
AttendanceService attendance) {
|
||||
this.clock = clock;
|
||||
this.policyEntities = policyEntities;
|
||||
this.recordEntities = recordEntities;
|
||||
this.queries = queries;
|
||||
this.accounts = accounts;
|
||||
this.calendar = calendar;
|
||||
this.attendance = attendance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the sole server-time check-in for the effective policy-local date.
|
||||
* Eligibility, workday, calendar, and exact frozen leave allocation are evaluated in the transaction;
|
||||
|
||||
+3
-4
@@ -6,6 +6,8 @@ import com.lab.labtimesheet.feature.account.service.AccountService;
|
||||
import com.lab.labtimesheet.feature.attendance.model.AttendanceActor;
|
||||
import com.lab.labtimesheet.feature.attendance.model.AttendanceRole;
|
||||
import java.security.Principal;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -13,14 +15,11 @@ import org.springframework.stereotype.Service;
|
||||
* Converts Spring Security principals into active Attendance authorization contexts through AccountService DTOs.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class AttendanceCurrentUserService {
|
||||
|
||||
private final AccountService accounts;
|
||||
|
||||
AttendanceCurrentUserService(AccountService accounts) {
|
||||
this.accounts = accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the authenticated email through the Account feature and rejects missing or inactive identities.
|
||||
*
|
||||
|
||||
+3
-2
@@ -8,16 +8,17 @@ import com.lab.labtimesheet.feature.attendance.model.AttendanceRecord;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Pure attendance punch rules over immutable policy, date context, and raw record values.
|
||||
*/
|
||||
@Service
|
||||
@NoArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public final class AttendanceService {
|
||||
|
||||
AttendanceService() {}
|
||||
|
||||
/**
|
||||
* Creates the sole raw check-in for an eligible Intern/date using the supplied server instant.
|
||||
* Equality at the grace boundary is accepted; violation classification remains attached-policy based.
|
||||
|
||||
+3
-9
@@ -12,6 +12,8 @@ import com.lab.labtimesheet.feature.attendance.repository.GlobalCalendarEventRep
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -20,21 +22,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* Transactional boundary for the locally authoritative global calendar and its cross-feature day-off decision.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class CalendarApplicationService {
|
||||
|
||||
private final Clock clock;
|
||||
private final AttendancePolicyRepository policies;
|
||||
private final GlobalCalendarEventRepository events;
|
||||
|
||||
CalendarApplicationService(
|
||||
Clock clock,
|
||||
AttendancePolicyRepository policies,
|
||||
GlobalCalendarEventRepository events) {
|
||||
this.clock = clock;
|
||||
this.policies = policies;
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Admin-authored custom event on a non-past policy-local date.
|
||||
*
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.lab.labtimesheet.feature.attendance;
|
||||
|
||||
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 AttendanceLombokBoilerplateTest {
|
||||
|
||||
private static final Path SOURCE_ROOT =
|
||||
Path.of("src/main/java/com/lab/labtimesheet/feature/attendance");
|
||||
|
||||
@Test
|
||||
void injectionOnlyComponentsUsePackageScopedRequiredArgsConstructors() throws IOException {
|
||||
for (String relativePath : List.of(
|
||||
"controller/AttendanceController.java",
|
||||
"controller/CalendarController.java",
|
||||
"service/AttendanceApplicationService.java",
|
||||
"service/AttendanceCurrentUserService.java",
|
||||
"service/CalendarApplicationService.java")) {
|
||||
String source = source(relativePath);
|
||||
String typeName = typeName(relativePath);
|
||||
|
||||
assertThat(source)
|
||||
.as(relativePath)
|
||||
.contains(
|
||||
"import lombok.AccessLevel;",
|
||||
"import lombok.RequiredArgsConstructor;",
|
||||
"@RequiredArgsConstructor(access = AccessLevel.PACKAGE)")
|
||||
.doesNotContain(typeName + "(");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void jpaTypesAndStatelessServiceUseTargetedNoArgsConstructors() throws IOException {
|
||||
for (String relativePath : List.of(
|
||||
"model/entity/AttendancePolicyEntity.java",
|
||||
"model/entity/AttendanceRecordEntity.java",
|
||||
"model/entity/GlobalCalendarEventEntity.java",
|
||||
"model/entity/LeaveRequestDayEntity.java",
|
||||
"model/entity/LeaveRequestDayId.java",
|
||||
"model/entity/LeaveRequestEntity.java")) {
|
||||
String source = source(relativePath);
|
||||
String typeName = typeName(relativePath);
|
||||
|
||||
assertThat(source)
|
||||
.as(relativePath)
|
||||
.contains(
|
||||
"import lombok.AccessLevel;",
|
||||
"import lombok.NoArgsConstructor;",
|
||||
"@NoArgsConstructor(access = AccessLevel.PROTECTED)")
|
||||
.doesNotContain("protected " + typeName + "()");
|
||||
}
|
||||
|
||||
assertThat(source("service/AttendanceService.java"))
|
||||
.contains(
|
||||
"import lombok.AccessLevel;",
|
||||
"import lombok.NoArgsConstructor;",
|
||||
"@NoArgsConstructor(access = AccessLevel.PACKAGE)")
|
||||
.doesNotContain("AttendanceService()");
|
||||
}
|
||||
|
||||
@Test
|
||||
void auditRetainsRecordsAndExplicitBusinessMethodsWithoutBlanketData() throws IOException {
|
||||
try (var sources = Files.walk(SOURCE_ROOT)) {
|
||||
for (Path sourcePath : sources.filter(path -> path.toString().endsWith(".java")).toList()) {
|
||||
assertThat(Files.readString(sourcePath)).as(sourcePath.toString()).doesNotContain("@Data");
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(source("model/AttendancePolicy.java")).contains("public record AttendancePolicy(");
|
||||
assertThat(source("model/AttendanceRecord.java"))
|
||||
.contains("public record AttendanceRecord(", "public AttendanceRecord checkOut(Instant at)");
|
||||
assertThat(source("model/dto/AttendanceHistoryItem.java"))
|
||||
.contains("public record AttendanceHistoryItem(");
|
||||
assertThat(source("model/entity/GlobalCalendarEventEntity.java"))
|
||||
.contains("public void update(", "public LocalDate calendarDate()", "public long version()");
|
||||
assertThat(source("model/entity/AttendanceRecordEntity.java"))
|
||||
.contains("public void setCheckOutAt(", "public LocalDate workDate()");
|
||||
assertThat(source("model/entity/LeaveRequestDayId.java"))
|
||||
.contains("public boolean equals(", "public int hashCode()");
|
||||
}
|
||||
|
||||
private static String source(String relativePath) throws IOException {
|
||||
return Files.readString(SOURCE_ROOT.resolve(relativePath));
|
||||
}
|
||||
|
||||
private static String typeName(String relativePath) {
|
||||
String fileName = Path.of(relativePath).getFileName().toString();
|
||||
return fileName.substring(0, fileName.length() - ".java".length());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user