Serenity Operating System
at master 366 lines 13 kB view raw
1/* 2 * Copyright (c) 2020, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/DeprecatedString.h> 10#include <AK/StringBuilder.h> 11#include <AK/Vector.h> 12#include <math.h> 13#include <unistd.h> 14 15TEST_CASE(is_integral_works_properly) 16{ 17 EXPECT(!IsIntegral<char const*>); 18 EXPECT(IsIntegral<unsigned long>); 19} 20 21TEST_CASE(format_string_literals) 22{ 23 EXPECT_EQ(DeprecatedString::formatted("prefix-{}-suffix", "abc"), "prefix-abc-suffix"); 24 EXPECT_EQ(DeprecatedString::formatted("{}{}{}", "a", "b", "c"), "abc"); 25} 26 27TEST_CASE(format_integers) 28{ 29 EXPECT_EQ(DeprecatedString::formatted("{}", 42u), "42"); 30 EXPECT_EQ(DeprecatedString::formatted("{:4}", 42u), " 42"); 31 EXPECT_EQ(DeprecatedString::formatted("{:08}", 42u), "00000042"); 32 EXPECT_EQ(DeprecatedString::formatted("{:7}", -17), " -17"); 33 EXPECT_EQ(DeprecatedString::formatted("{}", -17), "-17"); 34 EXPECT_EQ(DeprecatedString::formatted("{:04}", 13), "0013"); 35 EXPECT_EQ(DeprecatedString::formatted("{:08x}", 4096), "00001000"); 36 EXPECT_EQ(DeprecatedString::formatted("{:x}", 0x1111222233334444ull), "1111222233334444"); 37 EXPECT_EQ(DeprecatedString::formatted("{:4}", 12345678), "12345678"); 38} 39 40TEST_CASE(reorder_format_arguments) 41{ 42 EXPECT_EQ(DeprecatedString::formatted("{1}{0}", "a", "b"), "ba"); 43 EXPECT_EQ(DeprecatedString::formatted("{0}{1}", "a", "b"), "ab"); 44 // Compiletime check bypass: ignoring a passed argument. 45 EXPECT_EQ(DeprecatedString::formatted("{0}{0}{0}"sv, "a", "b"), "aaa"); 46 // Compiletime check bypass: ignoring a passed argument. 47 EXPECT_EQ(DeprecatedString::formatted("{1}{}{0}"sv, "a", "b", "c"), "baa"); 48} 49 50TEST_CASE(escape_braces) 51{ 52 EXPECT_EQ(DeprecatedString::formatted("{{{}", "foo"), "{foo"); 53 EXPECT_EQ(DeprecatedString::formatted("{}}}", "bar"), "bar}"); 54} 55 56TEST_CASE(everything) 57{ 58 EXPECT_EQ(DeprecatedString::formatted("{{{:04}/{}/{0:8}/{1}", 42u, "foo"), "{0042/foo/ 42/foo"); 59} 60 61TEST_CASE(string_builder) 62{ 63 StringBuilder builder; 64 builder.appendff(" {} ", 42); 65 builder.appendff("{1}{0} ", 1, 2); 66 67 EXPECT_EQ(builder.to_deprecated_string(), " 42 21 "); 68} 69 70TEST_CASE(format_without_arguments) 71{ 72 EXPECT_EQ(DeprecatedString::formatted("foo"), "foo"); 73} 74 75TEST_CASE(format_upper_case_integer) 76{ 77 EXPECT_EQ(DeprecatedString::formatted("{:4X}", 0xff), " FF"); 78 EXPECT_EQ(DeprecatedString::formatted("{:#4X}", 0xff), "0XFF"); 79 80 EXPECT_EQ(DeprecatedString::formatted("{:b}", 0xff), "11111111"); 81 EXPECT_EQ(DeprecatedString::formatted("{:B}", 0xff), "11111111"); 82 EXPECT_EQ(DeprecatedString::formatted("{:#b}", 0xff), "0b11111111"); 83} 84 85TEST_CASE(format_aligned) 86{ 87 EXPECT_EQ(DeprecatedString::formatted("{:*<8}", 13), "13******"); 88 EXPECT_EQ(DeprecatedString::formatted("{:*^8}", 13), "***13***"); 89 EXPECT_EQ(DeprecatedString::formatted("{:*>8}", 13), "******13"); 90 EXPECT_EQ(DeprecatedString::formatted("{:*>+8}", 13), "*****+13"); 91 EXPECT_EQ(DeprecatedString::formatted("{:*^ 8}", 13), "** 13***"); 92} 93 94TEST_CASE(format_octal) 95{ 96 EXPECT_EQ(DeprecatedString::formatted("{:o}", 0744), "744"); 97 EXPECT_EQ(DeprecatedString::formatted("{:#o}", 0744), "0744"); 98} 99 100TEST_CASE(zero_pad) 101{ 102 EXPECT_EQ(DeprecatedString::formatted("{: <010}", 42), "42 "); 103 EXPECT_EQ(DeprecatedString::formatted("{:010}", 42), "0000000042"); 104 EXPECT_EQ(DeprecatedString::formatted("{:/^010}", 42), "////42////"); 105 EXPECT_EQ(DeprecatedString::formatted("{:04x}", -32), "-0020"); 106 EXPECT_EQ(DeprecatedString::formatted("{:#06x}", -64), "-0x000040"); 107} 108 109TEST_CASE(replacement_field) 110{ 111 EXPECT_EQ(DeprecatedString::formatted("{:*>{1}}", 13, static_cast<size_t>(10)), "********13"); 112 EXPECT_EQ(DeprecatedString::formatted("{:*<{1}}", 7, 4), "7***"); 113 // Compiletime check bypass: intentionally ignoring extra arguments 114 EXPECT_EQ(DeprecatedString::formatted("{:{2}}"sv, -5, 8, 16), " -5"); 115 EXPECT_EQ(DeprecatedString::formatted("{{{:*^{1}}}}", 1, 3), "{*1*}"); 116 EXPECT_EQ(DeprecatedString::formatted("{:0{}}", 1, 3), "001"); 117} 118 119TEST_CASE(replacement_field_regression) 120{ 121 // FIXME: Compiletime check bypass: cannot parse '}}' correctly. 122 EXPECT_EQ(DeprecatedString::formatted("{:{}}"sv, "", static_cast<unsigned long>(6)), " "); 123} 124 125TEST_CASE(complex_string_specifiers) 126{ 127 EXPECT_EQ(DeprecatedString::formatted("{:.8}", "123456789"), "12345678"); 128 EXPECT_EQ(DeprecatedString::formatted("{:9}", "abcd"), "abcd "); 129 EXPECT_EQ(DeprecatedString::formatted("{:>9}", "abcd"), " abcd"); 130 EXPECT_EQ(DeprecatedString::formatted("{:^9}", "abcd"), " abcd "); 131 EXPECT_EQ(DeprecatedString::formatted("{:4.6}", "a"), "a "); 132 EXPECT_EQ(DeprecatedString::formatted("{:4.6}", "abcdef"), "abcdef"); 133 EXPECT_EQ(DeprecatedString::formatted("{:4.6}", "abcdefghi"), "abcdef"); 134} 135 136TEST_CASE(cast_integer_to_character) 137{ 138 EXPECT_EQ(DeprecatedString::formatted("{:c}", static_cast<int>('a')), "a"); 139 EXPECT_EQ(DeprecatedString::formatted("{:c}", static_cast<unsigned int>('f')), "f"); 140} 141 142TEST_CASE(boolean_values) 143{ 144 EXPECT_EQ(DeprecatedString::formatted("{}", true), "true"); 145 EXPECT_EQ(DeprecatedString::formatted("{}", false), "false"); 146 EXPECT_EQ(DeprecatedString::formatted("{:6}", true), "true "); 147 EXPECT_EQ(DeprecatedString::formatted("{:>4}", false), "false"); 148 EXPECT_EQ(DeprecatedString::formatted("{:d}", false), "0"); 149 EXPECT_EQ(DeprecatedString::formatted("{:d}", true), "1"); 150 EXPECT_EQ(DeprecatedString::formatted("{:#08x}", true), "0x00000001"); 151} 152 153TEST_CASE(pointers) 154{ 155 void* ptr = reinterpret_cast<void*>(0x4000); 156 157 if (sizeof(void*) == 4) { 158 EXPECT_EQ(DeprecatedString::formatted("{:p}", 32), "0x00000020"); 159 EXPECT_EQ(DeprecatedString::formatted("{:p}", ptr), "0x00004000"); 160 EXPECT_EQ(DeprecatedString::formatted("{}", ptr), "0x00004000"); 161 } else if (sizeof(void*) == 8) { 162 EXPECT_EQ(DeprecatedString::formatted("{:p}", 32), "0x0000000000000020"); 163 EXPECT_EQ(DeprecatedString::formatted("{:p}", ptr), "0x0000000000004000"); 164 EXPECT_EQ(DeprecatedString::formatted("{}", ptr), "0x0000000000004000"); 165 } else { 166 VERIFY_NOT_REACHED(); 167 } 168} 169 170// If the format implementation did absolutely nothing, all tests would pass. This 171// is because when a test fails we only write "FAIL" to stdout using format. 172// 173// This is a bit scary, thus this test. At least this test should fail in this case. 174TEST_CASE(ensure_that_format_works) 175{ 176 if (DeprecatedString::formatted("FAIL") != "FAIL") { 177 fprintf(stderr, "FAIL\n"); 178 exit(1); 179 } 180 181 if (DeprecatedString::formatted("{} FAIL {}", 1, 2) != "1 FAIL 2") { 182 fprintf(stderr, "FAIL\n"); 183 exit(1); 184 } 185} 186 187TEST_CASE(format_string_literal_as_pointer) 188{ 189 char const* literal = "abc"; 190 EXPECT_EQ(DeprecatedString::formatted("{:p}", literal), DeprecatedString::formatted("{:p}", reinterpret_cast<FlatPtr>(literal))); 191} 192 193TEST_CASE(format_character) 194{ 195 char a = 'a'; 196 EXPECT_EQ(DeprecatedString::formatted("{}", true ? a : 'b'), "a"); 197} 198 199struct A { 200}; 201struct B { 202}; 203template<> 204struct AK::Formatter<B> : Formatter<StringView> { 205 ErrorOr<void> format(FormatBuilder& builder, B) 206 { 207 return Formatter<StringView>::format(builder, "B"sv); 208 } 209}; 210 211TEST_CASE(format_if_supported) 212{ 213 EXPECT_EQ(DeprecatedString::formatted("{}", FormatIfSupported { A {} }), "?"); 214 EXPECT_EQ(DeprecatedString::formatted("{}", FormatIfSupported { B {} }), "B"); 215} 216 217TEST_CASE(file_descriptor) 218{ 219 char filename[] = "/tmp/test-file-descriptor-XXXXXX"; 220 221 int fd = mkstemp(filename); 222 FILE* file = fdopen(fd, "w+"); 223 224 outln(file, "{}", "Hello, World!"); 225 out(file, "foo"); 226 outln(file, "bar"); 227 228 rewind(file); 229 230 Array<u8, 256> buffer; 231 auto const nread = fread(buffer.data(), 1, buffer.size(), file); 232 233 EXPECT_EQ("Hello, World!\nfoobar\n"sv, StringView { buffer.span().trim(nread) }); 234 235 fclose(file); 236 237 unlink(filename); 238} 239 240TEST_CASE(floating_point_numbers) 241{ 242 EXPECT_EQ(DeprecatedString::formatted("{}", 1.12), "1.12"); 243 EXPECT_EQ(DeprecatedString::formatted("{}", 1.), "1"); 244 EXPECT_EQ(DeprecatedString::formatted("{:.3}", 1.12), "1.12"); 245 EXPECT_EQ(DeprecatedString::formatted("{:.1}", 1.12), "1.1"); 246 EXPECT_EQ(DeprecatedString::formatted("{}", -1.12), "-1.12"); 247 248 EXPECT_EQ(DeprecatedString::formatted("{}", NAN), "nan"); 249 EXPECT_EQ(DeprecatedString::formatted("{}", INFINITY), "inf"); 250 EXPECT_EQ(DeprecatedString::formatted("{}", -INFINITY), "-inf"); 251 252 // FIXME: There is always the question what we mean with the width field. Do we mean significant digits? 253 // Do we mean the whole width? This is what was the simplest to implement: 254 EXPECT_EQ(DeprecatedString::formatted("{:x>5.1}", 1.12), "xx1.1"); 255} 256 257TEST_CASE(no_precision_no_trailing_number) 258{ 259 EXPECT_EQ(DeprecatedString::formatted("{:.0}", 0.1), "0"); 260} 261 262TEST_CASE(yay_this_implementation_sucks) 263{ 264 EXPECT_EQ(DeprecatedString::formatted("{:.0}", .99999999999), "0"); 265} 266 267TEST_CASE(precision_with_trailing_zeros) 268{ 269 EXPECT_EQ(DeprecatedString::formatted("{:0.3}", 1.12), "1.120"); 270 EXPECT_EQ(DeprecatedString::formatted("{:0.1}", 1.12), "1.1"); 271} 272 273TEST_CASE(magnitude_less_than_zero) 274{ 275 EXPECT_EQ(DeprecatedString::formatted("{}", -0.654), "-0.654"); 276 EXPECT_EQ(DeprecatedString::formatted("{}", 0.654), "0.654"); 277} 278 279TEST_CASE(format_nullptr) 280{ 281 EXPECT_EQ(DeprecatedString::formatted("{}", nullptr), DeprecatedString::formatted("{:p}", static_cast<FlatPtr>(0))); 282} 283 284struct C { 285 int i; 286}; 287template<> 288struct AK::Formatter<C> : AK::Formatter<FormatString> { 289 ErrorOr<void> format(FormatBuilder& builder, C c) 290 { 291 return AK::Formatter<FormatString>::format(builder, "C(i={})"sv, c.i); 292 } 293}; 294 295TEST_CASE(use_format_string_formatter) 296{ 297 EXPECT_EQ(DeprecatedString::formatted("{:*<10}", C { 42 }), "C(i=42)***"); 298} 299 300TEST_CASE(long_long_regression) 301{ 302 EXPECT_EQ(DeprecatedString::formatted("{}", 0x0123456789abcdefLL), "81985529216486895"); 303 304 StringBuilder builder; 305 AK::FormatBuilder fmtbuilder { builder }; 306 MUST(fmtbuilder.put_i64(0x0123456789abcdefLL)); 307 308 EXPECT_EQ(builder.string_view(), "81985529216486895"); 309} 310 311TEST_CASE(hex_dump) 312{ 313 EXPECT_EQ(DeprecatedString::formatted("{:hex-dump}", "0000"), "30303030"); 314 EXPECT_EQ(DeprecatedString::formatted("{:>4hex-dump}", "0000"), "30303030 0000"); 315 EXPECT_EQ(DeprecatedString::formatted("{:>2hex-dump}", "0000"), "3030 00\n3030 00"); 316 EXPECT_EQ(DeprecatedString::formatted("{:*>4hex-dump}", "0000"), "30303030****0000"); 317} 318 319TEST_CASE(span_format) 320{ 321 { 322 Vector<int> v { 1, 2, 3, 4 }; 323 EXPECT_EQ(DeprecatedString::formatted("{}", v.span()), "[ 1, 2, 3, 4 ]"); 324 EXPECT_EQ(DeprecatedString::formatted("{}", const_cast<AddConst<decltype(v)>&>(v).span()), "[ 1, 2, 3, 4 ]"); 325 } 326 { 327 Vector<StringView> v { "1"sv, "2"sv, "3"sv, "4"sv }; 328 EXPECT_EQ(DeprecatedString::formatted("{}", v.span()), "[ 1, 2, 3, 4 ]"); 329 EXPECT_EQ(DeprecatedString::formatted("{}", const_cast<AddConst<decltype(v)>&>(v).span()), "[ 1, 2, 3, 4 ]"); 330 } 331 { 332 Vector<Vector<DeprecatedString>> v { { "1"sv, "2"sv }, { "3"sv, "4"sv } }; 333 EXPECT_EQ(DeprecatedString::formatted("{}", v.span()), "[ [ 1, 2 ], [ 3, 4 ] ]"); 334 EXPECT_EQ(DeprecatedString::formatted("{}", const_cast<AddConst<decltype(v)>&>(v).span()), "[ [ 1, 2 ], [ 3, 4 ] ]"); 335 } 336} 337 338TEST_CASE(vector_format) 339{ 340 { 341 Vector<int> v { 1, 2, 3, 4 }; 342 EXPECT_EQ(DeprecatedString::formatted("{}", v), "[ 1, 2, 3, 4 ]"); 343 } 344 { 345 Vector<StringView> v { "1"sv, "2"sv, "3"sv, "4"sv }; 346 EXPECT_EQ(DeprecatedString::formatted("{}", v), "[ 1, 2, 3, 4 ]"); 347 } 348 { 349 Vector<Vector<DeprecatedString>> v { { "1"sv, "2"sv }, { "3"sv, "4"sv } }; 350 EXPECT_EQ(DeprecatedString::formatted("{}", v), "[ [ 1, 2 ], [ 3, 4 ] ]"); 351 } 352} 353 354TEST_CASE(format_wchar) 355{ 356 EXPECT_EQ(DeprecatedString::formatted("{}", L'a'), "a"); 357 EXPECT_EQ(DeprecatedString::formatted("{}", L'\U0001F41E'), "\xF0\x9F\x90\x9E"); 358 EXPECT_EQ(DeprecatedString::formatted("{:x}", L'a'), "61"); 359 EXPECT_EQ(DeprecatedString::formatted("{:x}", L'\U0001F41E'), "1f41e"); 360 EXPECT_EQ(DeprecatedString::formatted("{:d}", L'a'), "97"); 361 EXPECT_EQ(DeprecatedString::formatted("{:d}", L'\U0001F41E'), "128030"); 362 363 EXPECT_EQ(DeprecatedString::formatted("{:6}", L'a'), "a "); 364 EXPECT_EQ(DeprecatedString::formatted("{:6d}", L'a'), " 97"); 365 EXPECT_EQ(DeprecatedString::formatted("{:#x}", L'\U0001F41E'), "0x1f41e"); 366}