-
-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
379 additions
and
145 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
jollyday-tests/src/test/java/de/focus_shift/jollyday/tests/CalendarCheckerApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package de.focus_shift.jollyday.tests; | ||
|
||
import de.focus_shift.jollyday.core.HolidayCalendar; | ||
import de.focus_shift.jollyday.core.HolidayType; | ||
|
||
import java.time.Month; | ||
import java.time.Year; | ||
|
||
public interface CalendarCheckerApi { | ||
|
||
interface Holiday { | ||
Properties hasFixedHoliday(final String propertyKey, final Month month, final int day); | ||
Properties hasFixedHoliday(final String propertyKey, final Month month, final int day, final HolidayType type); | ||
|
||
Properties hasChristianHoliday(final String propertyKey); | ||
Properties hasChristianHoliday(final String propertyKey, final HolidayType type); | ||
|
||
Properties hasIslamicHoliday(final String propertyKey); | ||
Properties hasIslamicHoliday(final String propertyKey, final HolidayType type); | ||
} | ||
|
||
interface Properties extends Subdivision, Between, Check { | ||
} | ||
|
||
interface Subdivision extends Check { | ||
Between inSubdivision(final String... subdivisions); | ||
} | ||
|
||
interface Between extends Check { | ||
Between between(Year from, Year to); | ||
} | ||
|
||
interface Check { | ||
Holiday and(); | ||
void check(); | ||
} | ||
|
||
static CalendarCheckerFluent assertFor(final HolidayCalendar calendar) { | ||
return new CalendarCheckerFluent(calendar); | ||
} | ||
} |
276 changes: 276 additions & 0 deletions
276
jollyday-tests/src/test/java/de/focus_shift/jollyday/tests/CalendarCheckerFluent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
package de.focus_shift.jollyday.tests; | ||
|
||
import de.focus_shift.jollyday.core.Holiday; | ||
import de.focus_shift.jollyday.core.HolidayCalendar; | ||
import de.focus_shift.jollyday.core.HolidayManager; | ||
import de.focus_shift.jollyday.core.HolidayType; | ||
import net.jqwik.api.Arbitraries; | ||
import net.jqwik.time.api.arbitraries.YearArbitrary; | ||
import org.junit.jupiter.api.Assertions; | ||
|
||
import java.time.LocalDate; | ||
import java.time.Month; | ||
import java.time.Year; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
|
||
import static de.focus_shift.jollyday.core.ManagerParameters.create; | ||
import static de.focus_shift.jollyday.tests.CalendarCheckerFluent.Category.BY_DAY; | ||
import static de.focus_shift.jollyday.tests.CalendarCheckerFluent.Category.BY_KEY; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
public class CalendarCheckerFluent implements CalendarCheckerApi.Holiday, CalendarCheckerApi.Between, CalendarCheckerApi.Properties { | ||
|
||
enum Category { | ||
BY_DAY, | ||
BY_KEY | ||
} | ||
|
||
private final HolidayCalendar calendar; | ||
private String propertyKey; | ||
private Month month; | ||
private int day; | ||
private HolidayType type; | ||
private Category category; | ||
private String[] subdivisions = new String[]{}; | ||
private List<YearRange> validRanges = new ArrayList<>(); | ||
|
||
private final List<HolidayCalendarCheck> checks = new ArrayList<>(); | ||
|
||
public CalendarCheckerFluent(HolidayCalendar calendar) { | ||
this.calendar = calendar; | ||
} | ||
|
||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasChristianHoliday(final String propertyKey) { | ||
return hasChristianHoliday(propertyKey, HolidayType.PUBLIC_HOLIDAY); | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasChristianHoliday(final String propertyKey, final HolidayType type) { | ||
Objects.requireNonNull(propertyKey, "propertyKey is required"); | ||
Objects.requireNonNull(type, "holiday type is required"); | ||
|
||
this.category = BY_KEY; | ||
this.propertyKey = "christian." + propertyKey; | ||
this.type = type; | ||
|
||
return this; | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasIslamicHoliday(final String propertyKey) { | ||
return hasIslamicHoliday(propertyKey, HolidayType.PUBLIC_HOLIDAY); | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasIslamicHoliday(final String propertyKey, final HolidayType type) { | ||
Objects.requireNonNull(propertyKey, "propertyKey is required"); | ||
Objects.requireNonNull(type, "holiday type is required"); | ||
|
||
this.category = BY_KEY; | ||
this.propertyKey = "islamic." + propertyKey; | ||
this.type = type; | ||
|
||
return this; | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasFixedHoliday(final String propertyKey, final Month month, final int day) { | ||
return hasFixedHoliday(propertyKey, month, day, HolidayType.PUBLIC_HOLIDAY); | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Properties hasFixedHoliday(final String propertyKey, final Month month, final int day, final HolidayType type) { | ||
|
||
Objects.requireNonNull(propertyKey, "propertyKey is required"); | ||
Objects.requireNonNull(month, "month is required"); | ||
if (day >= 32 || day <= 0) { | ||
throw new IllegalArgumentException("day must be between 1 and 31"); | ||
} | ||
Objects.requireNonNull(type, "holiday type is required"); | ||
|
||
this.category = BY_DAY; | ||
this.propertyKey = propertyKey; | ||
this.month = month; | ||
this.day = day; | ||
this.type = type; | ||
|
||
return this; | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Between between(final Year from, Year to) { | ||
validRanges.add(new YearRange(from, to)); | ||
return this; | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Between inSubdivision(String... subdivisions) { | ||
this.subdivisions = subdivisions; | ||
return this; | ||
} | ||
|
||
@Override | ||
public CalendarCheckerApi.Holiday and() { | ||
checks.add(new HolidayCalendarCheck(this.calendar, this.propertyKey, this.month, this.day, this.type, this.validRanges, this.subdivisions, this.category)); | ||
|
||
clearProperties(); | ||
|
||
return this; | ||
} | ||
|
||
private void clearProperties() { | ||
this.propertyKey = null; | ||
this.month = null; | ||
this.day = 0; | ||
this.type = null; | ||
this.category = null; | ||
this.subdivisions = new String[]{}; | ||
this.validRanges = new ArrayList<>(); | ||
} | ||
|
||
@Override | ||
public void check() { | ||
checks.add(new HolidayCalendarCheck(calendar, propertyKey, month, day, type, validRanges, subdivisions, category)); | ||
|
||
clearProperties(); | ||
|
||
for (HolidayCalendarCheck check : checks) { | ||
switch (check.category) { | ||
case BY_DAY: | ||
checkByDate(check); | ||
break; | ||
case BY_KEY: | ||
checkByKey(check); | ||
break; | ||
default: | ||
throw new IllegalStateException("Unexpected value: " + check.category); | ||
} | ||
} | ||
|
||
this.checks.clear(); | ||
} | ||
|
||
private void checkByDate(HolidayCalendarCheck check) { | ||
final HolidayManager holidayManager = HolidayManager.getInstance(create(check.calendar)); | ||
|
||
for (final YearRange validRange : check.getValidRanges()) { | ||
createYearArbitrary() | ||
.between(validRange.getFrom().getValue(), validRange.getTo().getValue()) | ||
.forEachValue(year -> { | ||
final Set<Holiday> holidays = holidayManager.getHolidays(year, check.getSubdivisions()); | ||
assertThat(holidays) | ||
.isNotEmpty() | ||
.contains(new Holiday(LocalDate.of(year.getValue(), check.getMonth(), check.getDay()), check.getPropertiesKey(), check.getHolidayType())); | ||
} | ||
); | ||
} | ||
} | ||
|
||
private void checkByKey(HolidayCalendarCheck check) { | ||
final HolidayManager holidayManager = HolidayManager.getInstance(create(check.calendar)); | ||
|
||
for (final YearRange validRange : check.getValidRanges()) { | ||
createYearArbitrary() | ||
.between(validRange.getFrom().getValue(), validRange.getTo().getValue()) | ||
.forEachValue(year -> { | ||
final Set<Holiday> holidays = holidayManager.getHolidays(year, check.getSubdivisions()); | ||
assertThat(holidays) | ||
.isNotEmpty() | ||
.filteredOn(holiday -> holiday.getPropertiesKey().equals(check.getPropertiesKey())) | ||
.extracting(Holiday::getType) | ||
.contains(check.getHolidayType()); | ||
} | ||
); | ||
} | ||
} | ||
|
||
private static YearArbitrary createYearArbitrary() { | ||
return (YearArbitrary) Arbitraries.defaultFor(Year.class); | ||
} | ||
|
||
private static final class HolidayCalendarCheck { | ||
|
||
private final HolidayCalendar calendar; | ||
private final List<YearRange> validRanges; | ||
private final Month month; | ||
private final int day; | ||
private final String propertiesKey; | ||
private final HolidayType holidayType; | ||
private final String[] subdivisions; | ||
private final Category category; | ||
|
||
HolidayCalendarCheck(HolidayCalendar calendar, | ||
String propertiesKey, Month month, int day, HolidayType holidayType, | ||
List<YearRange> validRanges, String[] subdivisions, Category category | ||
) { | ||
this.calendar = calendar; | ||
this.propertiesKey = propertiesKey; | ||
this.month = month; | ||
this.day = day; | ||
this.holidayType = holidayType; | ||
this.validRanges = validRanges.isEmpty() ? List.of(new YearRange(Year.of(1900), Year.of(2500))) : Collections.unmodifiableList(validRanges); | ||
this.subdivisions = subdivisions; | ||
this.category = category; | ||
} | ||
|
||
public HolidayCalendar getCalendar() { | ||
return calendar; | ||
} | ||
|
||
public List<YearRange> getValidRanges() { | ||
return validRanges; | ||
} | ||
|
||
public Month getMonth() { | ||
return month; | ||
} | ||
|
||
public int getDay() { | ||
return day; | ||
} | ||
|
||
public String getPropertiesKey() { | ||
return propertiesKey; | ||
} | ||
|
||
public HolidayType getHolidayType() { | ||
return holidayType; | ||
} | ||
|
||
public String[] getSubdivisions() { | ||
return subdivisions; | ||
} | ||
|
||
public Category getCategory() { | ||
return category; | ||
} | ||
} | ||
|
||
private static class YearRange { | ||
|
||
private final Year from; | ||
private final Year to; | ||
|
||
YearRange(final Year from, final Year to) { | ||
if (from != null && to != null) { | ||
Assertions.assertFalse(from.isAfter(to), "To must be greater than or equal to the from year."); | ||
} | ||
this.from = from; | ||
this.to = to; | ||
} | ||
|
||
public Year getFrom() { | ||
return from; | ||
} | ||
|
||
public Year getTo() { | ||
return to; | ||
} | ||
} | ||
} |
Oops, something went wrong.