-
Notifications
You must be signed in to change notification settings - Fork 7
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
1 parent
bf1f0df
commit d57ab04
Showing
4 changed files
with
451 additions
and
0 deletions.
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
agents/src/main/java/uk/ac/ox/poseidon/agents/regulations/predicates/BetweenDates.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,73 @@ | ||
/* | ||
* POSEIDON: an agent-based model of fisheries | ||
* Copyright (c) 2025 CoHESyS Lab cohesys.lab@gmail.com | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
package uk.ac.ox.poseidon.agents.regulations.predicates; | ||
|
||
import lombok.Getter; | ||
import lombok.NonNull; | ||
import uk.ac.ox.poseidon.agents.behaviours.Action; | ||
|
||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.util.function.Predicate; | ||
|
||
import static com.google.common.base.Preconditions.checkArgument; | ||
|
||
/** | ||
* The BetweenDates class implements a predicate to determine whether an {@code Action}'s start or | ||
* end date falls within a specified range of dates. It uses {@code LocalDate} for comparison of | ||
* date ranges. | ||
* <p> | ||
* This class is immutable and requires two {@code LocalDate} objects, representing the inclusive | ||
* start and end dates for the range. | ||
* <p> | ||
* The predicate evaluates {@code true} if either the start or the end date of the {@code Action} | ||
* lies within the specified date range. Otherwise, it evaluates to {@code false}. | ||
*/ | ||
@Getter | ||
public class BetweenDates implements Predicate<Action> { | ||
|
||
@NonNull private final LocalDate start; | ||
@NonNull private final LocalDate end; | ||
|
||
public BetweenDates( | ||
@NonNull final LocalDate start, | ||
@NonNull final LocalDate end | ||
) { | ||
this.start = start; | ||
this.end = end; | ||
checkArgument( | ||
!start.isAfter(end), | ||
"Start date (%s) must not be after end date (%s).", | ||
start, | ||
end | ||
); | ||
} | ||
|
||
@Override | ||
public boolean test(final Action action) { | ||
return betweenDates(action.getStart()) || betweenDates(action.getEnd()); | ||
} | ||
|
||
private boolean betweenDates(final LocalDateTime dateTime) { | ||
final var date = dateTime.toLocalDate(); | ||
return !(date.isBefore(start) || date.isAfter(end)); | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
...ts/src/main/java/uk/ac/ox/poseidon/agents/regulations/predicates/BetweenDatesFactory.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,45 @@ | ||
/* | ||
* POSEIDON: an agent-based model of fisheries | ||
* Copyright (c) 2025 CoHESyS Lab cohesys.lab@gmail.com | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
package uk.ac.ox.poseidon.agents.regulations.predicates; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import uk.ac.ox.poseidon.core.Factory; | ||
import uk.ac.ox.poseidon.core.GlobalScopeFactory; | ||
import uk.ac.ox.poseidon.core.Simulation; | ||
|
||
import java.time.LocalDate; | ||
|
||
@Getter | ||
@Setter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class BetweenDatesFactory extends GlobalScopeFactory<BetweenDates> { | ||
|
||
Factory<? extends LocalDate> startDate; | ||
Factory<? extends LocalDate> endDate; | ||
|
||
@Override | ||
protected BetweenDates newInstance(final Simulation simulation) { | ||
return new BetweenDates(startDate.get(simulation), endDate.get(simulation)); | ||
} | ||
} |
166 changes: 166 additions & 0 deletions
166
...rc/test/java/uk/ac/ox/poseidon/agents/regulations/predicates/BetweenDatesFactoryTest.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,166 @@ | ||
/* | ||
* POSEIDON: an agent-based model of fisheries | ||
* Copyright (c) 2025 CoHESyS Lab cohesys.lab@gmail.com | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
package uk.ac.ox.poseidon.agents.regulations.predicates; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
import uk.ac.ox.poseidon.core.Factory; | ||
import uk.ac.ox.poseidon.core.Simulation; | ||
|
||
import java.time.LocalDate; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
class BetweenDatesFactoryTest { | ||
|
||
/** | ||
* Test class for {@link BetweenDatesFactory}. | ||
* | ||
* This class contains tests for the `newInstance` method of `BetweenDatesFactory`. | ||
* The `newInstance` method creates a new {@link BetweenDates} object | ||
* using the start and end dates obtained from the provided {@link Simulation}. | ||
*/ | ||
|
||
/** | ||
* Test when `newInstance` method successfully creates a `BetweenDates` object with valid start | ||
* and end dates. | ||
*/ | ||
@Test | ||
void testNewInstance_createsBetweenDatesWithValidDates() { | ||
// Arrange | ||
final LocalDate startDateStub = LocalDate.of(2023, 1, 1); | ||
final LocalDate endDateStub = LocalDate.of(2023, 12, 31); | ||
|
||
final Factory<LocalDate> startDateFactory = mock(Factory.class); | ||
final Factory<LocalDate> endDateFactory = mock(Factory.class); | ||
final Simulation mockSimulation = mock(Simulation.class); | ||
|
||
when(startDateFactory.get(mockSimulation)).thenReturn(startDateStub); | ||
when(endDateFactory.get(mockSimulation)).thenReturn(endDateStub); | ||
|
||
final BetweenDatesFactory factory = new BetweenDatesFactory( | ||
startDateFactory, | ||
endDateFactory | ||
); | ||
|
||
// Act | ||
final BetweenDates result = factory.newInstance(mockSimulation); | ||
|
||
// Assert | ||
assertEquals( | ||
startDateStub, | ||
result.getStart(), | ||
"Start date should match the provided value." | ||
); | ||
assertEquals(endDateStub, result.getEnd(), "End date should match the provided value."); | ||
} | ||
|
||
/** | ||
* Test when `newInstance` method is invoked and startDateFactory returns null. | ||
*/ | ||
@Test | ||
void testNewInstance_startDateFactoryReturnsNull() { | ||
// Arrange | ||
final LocalDate endDateStub = LocalDate.of(2023, 12, 31); | ||
|
||
final Factory<LocalDate> startDateFactory = mock(Factory.class); | ||
final Factory<LocalDate> endDateFactory = mock(Factory.class); | ||
final Simulation mockSimulation = mock(Simulation.class); | ||
|
||
when(startDateFactory.get(mockSimulation)).thenReturn(null); | ||
when(endDateFactory.get(mockSimulation)).thenReturn(endDateStub); | ||
|
||
final BetweenDatesFactory factory = new BetweenDatesFactory( | ||
startDateFactory, | ||
endDateFactory | ||
); | ||
|
||
// Act & Assert | ||
try { | ||
factory.newInstance(mockSimulation); | ||
} catch (final NullPointerException e) { | ||
assertEquals( | ||
"start is marked non-null but is null", | ||
e.getMessage(), | ||
"Expected NullPointerException for null start date." | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Test when `newInstance` method is invoked and endDateFactory returns null. | ||
*/ | ||
@Test | ||
void testNewInstance_endDateFactoryReturnsNull() { | ||
// Arrange | ||
final LocalDate startDateStub = LocalDate.of(2023, 1, 1); | ||
|
||
final Factory<LocalDate> startDateFactory = mock(Factory.class); | ||
final Factory<LocalDate> endDateFactory = mock(Factory.class); | ||
final Simulation mockSimulation = mock(Simulation.class); | ||
|
||
when(startDateFactory.get(mockSimulation)).thenReturn(startDateStub); | ||
when(endDateFactory.get(mockSimulation)).thenReturn(null); | ||
|
||
final BetweenDatesFactory factory = new BetweenDatesFactory( | ||
startDateFactory, | ||
endDateFactory | ||
); | ||
|
||
// Act & Assert | ||
try { | ||
factory.newInstance(mockSimulation); | ||
} catch (final NullPointerException e) { | ||
assertEquals( | ||
"end is marked non-null but is null", | ||
e.getMessage(), | ||
"Expected NullPointerException for null end date." | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Test to verify that `newInstance` method calls `get` on both startDateFactory and | ||
* endDateFactory. | ||
*/ | ||
@Test | ||
void testNewInstance_callsGetOnFactories() { | ||
// Arrange | ||
final Factory<LocalDate> startDateFactory = mock(Factory.class); | ||
when(startDateFactory.get(Mockito.any())).thenReturn(LocalDate.now()); | ||
final Factory<LocalDate> endDateFactory = mock(Factory.class); | ||
when(endDateFactory.get(Mockito.any())).thenReturn(LocalDate.now()); | ||
final Simulation mockSimulation = mock(Simulation.class); | ||
|
||
final BetweenDatesFactory factory = new BetweenDatesFactory( | ||
startDateFactory, | ||
endDateFactory | ||
); | ||
|
||
// Act | ||
factory.newInstance(mockSimulation); | ||
|
||
// Assert | ||
Mockito.verify(startDateFactory).get(mockSimulation); | ||
Mockito.verify(endDateFactory).get(mockSimulation); | ||
} | ||
} |
Oops, something went wrong.