diff options
Diffstat (limited to 'Tests/AK/TestDuration.cpp')
-rw-r--r-- | Tests/AK/TestDuration.cpp | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/Tests/AK/TestDuration.cpp b/Tests/AK/TestDuration.cpp new file mode 100644 index 0000000000..d3f3b3dad6 --- /dev/null +++ b/Tests/AK/TestDuration.cpp @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2021, Ben Wiederhake <BenWiederhake.GitHub@gmx.de> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibTest/TestCase.h> + +#include <AK/Time.h> +#include <sys/time.h> + +#define EXPECT_DURATION(t, s, ns) \ + do { \ + auto ts = (t).to_timespec(); \ + EXPECT_EQ(ts.tv_sec, (s)); \ + EXPECT_EQ(ts.tv_nsec, (ns)); \ + } while (0) + +TEST_CASE(is_sane) +{ + auto t0 = Duration::from_seconds(0); + auto t2 = Duration::from_seconds(2); + auto t5 = Duration::from_seconds(5); + auto tn3 = Duration::from_seconds(-3); + EXPECT(t0 == t0); + EXPECT(t2 == t2); + EXPECT(t5 == t5); + EXPECT(t0 != t2); + EXPECT(t2 != tn3); + EXPECT(t2 != t5); + EXPECT_DURATION(t0, 0, 0); + EXPECT_DURATION(t2, 2, 0); + EXPECT_DURATION(t5, 5, 0); + EXPECT_DURATION(t2 + t5, 7, 0); + EXPECT_DURATION(tn3 + t2, -1, 0); + EXPECT_DURATION(tn3 + t5, 2, 0); +} + +TEST_CASE(limits) +{ + EXPECT_DURATION(Duration::min(), (i64)-0x8000'0000'0000'0000, 0); + EXPECT_DURATION(Duration::max(), 0x7fff'ffff'ffff'ffff, 999'999'999); +} + +TEST_CASE(seconds_parsing) +{ + EXPECT_DURATION(Duration::from_seconds(0), 0, 0); + EXPECT_DURATION(Duration::from_seconds(42), 42, 0); + EXPECT_DURATION(Duration::from_seconds(-1), -1, 0); + + // "6.4.4.1.5: The type of an integer constant is the first of the corresponding list in which its value can be represented." + // In the case of "0x8000'0000", the list is "int, unsigned int, …", and unsigned int (u32) matches. + // Then the unary minus: On unsigned 32-bit integers, -0x8000'0000 == 0x8000'0000, which only then is made signed again. + // So we would pass a medium-large *positive* number to 'from_seconds', which is not what we want to test here. + // That's why this is the only place that needs an "LL" suffix. + EXPECT_DURATION(Duration::from_seconds(-0x8000'0000LL), -0x8000'0000LL, 0); + EXPECT_DURATION(Duration::from_seconds(-0x8000'0000'0000'0000), (i64)-0x8000'0000'0000'0000, 0); + EXPECT_DURATION(Duration::from_seconds(0x7fff'ffff'ffff'ffff), 0x7fff'ffff'ffff'ffff, 0); +} + +TEST_CASE(timespec_parsing) +{ + EXPECT_DURATION(Duration::from_timespec(timespec { 2, 4 }), 2, 4); + EXPECT_DURATION(Duration::from_timespec(timespec { 1234, 5678 }), 1234, 5678); + + EXPECT_DURATION(Duration::from_timespec(timespec { 0, 1'000'000'000 }), 1, 0); + EXPECT_DURATION(Duration::from_timespec(timespec { 8, 2'000'000'000 }), 10, 0); + EXPECT_DURATION(Duration::from_timespec(timespec { 0, 2'147'483'647 }), 2, 147'483'647); + + EXPECT_DURATION(Duration::from_timespec(timespec { 1, -1 }), 0, 999'999'999); + EXPECT_DURATION(Duration::from_timespec(timespec { 0, -1 }), -1, 999'999'999); + EXPECT_DURATION(Duration::from_timespec(timespec { -1, 0 }), -1, 0); + EXPECT_DURATION(Duration::from_timespec(timespec { -1, 1'000'000'001 }), 0, 1); + EXPECT_DURATION(Duration::from_timespec(timespec { -2, 2'000'000'003 }), 0, 3); + EXPECT_DURATION(Duration::from_timespec(timespec { -2, 1'999'999'999 }), -1, 999'999'999); + + EXPECT_DURATION(Duration::from_timespec(timespec { 0x7fff'ffff'ffff'fffe, 999'999'998 }), 0x7fff'ffff'ffff'fffe, 999'999'998); + EXPECT_DURATION(Duration::from_timespec(timespec { 0x7fff'ffff'ffff'fffe, 1'999'999'998 }), 0x7fff'ffff'ffff'ffff, 999'999'998); + EXPECT_DURATION(Duration::from_timespec(timespec { 0x7fff'ffff'ffff'fffe, 1'999'999'999 }), 0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_DURATION(Duration::from_timespec(timespec { 0x7fff'ffff'ffff'fffe, 2'000'000'000 }), 0x7fff'ffff'ffff'ffff, 999'999'999); + + EXPECT_DURATION(Duration::from_timespec(timespec { -0x7fff'ffff'ffff'fffe, -1 }), -0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_DURATION(Duration::from_timespec(timespec { -0x7fff'ffff'ffff'fffe, -999'999'999 }), -0x7fff'ffff'ffff'ffff, 1); + EXPECT_DURATION(Duration::from_timespec(timespec { -0x7fff'ffff'ffff'fffe, -1'999'999'999 }), (i64)-0x8000'0000'0000'0000, 1); + EXPECT_DURATION(Duration::from_timespec(timespec { -0x7fff'ffff'ffff'fffe, -2'000'000'000 }), (i64)-0x8000'0000'0000'0000, 0); + EXPECT_DURATION(Duration::from_timespec(timespec { -0x7fff'ffff'ffff'fffe, -2'000'000'001 }), (i64)-0x8000'0000'0000'0000, 0); +} + +TEST_CASE(timeval_parsing) +{ + EXPECT_DURATION(Duration::from_timeval(timeval { 2, 4 }), 2, 4'000); + EXPECT_DURATION(Duration::from_timeval(timeval { 1234, 5'678 }), 1234, 5'678'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -123, -45'678 }), -124, 954'322'000); + + EXPECT_DURATION(Duration::from_timeval(timeval { 0, 1'000'000 }), 1, 0); + EXPECT_DURATION(Duration::from_timeval(timeval { 0, 1'000'000'000 }), 1'000, 0); + EXPECT_DURATION(Duration::from_timeval(timeval { 8, 2'000'000 }), 10, 0); + EXPECT_DURATION(Duration::from_timeval(timeval { 0, 2'147'483'647 }), 2'147, 483'647'000); + + EXPECT_DURATION(Duration::from_timeval(timeval { 1, -1 }), 0, 999'999'000); + EXPECT_DURATION(Duration::from_timeval(timeval { 0, -1 }), -1, 999'999'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -1, 0 }), -1, 0); + EXPECT_DURATION(Duration::from_timeval(timeval { -1, 1'000'001 }), 0, 1'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -2, 2'000'003 }), 0, 3'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -2, 1'999'999 }), -1, 999'999'000); + + EXPECT_DURATION(Duration::from_timeval(timeval { 0x7fff'ffff'ffff'fffe, 999'998 }), 0x7fff'ffff'ffff'fffe, 999'998'000); + EXPECT_DURATION(Duration::from_timeval(timeval { 0x7fff'ffff'ffff'fffe, 1'999'998 }), 0x7fff'ffff'ffff'ffff, 999'998'000); + EXPECT_DURATION(Duration::from_timeval(timeval { 0x7fff'ffff'ffff'fffe, 1'999'999 }), 0x7fff'ffff'ffff'ffff, 999'999'000); + EXPECT_DURATION(Duration::from_timeval(timeval { 0x7fff'ffff'ffff'fffe, 2'000'000 }), 0x7fff'ffff'ffff'ffff, 999'999'999); + + EXPECT_DURATION(Duration::from_timeval(timeval { -0x7fff'ffff'ffff'fffe, -1 }), -0x7fff'ffff'ffff'ffff, 999'999'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -0x7fff'ffff'ffff'fffe, -999'999 }), -0x7fff'ffff'ffff'ffff, 1'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -0x7fff'ffff'ffff'fffe, -1'999'999 }), (i64)-0x8000'0000'0000'0000, 1'000); + EXPECT_DURATION(Duration::from_timeval(timeval { -0x7fff'ffff'ffff'fffe, -2'000'000 }), (i64)-0x8000'0000'0000'0000, 0); + EXPECT_DURATION(Duration::from_timeval(timeval { -0x7fff'ffff'ffff'fffe, -2'000'001 }), (i64)-0x8000'0000'0000'0000, 0); +} + +#define DURATION(s, ns) \ + Duration::from_timespec(timespec { (s), (ns) }) + +TEST_CASE(addition) +{ +#define EXPECT_ADDITION(s1, ns1, s2, ns2, sr, nsr) \ + do { \ + EXPECT_DURATION(DURATION(s1, ns1) + DURATION(s2, ns2), sr, nsr); \ + EXPECT_DURATION(DURATION(s2, ns2) + DURATION(s1, ns1), sr, nsr); \ + auto t = DURATION(s1, ns1); \ + t += DURATION(s2, ns2); \ + EXPECT_DURATION(t, sr, nsr); \ + } while (0) + + EXPECT_ADDITION(11, 123'456'789, 22, 900'000'000, 34, 23'456'789); + + EXPECT_ADDITION(0, 0, 9223372036854775807LL, 999'999'998, 0x7fff'ffff'ffff'ffff, 999'999'998); + EXPECT_ADDITION(0, 1, 9223372036854775807LL, 999'999'998, 0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_ADDITION(0, 2, 9223372036854775807LL, 999'999'998, 0x7fff'ffff'ffff'ffff, 999'999'999); + + EXPECT_ADDITION(0x80, 40, 0x7fff'ffff'ffff'ff7f, 999'999'958, 0x7fff'ffff'ffff'ffff, 999'999'998); + EXPECT_ADDITION(0x80, 41, 0x7fff'ffff'ffff'ff7f, 999'999'958, 0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_ADDITION(0x80, 42, 0x7fff'ffff'ffff'ff7f, 999'999'958, 0x7fff'ffff'ffff'ffff, 999'999'999); + + EXPECT_ADDITION(-2, 5, -3, 7, -5, 12); + EXPECT_ADDITION(-2, 999'999'995, -3, 999'999'997, -4, 999'999'992); + + EXPECT_ADDITION(-0x7fff'ffff'ffff'ffff, 999'999'995, -1, 6, -0x7fff'ffff'ffff'ffff, 1); + EXPECT_ADDITION(-0x7fff'ffff'ffff'ffff, 999'999'995, -2, 6, (i64)-0x8000'0000'0000'0000, 1); + EXPECT_ADDITION(-0x7fff'ffff'ffff'ffff, 999'999'995, -2, 5, (i64)-0x8000'0000'0000'0000, 0); + EXPECT_ADDITION(-0x7fff'ffff'ffff'ffff, 999'999'995, -2, 4, (i64)-0x8000'0000'0000'0000, 0); + + EXPECT_ADDITION((i64)-0x8000'0000'0000'0000, 999'999'995, 0x7fff'ffff'ffff'ffff, 4, -1, 999'999'999); + EXPECT_ADDITION((i64)-0x8000'0000'0000'0000, 999'999'995, 0x7fff'ffff'ffff'ffff, 5, 0, 0); + EXPECT_ADDITION((i64)-0x8000'0000'0000'0000, 999'999'995, 0x7fff'ffff'ffff'ffff, 6, 0, 1); +#undef EXPECT_ADDITION +} + +TEST_CASE(subtraction) +{ +#define EXPECT_SUBTRACTION(s1, ns1, s2, ns2, sr, nsr) \ + do { \ + EXPECT_DURATION(DURATION(s1, ns1) - DURATION(s2, ns2), sr, nsr); \ + auto t = DURATION(s1, ns1); \ + t -= DURATION(s2, ns2); \ + EXPECT_DURATION(t, sr, nsr); \ + } while (0) + + EXPECT_SUBTRACTION(5, 0, 3, 0, 2, 0); + EXPECT_SUBTRACTION(0, 0, 0, 0, 0, 0); + EXPECT_SUBTRACTION(0, 5, 0, 3, 0, 2); + EXPECT_SUBTRACTION(0x7fff'ffff'ffff'ffff, 999'999'999, 8, 123, 0x7fff'ffff'ffff'fff7, 999'999'876); + + EXPECT_SUBTRACTION(1, 0, 0, 999'999'999, 0, 1); + EXPECT_SUBTRACTION(0x7fff'ffff'ffff'ffff, 0, 1, 999'999'999, 0x7fff'ffff'ffff'fffd, 1); + + EXPECT_SUBTRACTION(3, 0, 5, 0, -2, 0); + EXPECT_SUBTRACTION(0, 3, 0, 5, -1, 999'999'998); + EXPECT_SUBTRACTION(0, 0, 0x7fff'ffff'ffff'ffff, 999'999'999, (i64)-0x8000'0000'0000'0000, 1); + EXPECT_SUBTRACTION(0, 0, (i64)-0x8000'0000'0000'0000, 0, 0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_SUBTRACTION(-1, 999'999'999, (i64)-0x8000'0000'0000'0000, 0, 0x7fff'ffff'ffff'ffff, 999'999'999); + EXPECT_SUBTRACTION(-1, 999'999'998, (i64)-0x8000'0000'0000'0000, 0, 0x7fff'ffff'ffff'ffff, 999'999'998); + + EXPECT_SUBTRACTION(123, 456, 123, 455, 0, 1); + EXPECT_SUBTRACTION(123, 456, 123, 456, 0, 0); + EXPECT_SUBTRACTION(123, 456, 123, 457, -1, 999'999'999); + + EXPECT_SUBTRACTION(124, 456, 123, 455, 1, 1); + EXPECT_SUBTRACTION(124, 456, 123, 456, 1, 0); + EXPECT_SUBTRACTION(124, 456, 123, 457, 0, 999'999'999); + + EXPECT_SUBTRACTION(-0x7fff'ffff'ffff'ffff, 999'999'995, 1, 999'999'994, (i64)-0x8000'0000'0000'0000, 1); + EXPECT_SUBTRACTION(-0x7fff'ffff'ffff'ffff, 999'999'995, 1, 999'999'995, (i64)-0x8000'0000'0000'0000, 0); + EXPECT_SUBTRACTION(-0x7fff'ffff'ffff'ffff, 999'999'995, 1, 999'999'996, (i64)-0x8000'0000'0000'0000, 0); +} + +TEST_CASE(rounding) +{ + EXPECT_EQ(DURATION(2, 800'800'800).to_seconds(), 3); + EXPECT_EQ(DURATION(2, 800'800'800).to_milliseconds(), 2'801); + EXPECT_EQ(DURATION(2, 800'800'800).to_microseconds(), 2'800'801); + EXPECT_EQ(DURATION(2, 800'800'800).to_nanoseconds(), 2'800'800'800); + EXPECT_EQ(DURATION(-2, 800'800'800).to_seconds(), -2); + EXPECT_EQ(DURATION(-2, 800'800'800).to_milliseconds(), -1'200); + EXPECT_EQ(DURATION(-2, 800'800'800).to_microseconds(), -1'199'200); + EXPECT_EQ(DURATION(-2, 800'800'800).to_nanoseconds(), -1'199'199'200); + + EXPECT_EQ(DURATION(0, 0).to_seconds(), 0); + EXPECT_EQ(DURATION(0, 0).to_milliseconds(), 0); + EXPECT_EQ(DURATION(0, 0).to_microseconds(), 0); + EXPECT_EQ(DURATION(0, 0).to_nanoseconds(), 0); + + EXPECT_EQ(DURATION(0, 1).to_seconds(), 1); + EXPECT_EQ(DURATION(0, 1).to_milliseconds(), 1); + EXPECT_EQ(DURATION(0, 1).to_microseconds(), 1); + EXPECT_EQ(DURATION(0, 1).to_nanoseconds(), 1); + EXPECT_EQ(DURATION(0, -1).to_seconds(), -1); + EXPECT_EQ(DURATION(0, -1).to_milliseconds(), -1); + EXPECT_EQ(DURATION(0, -1).to_microseconds(), -1); + EXPECT_EQ(DURATION(0, -1).to_nanoseconds(), -1); + + EXPECT_EQ(DURATION(-9223372037, 145'224'191).to_nanoseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372037, 145'224'192).to_nanoseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372037, 145'224'193).to_nanoseconds(), -0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036, 854'775'806).to_nanoseconds(), 0x7fff'ffff'ffff'fffe); + EXPECT_EQ(DURATION(9223372036, 854'775'807).to_nanoseconds(), 0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036, 854'775'808).to_nanoseconds(), 0x7fff'ffff'ffff'ffff); +} + +TEST_CASE(truncation) +{ + // Sanity + EXPECT_EQ(DURATION(2, 0).to_truncated_seconds(), 2); + EXPECT_EQ(DURATION(-2, 0).to_truncated_seconds(), -2); + EXPECT_EQ(DURATION(2, 800'800'800).to_truncated_seconds(), 2); + EXPECT_EQ(DURATION(2, 800'800'800).to_truncated_milliseconds(), 2'800); + EXPECT_EQ(DURATION(2, 800'800'800).to_truncated_microseconds(), 2'800'800); + EXPECT_EQ(DURATION(-2, -800'800'800).to_truncated_seconds(), -2); + EXPECT_EQ(DURATION(-2, -800'800'800).to_truncated_milliseconds(), -2'800); + EXPECT_EQ(DURATION(-2, -800'800'800).to_truncated_microseconds(), -2'800'800); + + // Overflow, seconds + EXPECT_EQ(Duration::min().to_truncated_seconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(Duration::max().to_truncated_seconds(), 0x7fff'ffff'ffff'ffff); + + // Overflow, milliseconds + EXPECT_EQ(DURATION(-9223372036854776, 191'000'000).to_truncated_milliseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372036854776, 192'000'000).to_truncated_milliseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372036854776, 192'000'001).to_truncated_milliseconds(), -0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(-9223372036854776, 193'000'000).to_truncated_milliseconds(), -0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036854775, 806'000'000).to_truncated_milliseconds(), 0x7fff'ffff'ffff'fffe); + EXPECT_EQ(DURATION(9223372036854775, 806'999'999).to_truncated_milliseconds(), 0x7fff'ffff'ffff'fffe); + EXPECT_EQ(DURATION(9223372036854775, 807'000'000).to_truncated_milliseconds(), 0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036854775, 808'000'000).to_truncated_milliseconds(), 0x7fff'ffff'ffff'ffff); + + // Overflow, microseconds + EXPECT_EQ(DURATION(-9223372036855, 224'191'000).to_truncated_microseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372036855, 224'192'000).to_truncated_microseconds(), (i64)-0x8000'0000'0000'0000); + EXPECT_EQ(DURATION(-9223372036855, 224'192'001).to_truncated_microseconds(), (i64)-0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(-9223372036855, 224'193'000).to_truncated_microseconds(), (i64)-0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036854, 775'806'000).to_truncated_microseconds(), 0x7fff'ffff'ffff'fffe); + EXPECT_EQ(DURATION(9223372036854, 775'806'999).to_truncated_microseconds(), 0x7fff'ffff'ffff'fffe); + EXPECT_EQ(DURATION(9223372036854, 775'807'000).to_truncated_microseconds(), 0x7fff'ffff'ffff'ffff); + EXPECT_EQ(DURATION(9223372036854, 775'808'000).to_truncated_microseconds(), 0x7fff'ffff'ffff'ffff); +} + +TEST_CASE(is_negative) +{ + auto small = Duration::from_nanoseconds(10); + auto large = Duration::from_nanoseconds(15); + auto result = small - large; + EXPECT_EQ(result.to_nanoseconds(), -5); + EXPECT(result.is_negative()); + + result = large - small; + EXPECT_EQ(result.to_nanoseconds(), 5); + EXPECT(!result.is_negative()); +} + +struct YearAndDays { + int year; + i64 days; +}; + +TEST_CASE(years_to_days_since_epoch_points) +{ + Array<YearAndDays, 24> test_data = { { + { 1969, -365 }, + { 1970, 0 }, + { 1971, 365 }, + { 1900, -25567 }, + { 2023, 19358 }, + { 1800, -62091 }, + { 2100, 47482 }, + { 0, -719528 }, + { -1, -719893 }, + { -2, -720258 }, + { -3, -720623 }, + { -4, -720989 }, + { -5, -721354 }, + { -6, -721719 }, + { 4000, 741442 }, + { -10000, -4371953 }, + { 10000, 2932897 }, + { -1000000, -365962028 }, + { 1000000, 364522972 }, + { -5877640, -2147483456 }, + { 5881474, 2147444740 }, + // Very important year: https://github.com/SerenityOS/serenity/pull/16760#issuecomment-1369054745 + { -999999, -365961662 }, + // The following two values haven't been verified by any other algorithm, but are very close to "year * 365.2425", and prove that there is no UB due to signed overflow: + { 2147483647, 784351576412 }, + { -2147483648, -784353015833 }, + } }; + for (auto entry : test_data) { + int year = entry.year; + i64 expected_days = entry.days; + i64 actual_days = years_to_days_since_epoch(year); + EXPECT_EQ(actual_days, expected_days); + } +} + +BENCHMARK_CASE(years_to_days_since_epoch_benchmark) +{ + // This benchmark takes consistently "0ms" on Linux, and "0ms" on Serenity. + for (size_t i = 0; i < 100; ++i) { + i64 actual_days = years_to_days_since_epoch(-5877640); + (void)actual_days; + EXPECT_EQ(actual_days, -2147483456); + } +} + +TEST_CASE(div_floor_by) +{ + EXPECT_EQ(AK::Detail::floor_div_by<4>(-5), -2); + EXPECT_EQ(AK::Detail::floor_div_by<4>(-4), -1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(-3), -1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(-2), -1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(-1), -1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+0), +0); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+1), +0); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+2), +0); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+3), +0); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+4), +1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+5), +1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+6), +1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+7), +1); + EXPECT_EQ(AK::Detail::floor_div_by<4>(+8), +2); +} + +TEST_CASE(mod_zeros_in_range) +{ + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 0), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 1), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 2), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 3), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 4), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 5), 2); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(0, 6), 2); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 1), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 2), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 3), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 4), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 5), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(1, 6), 1); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(2, 2), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(2, 3), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(2, 4), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(2, 5), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(2, 6), 1); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(3, 3), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(3, 4), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(3, 5), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(3, 6), 1); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(4, 4), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(4, 5), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(4, 6), 1); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(5, 5), 0); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(5, 6), 0); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(6, 6), 0); + + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-5, 3), 2); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-4, 3), 2); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-3, 3), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-2, 3), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-1, 3), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(-0, 3), 1); + EXPECT_EQ(AK::Detail::mod_zeros_in_range<4>(+1, 3), 0); +} + +TEST_CASE(years_to_days_since_epoch_span) +{ + auto test_data_start_year = 1900; + // Data was pre-computed with a slow, but known-correct implementation. + // clang-format off + auto test_data = Array { + -25567, -25202, -24837, -24472, -24107, -23741, -23376, -23011, + -22646, -22280, -21915, -21550, -21185, -20819, -20454, -20089, + -19724, -19358, -18993, -18628, -18263, -17897, -17532, -17167, + -16802, -16436, -16071, -15706, -15341, -14975, -14610, -14245, + -13880, -13514, -13149, -12784, -12419, -12053, -11688, -11323, + -10958, -10592, -10227, -9862, -9497, -9131, -8766, -8401, -8036, + -7670, -7305, -6940, -6575, -6209, -5844, -5479, -5114, -4748, -4383, + -4018, -3653, -3287, -2922, -2557, -2192, -1826, -1461, -1096, -731, + -365, 0, 365, 730, 1096, 1461, 1826, 2191, 2557, 2922, 3287, 3652, + 4018, 4383, 4748, 5113, 5479, 5844, 6209, 6574, 6940, 7305, 7670, + 8035, 8401, 8766, 9131, 9496, 9862, 10227, 10592, 10957, 11323, 11688, + 12053, 12418, 12784, 13149, 13514, 13879, 14245, 14610, 14975, 15340, + 15706, 16071, 16436, 16801, 17167, 17532, 17897, 18262, 18628, 18993, + 19358, 19723, 20089, 20454, 20819, 21184, 21550, 21915, 22280, 22645, + 23011, 23376, 23741, 24106, 24472, 24837, 25202, 25567, 25933, 26298, + 26663, 27028, 27394, 27759, 28124, 28489, 28855, 29220, 29585, 29950, + 30316, 30681, 31046, 31411, 31777, 32142, 32507, 32872, 33238, 33603, + 33968, 34333, 34699, 35064, 35429, 35794, 36160, 36525, 36890, 37255, + 37621, 37986, 38351, 38716, 39082, 39447, 39812, 40177, 40543, 40908, + 41273, 41638, 42004, 42369, 42734, 43099, 43465, 43830, 44195, 44560, + 44926, 45291, 45656, 46021, 46387, 46752, 47117, 47482, 47847, 48212, + 48577, 48942, 49308, 49673, 50038, 50403, 50769, 51134, 51499, 51864, + 52230, 52595, 52960, 53325, 53691, 54056, 54421, 54786, 55152, 55517, + 55882, 56247, 56613, 56978, 57343, 57708, 58074, 58439, 58804, 59169, + 59535, 59900, 60265, 60630, 60996, 61361, 61726, 62091, 62457, 62822, + 63187, 63552, 63918, 64283, 64648, 65013, 65379, 65744, 66109, 66474, + 66840, 67205, 67570, 67935, 68301, 68666, 69031, 69396, 69762, 70127, + 70492, 70857, 71223, 71588, 71953, 72318, 72684, 73049, 73414, 73779, + 74145, 74510, 74875, 75240, 75606, 75971, 76336, 76701, 77067, 77432, + 77797, 78162, 78528, 78893, 79258, 79623, 79989, 80354, 80719, 81084, + 81450, 81815, 82180, 82545, 82911, 83276, 83641, 84006, 84371, 84736, + 85101, 85466, 85832, 86197, 86562, 86927, 87293, 87658, 88023, 88388, + 88754, 89119, 89484, 89849, 90215, 90580, 90945, 91310, 91676, 92041, + 92406, 92771, 93137, 93502, 93867, 94232, 94598, 94963, 95328, 95693, + 96059, 96424, 96789, 97154, 97520, 97885, 98250, 98615, 98981, 99346, + 99711, 100076, 100442, 100807, 101172, 101537, 101903, 102268, 102633, + 102998, 103364, 103729, 104094, 104459, 104825, 105190, 105555, + 105920, 106286, 106651, 107016, 107381, 107747, 108112, 108477, + 108842, 109208, 109573, 109938, 110303, 110669, 111034, 111399, + 111764, 112130, 112495, 112860, 113225, 113591, 113956, 114321, + 114686, 115052, 115417, 115782, 116147, 116513, 116878, 117243, + 117608, 117974, 118339, 118704, 119069, 119435, 119800, 120165, + 120530, 120895, 121260, 121625, 121990, 122356, 122721, 123086, + 123451, 123817, 124182, 124547, 124912, 125278, 125643, 126008, + 126373, 126739, 127104, 127469, 127834, 128200, 128565, 128930, + 129295, 129661, 130026, 130391, 130756, 131122, 131487, 131852, + 132217, 132583, 132948, 133313, 133678, 134044, 134409, 134774, + 135139, 135505, 135870, 136235, 136600, 136966, 137331, 137696, + 138061, 138427, 138792, 139157, 139522, 139888, 140253, 140618, + 140983, 141349, 141714, 142079, 142444, 142810, 143175, 143540, + 143905, 144271, 144636, 145001, 145366, 145732, 146097, 146462, + 146827, 147193, 147558, 147923, 148288, 148654, 149019, 149384, + 149749, 150115, 150480, 150845, 151210, 151576, 151941, 152306, + 152671, 153037, 153402, 153767, 154132, 154498, 154863, 155228, + 155593, 155959, 156324, 156689, 157054, 157420, 157785, 158150, + 158515, 158881, 159246, 159611, 159976, 160342, 160707, 161072, + 161437, 161803, 162168, 162533, 162898, 163264, 163629, 163994, + 164359, 164725, 165090, 165455, 165820, 166186, 166551, 166916, + 167281, 167647, 168012, 168377, 168742, 169108, 169473, 169838, + 170203, 170569, 170934, 171299, 171664, 172030, 172395, 172760, + 173125, 173491, 173856, 174221, 174586, 174952, 175317, 175682, + 176047, 176413, 176778, 177143, 177508, 177874, 178239, 178604, + 178969, 179335, 179700, 180065, 180430, 180796, 181161, 181526, + 181891, 182257, 182622, 182987, 183352, 183718, 184083, 184448, + 184813, 185179, 185544, 185909, 186274, 186640, 187005, 187370, + 187735, 188101, 188466, 188831, 189196, 189562, 189927, 190292, + 190657, 191023, 191388, 191753, 192118, 192484, 192849, 193214, + 193579, 193944, 194309, 194674, 195039, 195405, + }; + // clang-format on + for (size_t offset = 0; offset < test_data.size(); ++offset) { + int year = offset + test_data_start_year; + i64 expected_days = test_data[offset]; + i64 actual_days = years_to_days_since_epoch(year); + EXPECT_EQ(actual_days, expected_days); + } +} + +TEST_CASE(user_defined_literals) +{ + using namespace AK::TimeLiterals; + static_assert(Duration::from_nanoseconds(123) == 123_ns, "Factory is same as UDL"); + + static_assert(100_ms > 10_ms, "LT UDL"); + static_assert(1000_ns == 1_us, "EQ UDL"); + static_assert(1_sec > 1_ms, "GT UDL"); + static_assert(100_ms >= 100'000_us, "GE UDL (eq)"); + static_assert(100_ms >= 99'999_us, "GE UDL (gt)"); + static_assert(100_ms <= 100'000_us, "LE UDL (eq)"); + static_assert(100_ms <= 100'001_us, "LE UDL (lt)"); + static_assert(1_sec != 2_sec, "NE UDL"); +} |