Improve tests

* Dedup using parameterized tests
* Make ``now`` controllable
This commit is contained in:
litetex 2025-01-23 21:48:29 +01:00
parent ae07ba3c72
commit 746b36e80d
No known key found for this signature in database
GPG Key ID: 525B43E6039B3689
3 changed files with 126 additions and 134 deletions

View File

@ -28,8 +28,22 @@ public class TimeAgoParser {
* language word separator. * language word separator.
*/ */
public TimeAgoParser(final PatternsHolder patternsHolder) { public TimeAgoParser(final PatternsHolder patternsHolder) {
this(patternsHolder, OffsetDateTime.now(ZoneOffset.UTC));
}
/**
* Creates a helper to parse upload dates in the format '2 days ago'.
* <p>
* Instantiate a new {@link TimeAgoParser} every time you extract a new batch of items.
* </p>
*
* @param patternsHolder An object that holds the "time ago" patterns, special cases, and the
* language word separator.
* @param now The current time
*/
public TimeAgoParser(final PatternsHolder patternsHolder, final OffsetDateTime now) {
this.patternsHolder = patternsHolder; this.patternsHolder = patternsHolder;
now = OffsetDateTime.now(ZoneOffset.UTC); this.now = now;
} }
/** /**

View File

@ -3,6 +3,8 @@ package org.schabi.newpipe.extractor.localization;
import org.schabi.newpipe.extractor.timeago.PatternsHolder; import org.schabi.newpipe.extractor.timeago.PatternsHolder;
import org.schabi.newpipe.extractor.timeago.PatternsManager; import org.schabi.newpipe.extractor.timeago.PatternsManager;
import java.time.OffsetDateTime;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -26,4 +28,17 @@ public final class TimeAgoPatternsManager {
return new TimeAgoParser(holder); return new TimeAgoParser(holder);
} }
@Nullable
public static TimeAgoParser getTimeAgoParserFor(
@Nonnull final Localization localization,
@Nonnull final OffsetDateTime now) {
final PatternsHolder holder = getPatternsFor(localization);
if (holder == null) {
return null;
}
return new TimeAgoParser(holder, now);
}
} }

View File

@ -1,151 +1,114 @@
package org.schabi.newpipe.extractor.localization; package org.schabi.newpipe.extractor.localization;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.greaterThanDay;
import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.lessThanDay;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.junit.jupiter.params.provider.MethodSource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
public class TimeAgoParserTest { class TimeAgoParserTest {
private static TimeAgoParser parser; public static Stream<Arguments> parseTimeAgo() {
private static OffsetDateTime now; return Stream.of(
lessThanDay(Duration.ofSeconds(1), "1 second", "1 sec"),
@BeforeAll lessThanDay(Duration.ofSeconds(12), "12 second", "12 sec"),
public static void setUp() { lessThanDay(Duration.ofMinutes(1), "1 minute", "1 min"),
parser = TimeAgoPatternsManager.getTimeAgoParserFor(Localization.DEFAULT); lessThanDay(Duration.ofMinutes(23), "23 minutes", "23 min"),
now = OffsetDateTime.now(ZoneOffset.UTC); lessThanDay(Duration.ofHours(1), "1 hour", "1 hr"),
lessThanDay(Duration.ofHours(8), "8 hour", "8 hr"),
greaterThanDay(d -> d.minusDays(1), "1 day", "1 day"),
greaterThanDay(d -> d.minusDays(3), "3 days", "3 day"),
greaterThanDay(d -> d.minusWeeks(1), "1 week", "1 wk"),
greaterThanDay(d -> d.minusWeeks(3), "3 weeks", "3 wk"),
greaterThanDay(d -> d.minusMonths(1), "1 month", "1 mo"),
greaterThanDay(d -> d.minusMonths(3), "3 months", "3 mo"),
greaterThanDay(d -> d.minusYears(1).minusDays(1), "1 year", "1 yr"),
greaterThanDay(d -> d.minusYears(3).minusDays(1), "3 years", "3 yr")
).map(Arguments::of);
} }
@Test @ParameterizedTest
void parseTimeAgo() throws ParsingException { @MethodSource
assertTimeWithin1s( void parseTimeAgo(final ParseTimeAgoTestData testData) {
now.minusSeconds(1), final OffsetDateTime now = OffsetDateTime.of(
parser.parse("1 second ago").offsetDateTime() LocalDateTime.of(2020, 1, 1, 1, 1, 1),
); ZoneOffset.UTC);
assertTimeWithin1s( final TimeAgoParser parser = Objects.requireNonNull(
now.minusSeconds(12), TimeAgoPatternsManager.getTimeAgoParserFor(Localization.DEFAULT, now));
parser.parse("12 second ago").offsetDateTime()
); final OffsetDateTime expected = testData.getExpectedApplyToNow().apply(now);
assertTimeWithin1s(
now.minusMinutes(1), assertAll(
parser.parse("1 minute ago").offsetDateTime() Stream.of(
); testData.getTextualDateLong(),
assertTimeWithin1s( testData.getTextualDateShort())
now.minusMinutes(23), .map(textualDate -> () -> assertEquals(
parser.parse("23 minutes ago").offsetDateTime() expected,
); parser.parse(textualDate).offsetDateTime(),
assertTimeWithin1s( "Expected " + expected + " for " + textualDate
now.minusHours(1), ))
parser.parse("1 hour ago").offsetDateTime()
);
assertTimeWithin1s(
now.minusHours(8),
parser.parse("8 hours ago").offsetDateTime()
);
assertEquals(
now.minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 day ago").offsetDateTime()
);
assertEquals(
now.minusDays(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 days ago").offsetDateTime()
);
assertEquals(
now.minusWeeks(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 week ago").offsetDateTime()
);
assertEquals(
now.minusWeeks(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 weeks ago").offsetDateTime()
);
assertEquals(
now.minusMonths(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 month ago").offsetDateTime()
);
assertEquals(
now.minusMonths(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 months ago").offsetDateTime()
);
assertEquals(
now.minusYears(1).minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 year ago").offsetDateTime()
);
assertEquals(
now.minusYears(3).minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 years ago").offsetDateTime()
); );
} }
@Test static class ParseTimeAgoTestData {
void parseTimeAgoShort() throws ParsingException { public static final String AGO_SUFFIX = " ago";
final TimeAgoParser parser = TimeAgoPatternsManager.getTimeAgoParserFor(Localization.DEFAULT); private final Function<OffsetDateTime, OffsetDateTime> expectedApplyToNow;
final OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC); private final String textualDateLong;
private final String textualDateShort;
assertTimeWithin1s( ParseTimeAgoTestData(
now.minusSeconds(1), final Function<OffsetDateTime, OffsetDateTime> expectedApplyToNow,
parser.parse("1 sec ago").offsetDateTime() final String textualDateLong,
); final String textualDateShort
assertTimeWithin1s( ) {
now.minusSeconds(12), this.expectedApplyToNow = expectedApplyToNow;
parser.parse("12 sec ago").offsetDateTime() this.textualDateLong = textualDateLong;
); this.textualDateShort = textualDateShort;
assertTimeWithin1s( }
now.minusMinutes(1),
parser.parse("1 min ago").offsetDateTime()
);
assertTimeWithin1s(
now.minusMinutes(23),
parser.parse("23 min ago").offsetDateTime()
);
assertTimeWithin1s(
now.minusHours(1),
parser.parse("1 hr ago").offsetDateTime()
);
assertTimeWithin1s(
now.minusHours(8),
parser.parse("8 hr ago").offsetDateTime()
);
assertEquals(
now.minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 day ago").offsetDateTime()
);
assertEquals(
now.minusDays(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 days ago").offsetDateTime()
);
assertEquals(
now.minusWeeks(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 wk ago").offsetDateTime()
);
assertEquals(
now.minusWeeks(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 wk ago").offsetDateTime()
);
assertEquals(
now.minusMonths(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 mo ago").offsetDateTime()
);
assertEquals(
now.minusMonths(3).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 mo ago").offsetDateTime()
);
assertEquals(
now.minusYears(1).minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("1 yr ago").offsetDateTime()
);
assertEquals(
now.minusYears(3).minusDays(1).truncatedTo(ChronoUnit.HOURS),
parser.parse("3 yr ago").offsetDateTime()
);
}
void assertTimeWithin1s(final OffsetDateTime expected, final OffsetDateTime actual) { public static ParseTimeAgoTestData lessThanDay(
final long delta = Math.abs(expected.toEpochSecond() - actual.toEpochSecond()); final Duration duration,
assertTrue(delta <= 1, String.format("Expected: %s\nActual: %s", expected, actual)); final String textualDateLong,
final String textualDateShort
) {
return new ParseTimeAgoTestData(
d -> d.minus(duration),
textualDateLong + AGO_SUFFIX,
textualDateShort + AGO_SUFFIX);
}
public static ParseTimeAgoTestData greaterThanDay(
final Function<OffsetDateTime, OffsetDateTime> expectedApplyToNow,
final String textualDateLong,
final String textualDateShort
) {
return new ParseTimeAgoTestData(
d -> expectedApplyToNow.apply(d).truncatedTo(ChronoUnit.HOURS),
textualDateLong + AGO_SUFFIX,
textualDateShort + AGO_SUFFIX);
}
public Function<OffsetDateTime, OffsetDateTime> getExpectedApplyToNow() {
return expectedApplyToNow;
}
public String getTextualDateLong() {
return textualDateLong;
}
public String getTextualDateShort() {
return textualDateShort;
}
} }
} }