diff --git a/src/openrct2/localisation/Formatting.cpp b/src/openrct2/localisation/Formatting.cpp index 0fe237ee8e..cb05316b41 100644 --- a/src/openrct2/localisation/Formatting.cpp +++ b/src/openrct2/localisation/Formatting.cpp @@ -341,6 +341,11 @@ namespace OpenRCT2 buffer[i++] = static_cast('0' + (num % 10)); num /= 10; } + // handle case where value has fewer sig figs than required decimal places + while (num == 0 && i < TDecimalPlace && i < sizeof(buffer)) + { + buffer[i++] = '0'; + } auto decSep = GetDecimalSeparator(); AppendSeparator(buffer, i, decSep); diff --git a/test/tests/FormattingTests.cpp b/test/tests/FormattingTests.cpp index 125994664a..b34ec5e15b 100644 --- a/test/tests/FormattingTests.cpp +++ b/test/tests/FormattingTests.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include using namespace OpenRCT2; @@ -336,3 +338,269 @@ TEST_F(FormattingTests, using_legacy_buffer_args) ASSERT_EQ(len, 23U); ASSERT_STREQ("Queuing for Boat Hire 2", buffer); } + +TEST_F(FormattingTests, format_number_basic) +{ + std::stringstream ss; + // test basic integral conversion + FormatArgument(ss, FormatToken::UInt16, 123); + ASSERT_STREQ("123", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_basic_int32) +{ + std::stringstream ss; + // test that case fallthrough works + FormatArgument(ss, FormatToken::Int32, 123); + ASSERT_STREQ("123", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_negative) +{ + std::stringstream ss; + // test negative conversion + FormatArgument(ss, FormatToken::Int32, -123); + ASSERT_STREQ("-123", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_basic) +{ + std::stringstream ss; + // test separator formatter + // test base case separator formatter + FormatArgument(ss, FormatToken::Comma16, 123); + ASSERT_STREQ("123", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_negative) +{ + std::stringstream ss; + // test separator formatter + // test base case separator formatter + FormatArgument(ss, FormatToken::Comma16, -123); + ASSERT_STREQ("-123", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_large) +{ + std::stringstream ss; + // test larger value for separator formatter + FormatArgument(ss, FormatToken::Comma16, 123456789); + ASSERT_STREQ("123,456,789", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_large_negative) +{ + std::stringstream ss; + // test larger value for separator formatter with negative + FormatArgument(ss, FormatToken::Comma16, -123456789); + ASSERT_STREQ("-123,456,789", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_uneven) +{ + std::stringstream ss; + // test non-multiple of 3 + FormatArgument(ss, FormatToken::Comma16, 12345678); + ASSERT_STREQ("12,345,678", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_uneven_negative) +{ + std::stringstream ss; + // test non-multiple of 3 with negative + FormatArgument(ss, FormatToken::Comma16, -12345678); + ASSERT_STREQ("-12,345,678", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma16_zero) +{ + std::stringstream ss; + // test zero + FormatArgument(ss, FormatToken::Comma16, 0); + ASSERT_STREQ("0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_zero) +{ + std::stringstream ss; + // zero case + FormatArgument(ss, FormatToken::Comma1dp16, 0); + ASSERT_STREQ("0.0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_leading_zero) +{ + std::stringstream ss; + // test leading zero + FormatArgument(ss, FormatToken::Comma1dp16, 5); + ASSERT_STREQ("0.5", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_leading_zero_negative) +{ + std::stringstream ss; + // test leading zero with negative value + FormatArgument(ss, FormatToken::Comma1dp16, -5); + ASSERT_STREQ("-0.5", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_small_value) +{ + std::stringstream ss; + // test small value + FormatArgument(ss, FormatToken::Comma1dp16, 75); + ASSERT_STREQ("7.5", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_small_value_negative) +{ + std::stringstream ss; + // test small value with negative + FormatArgument(ss, FormatToken::Comma1dp16, -75); + ASSERT_STREQ("-7.5", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_trailing_zeros) +{ + std::stringstream ss; + // test value with trailing zero, no commas + FormatArgument(ss, FormatToken::Comma1dp16, 1000); + ASSERT_STREQ("100.0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_trailing_zeros_negative) +{ + std::stringstream ss; + // test value with trailing zero, no commas + FormatArgument(ss, FormatToken::Comma1dp16, -1000); + ASSERT_STREQ("-100.0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_large_trailing_zeros) +{ + std::stringstream ss; + // test value with commas and trailing zeros + FormatArgument(ss, FormatToken::Comma1dp16, 10000000); + ASSERT_STREQ("1,000,000.0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_large_trailing_zeros_negative) +{ + std::stringstream ss; + // test value with commas and trailing zeros + FormatArgument(ss, FormatToken::Comma1dp16, -10000000); + ASSERT_STREQ("-1,000,000.0", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_large_value) +{ + std::stringstream ss; + // test large value + FormatArgument(ss, FormatToken::Comma1dp16, 123456789); + ASSERT_STREQ("12,345,678.9", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma1dp16_large_value_negative) +{ + std::stringstream ss; + // test large value + FormatArgument(ss, FormatToken::Comma1dp16, -123456789); + ASSERT_STREQ("-12,345,678.9", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_zero) +{ + std::stringstream ss; + // zero case + FormatArgument(ss, FormatToken::Comma2dp32, 0); + ASSERT_STREQ("0.00", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_less_sig_figs) +{ + std::stringstream ss; + // test leading zero + FormatArgument(ss, FormatToken::Comma2dp32, 5); + ASSERT_STREQ("0.05", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_less_sig_figs_negative) +{ + std::stringstream ss; + // test leading zero + FormatArgument(ss, FormatToken::Comma2dp32, -5); + ASSERT_STREQ("-0.05", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_leading_zero) +{ + std::stringstream ss; + // test small value + FormatArgument(ss, FormatToken::Comma2dp32, 75); + ASSERT_STREQ("0.75", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_leading_zero_negative) +{ + std::stringstream ss; + // test small value + FormatArgument(ss, FormatToken::Comma2dp32, -75); + ASSERT_STREQ("-0.75", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_trailing_zeros) +{ + std::stringstream ss; + // test value with trailing zero, no commas + FormatArgument(ss, FormatToken::Comma2dp32, 1000); + ASSERT_STREQ("10.00", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_trailing_zeros_negative) +{ + std::stringstream ss; + // test value with trailing zero, no commas + FormatArgument(ss, FormatToken::Comma2dp32, -1000); + ASSERT_STREQ("-10.00", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_large_trailing_zeros) +{ + std::stringstream ss; + // test value with commas and trailing zeros + FormatArgument(ss, FormatToken::Comma2dp32, 10000000); + ASSERT_STREQ("100,000.00", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_large_trailing_zeros_negative) +{ + std::stringstream ss; + // test value with commas and trailing zeros + FormatArgument(ss, FormatToken::Comma2dp32, -10000000); + ASSERT_STREQ("-100,000.00", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_large_value) +{ + std::stringstream ss; + // test large value + FormatArgument(ss, FormatToken::Comma2dp32, 123456789); + ASSERT_STREQ("1,234,567.89", ss.str().c_str()); +} + +TEST_F(FormattingTests, format_number_comma2dp32_large_value_negative) +{ + std::stringstream ss; + // test large value + FormatArgument(ss, FormatToken::Comma2dp32, -123456789); + ASSERT_STREQ("-1,234,567.89", ss.str().c_str()); + + // extra note: + // for some reason the FormatArgument function contains constexpr + // checks for std::is_floating_point, even though a template + // specialization for which that would ever be the case is never + // declared. As such the following line won't be able to find + // the necessary symbol to link with. + // FormatArgument(ss, FormatToken::Comma1dp16, 12.372); +}