From 7fd551d6f8bbf2185cfdfae0e63e67a2b50fadda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 11:40:44 +0100 Subject: [PATCH 1/7] EmailValidator test suite --- .../MakeItFit/utils/EmailValidatorTest.java | 85 +++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java index 1a7605a..90b1c6a 100644 --- a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java +++ b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java @@ -1,13 +1,88 @@ package MakeItFit.utils; -import MakeItFit.utils.MakeItFitDate; -import org.junit.jupiter.api.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class EmailValidatorTest { @Test - public void testValid() { - assertTrue(EmailValidator.isValidEmail("jonh@mail.com")); + void testQuotedAndDoubleDot() { + assertTrue(EmailValidator.isValidEmail("\"john..doe\"@uminho.pt")); + } + + @Test + void testIPv4LiteralDomain() { + assertTrue(EmailValidator.isValidEmail("user@[192.168.0.1]")); + } + + @Test + void testLocalBangAndPercent() { + assertTrue(EmailValidator.isValidEmail("user%example.com@example.org")); + } + + @Test + void testSingleLetters() { + assertTrue(EmailValidator.isValidEmail("x@y.co")); + } + + @Test + void testLocalQuotedSingleLetter() { + assertTrue(EmailValidator.isValidEmail("\"a\"@b.co")); + } + + @Test + void testLocalPlusTag() { + assertTrue(EmailValidator.isValidEmail("first.last+tag@example.com")); + } + + @Test + void testLocalAndDomainHyphenOrUnderscore() { + assertTrue(EmailValidator.isValidEmail("first_last-123@sub-domain.example.co.uk")); + } + + @Test + void testDomainStartsWithHyphen() { + assertFalse(EmailValidator.isValidEmail("user@-example.com")); + } + + @Test + void testDomainEndsWithHyphen() { + assertFalse(EmailValidator.isValidEmail("user@example-.com")); + } + + @Test + void testDomainConsecutiveDots() { + assertFalse(EmailValidator.isValidEmail("user@sub..example.com")); + } + + @Test + void testLocalTrailingDot() { + assertFalse(EmailValidator.isValidEmail("user.@example.com")); + } + + @Test + void testLocalStartsWithDot() { + assertFalse(EmailValidator.isValidEmail(".user@example.com")); + } + + @Test + void testDomainSpace() { + assertFalse(EmailValidator.isValidEmail("user@exa mple.com")); + } + + @Test + void testTLDMissing() { + assertFalse(EmailValidator.isValidEmail("user@example")); + } + + @Test + void testQuotedAndSpace() { + assertFalse(EmailValidator.isValidEmail("\"john doe\"@uminho.pt")); + } + + @Test + void testEmpty() { + assertFalse(EmailValidator.isValidEmail("")); } } From 815276684e16d1177ad03447b98a11271ed8d7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 11:41:13 +0100 Subject: [PATCH 2/7] implement new regex to better handle email validation --- src/main/java/MakeItFit/utils/EmailValidator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/MakeItFit/utils/EmailValidator.java b/src/main/java/MakeItFit/utils/EmailValidator.java index 4980f9a..10dcc25 100644 --- a/src/main/java/MakeItFit/utils/EmailValidator.java +++ b/src/main/java/MakeItFit/utils/EmailValidator.java @@ -1,6 +1,5 @@ package MakeItFit.utils; -import java.io.Serializable; import java.util.regex.Pattern; /** @@ -11,7 +10,10 @@ */ public class EmailValidator { + /* fails several tests private static final String EMAIL_PATTERN = "^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; + */ + private static final String EMAIL_PATTERN = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; /** * Verifies if the email is valid. From fef789e8d4942f9a6d35d019314234ef4ea40a75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 15:20:18 +0100 Subject: [PATCH 3/7] add constructor initiation --- src/unittests/java/MakeItFit/utils/EmailValidatorTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java index 90b1c6a..707427a 100644 --- a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java +++ b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java @@ -1,6 +1,7 @@ package MakeItFit.utils; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.junit.jupiter.api.Test; @@ -85,4 +86,9 @@ void testQuotedAndSpace() { void testEmpty() { assertFalse(EmailValidator.isValidEmail("")); } + + @Test + void testToForceCoverage() { + new EmailValidator(); + } } From 0c61dc723e7ae92795ed2df4c093a2d12bbc804e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 15:22:06 +0100 Subject: [PATCH 4/7] new test suites --- .../MakeItFit/utils/ExtendedRandomTest.java | 69 ++++++++++++++++ .../MakeItFit/utils/MakeItFitDateTest.java | 82 +++++++++++++++++++ .../java/MakeItFit/utils/MyTupleTest.java | 3 + 3 files changed, 154 insertions(+) create mode 100644 src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java create mode 100644 src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java create mode 100644 src/unittests/java/MakeItFit/utils/MyTupleTest.java diff --git a/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java b/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java new file mode 100644 index 0000000..feb58f8 --- /dev/null +++ b/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java @@ -0,0 +1,69 @@ +package MakeItFit.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +public class ExtendedRandomTest { + private int SAMPLE_SIZE = 1000; + + @Test + void testRangeBoundariesUnseededRandom() { + ExtendedRandom unseededRandom = new ExtendedRandom(); + for (int i = 0; i < SAMPLE_SIZE; i++) { + int expected = unseededRandom.nextInt(5, 15); + assertTrue(expected >= 5 && expected < 15); + } + } + + @Test + void testDeterministicOutputSeededRandom() { + ExtendedRandom seededRandom = new ExtendedRandom(123456L); + int[] firstRun = new int[5]; + for (int i = 0; i < firstRun.length; i++) { + firstRun[i] = seededRandom.nextInt(5, 10); + } + + ExtendedRandom repeatRandom = new ExtendedRandom(123456L); + for (int i = 0; i < firstRun.length; i++) { + assertEquals(firstRun[i], repeatRandom.nextInt(5, 10)); + } + } + + @Test + void testOriginEqualThrows() { + ExtendedRandom unseededRandom = new ExtendedRandom(); + assertThrows( + IllegalArgumentException.class, + () -> unseededRandom.nextInt(10, 10) + ); + } + + @Test + void testOriginGreaterThrows() { + ExtendedRandom unseededRandom = new ExtendedRandom(); + assertThrows( + IllegalArgumentException.class, + () -> unseededRandom.nextInt(15, 5) + ); + } + + @Test + void testSingleValueRange() { + ExtendedRandom unseededRandom = new ExtendedRandom(); + for (int i = 0; i < SAMPLE_SIZE; i++) { + assertEquals(5, unseededRandom.nextInt(5, 6)); + } + } + + @Test + void testNegativeOriginPositiveBound() { + ExtendedRandom unseededRandom = new ExtendedRandom(); + for (int i = 0; i < SAMPLE_SIZE; i++) { + int expected = unseededRandom.nextInt(-5, 5); + assertTrue(expected >= -5 && expected < 5); + } + } +} diff --git a/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java b/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java new file mode 100644 index 0000000..48c7a52 --- /dev/null +++ b/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java @@ -0,0 +1,82 @@ +package MakeItFit.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.jupiter.api.Test; + +public class MakeItFitDateTest { + + @Test + void testFromStringValidStandardFormat() { + MakeItFitDate date = MakeItFitDate.fromString("04/06/2025"); + assertEquals(4, date.getDayOfMonth()); + assertEquals(6, date.getMonth()); + assertEquals(2025, date.getYear()); + assertEquals(4, date.getDayOfWeek()); + } + + @Test + void testFromStringValidBoundary() { + MakeItFitDate d = MakeItFitDate.fromString("31/12/1999"); + assertEquals(31, d.getDayOfMonth()); + assertEquals(12, d.getMonth()); + assertEquals(1999, d.getYear()); + } + + @Test + void testFromStringInvalidDelimiter() { + assertThrows( + IllegalArgumentException.class, + () -> MakeItFitDate.fromString("04-06-2025") + ); + } + + @Test + void testFromStringInvalidPartsCount() { + assertThrows( + IllegalArgumentException.class, + () -> MakeItFitDate.fromString("01/01")); + } + + @Test + void testFromStringInvalidNonNumeric() { + assertThrows( + IllegalArgumentException.class, + () -> MakeItFitDate.fromString("aa/bb/cccc" + )); + } + + /* + @Test + @DisplayName("Invalid day (32/01/2020)") + void invalidDayOutOfRange() { + // LocalDate.of throws DateTimeException when day = 32—MakeItFitDate wraps it in IllegalArgumentException—turn1search6 + assertThrows(IllegalArgumentException.class, + () -> MakeItFitDate.fromString("32/01/2020")); + } + + @Test + @DisplayName("Invalid month (15/13/2020)") + void invalidMonthOutOfRange() { + assertThrows(IllegalArgumentException.class, + () -> MakeItFitDate.fromString("15/13/2020")); + } + + @Test + @DisplayName("Non‐existent leap date (29/02/2019)") + void invalidNonLeapYear() { + // 2019 is not a leap year, so LocalDate.of(2019, 2, 29) throws DateTimeException—wrapped as IllegalArgumentException—turn1search6 + assertThrows(IllegalArgumentException.class, + () -> MakeItFitDate.fromString("29/02/2019")); + } + + @Test + @DisplayName("Empty string") + void invalidEmptyString() { + assertThrows(IllegalArgumentException.class, + () -> MakeItFitDate.fromString(""), + "Empty string"); + } + */ +} diff --git a/src/unittests/java/MakeItFit/utils/MyTupleTest.java b/src/unittests/java/MakeItFit/utils/MyTupleTest.java new file mode 100644 index 0000000..2ad43b1 --- /dev/null +++ b/src/unittests/java/MakeItFit/utils/MyTupleTest.java @@ -0,0 +1,3 @@ +package MakeItFit.utils; + +public class MyTupleTest {} From a89c3ad0999f2a64a3182bc057e432bc1b4d1bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 17:26:31 +0100 Subject: [PATCH 5/7] finish utils test suite --- .../MakeItFit/utils/EmailValidatorTest.java | 4 +- .../MakeItFit/utils/ExtendedRandomTest.java | 22 +- .../MakeItFit/utils/MakeItFitDateTest.java | 223 ++++++++++++++---- .../java/MakeItFit/utils/MyTupleTest.java | 94 +++++++- 4 files changed, 275 insertions(+), 68 deletions(-) diff --git a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java index 707427a..654ccce 100644 --- a/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java +++ b/src/unittests/java/MakeItFit/utils/EmailValidatorTest.java @@ -1,11 +1,11 @@ package MakeItFit.utils; +import org.junit.jupiter.api.Test; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import org.junit.jupiter.api.Test; - public class EmailValidatorTest { @Test void testQuotedAndDoubleDot() { diff --git a/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java b/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java index feb58f8..8d5f772 100644 --- a/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java +++ b/src/unittests/java/MakeItFit/utils/ExtendedRandomTest.java @@ -1,11 +1,11 @@ package MakeItFit.utils; +import org.junit.jupiter.api.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import org.junit.jupiter.api.Test; - public class ExtendedRandomTest { private int SAMPLE_SIZE = 1000; @@ -14,14 +14,15 @@ void testRangeBoundariesUnseededRandom() { ExtendedRandom unseededRandom = new ExtendedRandom(); for (int i = 0; i < SAMPLE_SIZE; i++) { int expected = unseededRandom.nextInt(5, 15); - assertTrue(expected >= 5 && expected < 15); + assertTrue(expected >= 5); + assertTrue(expected < 15); } } @Test void testDeterministicOutputSeededRandom() { ExtendedRandom seededRandom = new ExtendedRandom(123456L); - int[] firstRun = new int[5]; + int[] firstRun = new int[5]; for (int i = 0; i < firstRun.length; i++) { firstRun[i] = seededRandom.nextInt(5, 10); } @@ -35,19 +36,13 @@ void testDeterministicOutputSeededRandom() { @Test void testOriginEqualThrows() { ExtendedRandom unseededRandom = new ExtendedRandom(); - assertThrows( - IllegalArgumentException.class, - () -> unseededRandom.nextInt(10, 10) - ); + assertThrows(IllegalArgumentException.class, () -> unseededRandom.nextInt(10, 10)); } @Test void testOriginGreaterThrows() { ExtendedRandom unseededRandom = new ExtendedRandom(); - assertThrows( - IllegalArgumentException.class, - () -> unseededRandom.nextInt(15, 5) - ); + assertThrows(IllegalArgumentException.class, () -> unseededRandom.nextInt(15, 5)); } @Test @@ -63,7 +58,8 @@ void testNegativeOriginPositiveBound() { ExtendedRandom unseededRandom = new ExtendedRandom(); for (int i = 0; i < SAMPLE_SIZE; i++) { int expected = unseededRandom.nextInt(-5, 5); - assertTrue(expected >= -5 && expected < 5); + assertTrue(expected >= -5); + assertTrue(expected < 5); } } } diff --git a/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java b/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java index 48c7a52..5a5eed2 100644 --- a/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java +++ b/src/unittests/java/MakeItFit/utils/MakeItFitDateTest.java @@ -1,11 +1,22 @@ package MakeItFit.utils; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; +import java.time.LocalDate; import org.junit.jupiter.api.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + public class MakeItFitDateTest { + @Test + void testConstructor() { + MakeItFitDate currentDate = new MakeItFitDate(); + assertTrue(LocalDate.now().isBefore(currentDate.getDate()) || + LocalDate.now().isEqual(currentDate.getDate())); + } @Test void testFromStringValidStandardFormat() { @@ -13,70 +24,178 @@ void testFromStringValidStandardFormat() { assertEquals(4, date.getDayOfMonth()); assertEquals(6, date.getMonth()); assertEquals(2025, date.getYear()); - assertEquals(4, date.getDayOfWeek()); + assertEquals(3, date.getDayOfWeek()); } @Test void testFromStringValidBoundary() { - MakeItFitDate d = MakeItFitDate.fromString("31/12/1999"); - assertEquals(31, d.getDayOfMonth()); - assertEquals(12, d.getMonth()); - assertEquals(1999, d.getYear()); + MakeItFitDate date = MakeItFitDate.fromString("31/12/1999"); + assertEquals(31, date.getDayOfMonth()); + assertEquals(12, date.getMonth()); + assertEquals(1999, date.getYear()); } @Test void testFromStringInvalidDelimiter() { - assertThrows( - IllegalArgumentException.class, - () -> MakeItFitDate.fromString("04-06-2025") - ); + assertThrows(IllegalArgumentException.class, () -> MakeItFitDate.fromString("04-06-2025")); } @Test void testFromStringInvalidPartsCount() { - assertThrows( - IllegalArgumentException.class, - () -> MakeItFitDate.fromString("01/01")); + assertThrows(IllegalArgumentException.class, () -> MakeItFitDate.fromString("01/01")); } @Test void testFromStringInvalidNonNumeric() { - assertThrows( - IllegalArgumentException.class, - () -> MakeItFitDate.fromString("aa/bb/cccc" - )); - } - - /* - @Test - @DisplayName("Invalid day (32/01/2020)") - void invalidDayOutOfRange() { - // LocalDate.of throws DateTimeException when day = 32—MakeItFitDate wraps it in IllegalArgumentException—turn1search6 - assertThrows(IllegalArgumentException.class, - () -> MakeItFitDate.fromString("32/01/2020")); - } - - @Test - @DisplayName("Invalid month (15/13/2020)") - void invalidMonthOutOfRange() { - assertThrows(IllegalArgumentException.class, - () -> MakeItFitDate.fromString("15/13/2020")); - } - - @Test - @DisplayName("Non‐existent leap date (29/02/2019)") - void invalidNonLeapYear() { - // 2019 is not a leap year, so LocalDate.of(2019, 2, 29) throws DateTimeException—wrapped as IllegalArgumentException—turn1search6 - assertThrows(IllegalArgumentException.class, - () -> MakeItFitDate.fromString("29/02/2019")); - } - - @Test - @DisplayName("Empty string") - void invalidEmptyString() { - assertThrows(IllegalArgumentException.class, - () -> MakeItFitDate.fromString(""), - "Empty string"); - } - */ + assertThrows(IllegalArgumentException.class, () -> MakeItFitDate.fromString("aa/bb/cccc")); + } + + @Test + void testFromStringInvalidEmptyString() { + assertThrows(IllegalArgumentException.class, () -> MakeItFitDate.fromString("")); + } + + @Test + void testsFromStringInvalidNullString() { + assertThrows(NullPointerException.class, () -> MakeItFitDate.fromString(null)); + } + + @Test + void testsToStringFormat() { + assertEquals("04/06/2025", MakeItFitDate.of(2025, 6, 4).toString()); + } + + @Test + void testCrossMonthBoundary() { + assertEquals("02/02/2021", MakeItFitDate.fromString("28/01/2021").plusDays(5).toString()); + } + + @Test + void testCompareToOrdering() { + assertTrue(MakeItFitDate.fromString("01/01/2025") + .compareTo(MakeItFitDate.fromString("15/06/2025")) < 0); + assertTrue(MakeItFitDate.fromString("15/06/2025") + .compareTo(MakeItFitDate.fromString("01/01/2025")) > 0); + } + + @Test + void testIsBefore() { + assertTrue(MakeItFitDate.fromString("01/01/2025") + .isBefore(MakeItFitDate.fromString("15/06/2025"))); + } + + @Test + void testIsBefore2() { + assertFalse(MakeItFitDate.fromString("15/06/2025") + .isBefore(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsBefore3() { + assertFalse(MakeItFitDate.fromString("01/01/2025") + .isBefore(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsBeforeOrSame() { + assertTrue(MakeItFitDate.fromString("01/01/2025") + .isBeforeOrSame(MakeItFitDate.fromString("15/06/2025"))); + } + + @Test + void testIsBeforeOrSame2() { + assertFalse(MakeItFitDate.fromString("15/06/2025") + .isBeforeOrSame(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsBeforeOrSame3() { + assertTrue(MakeItFitDate.fromString("01/01/2025") + .isBeforeOrSame(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsAfter() { + assertFalse( + MakeItFitDate.fromString("01/01/2025").isAfter(MakeItFitDate.fromString("15/06/2025"))); + } + + @Test + void testIsAfter2() { + assertTrue( + MakeItFitDate.fromString("15/06/2025").isAfter(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsAfter3() { + assertFalse( + MakeItFitDate.fromString("01/01/2025").isAfter(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsAfterOrSame() { + assertFalse(MakeItFitDate.fromString("01/01/2025") + .isAfterOrSame(MakeItFitDate.fromString("15/06/2025"))); + } + + @Test + void testIsAfterOrSame2() { + assertTrue(MakeItFitDate.fromString("15/06/2025") + .isAfterOrSame(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testIsAfterOrSame3() { + assertTrue(MakeItFitDate.fromString("01/01/2025") + .isAfterOrSame(MakeItFitDate.fromString("01/01/2025"))); + } + + @Test + void testDistanceReturnsZero() { + assertEquals(0, + MakeItFitDate.fromString("04/06/2025") + .distance(MakeItFitDate.fromString("04/06/2025"))); + } + + @Test + void testDistanceAdjacentDays() { + assertEquals(1, + MakeItFitDate.fromString("10/10/2025") + .distance(MakeItFitDate.fromString("11/10/2025"))); + } + + @Test + void testDistanceAcrossMonths() { + assertEquals(5, + MakeItFitDate.fromString("28/01/2025") + .distance(MakeItFitDate.fromString("02/02/2025"))); + } + + @Test + void testDistanceAcrossYears() { + assertEquals(7305, + MakeItFitDate.fromString("01/01/2000") + .distance(MakeItFitDate.fromString("01/01/2020"))); + } + + @Test + void testEqualsTrue() { + assertTrue( + MakeItFitDate.fromString("15/05/2025").equals(MakeItFitDate.fromString("15/05/2025"))); + } + + @Test + void testEqualsFalse() { + assertFalse( + MakeItFitDate.fromString("15/05/2015").equals(MakeItFitDate.fromString("16/05/2015"))); + } + + @Test + void testClone() { + MakeItFitDate date = MakeItFitDate.of(2025, 06, 04); + MakeItFitDate dateClone = date.clone(); + + assertTrue(dateClone.equals(date)); + assertNotSame(dateClone, date); + } } diff --git a/src/unittests/java/MakeItFit/utils/MyTupleTest.java b/src/unittests/java/MakeItFit/utils/MyTupleTest.java index 2ad43b1..3d57977 100644 --- a/src/unittests/java/MakeItFit/utils/MyTupleTest.java +++ b/src/unittests/java/MakeItFit/utils/MyTupleTest.java @@ -1,3 +1,95 @@ package MakeItFit.utils; -public class MyTupleTest {} +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class MyTupleTest { + @Test + void testConstructor() { + MyTuple tuple = new MyTuple<>("hello", "world"); + assertEquals("hello", tuple.getItem1()); + assertEquals("world", tuple.getItem2()); + } + + @Test + void tesConstructorNullParameters() { + MyTuple tuple = new MyTuple<>(null, null); + assertNull(tuple.getItem1()); + assertNull(tuple.getItem2()); + } + + @Test + void testToStringFormat() { + MyTuple tuple = new MyTuple<>("A", 24); + assertEquals("(A, 24)", tuple.toString()); + } + + @Test + void testEqualsItem1Differs() { + MyTuple tuple1 = new MyTuple<>("A", 24); + MyTuple tuple2 = new MyTuple<>("B", 24); + assertFalse(tuple1.equals(tuple2)); + } + + @Test + void testEqualsItem2Differs() { + MyTuple tuple1 = new MyTuple<>("A", 24); + MyTuple tuple2 = new MyTuple<>("A", 25); + assertFalse(tuple1.equals(tuple2)); + } + + @Test + void testEquals() { + MyTuple tuple = new MyTuple<>("A", "24"); + assertTrue(tuple.equals(tuple)); + } + + @Test + void testEqualsNullParameter() { + MyTuple tuple = new MyTuple<>(24, "A"); + assertFalse(tuple.equals(null)); + } + + @Test + @SuppressWarnings("unlikely-arg-type") + void testEqualsDifferentClass() { + MyTuple tuple = new MyTuple<>("A", 24); + assertFalse(tuple.equals("(A, 24)")); + } + + @Test + void testCompareToItem1Different() { + MyTuple tuple1 = new MyTuple<>("A", 24); + MyTuple tuple2 = new MyTuple<>("B", 24); + assertTrue(tuple1.compareTo(tuple2) < 0); + assertTrue(tuple2.compareTo(tuple1) > 0); + } + + @Test + void testCompareToItem2Different() { + MyTuple tuple1 = new MyTuple<>("A", 24); + MyTuple tuple2 = new MyTuple<>("A", 25); + assertTrue(tuple1.compareTo(tuple2) < 0); + assertTrue(tuple2.compareTo(tuple1) > 0); + } + + @Test + void testCompareToEqualTuples() { + MyTuple tuple1 = new MyTuple<>("A", 24); + MyTuple tuple2 = new MyTuple<>("A", 24); + assertTrue(tuple1.compareTo(tuple2) == 0); + } + + @Test + void testClone() { + MyTuple tuple = new MyTuple<>("A", 24); + MyTuple tupleClone = tuple.clone(); + assertEquals(tuple, tupleClone); + assertNotSame(tuple, tupleClone); + } +} From bf02f8fa2b969dd7ff9617f1f552614802e2c464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 17:27:33 +0100 Subject: [PATCH 6/7] apply formater and fix compiler warnings related to MyTupple --- src/main/java/MakeItFit/utils/EmailValidator.java | 3 ++- src/main/java/MakeItFit/utils/MyTuple.java | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/MakeItFit/utils/EmailValidator.java b/src/main/java/MakeItFit/utils/EmailValidator.java index 10dcc25..5acabcf 100644 --- a/src/main/java/MakeItFit/utils/EmailValidator.java +++ b/src/main/java/MakeItFit/utils/EmailValidator.java @@ -13,7 +13,8 @@ public class EmailValidator { /* fails several tests private static final String EMAIL_PATTERN = "^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; */ - private static final String EMAIL_PATTERN = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; + private static final String EMAIL_PATTERN = + "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; /** * Verifies if the email is valid. diff --git a/src/main/java/MakeItFit/utils/MyTuple.java b/src/main/java/MakeItFit/utils/MyTuple.java index 12b3ceb..ebb1f7d 100644 --- a/src/main/java/MakeItFit/utils/MyTuple.java +++ b/src/main/java/MakeItFit/utils/MyTuple.java @@ -11,7 +11,7 @@ * @author Afonso Santos (a104276), Hélder Gomes (a104100) and Pedro Pereira (a104082) * @version (11052024) */ -public class MyTuple implements Serializable, Comparable { +public class MyTuple implements Serializable, Comparable> { private final T1 item1; private final T2 item2; @@ -81,7 +81,7 @@ public boolean equals(Object o) { * or greater than the other tuple */ @Override - public int compareTo(MyTuple other) { + public int compareTo(MyTuple other) { int compareItem1 = this.item1.toString().compareTo(other.item1.toString()); if (compareItem1 == 0) { return this.item2.toString().compareTo(other.item2.toString()); @@ -95,7 +95,7 @@ public int compareTo(MyTuple other) { * @return A new MyTuple instance that is a copy of the current instance. */ @Override - public MyTuple clone() { - return new MyTuple(this.item1, this.item2); + public MyTuple clone() { + return new MyTuple(this.item1, this.item2); } } From 1439a19c4b9dd6dd67143dc555bd2554c2247e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lopes?= Date: Wed, 4 Jun 2025 17:42:12 +0100 Subject: [PATCH 7/7] add notations about code changes --- src/main/java/MakeItFit/utils/MyTuple.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/MakeItFit/utils/MyTuple.java b/src/main/java/MakeItFit/utils/MyTuple.java index ebb1f7d..f18b6fb 100644 --- a/src/main/java/MakeItFit/utils/MyTuple.java +++ b/src/main/java/MakeItFit/utils/MyTuple.java @@ -11,6 +11,9 @@ * @author Afonso Santos (a104276), Hélder Gomes (a104100) and Pedro Pereira (a104082) * @version (11052024) */ +/* References to generic type MyTuple should be parameterized +public class MyTuple implements Serializable, Comparable { +*/ public class MyTuple implements Serializable, Comparable> { private final T1 item1; @@ -81,6 +84,9 @@ public boolean equals(Object o) { * or greater than the other tuple */ @Override + /* References to generic type MyTuple should be parameterized + public int compareTo(MyTuple other) { + */ public int compareTo(MyTuple other) { int compareItem1 = this.item1.toString().compareTo(other.item1.toString()); if (compareItem1 == 0) { @@ -95,6 +101,10 @@ public int compareTo(MyTuple other) { * @return A new MyTuple instance that is a copy of the current instance. */ @Override + /* References to generic type MyTuple should be parameterized + public MyTuple clone() { + return new MyTuple(this.item1, this.item2); + */ public MyTuple clone() { return new MyTuple(this.item1, this.item2); }