714 lines
28 KiB
Plaintext
714 lines
28 KiB
Plaintext
print_int_tests :: () {
|
||
assert(tprint("%", 0) == "0", "0: Plain failed");
|
||
assert(tprint("%", formatInt(0)) == "0", "0: Default failed");
|
||
assert(tprint("%", formatInt(0, minimum_digits = 0)) == "", "0: Explicit 0 failed");
|
||
assert(tprint("%", formatInt(0, minimum_digits = 1)) == "0", "0: Explicit 1 failed");
|
||
assert(tprint("%", formatInt(0, minimum_digits = 3)) == "000", "0: Explicit 3 failed");
|
||
|
||
assert(tprint("%", 25) == "25", "25: Plain failed");
|
||
assert(tprint("%", formatInt(25)) == "25", "25: Default failed");
|
||
assert(tprint("%", formatInt(25, minimum_digits = 3)) == "025", "25: Explicit 3 failed");
|
||
assert(tprint("%", formatInt(25, minimum_digits = 1)) == "25", "25: Explicit 1 failed");
|
||
assert(tprint("%", formatInt(25, minimum_digits = 0)) == "25", "25: Explicit 0 failed");
|
||
|
||
assert(tprint("%", formatInt(1234, minimum_digits = 0)) == "1234", "1234: Explicit 0 failed");
|
||
assert(tprint("%", formatInt(1234, minimum_digits = 1)) == "1234", "1234: Explicit 1 failed");
|
||
|
||
} @test
|
||
|
||
print_int_hex_tests :: () {
|
||
assert(tprint("%", formatInt(25, base = 16)) == "19", "Default failed");
|
||
assert(tprint("%", formatInt(25, base = 16, minimum_digits = 3)) == "019", "3 failed");
|
||
assert(tprint("%", formatInt(25, base = 16, minimum_digits = 1)) == "19", "1 failed");
|
||
}
|
||
|
||
print_float_tests :: () {
|
||
assert(tprint("%", 1234.5) == "1234.5", "Plain failed");
|
||
assert(tprint("%", formatFloat(1234.5)) == "1234.5", "Default failed");
|
||
assert(tprint("%", formatFloat(1234.5, trailing_width = 1)) == "1234.5", "Traling 1 failed");
|
||
assert(tprint("%", formatFloat(1234.5, trailing_width = 4, zero_removal = .NO)) == "1234.5000", "Traling 4 no_removal failed");
|
||
assert(tprint("%", formatFloat(1234.5, trailing_width = 4)) == "1234.5 ", "Traling 4 failed");
|
||
assert(tprint("%", formatFloat(1234.5, mode = .SHORTEST)) == "1234.5", "Shortest 1 failed");
|
||
assert(tprint("%", formatFloat(60.0, mode = .SHORTEST)) == "60", "Shortest 2 failed");
|
||
assert(tprint("%", formatFloat(60.0, mode = .SHORTEST, zero_removal = .NO)) == "60", "Shortest without zero removal failed");
|
||
assert(tprint("%", formatFloat(2.0e-31, mode = .SHORTEST)) == "2e-31", "Shortest scientific failed");
|
||
print("%", formatFloat(60.0, trailing_width=2, mode = .SCIENTIFIC));
|
||
{
|
||
scientific := tprint("%", formatFloat(60.0, mode = .SCIENTIFIC, zero_removal = .NO));
|
||
EXPECTED_SCIENTIFIC :: "6.000000e+01";
|
||
assert(scientific == EXPECTED_SCIENTIFIC, "Scientific w/o zero removal failed: % vs %", scientific, EXPECTED_SCIENTIFIC);
|
||
}
|
||
// @ToDo: This one fails for the old implementation but there’s no point fixing that if we plan to ditch it very soon.
|
||
// Enable this test when we switch to the new implementation.
|
||
// -rluba, 2023-08-07
|
||
// {
|
||
// scientific := tprint("%", formatFloat(60.0, mode = .SCIENTIFIC));
|
||
// EXPECTED_SCIENTIFIC :: "6e+01";
|
||
// assert(scientific == EXPECTED_SCIENTIFIC, "Scientific with zero removal failed: % vs %", scientific, EXPECTED_SCIENTIFIC);
|
||
// }
|
||
print("%\n", formatFloat(8.314472e0, mode = .SCIENTIFIC));
|
||
print("%\n", formatFloat(8.314472e0, mode = .SCIENTIFIC, zero_removal = .NO));
|
||
assert(tprint("%", formatFloat(8.314472e0, mode = .SCIENTIFIC)) == "8.314472e+00", "Scientific 2 failed");
|
||
|
||
}
|
||
|
||
simple_string_tests :: () { // Very simple, to get the ball rolling.
|
||
SIZE :: 15;
|
||
|
||
s1 : [SIZE] u8;
|
||
memcpy(s1.data, "Hello, Sailor!".data, SIZE-1);
|
||
s1[SIZE-1] = 0;
|
||
|
||
// @todo @abner use temporary_storage too and add is_* tests (but those may be moved out of Basic)
|
||
|
||
// @Cleanup: These asserts are awful, wtf.
|
||
|
||
assert(c_style_strlen(s1.data) == SIZE-1);
|
||
assert(cast(string)s1 == "Hello, Sailor!\0");
|
||
assert(to_string(s1.data) == "Hello, Sailor!");
|
||
assert(to_string(s1.data, SIZE-1) == "Hello, Sailor!");
|
||
|
||
s2 : [..] u8;
|
||
for index : 0..SIZE-2 array_add(*s2, s1[index]); // Inefficient, but uses array_add which is part of Basic so it's good to test.
|
||
|
||
assert(cast(string)s2 == "Hello, Sailor!");
|
||
|
||
s3 := cast(string) s2;
|
||
s3_c_string := to_c_string(s3);
|
||
defer free(s3_c_string);
|
||
|
||
assert(c_style_strlen(s3_c_string) == SIZE-1);
|
||
assert(memcmp(s3_c_string, s3.data, SIZE-1) == 0);
|
||
|
||
advance(*s3, 0);
|
||
assert(s3[0] == #char "H", message="s3[0] (%) == #char \"H\"", s3[0]);
|
||
|
||
advance(*s3, SIZE-2);
|
||
assert(s3[0] == #char "!", message="s3[0] (%) == #char \"!\"", s3[0]);
|
||
}
|
||
|
||
|
||
string_builder_tests :: () { // Very simple, to get the ball rolling.
|
||
builder : String_Builder;
|
||
|
||
init_string_builder(*builder);
|
||
|
||
assert(get_current_buffer(*builder).count == 0);
|
||
assert(builder_to_string(*builder) == "");
|
||
assert(builder_string_length(*builder) == 0);
|
||
|
||
//
|
||
// Append nothing, string literals, and u8s.
|
||
//
|
||
|
||
// @todo @abner test string builder's buffer swap strategy; so if we append something bigger than BUFFER_SIZE
|
||
// we could assert current_buffer is a new address.
|
||
|
||
append(*builder, "");
|
||
|
||
{
|
||
output := builder_to_string(*builder);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(get_current_buffer(*builder).count == 0, message="get_current_buffer(*builder).count (%) == 0", get_current_buffer(*builder).count);
|
||
assert(output == "", message="builder_to_string(*builder) (%) == \"\"", output);
|
||
assert(length == 0, message="builder_string_length(*builder) (%) == 0", length);
|
||
}
|
||
|
||
append(*builder, "Hello");
|
||
|
||
{
|
||
output := builder_to_string(*builder, do_reset=false);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(output == "Hello", message="builder_to_string(*builder) (\"%\") == \"%\"", builder_to_string(*builder, do_reset=false), "Hello");
|
||
assert(length == 5, message="builder_string_length(*builder) (%) == %", length, 5);
|
||
assert(get_current_buffer(*builder).count == length, message="get_current_buffer(*builder).count (%) == %", get_current_buffer(*builder).count, length);
|
||
}
|
||
|
||
append(*builder, ", ");
|
||
|
||
{
|
||
output := builder_to_string(*builder, do_reset=false);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(output == "Hello, ", message="builder_to_string(*builder) (\"%\") == \"%\"", output, "Hello, ");
|
||
assert(length == 7, message="builder_string_length(*builder) (%) == %", length, 7);
|
||
assert(get_current_buffer(*builder).count == length, message="get_current_buffer(*builder).count (%) == %", get_current_buffer(*builder).count, length);
|
||
}
|
||
|
||
append(*builder, "Sailor!");
|
||
|
||
{
|
||
output := builder_to_string(*builder, do_reset=false);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(output == "Hello, Sailor!", message="builder_to_string(*builder) (\"%\") == \"%\"", output, "Hello, Sailor!");
|
||
assert(length == 14, message="builder_string_length(*builder) (%) == %", length, 14);
|
||
assert(get_current_buffer(*builder).count == 14, message="get_current_buffer(*builder).count (%) == %", get_current_buffer(*builder).count, 14);
|
||
}
|
||
|
||
SIZE :: 13;
|
||
goodbye : [SIZE] u8;
|
||
memcpy(goodbye.data, " Goodbye now.".data, SIZE);
|
||
append(*builder, goodbye.data, SIZE);
|
||
|
||
{
|
||
output := builder_to_string(*builder, do_reset=false);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(output == "Hello, Sailor! Goodbye now.", message="builder_to_string(*builder) (\"%\") == \"%\"", output, "Hello, Sailor! Goodbye now.");
|
||
assert(length == 14+SIZE, message="builder_string_length(*builder) (%) == %", length, 14+SIZE);
|
||
assert(get_current_buffer(*builder).count == 14+SIZE, message="get_current_buffer(*builder).count (%) == %", get_current_buffer(*builder).count, 14+SIZE);
|
||
}
|
||
|
||
//
|
||
// Reset
|
||
//
|
||
|
||
reset(*builder);
|
||
|
||
{
|
||
output := builder_to_string(*builder);
|
||
defer free(output);
|
||
length := builder_string_length(*builder);
|
||
|
||
assert(get_current_buffer(*builder).count == 0, message="get_current_buffer(*builder).count (%) == 0", get_current_buffer(*builder).count);
|
||
assert(output == "", message="builder_to_string(*builder) (%) == \"\"", output);
|
||
assert(length == 0, message="builder_string_length(*builder) (%) == 0", length);
|
||
}
|
||
|
||
// Stealing
|
||
{
|
||
victim: String_Builder;
|
||
thief: String_Builder;
|
||
|
||
append(*victim, "First line\n");
|
||
old_victim_count := builder_string_length(*victim);
|
||
|
||
append_and_steal_buffers(*thief, *victim);
|
||
log("Result after heist #1: %", builder_to_string(*thief, do_reset = false));
|
||
|
||
thief_count := builder_string_length(*thief);
|
||
assert(thief_count == old_victim_count);
|
||
assert(builder_string_length(*victim) == 0);
|
||
|
||
// The first one only copied from the base buffer.
|
||
// Let’s try actual stealing:
|
||
old_thief_count := thief_count;
|
||
for 1..100 {
|
||
print_to_builder(*victim, "This will be stolen next and we want multiple buffers, part %\n", it);
|
||
}
|
||
old_victim_count = builder_string_length(*victim);
|
||
|
||
append_and_steal_buffers(*thief, *victim);
|
||
log("\n\nResult after heist #2: %", builder_to_string(*thief, do_reset = false));
|
||
|
||
thief_count = builder_string_length(*thief);
|
||
assert(thief_count == old_victim_count + old_thief_count);
|
||
assert(builder_string_length(*victim) == 0);
|
||
|
||
// Make sure that we can append normally after stealing from victim a bunch:
|
||
old_thief_count = thief_count;
|
||
INTERMISSION :: "Appended between heist jobs\n";
|
||
print_to_builder(*thief, INTERMISSION);
|
||
log("\n\nResult after intermission: %", builder_to_string(*thief, do_reset = false));
|
||
thief_count = builder_string_length(*thief);
|
||
assert(thief_count == old_thief_count + INTERMISSION.count);
|
||
|
||
// Try stealing some more now that thief also has multiple buffers:
|
||
old_thief_count = thief_count;
|
||
for 1..100 {
|
||
print_to_builder(*victim, "This will be stolen again and we want to make sure we have multiple buffers, part %\n", it);
|
||
}
|
||
old_victim_count = builder_string_length(*victim);
|
||
|
||
append_and_steal_buffers(*thief, *victim);
|
||
log("\n\nResult after heist #3: %", builder_to_string(*thief, do_reset = false));
|
||
|
||
thief_count = builder_string_length(*thief);
|
||
assert(thief_count == old_victim_count + old_thief_count);
|
||
assert(builder_string_length(*victim) == 0);
|
||
}
|
||
} @test
|
||
|
||
copy_string_builder_tests :: () {
|
||
{
|
||
builder := create_builder("What", "we", "expected", init = false);
|
||
print("Builder %, outer current buffer: %\n", *builder, builder.current_buffer);
|
||
|
||
stuff := do_other_stack_stuff();
|
||
assert(stuff[0] == 0); // Just so the optimizer doesn't get rid of it
|
||
assert(stuff[1023] == 255); // Just so the optimizer doesn't get rid of it
|
||
|
||
output := builder_to_string(*builder);
|
||
print("Outer output: %\n", output);
|
||
assert(output == "What we expected");
|
||
}
|
||
{
|
||
builder := create_builder("What", "we", "expected", init = true);
|
||
print("Builder %, outer current buffer: %\n", *builder, builder.current_buffer);
|
||
|
||
stuff := do_other_stack_stuff();
|
||
assert(stuff[0] == 0); // Just so the optimizer doesn't get rid of it
|
||
assert(stuff[1023] == 255); // Just so the optimizer doesn't get rid of it
|
||
|
||
output := builder_to_string(*builder);
|
||
print("Outer output: %\n", output);
|
||
assert(output == "What we expected");
|
||
}
|
||
print("OK\n");
|
||
}
|
||
|
||
|
||
apollo_time_tests :: () {
|
||
#if OS != .WINDOWS {
|
||
unix_epoch_start := timespec_to_apollo(.{0, 0});
|
||
ct := to_calendar(unix_epoch_start, .UTC);
|
||
log("Unix epoch start: %", ct);
|
||
|
||
assert(ct.year == 1970);
|
||
assert(ct.month_starting_at_0 == 0);
|
||
assert(ct.day_of_month_starting_at_0 == 0);
|
||
assert(ct.day_of_week_starting_at_0 == 4);
|
||
assert(ct.hour == 0);
|
||
assert(ct.minute == 0);
|
||
assert(ct.second == 0);
|
||
assert(ct.millisecond == 0);
|
||
assert(ct.time_zone == .UTC);
|
||
}
|
||
|
||
{
|
||
ct: Calendar_Time;
|
||
ct.year = 2022;
|
||
ct.month_starting_at_0 = 3;
|
||
ct.day_of_month_starting_at_0 = 5;
|
||
ct.hour = 16;
|
||
ct.minute = 26;
|
||
ct.second = 30;
|
||
ct.millisecond = 500;
|
||
ct.time_zone = .LOCAL;
|
||
|
||
apollo_time := calendar_to_apollo(ct);
|
||
ct_roundtrip := to_calendar(apollo_time, ct.time_zone);
|
||
log("Calendar to Apollo to Calendar roundtrip for %: %", ct, ct_roundtrip);
|
||
|
||
assert(ct_roundtrip.year == 2022);
|
||
assert(ct_roundtrip.month_starting_at_0 == 3);
|
||
assert(ct_roundtrip.day_of_month_starting_at_0 == 5);
|
||
assert(ct_roundtrip.hour == 16);
|
||
assert(ct_roundtrip.minute == 26);
|
||
assert(ct_roundtrip.second == 30);
|
||
assert(ct_roundtrip.millisecond == 500);
|
||
assert(ct_roundtrip.time_zone == .LOCAL);
|
||
}
|
||
{
|
||
ct: Calendar_Time;
|
||
ct.year = 2022;
|
||
ct.month_starting_at_0 = 3;
|
||
ct.day_of_month_starting_at_0 = 5;
|
||
ct.hour = 16;
|
||
ct.minute = 26;
|
||
ct.second = 30;
|
||
ct.millisecond = 500;
|
||
ct.time_zone = .UTC;
|
||
|
||
apollo_time := calendar_to_apollo(ct);
|
||
ct_roundtrip := to_calendar(apollo_time, ct.time_zone);
|
||
log("Calendar to Apollo to Calendar roundtrip for %: %", ct, ct_roundtrip);
|
||
|
||
assert(ct_roundtrip.year == 2022);
|
||
assert(ct_roundtrip.month_starting_at_0 == 3);
|
||
assert(ct_roundtrip.day_of_month_starting_at_0 == 5);
|
||
assert(ct_roundtrip.hour == 16);
|
||
assert(ct_roundtrip.minute == 26);
|
||
assert(ct_roundtrip.second == 30);
|
||
assert(ct_roundtrip.millisecond == 500);
|
||
assert(ct_roundtrip.time_zone == .UTC);
|
||
}
|
||
} @test
|
||
|
||
create_builder :: (strings: .. string, init: bool) -> String_Builder {
|
||
builder: String_Builder;
|
||
if init init_string_builder(*builder);
|
||
|
||
for strings {
|
||
if it_index {
|
||
append(*builder, " ");
|
||
}
|
||
append(*builder, it);
|
||
}
|
||
|
||
print("Current buffer: %\n", builder.current_buffer);
|
||
output := builder_to_string(*builder, do_reset=false);
|
||
print("Inner output: %\n", output);
|
||
return builder;
|
||
}
|
||
|
||
do_other_stack_stuff :: () -> [1024] u8 {
|
||
my_array: [1024] u8;
|
||
for 0..my_array.count - 1 {
|
||
my_array[it] = xx (it % 256);
|
||
}
|
||
|
||
return my_array;
|
||
}
|
||
|
||
parse_int_tests :: () {
|
||
result_10 := string_to_int("105", 10, u8);
|
||
assert(result_10 == 105);
|
||
result_16 := string_to_int("105", 16, u16);
|
||
assert(result_16 == 0x105);
|
||
result_8 := string_to_int("105", 8, u8);
|
||
assert(result_8 == 69);
|
||
result_2 := string_to_int("101", 2, u8);
|
||
assert(result_2 == 0b101);
|
||
}
|
||
|
||
parse_float_tests :: () {
|
||
// Check that parsing denormalized float values is fine. This is the minimum positive subnormal value:
|
||
parsed_value, success, remainder := string_to_float64("4.9406564584124654e-324");
|
||
print("Result: % % %", parsed_value, success, remainder);
|
||
assert(success == true);
|
||
assert(parsed_value == 0h0000_0000_0000_0001, "Unexpected parsed value: 0h%", formatInt((.*)(cast(*u64) *parsed_value), base=16, minimum_digits = 16, digits_per_comma = 4, comma_string = "_"));
|
||
}
|
||
|
||
|
||
test_single_apollo_time_conversion :: (time: Apollo_Time, factor: u64, $round: bool, expected_result: s64, expected_success: bool) -> fail: int {
|
||
to_string :: (x: S128) -> string {
|
||
chars: [39] u8;
|
||
count := 0;
|
||
|
||
n := x;
|
||
|
||
while n != .{} {
|
||
n=, digit := signed_divide_with_remainder(n, .{10, 0});
|
||
if digit == S128_ERROR return "<overflow>";
|
||
chars[count] = cast,trunc(u8)(digit.low) + #char "0";
|
||
count += 1;
|
||
}
|
||
|
||
builder: String_Builder;
|
||
if x < .{} append(*builder, "-");
|
||
for < 0..count - 1 append(*builder, chars[it]);
|
||
return builder_to_string(*builder);
|
||
}
|
||
|
||
result, success := ConvertFromApollo(time, factor, round);
|
||
error := false;
|
||
if success {
|
||
print("% % / % = % ", ifx round then "^" else " ", to_string(time), factor, result);
|
||
if expected_success error = expected_result != result;
|
||
else error = true;
|
||
} else {
|
||
print("% % / % = % ", ifx round then "^" else " ", to_string(time), factor, "<OVERFLOW>");
|
||
error = expected_success;
|
||
}
|
||
if error print_color("FAIL\n", color = .RED);
|
||
else print_color("OK\n", color = .GREEN);
|
||
|
||
return ifx error then 1 else 0;
|
||
}
|
||
|
||
test_apollo_time_conversion :: () {
|
||
test :: (time: Apollo_Time, factor: u64, expected_result: s64) -> fail: int {
|
||
return test_single_apollo_time_conversion(time, factor, false, expected_result, true);
|
||
}
|
||
|
||
test_round :: (time: Apollo_Time, factor: u64, expected_result: s64) -> fail: int {
|
||
return test_single_apollo_time_conversion(time, factor, true, expected_result, true);
|
||
}
|
||
|
||
test :: (time: Apollo_Time, factor: u64, expected_success: bool) -> fail: int {
|
||
return test_single_apollo_time_conversion(time, factor, false, 0, expected_success);
|
||
}
|
||
|
||
test_round :: (time: Apollo_Time, factor: u64, expected_success: bool) -> fail: int {
|
||
return test_single_apollo_time_conversion(time, factor, true, 0, expected_success);
|
||
}
|
||
|
||
fails := 0;
|
||
print("\nApollo Time Conversion:\n\n");
|
||
|
||
// expected values ascertained from wolfram alpha
|
||
|
||
plus_one := Apollo_Time.{low = 1, high = 0};
|
||
fails += test(plus_one, 1, 1);
|
||
fails += test(plus_one, 2, 0);
|
||
fails += test(plus_one, 3, 0);
|
||
fails += test(plus_one, 4, 0);
|
||
fails += test(plus_one, 5, 0);
|
||
fails += test(plus_one, xx S64_MAX, 0);
|
||
fails += test(plus_one, 0x80000000_00000000, 0);
|
||
fails += test(plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(plus_one, 1, 1);
|
||
fails += test_round(plus_one, 2, 1);
|
||
fails += test_round(plus_one, 3, 0);
|
||
fails += test_round(plus_one, 4, 0);
|
||
fails += test_round(plus_one, 5, 0);
|
||
fails += test_round(plus_one, xx S64_MAX, 0);
|
||
fails += test_round(plus_one, 0x80000000_00000000, 0);
|
||
fails += test_round(plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
fails += test(-plus_one, 1, -1);
|
||
fails += test(-plus_one, 2, 0);
|
||
fails += test(-plus_one, 3, 0);
|
||
fails += test(-plus_one, 4, 0);
|
||
fails += test(-plus_one, 5, 0);
|
||
fails += test(-plus_one, xx S64_MAX, 0);
|
||
fails += test(-plus_one, 0x80000000_00000000, 0);
|
||
fails += test(-plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(-plus_one, 1, -1);
|
||
fails += test_round(-plus_one, 2, 0);
|
||
fails += test_round(-plus_one, 3, 0);
|
||
fails += test_round(-plus_one, 4, 0);
|
||
fails += test_round(-plus_one, 5, 0);
|
||
fails += test_round(-plus_one, xx S64_MAX, 0);
|
||
fails += test_round(-plus_one, 0x80000000_00000000, 0);
|
||
fails += test_round(-plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
plus_two := Apollo_Time.{low = 2, high = 0};
|
||
fails += test(plus_two, 1, 2);
|
||
fails += test(plus_two, 2, 1);
|
||
fails += test(plus_two, 3, 0);
|
||
fails += test(plus_two, 4, 0);
|
||
fails += test(plus_two, 5, 0);
|
||
fails += test(plus_two, xx S64_MAX, 0);
|
||
fails += test(plus_two, 0x80000000_00000000, 0);
|
||
fails += test(plus_two, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(plus_two, 1, 2);
|
||
fails += test_round(plus_two, 2, 1);
|
||
fails += test_round(plus_two, 3, 1);
|
||
fails += test_round(plus_two, 4, 1);
|
||
fails += test_round(plus_two, 5, 0);
|
||
fails += test_round(plus_two, xx S64_MAX, 0);
|
||
fails += test_round(plus_two, 0x80000000_00000000, 0);
|
||
fails += test_round(plus_two, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
fails += test(-plus_two, 1, -2);
|
||
fails += test(-plus_two, 2, -1);
|
||
fails += test(-plus_two, 3, 0);
|
||
fails += test(-plus_two, 4, 0);
|
||
fails += test(-plus_two, 5, 0);
|
||
fails += test(-plus_two, xx S64_MAX, 0);
|
||
fails += test(-plus_two, 0x80000000_00000000, 0);
|
||
fails += test(-plus_two, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(-plus_two, 1, -2);
|
||
fails += test_round(-plus_two, 2, -1);
|
||
fails += test_round(-plus_two, 3, -1);
|
||
fails += test_round(-plus_two, 4, 0);
|
||
fails += test_round(-plus_two, 5, 0);
|
||
fails += test_round(-plus_two, xx S64_MAX, 0);
|
||
fails += test_round(-plus_two, 0x80000000_00000000, 0);
|
||
fails += test_round(-plus_two, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
|
||
// 9223372036854775807
|
||
s64_max := Apollo_Time.{low = xx S64_MAX, high = 0};
|
||
fails += test(s64_max, 1, 9223372036854775807);
|
||
fails += test(s64_max, 2, 4611686018427387903);
|
||
fails += test(s64_max, 3, 3074457345618258602);
|
||
fails += test(s64_max, 4, 2305843009213693951);
|
||
fails += test(s64_max, 5, 1844674407370955161);
|
||
fails += test(s64_max, xx S64_MAX, 1);
|
||
fails += test(s64_max, 0x80000000_00000000, 0);
|
||
fails += test(s64_max, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(s64_max, 1, 9223372036854775807);
|
||
fails += test_round(s64_max, 2, 4611686018427387904);
|
||
fails += test_round(s64_max, 3, 3074457345618258602);
|
||
fails += test_round(s64_max, 4, 2305843009213693952);
|
||
fails += test_round(s64_max, 5, 1844674407370955161);
|
||
fails += test_round(s64_max, xx S64_MAX, 1);
|
||
fails += test_round(s64_max, 0x80000000_00000000, 1);
|
||
fails += test_round(s64_max, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
// -9223372036854775807
|
||
fails += test(-s64_max, 1, -9223372036854775807);
|
||
fails += test(-s64_max, 2, -4611686018427387903);
|
||
fails += test(-s64_max, 3, -3074457345618258602);
|
||
fails += test(-s64_max, 4, -2305843009213693951);
|
||
fails += test(-s64_max, 5, -1844674407370955161);
|
||
fails += test(-s64_max, xx S64_MAX, -1);
|
||
fails += test(-s64_max, 0x80000000_00000000, 0);
|
||
fails += test(-s64_max, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(-s64_max, 1, -9223372036854775807);
|
||
fails += test_round(-s64_max, 2, -4611686018427387903);
|
||
fails += test_round(-s64_max, 3, -3074457345618258602);
|
||
fails += test_round(-s64_max, 4, -2305843009213693952);
|
||
fails += test_round(-s64_max, 5, -1844674407370955161);
|
||
fails += test_round(-s64_max, xx S64_MAX, -1);
|
||
fails += test_round(-s64_max, 0x80000000_00000000, -1);
|
||
fails += test_round(-s64_max, U64_MAX, 0);
|
||
print("\n");
|
||
|
||
// 9223372036854775808
|
||
s64_max_plus_one := s64_max + .{1, 0};
|
||
fails += test(s64_max_plus_one, 1, false);
|
||
fails += test(s64_max_plus_one, 2, 4611686018427387904);
|
||
fails += test(s64_max_plus_one, 3, 3074457345618258602);
|
||
fails += test(s64_max_plus_one, 4, 2305843009213693952);
|
||
fails += test(s64_max_plus_one, 5, 1844674407370955161);
|
||
fails += test(s64_max_plus_one, xx S64_MAX, 1);
|
||
fails += test(s64_max_plus_one, 0x80000000_00000000, 1);
|
||
fails += test(s64_max_plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(s64_max_plus_one, 1, false);
|
||
fails += test_round(s64_max_plus_one, 2, 4611686018427387904);
|
||
fails += test_round(s64_max_plus_one, 3, 3074457345618258603);
|
||
fails += test_round(s64_max_plus_one, 4, 2305843009213693952);
|
||
fails += test_round(s64_max_plus_one, 5, 1844674407370955162);
|
||
fails += test_round(s64_max_plus_one, xx S64_MAX, 1);
|
||
fails += test_round(s64_max_plus_one, 0x80000000_00000000, 1);
|
||
fails += test_round(s64_max_plus_one, U64_MAX, 1);
|
||
print("\n");
|
||
|
||
// -9223372036854775808
|
||
fails += test(-s64_max_plus_one, 1, -9223372036854775808);
|
||
fails += test(-s64_max_plus_one, 2, -4611686018427387904);
|
||
fails += test(-s64_max_plus_one, 3, -3074457345618258602);
|
||
fails += test(-s64_max_plus_one, 4, -2305843009213693952);
|
||
fails += test(-s64_max_plus_one, 5, -1844674407370955161);
|
||
fails += test(-s64_max_plus_one, xx S64_MAX, -1);
|
||
fails += test(-s64_max_plus_one, 0x80000000_00000000, -1);
|
||
fails += test(-s64_max_plus_one, U64_MAX, 0);
|
||
print("\n");
|
||
fails += test_round(-s64_max_plus_one, 1, -9223372036854775808);
|
||
fails += test_round(-s64_max_plus_one, 2, -4611686018427387904);
|
||
fails += test_round(-s64_max_plus_one, 3, -3074457345618258603);
|
||
fails += test_round(-s64_max_plus_one, 4, -2305843009213693952);
|
||
fails += test_round(-s64_max_plus_one, 5, -1844674407370955162);
|
||
fails += test_round(-s64_max_plus_one, xx S64_MAX, -1);
|
||
fails += test_round(-s64_max_plus_one, 0x80000000_00000000, -1);
|
||
fails += test_round(-s64_max_plus_one, U64_MAX, -1);
|
||
print("\n");
|
||
|
||
|
||
// 18446744073709551615
|
||
u64_max := Apollo_Time.{low = U64_MAX, high = 0};
|
||
fails += test(u64_max, 1, false);
|
||
fails += test(u64_max, 2, 9223372036854775807);
|
||
fails += test(u64_max, 3, 6148914691236517205);
|
||
fails += test(u64_max, 4, 4611686018427387903);
|
||
fails += test(u64_max, 5, 3689348814741910323);
|
||
fails += test(u64_max, xx S64_MAX, 2);
|
||
fails += test(u64_max, 0x80000000_00000000, 1);
|
||
fails += test(u64_max, U64_MAX, 1);
|
||
print("\n");
|
||
fails += test_round(u64_max, 1, false);
|
||
fails += test_round(u64_max, 2, false);
|
||
fails += test_round(u64_max, 3, 6148914691236517205);
|
||
fails += test_round(u64_max, 4, 4611686018427387904);
|
||
fails += test_round(u64_max, 5, 3689348814741910323);
|
||
fails += test_round(u64_max, xx S64_MAX, 2);
|
||
fails += test_round(u64_max, 0x80000000_00000000, 2);
|
||
fails += test_round(u64_max, U64_MAX, 1);
|
||
print("\n");
|
||
|
||
// -18446744073709551615
|
||
fails += test(-u64_max, 1, false);
|
||
fails += test(-u64_max, 2, -9223372036854775807);
|
||
fails += test(-u64_max, 3, -6148914691236517205);
|
||
fails += test(-u64_max, 4, -4611686018427387903);
|
||
fails += test(-u64_max, 5, -3689348814741910323);
|
||
fails += test(-u64_max, xx S64_MAX, -2);
|
||
fails += test(-u64_max, 0x80000000_00000000, -1);
|
||
fails += test(-u64_max, U64_MAX, -1);
|
||
print("\n");
|
||
fails += test_round(-u64_max, 1, false);
|
||
fails += test_round(-u64_max, 2, -9223372036854775807);
|
||
fails += test_round(-u64_max, 3, -6148914691236517205);
|
||
fails += test_round(-u64_max, 4, -4611686018427387904);
|
||
fails += test_round(-u64_max, 5, -3689348814741910323);
|
||
fails += test_round(-u64_max, xx S64_MAX, -2);
|
||
fails += test_round(-u64_max, 0x80000000_00000000, -2);
|
||
fails += test_round(-u64_max, U64_MAX, -1);
|
||
print("\n");
|
||
|
||
// 36893488147419103230
|
||
double_u64_max := u64_max * .{2, 0};
|
||
fails += test(double_u64_max, 1, false);
|
||
fails += test(double_u64_max, 2, false);
|
||
fails += test(double_u64_max, 3, false);
|
||
fails += test(double_u64_max, 4, 9223372036854775807);
|
||
fails += test(double_u64_max, 5, 7378697629483820646);
|
||
fails += test(double_u64_max, xx S64_MAX, 4);
|
||
fails += test(double_u64_max, 0x80000000_00000000, 3);
|
||
fails += test(double_u64_max, U64_MAX, 2);
|
||
print("\n");
|
||
fails += test_round(double_u64_max, 1, false);
|
||
fails += test_round(double_u64_max, 2, false);
|
||
fails += test_round(double_u64_max, 3, false);
|
||
fails += test_round(double_u64_max, 4, false);
|
||
fails += test_round(double_u64_max, 5, 7378697629483820646);
|
||
fails += test_round(double_u64_max, xx S64_MAX, 4);
|
||
fails += test_round(double_u64_max, 0x80000000_00000000, 4);
|
||
fails += test_round(double_u64_max, U64_MAX, 2);
|
||
print("\n");
|
||
|
||
// -36893488147419103230
|
||
fails += test(-double_u64_max, 1, false);
|
||
fails += test(-double_u64_max, 2, false);
|
||
fails += test(-double_u64_max, 3, false);
|
||
fails += test(-double_u64_max, 4, -9223372036854775807);
|
||
fails += test(-double_u64_max, 5, -7378697629483820646);
|
||
fails += test(-double_u64_max, xx S64_MAX, -4);
|
||
fails += test(-double_u64_max, 0x80000000_00000000, -3);
|
||
fails += test(-double_u64_max, U64_MAX, -2);
|
||
print("\n");
|
||
fails += test_round(-double_u64_max, 1, false);
|
||
fails += test_round(-double_u64_max, 2, false);
|
||
fails += test_round(-double_u64_max, 3, false);
|
||
fails += test_round(-double_u64_max, 4, -9223372036854775807);
|
||
fails += test_round(-double_u64_max, 5, -7378697629483820646);
|
||
fails += test_round(-double_u64_max, xx S64_MAX, -4);
|
||
fails += test_round(-double_u64_max, 0x80000000_00000000, -4);
|
||
fails += test_round(-double_u64_max, U64_MAX, -2);
|
||
print("\n");
|
||
|
||
if fails print("% FAILED TESTS!\n", fails);
|
||
else print("ALL TESTS PASSED\n");
|
||
}
|
||
|
||
#import "Basic";
|
||
#import "Math";
|
||
#import "Print_Color";
|
||
#import "Random";
|
||
|
||
main :: () {
|
||
print_int_tests();
|
||
print_float_tests();
|
||
simple_string_tests();
|
||
string_builder_tests();
|
||
apollo_time_tests();
|
||
|
||
parse_int_tests();
|
||
parse_float_tests();
|
||
|
||
seed := random_get();
|
||
print("\n\nRandom seed: %\n", seed);
|
||
random_seed(seed);
|
||
#if CPU == .X64 {
|
||
test_unsigned_division(10000, random_get);
|
||
}
|
||
test_apollo_time_conversion();
|
||
}
|
||
|
||
// @ToDo @Fixme: parse_float_tests() fails when running at compile time, so there is something very sus going on…
|
||
// #run main();
|