1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 09:07:45 +00:00

LibTest: Add more numeric generators

Rename unsigned_int generator to number_u32.
Add generators:
- number_u64
- number_f64
- percentage
This commit is contained in:
Martin Janiczek 2023-12-30 16:23:59 +01:00 committed by Andrew Kaster
parent dd53f64d2f
commit d52ffcd830
15 changed files with 312 additions and 133 deletions

View file

@ -28,13 +28,13 @@ TEST_CASE(all_but_one_false)
RANDOMIZED_TEST_CASE(trivial_all_true)
{
GEN(vec, Gen::vector(0, 10, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(0, 10, []() { return Gen::number_u64(); }));
EXPECT(all_of(vec.begin(), vec.end(), [](auto) { return true; }));
}
RANDOMIZED_TEST_CASE(trivial_all_false)
{
GEN(vec, Gen::vector(1, 10, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(1, 10, []() { return Gen::number_u64(); }));
EXPECT(!all_of(vec.begin(), vec.end(), [](auto) { return false; }));
}

View file

@ -28,13 +28,13 @@ TEST_CASE(all_false)
RANDOMIZED_TEST_CASE(trivial_all_true)
{
GEN(vec, Gen::vector(1, 10, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(1, 10, []() { return Gen::number_u64(); }));
EXPECT(any_of(vec.begin(), vec.end(), [](auto) { return true; }));
}
RANDOMIZED_TEST_CASE(trivial_all_false)
{
GEN(vec, Gen::vector(0, 10, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(0, 10, []() { return Gen::number_u64(); }));
EXPECT(!any_of(vec.begin(), vec.end(), [](auto) { return false; }));
}

View file

@ -70,35 +70,35 @@ TEST_CASE(large_populate_reverse)
RANDOMIZED_TEST_CASE(pop_min_is_min)
{
GEN(vec, Gen::vector(1, 10, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(1, 10, []() { return Gen::number_u64(); }));
auto sorted { vec };
AK::quick_sort(sorted);
BinaryHeap<u32, u32, 10> heap;
BinaryHeap<u64, u64, 10> heap;
// insert in a non-sorted order
for (u32 n : vec) {
for (u64 n : vec) {
heap.insert(n, n);
}
// check in a sorted order
for (u32 sorted_n : sorted) {
for (u64 sorted_n : sorted) {
EXPECT_EQ(heap.pop_min(), sorted_n);
}
}
RANDOMIZED_TEST_CASE(peek_min_same_as_pop_min)
{
GEN(vec, Gen::vector(1, 10, []() { return Gen::unsigned_int(); }));
BinaryHeap<u32, u32, 10> heap;
for (u32 n : vec) {
GEN(vec, Gen::vector(1, 10, []() { return Gen::number_u64(); }));
BinaryHeap<u64, u64, 10> heap;
for (u64 n : vec) {
heap.insert(n, n);
}
while (!heap.is_empty()) {
u32 peeked = heap.peek_min();
u32 popped = heap.pop_min();
u64 peeked = heap.peek_min();
u64 popped = heap.pop_min();
EXPECT_EQ(peeked, popped);
}
}

View file

@ -122,10 +122,10 @@ TEST_CASE(unsigned_to_signed_regression)
RANDOMIZED_TEST_CASE(finds_number_that_is_present)
{
GEN(vec, Gen::vector(1, 16, []() { return Gen::unsigned_int(); }));
GEN(i, Gen::unsigned_int(0, vec.size() - 1));
GEN(vec, Gen::vector(1, 16, []() { return Gen::number_u64(); }));
GEN(i, Gen::number_u64(0, vec.size() - 1));
AK::quick_sort(vec);
u32 n = vec[i];
u64 n = vec[i];
auto ptr = binary_search(vec, n);
EXPECT_NE(ptr, nullptr);
EXPECT_EQ(*ptr, n);
@ -133,10 +133,10 @@ RANDOMIZED_TEST_CASE(finds_number_that_is_present)
RANDOMIZED_TEST_CASE(doesnt_find_number_that_is_not_present)
{
GEN(vec, Gen::vector(1, 16, []() { return Gen::unsigned_int(); }));
GEN(vec, Gen::vector(1, 16, []() { return Gen::number_u64(); }));
AK::quick_sort(vec);
u32 not_present = 0;
u64 not_present = 0;
while (!vec.find(not_present).is_end()) {
++not_present;
}

View file

@ -201,7 +201,7 @@ TEST_CASE(bit_reads_beyond_stream_limits)
RANDOMIZED_TEST_CASE(roundtrip_u8_little_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u8>::max()));
GEN(n, Gen::number_u64(NumericLimits<u8>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
LittleEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };
@ -216,7 +216,7 @@ RANDOMIZED_TEST_CASE(roundtrip_u8_little_endian)
RANDOMIZED_TEST_CASE(roundtrip_u16_little_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u16>::max()));
GEN(n, Gen::number_u64(NumericLimits<u16>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
LittleEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };
@ -231,7 +231,7 @@ RANDOMIZED_TEST_CASE(roundtrip_u16_little_endian)
RANDOMIZED_TEST_CASE(roundtrip_u32_little_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u32>::max()));
GEN(n, Gen::number_u64(NumericLimits<u32>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
LittleEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };
@ -246,7 +246,7 @@ RANDOMIZED_TEST_CASE(roundtrip_u32_little_endian)
RANDOMIZED_TEST_CASE(roundtrip_u8_big_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u8>::max()));
GEN(n, Gen::number_u64(NumericLimits<u8>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
BigEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };
@ -260,7 +260,7 @@ RANDOMIZED_TEST_CASE(roundtrip_u8_big_endian)
RANDOMIZED_TEST_CASE(roundtrip_u16_big_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u16>::max()));
GEN(n, Gen::number_u64(NumericLimits<u16>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
BigEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };
@ -274,7 +274,7 @@ RANDOMIZED_TEST_CASE(roundtrip_u16_big_endian)
RANDOMIZED_TEST_CASE(roundtrip_u32_big_endian)
{
GEN(n, Gen::unsigned_int(NumericLimits<u32>::max()));
GEN(n, Gen::number_u64(NumericLimits<u32>::max()));
auto memory_stream = make<AllocatingMemoryStream>();
BigEndianOutputBitStream sut_write { MaybeOwned<Stream>(*memory_stream) };

View file

@ -283,8 +283,8 @@ RANDOMIZED_TEST_CASE(set_get)
{
GEN(init, Gen::boolean());
GEN(new_value, Gen::boolean());
GEN(size, Gen::unsigned_int(1, 64));
GEN(i, Gen::unsigned_int(size - 1));
GEN(size, Gen::number_u64(1, 64));
GEN(i, Gen::number_u64(size - 1));
auto bitmap = MUST(Bitmap::create(size, init));
bitmap.set(i, new_value);
@ -295,11 +295,11 @@ RANDOMIZED_TEST_CASE(set_get)
RANDOMIZED_TEST_CASE(set_range)
{
GEN(init, Gen::boolean());
GEN(size, Gen::unsigned_int(1, 64));
GEN(size, Gen::number_u64(1, 64));
GEN(new_value, Gen::boolean());
GEN(start, Gen::unsigned_int(size - 1));
GEN(len, Gen::unsigned_int(size - start - 1));
GEN(start, Gen::number_u64(size - 1));
GEN(len, Gen::number_u64(size - start - 1));
auto bitmap = MUST(Bitmap::create(size, init));
bitmap.set_range(start, len, new_value);
@ -313,7 +313,7 @@ RANDOMIZED_TEST_CASE(set_range)
RANDOMIZED_TEST_CASE(fill)
{
GEN(init, Gen::boolean());
GEN(size, Gen::unsigned_int(1, 64));
GEN(size, Gen::number_u64(1, 64));
GEN(new_value, Gen::boolean());
auto bitmap = MUST(Bitmap::create(size, init));
@ -334,11 +334,11 @@ TEST_CASE(find_one_anywhere_edge_case)
RANDOMIZED_TEST_CASE(find_one_anywhere)
{
GEN(init, Gen::boolean());
GEN(size, Gen::unsigned_int(1, 64));
GEN(hint, Gen::unsigned_int(size - 1));
GEN(size, Gen::number_u64(1, 64));
GEN(hint, Gen::number_u64(size - 1));
GEN(new_value, Gen::boolean());
GEN(i, Gen::unsigned_int(size - 1));
GEN(i, Gen::number_u64(size - 1));
auto bitmap = MUST(Bitmap::create(size, init));
bitmap.set(i, new_value);
@ -363,10 +363,10 @@ TEST_CASE(find_first_edge_case)
RANDOMIZED_TEST_CASE(find_first)
{
GEN(init, Gen::boolean());
GEN(size, Gen::unsigned_int(1, 64));
GEN(size, Gen::number_u64(1, 64));
GEN(new_value, Gen::boolean());
GEN(i, Gen::unsigned_int(size - 1));
GEN(i, Gen::number_u64(size - 1));
auto bitmap = MUST(Bitmap::create(size, init));
bitmap.set(i, new_value);

View file

@ -72,13 +72,13 @@ RANDOMIZED_TEST_CASE(count_leading_zeroes)
{
// count_leading_zeroes(0b000...0001000...000)
// == count_leading_zeroes(0b000...0001___...___) (where _ is 0 or 1)
GEN(e, Gen::unsigned_int(0, 63));
GEN(e, Gen::number_u64(0, 63));
auto power_of_two = 1ULL << e;
// We add random one-bits below the leftmost (and only) one-bit.
// This shouldn't change the output of count_leading_zeroes because
// the function should only care about the most significant one.
GEN(below, Gen::unsigned_int(0, power_of_two - 1));
GEN(below, Gen::number_u64(0, power_of_two - 1));
auto n = power_of_two + below;
EXPECT_EQ(count_leading_zeroes(n), count_leading_zeroes(power_of_two));
@ -89,7 +89,7 @@ RANDOMIZED_TEST_CASE(count_required_bits)
// count_required_bits(n) == log2(n) + 1
// log2(0) is -infinity, we don't care about that
GEN(n, Gen::unsigned_int(1, NumericLimits<u32>::max()));
GEN(n, Gen::number_u32(1, NumericLimits<u32>::max()));
size_t expected = AK::log2(static_cast<double>(n)) + 1;
@ -99,6 +99,6 @@ RANDOMIZED_TEST_CASE(count_required_bits)
RANDOMIZED_TEST_CASE(bit_scan_forward_count_trailing_zeroes)
{
// Behaviour for 0 differs, so we skip it.
GEN(n, Gen::unsigned_int(1, 1 << 31));
GEN(n, Gen::number_u32(1, 1 << 31));
EXPECT_EQ(bit_scan_forward(n), count_trailing_zeroes(n) + 1);
}

View file

@ -42,7 +42,7 @@ void randomized_compare_bool_output_over(u32 range, auto& old_function, auto& ne
for (u32 n = 0; n < 100; ++n) {
bool result1 = false;
bool result2 = false;
GEN(i, Gen::unsigned_int(range - 1));
GEN(i, Gen::number_u64(range - 1));
EXPECT_EQ(result1 = (old_function(i) > 0), result2 = (new_function(i) > 0));
if (result1 != result2)
FAIL(String::formatted("New result {} does not match old result {} for input {}.", result1, result2, i));
@ -55,7 +55,7 @@ void randomized_compare_value_output_over(u32 range, auto& old_function, auto& n
for (u32 n = 0; n < 100; ++n) {
i64 result1 = false;
i64 result2 = false;
GEN(i, Gen::unsigned_int(range - 1));
GEN(i, Gen::number_u64(range - 1));
EXPECT_EQ(result1 = old_function(i), result2 = new_function(i));
if (result1 != result2)
FAIL(String::formatted("New result {} does not match old result {} for input {}.", result1, result2, i));

View file

@ -7,46 +7,47 @@
#include <AK/StdLibExtras.h>
#include <LibTest/Randomized/Generator.h>
#include <LibTest/TestCase.h>
#include <math.h>
using namespace Test::Randomized;
RANDOMIZED_TEST_CASE(unsigned_int_max_bounds)
RANDOMIZED_TEST_CASE(number_u64_max_bounds)
{
GEN(n, Gen::unsigned_int(10));
GEN(n, Gen::number_u64(10));
EXPECT(n <= 10);
}
RANDOMIZED_TEST_CASE(unsigned_int_min_max_bounds)
RANDOMIZED_TEST_CASE(number_u64_min_max_bounds)
{
GEN(n, Gen::unsigned_int(3, 6));
GEN(n, Gen::number_u64(3, 6));
EXPECT(n >= 3 && n <= 6);
}
RANDOMIZED_TEST_CASE(assume)
{
GEN(n, Gen::unsigned_int(10));
GEN(n, Gen::number_u64(10));
ASSUME(n % 2 == 0); // This will try to generate until it finds an even number
EXPECT(n % 2 == 0); // This will then succeed
// It will give up if the value doesn't pass the ASSUME(...) predicate 15 times in a row.
}
// TODO find a way to test that a test "unsigned_int(3) can't reach 0" fails
// TODO find a way to test that a test "unsigned_int(3) can't reach 3" fails
// TODO find a way to test that a test "unsigned_int(3,6) can't reach 3" fails
// TODO find a way to test that a test "unsigned_int(3,6) can't reach 6" fails
// TODO find a way to test that a test "unsigned_int(10) can reach n>10" fails
// TODO find a way to test that a test "number_u64(3) can't reach 0" fails
// TODO find a way to test that a test "number_u64(3) can't reach 3" fails
// TODO find a way to test that a test "number_u64(3,6) can't reach 3" fails
// TODO find a way to test that a test "number_u64(3,6) can't reach 6" fails
// TODO find a way to test that a test "number_u64(10) can reach n>10" fails
RANDOMIZED_TEST_CASE(map_like)
{
GEN(n1, Gen::unsigned_int(10));
GEN(n1, Gen::number_u64(10));
GEN(n2, n1 * 2);
EXPECT(n2 % 2 == 0);
}
RANDOMIZED_TEST_CASE(bind_like)
{
GEN(n1, Gen::unsigned_int(1, 9));
GEN(n2, Gen::unsigned_int(n1 * 10, n1 * 100));
GEN(n1, Gen::number_u64(1, 9));
GEN(n2, Gen::number_u64(n1 * 10, n1 * 100));
EXPECT(n2 >= 10 && n2 <= 900);
}
@ -68,7 +69,7 @@ RANDOMIZED_TEST_CASE(bind_like)
template<typename FN>
Vector<InvokeResult<FN>> vector_suboptimal(FN item_gen)
{
u32 length = Gen::unsigned_int(5);
u32 length = Gen::number_u64(5);
Vector<InvokeResult<FN>> acc;
for (u32 i = 0; i < length; ++i) {
acc.append(item_gen());
@ -79,7 +80,7 @@ Vector<InvokeResult<FN>> vector_suboptimal(FN item_gen)
RANDOMIZED_TEST_CASE(bind_vector_suboptimal)
{
u32 max_item = 5;
GEN(vec, vector_suboptimal([&]() { return Gen::unsigned_int(max_item); }));
GEN(vec, vector_suboptimal([&]() { return Gen::number_u64(max_item); }));
u32 sum = 0;
for (u32 n : vec) {
sum += n;
@ -90,21 +91,21 @@ RANDOMIZED_TEST_CASE(bind_vector_suboptimal)
RANDOMIZED_TEST_CASE(vector)
{
u32 max_item = 5;
GEN(vec, Gen::vector([&]() { return Gen::unsigned_int(max_item); }));
GEN(vec, Gen::vector([&]() { return Gen::number_u64(max_item); }));
EXPECT(vec.size() <= 32);
}
RANDOMIZED_TEST_CASE(vector_length)
{
u32 max_item = 5;
GEN(vec, Gen::vector(3, [&]() { return Gen::unsigned_int(max_item); }));
GEN(vec, Gen::vector(3, [&]() { return Gen::number_u64(max_item); }));
EXPECT(vec.size() == 3);
}
RANDOMIZED_TEST_CASE(vector_min_max)
{
u32 max_item = 5;
GEN(vec, Gen::vector(1, 4, [&]() { return Gen::unsigned_int(max_item); }));
GEN(vec, Gen::vector(1, 4, [&]() { return Gen::number_u64(max_item); }));
EXPECT(vec.size() >= 1 && vec.size() <= 4);
}
@ -160,9 +161,57 @@ RANDOMIZED_TEST_CASE(boolean_false)
EXPECT(b == false);
}
RANDOMIZED_TEST_CASE(one_of_int)
{
GEN(x, Gen::one_of(1, 2));
EXPECT(x == 1 || x == 2);
}
RANDOMIZED_TEST_CASE(frequency_int)
{
GEN(x, Gen::frequency(Gen::Choice { 5, 'x' }, Gen::Choice { 1, 'o' }));
ASSUME(x == 'x');
EXPECT(x == 'x');
}
RANDOMIZED_TEST_CASE(percentage)
{
GEN(x, Gen::percentage());
EXPECT(x >= 0 && x <= 1);
}
RANDOMIZED_TEST_CASE(number_f64_max_bounds)
{
GEN(x, Gen::number_f64(10));
EXPECT(x <= 10);
}
RANDOMIZED_TEST_CASE(number_f64_min_max_bounds)
{
GEN(x, Gen::number_f64(-10, 10));
EXPECT(x >= -10 && x <= 10);
}
RANDOMIZED_TEST_CASE(number_f64_never_nan)
{
GEN(x, Gen::number_f64());
EXPECT(!isnan(x));
}
RANDOMIZED_TEST_CASE(number_f64_never_infinite)
{
GEN(x, Gen::number_f64());
EXPECT(!isinf(x));
}
RANDOMIZED_TEST_CASE(number_u32_max_bounds)
{
GEN(n, Gen::number_u32(10));
EXPECT(n <= 10);
}
RANDOMIZED_TEST_CASE(number_u32_min_max_bounds)
{
GEN(n, Gen::number_u32(3, 6));
EXPECT(n >= 3 && n <= 6);
}