Commit 8be97bfa authored by Christoph Schimeczek's avatar Christoph Schimeczek
Browse files

Merge branch '169-timestamp-add-matches' into 'dev'

Resolve "TimeStamp: add matches()"

Closes #169

See merge request !152
parents f65fe4ac bebe57e7
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)_
### Added
- Add `spotless` to CI to enforce code formatting standards #145 (@dlr-cjs)
- Add warning if input data cannot be matched to an Agent's parameters #101 (@dlr-cjs)
- Add additional comparison for `TimeStamp` that avoids `instanceof` #169 (@dlr-cjs)
- Add tests with Java 25 to CI #164 (@dlr-cjs)

## [2.0.3](https://gitlab.com/fame-framework/fame-core/-/releases/v2.0.3) - 2025-04-05
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 -->

  <groupId>de.dlr.gitlab.fame</groupId>
  <artifactId>core</artifactId>
  <version>3.0.0-alpha7</version>
  <version>3.0.0-alpha8</version>

  <name>FAME-Core</name>
  <description>An open framework for distributed agent-based modeling of energy systems</description>
+10 −3
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2020-2025 German Aerospace Center <fame@dlr.de>
// SPDX-FileCopyrightText: 2020-2026 German Aerospace Center <fame@dlr.de>
//
// SPDX-License-Identifier: Apache-2.0
package de.dlr.gitlab.fame.time;
@@ -226,9 +226,9 @@ public final class TimeStamp implements Comparable<TimeStamp>, Portable {
		return Long.hashCode(getStep());
	}

	/** Return true if this {@link TimeStamp} represents the same simulation time as the specified TimeStamp
	/** Return true if the given Object is a {@link TimeStamp} with the same simulation time as this {@link TimeStamp}
	 * 
	 * @return true if this {@link TimeStamp} represents the same simulation time as the specified TimeStamp */
	 * @return true if the given Object is a {@link TimeStamp} with the same simulation time as this {@link TimeStamp} */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof TimeStamp) {
@@ -237,4 +237,11 @@ public final class TimeStamp implements Comparable<TimeStamp>, Portable {
		}
		return false;
	}

	/** Return true if given {@link TimeStamp} represents the same simulation time as this {@link TimeStamp}
	 * 
	 * @return true if given {@link TimeStamp} represents the same simulation time as this {@link TimeStamp} */
	public boolean matches(TimeStamp other) {
		return other == null ? false : getStep() == other.getStep();
	}
}
 No newline at end of file
+102 −57
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2020-2025 German Aerospace Center <fame@dlr.de>
// SPDX-FileCopyrightText: 2020-2026 German Aerospace Center <fame@dlr.de>
//
// SPDX-License-Identifier: Apache-2.0
package de.dlr.gitlab.fame.time;
@@ -23,37 +23,37 @@ public class TimeStampTest {
	TimeStamp simulationBegin = new TimeStamp(0);

	@Test
	public void testFirstHour() {
	public void toCalendar_firstHour_correctFormat() {
		assertEquals("2000-01-01 00:00:00", simulationBegin.toCalendar());
	}

	@Test
	public void testFirstDay() {
	public void toCalendar_firstDay_correctFormat() {
		TimeStamp timeStamp = simulationBegin.laterBy(new TimeSpan(1, Interval.DAYS));
		assertEquals("2000-01-02 00:00:00", timeStamp.toCalendar());
	}

	@Test
	public void testFirstMonth() {
	public void toCalendar_firstMonth_correctFormat() {
		TimeStamp timeStamp = simulationBegin.laterBy(new TimeSpan(1, Interval.MONTHS));
		assertEquals("2000-01-31 10:00:00", timeStamp.toCalendar());
	}

	@Test
	public void testLeapYearA() {
	public void toCalendar_leapYearBeginning_correctFormat() {
		TimeStamp timeStamp = simulationBegin.laterBy(new TimeSpan(1, Interval.YEARS));
		assertEquals("2001-01-01 00:00:00", timeStamp.toCalendar());
	}

	@Test
	public void testLeapYearLastHour() {
	public void toCalendar_leapYearLastHour_correctFormat() {
		TimeStamp timeStamp = simulationBegin.laterBy(new TimeSpan(1, Interval.YEARS))
				.earlierBy(new TimeSpan(1, Interval.SECONDS));
		assertEquals("2000-12-30 23:59:59", timeStamp.toCalendar());
	}

	@Test
	public void test2018_08_14_11_55_12() {
	public void toCalendar_2018_08_14_11_55_12_correctFormat() {
		TimeSpan timeSpan = TimeSpan.combine(new TimeSpan(18, Interval.YEARS), new TimeSpan(225, Interval.DAYS),
				new TimeSpan(11, Interval.HOURS), new TimeSpan(55, Interval.MINUTES), new TimeSpan(12, Interval.SECONDS));
		TimeStamp timeStamp = simulationBegin.laterBy(timeSpan);
@@ -61,26 +61,47 @@ public class TimeStampTest {
	}

	@Test
	public void testGreaterThan() {
		TimeStamp lesserTime = new TimeStamp(0);
		TimeStamp higherTime = new TimeStamp(1);
		assertTrue(higherTime.isGreaterThan(lesserTime));
		assertFalse(lesserTime.isGreaterThan(higherTime));
		assertFalse(higherTime.isGreaterThan(higherTime));
	public void greaterThan_earlier_returnsFalse() {
		TimeStamp earlierTime = new TimeStamp(0);
		TimeStamp laterTime = new TimeStamp(1);
		assertFalse(earlierTime.isGreaterThan(laterTime));
	}

	@Test
	public void testCompareTo() {
		TimeStamp lesserTime = new TimeStamp(0);
		TimeStamp higherTime = new TimeStamp(1);
	public void greaterThan_equals_returnsFalse() {
		TimeStamp laterTime = new TimeStamp(1);
		assertFalse(laterTime.isGreaterThan(laterTime));
	}

		assertTrue(lesserTime.compareTo(higherTime) < 0);
		assertTrue(higherTime.compareTo(higherTime) == 0);
		assertTrue(higherTime.compareTo(lesserTime) > 0);
	@Test
	public void greaterThan_later_returnsTrue() {
		TimeStamp earlierTime = new TimeStamp(0);
		TimeStamp laterTime = new TimeStamp(1);
		assertTrue(laterTime.isGreaterThan(earlierTime));
	}

	@Test
	public void testNextTimeOfDayLaterToday() {
	public void compareTo_later_returnsNegative() {
		TimeStamp earlierTime = new TimeStamp(0);
		TimeStamp laterTime = new TimeStamp(1);
		assertTrue(earlierTime.compareTo(laterTime) < 0);
	}

	@Test
	public void compareTo_equal_returnsZero() {
		TimeStamp laterTime = new TimeStamp(1);
		assertEquals(0, laterTime.compareTo(laterTime));
	}

	@Test
	public void compareTo_earlier_returnsPositive() {
		TimeStamp earlierTime = new TimeStamp(0);
		TimeStamp laterTime = new TimeStamp(1);
		assertTrue(laterTime.compareTo(earlierTime) > 0);
	}

	@Test
	public void nextTimeOfDay_laterToday_returnsToday() {
		TimeStamp currentTime = simulationBegin.laterBy(new TimeSpan(5, Interval.HOURS));
		TimeOfDay timeOfDay = new TimeOfDay(15, 0, 0);
		TimeStamp nextTime = currentTime.nextTimeOfDay(timeOfDay);
@@ -88,7 +109,7 @@ public class TimeStampTest {
	}

	@Test
	public void testNextTimeOfDayTomorrow() {
	public void nextTimeOfDay_laterThanToday_returnsNextDay() {
		TimeStamp currentTime = simulationBegin.laterBy(new TimeSpan(15, Interval.HOURS));
		TimeOfDay timeOfDay = new TimeOfDay(5, 0, 0);
		TimeStamp nextTime = currentTime.nextTimeOfDay(timeOfDay);
@@ -96,7 +117,7 @@ public class TimeStampTest {
	}

	@Test
	public void testNextTimeOfDayMatchesNow() {
	public void nextTimeOfDay_exactMatch_returnsNextDay() {
		TimeStamp currentTime = simulationBegin.laterBy(new TimeSpan(15, Interval.HOURS));
		TimeOfDay timeOfDay = new TimeOfDay(15, 0, 0);
		TimeStamp nextTime = currentTime.nextTimeOfDay(timeOfDay);
@@ -104,162 +125,162 @@ public class TimeStampTest {
	}

	@Test
	public void testIsLessThanLesser() {
	public void isLessThan_lesser_returnsFalse() {
		TimeStamp later = new TimeStamp(10L);
		assertFalse(later.isLessThan(new TimeStamp(0L)));
	}

	@Test
	public void testIsLessThanGreater() {
	public void isLessThan_greater_returnsTrue() {
		TimeStamp later = new TimeStamp(0L);
		assertTrue(later.isLessThan(new TimeStamp(10L)));
	}

	@Test
	public void testIsLessThanEqual() {
	public void isLessThan_equal_returnsFalse() {
		TimeStamp later = new TimeStamp(10L);
		assertFalse(later.isLessThan(new TimeStamp(10L)));
	}

	@Test
	public void testIsLessEqualTo_Less() {
	public void isLessEqualTo_greater_returnsTrue() {
		TimeStamp earlier = new TimeStamp(5L);
		TimeStamp later = new TimeStamp(10L);
		assertTrue(earlier.isLessEqualTo(later));
	}

	@Test
	public void testIsLessEqualTo_Equal() {
	public void isLessEqualTo_equal_returnsTrue() {
		TimeStamp now = new TimeStamp(10L);
		TimeStamp alsoNow = new TimeStamp(10L);
		assertTrue(now.isLessEqualTo(alsoNow));
	}

	@Test
	public void testIsLessEqualTo_Greater() {
	public void isLessEqualTo_smaller_returnsFalse() {
		TimeStamp earlier = new TimeStamp(5L);
		TimeStamp later = new TimeStamp(10L);
		assertFalse(later.isLessEqualTo(earlier));
	}

	@Test
	public void testIsGreaterEqualThanLess() {
	public void isGreaterEqualTo_smaller_returnsTrue() {
		TimeStamp now = new TimeStamp(10L);
		assertTrue(now.isGreaterEqualTo(now.earlierByOne()));
	}

	@Test
	public void testIsGreaterEqualThanEqual() {
	public void isGreaterEqualTo_equal_returnsTrue() {
		TimeStamp now = new TimeStamp(10L);
		assertTrue(now.isGreaterEqualTo(new TimeStamp(10L)));
	}

	@Test
	public void testIsGreaterEqualThanGreater() {
	public void isGreaterEqualTo_greater_returnsFalse() {
		TimeStamp now = new TimeStamp(10L);
		assertFalse(now.isGreaterEqualTo(now.laterByOne()));
	}

	@Test
	public void testGetStep_FailWhenInvalid() {
	public void getStep_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).getStep());
	}

	@Test
	public void testToString_FailWhenInvalid() {
	public void toString_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).toCalendar());
	}

	@Test
	public void testLaterBy_FailWhenInvalid() {
	public void laterBy_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).laterBy(new TimeSpan(1)));
	}

	@Test
	public void testLaterByOne_FailWhenInvalid() {
	public void laterByOne_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).laterByOne());
	}

	@Test
	public void testEarlierBy_FailWhenInvalid() {
	public void earlierBy_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).earlierBy(new TimeSpan(1)));
	}

	@Test
	public void testIsLessEqualTo_FailWhenInvalid() {
	public void isLessEqualTo_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).isLessEqualTo(simulationBegin));
	}

	@Test
	public void testIsLessThan_FailWhenInvalid() {
	public void isLessThan_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).isLessThan(simulationBegin));
	}

	@Test
	public void testIsGreaterEqualTo_FailWhenInvalid() {
	public void tsGreaterEqualTo_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).isGreaterEqualTo(simulationBegin));
	}

	@Test
	public void testIsGreaterThan_FailWhenInvalid() {
	public void isGreaterThan_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).isGreaterThan(simulationBegin));
	}

	@Test
	public void testNextTimeOfDay_FailWhenInvalid() {
	public void nextTimeOfDay_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).nextTimeOfDay(new TimeOfDay(0, 0, 0)));
	}

	@Test
	public void testHashCode_FailWhenInvalid() {
	public void hashCode_uninitialised_throws() {
		assertThrowsFatalMessage(TimeStamp.ERR_INVALID, () -> (new TimeStamp()).hashCode());
	}

	@Test
	public void testHashCode_IdenticalObjects() {
	public void hashCode_identicalObjects_returnsSameHash() {
		assertEquals(simulationBegin.hashCode(), simulationBegin.hashCode());
	}

	@Test
	public void testEquals_IdenticalObjects() {
	public void equals_identicalObjects_returnsTrue() {
		assertTrue(simulationBegin.equals(simulationBegin));
	}

	@Test
	public void testHashCode_SameTimes() {
	public void hashCode_sameTimes_returnSameHash() {
		TimeStamp a = new TimeStamp(42L);
		TimeStamp b = new TimeStamp(42L);
		assertEquals(a.hashCode(), b.hashCode());
	}

	@Test
	public void testEquals_SameTimes() {
	public void equals_sameTimes_returnsTrue() {
		TimeStamp a = new TimeStamp(42L);
		TimeStamp b = new TimeStamp(42L);
		assertTrue(a.equals(b));
	}

	@Test
	public void testEquals_DifferentTimes() {
	public void equals_differentTimes_returnsFalse() {
		TimeStamp a = new TimeStamp(451L);
		TimeStamp b = new TimeStamp(19L);
		assertFalse(a.equals(b));
	}

	@Test
	public void testEquals_Null() {
	public void equals_null_returnsFalse() {
		assertFalse(simulationBegin.equals(null));
	}

	@SuppressWarnings("unlikely-arg-type")
	@Test
	public void testEquals_NoInstance() {
	public void equals_noInstance_returnsFalse() {
		TimeStamp timeStamp = new TimeStamp(21L);
		assertFalse(timeStamp.equals("NotATimeStamp"));
	}

	@Test
	public void testAddComponentsTo() {
	public void addComponentsTo_componentsAdded() {
		ComponentCollector mockCollector = mock(ComponentCollector.class);
		TimeStamp timeStamp = new TimeStamp(7L);
		timeStamp.addComponentsTo(mockCollector);
@@ -267,7 +288,7 @@ public class TimeStampTest {
	}

	@Test
	public void testPopulate() {
	public void populate_populatesAttributes() {
		TimeStamp timeStamp = new TimeStamp();
		ComponentProvider mockProvider = mock(ComponentProvider.class);
		when(mockProvider.nextLong()).thenReturn(76L);
@@ -286,33 +307,33 @@ public class TimeStampTest {
	}

	@Test
	public void testLaterByMultiples() {
	public void laterBy_positiveMultiple_returnsExpected() {
		TimeStamp timeStamp = new TimeStamp(0);
		TimeStamp result = timeStamp.laterBy(new TimeSpan(54), 33);
		assertEquals(54 * 33, result.getStep());
	}

	@Test
	public void testLaterByMultiplesFailNegative() {
	public void laterBy_negativeMultiple_throws() {
		TimeStamp timeStamp = new TimeStamp(0);
		assertThrowsFatalMessage(TimeStamp.ERR_NOT_POSITIVE, () -> timeStamp.laterBy(new TimeSpan(2), -2));
	}

	@Test
	public void testEarlierByMultiples() {
	public void earlierBy_positiveMultiple_returnsExpected() {
		TimeStamp timeStamp = new TimeStamp(0);
		TimeStamp result = timeStamp.earlierBy(new TimeSpan(54), 33);
		assertEquals(-54 * 33, result.getStep());
	}

	@Test
	public void testEarlierByMultiplesFailNegative() {
	public void earlierBy_negativeMultiple_throws() {
		TimeStamp timeStamp = new TimeStamp(0);
		assertThrowsFatalMessage(TimeStamp.ERR_NOT_POSITIVE, () -> timeStamp.earlierBy(new TimeSpan(2), -2));
	}

	@Test
	public void testToStringCallsFormatter() {
	public void toString_callsFormatter() {
		long step = 55;
		TimeStamp timeStamp = new TimeStamp(step);
		try (MockedStatic<Formatter> formatterMock = Mockito.mockStatic(Formatter.class)) {
@@ -322,10 +343,34 @@ public class TimeStampTest {
	}

	@Test
	public void testToStringReturnsFormatterResult() {
	public void toString_returnsFormatterResult() {
		long step = 389748923745L;
		TimeStamp timeStamp = new TimeStamp(step);
		String result = timeStamp.toString();
		assertEquals(Formatter.formatTimeStamp(step), result);
	}

	@Test
	public void matches_null_returnsFalse() {
		TimeStamp timeStamp = new TimeStamp(0);
		assertFalse(timeStamp.matches(null));
	}

	@Test
	public void matches_different_returnsFalse() {
		TimeStamp timeStamp = new TimeStamp(0);
		assertFalse(timeStamp.matches(new TimeStamp(99)));
	}

	@Test
	public void matches_positiveEquals_returnsTrue() {
		TimeStamp timeStamp = new TimeStamp(42);
		assertTrue(timeStamp.matches(new TimeStamp(42)));
	}

	@Test
	public void matches_negativeEquals_returnsTrue() {
		TimeStamp timeStamp = new TimeStamp(-42);
		assertTrue(timeStamp.matches(new TimeStamp(-42)));
	}
}
 No newline at end of file