format_tests.c (10772B)
1 #include "format.h" 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <time.h> 6 7 #include "utest.h" 8 9 UTEST(print_time, PositiveOffset) { 10 char* buf = NULL; 11 size_t size = 0; 12 FILE* out = open_memstream(&buf, &size); 13 ASSERT_NE(NULL, out); 14 15 /* Test time: 2023-12-08 10:30:00 UTC */ 16 time_t test_time = 1702031400; 17 int timezone_offset = 540; /* +09:00 */ 18 19 print_time(out, test_time, timezone_offset); 20 fclose(out); 21 22 EXPECT_STREQ("Fri, 8 Dec 2023 19:30:00 +0900", buf); 23 24 free(buf); 25 } 26 27 UTEST(print_time, NegativeOffset) { 28 char* buf = NULL; 29 size_t size = 0; 30 FILE* out = open_memstream(&buf, &size); 31 ASSERT_NE(NULL, out); 32 33 /* Test time: 2023-12-08 10:30:00 UTC */ 34 time_t test_time = 1702031400; 35 int timezone_offset = -300; /* -05:00 */ 36 37 print_time(out, test_time, timezone_offset); 38 fclose(out); 39 40 EXPECT_STREQ("Fri, 8 Dec 2023 05:30:00 -0500", buf); 41 42 free(buf); 43 } 44 45 UTEST(print_time, ZeroOffset) { 46 char* buf = NULL; 47 size_t size = 0; 48 FILE* out = open_memstream(&buf, &size); 49 ASSERT_NE(NULL, out); 50 51 /* Test time: 2023-12-08 10:30:00 UTC */ 52 time_t test_time = 1702031400; 53 int timezone_offset = 0; /* UTC */ 54 55 print_time(out, test_time, timezone_offset); 56 fclose(out); 57 58 EXPECT_STREQ("Fri, 8 Dec 2023 10:30:00 +0000", buf); 59 60 free(buf); 61 } 62 63 UTEST(print_time, IllegalOffset) { 64 char* buf = NULL; 65 size_t size = 0; 66 FILE* out = open_memstream(&buf, &size); 67 ASSERT_NE(NULL, out); 68 69 /* Test time: 2023-12-08 10:30:00 UTC */ 70 time_t test_time = 1702031400; 71 int timezone_offset = 1441; /* 24 hours + 1 minute */ 72 73 print_time(out, test_time, timezone_offset); 74 fclose(out); 75 76 EXPECT_STREQ("", buf); 77 78 free(buf); 79 } 80 81 UTEST(print_time_z, Basic) { 82 char* buf = NULL; 83 size_t size = 0; 84 FILE* out = open_memstream(&buf, &size); 85 ASSERT_NE(NULL, out); 86 87 /* Test time: 2023-12-08 10:30:00 UTC */ 88 time_t test_time = 1702031400; 89 90 print_time_z(out, test_time); 91 fclose(out); 92 93 EXPECT_STREQ("2023-12-08T10:30:00Z", buf); 94 95 free(buf); 96 } 97 98 UTEST(print_time_short, Basic) { 99 char* buf = NULL; 100 size_t size = 0; 101 FILE* out = open_memstream(&buf, &size); 102 ASSERT_NE(NULL, out); 103 104 /* Test time: 2023-12-08 10:30:00 UTC */ 105 time_t test_time = 1702031400; 106 107 print_time_short(out, test_time); 108 fclose(out); 109 110 EXPECT_STREQ("2023-12-08 10:30", buf); 111 112 free(buf); 113 } 114 115 UTEST(print_percent_encoded, NoEncoding) { 116 char* buf = NULL; 117 size_t size = 0; 118 FILE* out = open_memstream(&buf, &size); 119 ASSERT_NE(NULL, out); 120 121 print_percent_encoded(out, "abcdef-1234/.,"); 122 fclose(out); 123 124 EXPECT_STREQ("abcdef-1234/.,", buf); 125 126 free(buf); 127 } 128 129 UTEST(print_percent_encoded, SimpleEncoding) { 130 char* buf = NULL; 131 size_t size = 0; 132 FILE* out = open_memstream(&buf, &size); 133 ASSERT_NE(NULL, out); 134 135 print_percent_encoded(out, "hello world"); 136 fclose(out); 137 138 EXPECT_STREQ("hello%20world", buf); 139 140 free(buf); 141 } 142 143 UTEST(print_percent_encoded, ReservedChars) { 144 char* buf = NULL; 145 size_t size = 0; 146 FILE* out = open_memstream(&buf, &size); 147 ASSERT_NE(NULL, out); 148 149 print_percent_encoded(out, " \"%[]:?@"); 150 fclose(out); 151 152 EXPECT_STREQ("%20%22%25%5B%5D%3A%3F%40", buf); 153 154 free(buf); 155 } 156 157 UTEST(print_percent_encoded, EmptyString) { 158 char* buf = NULL; 159 size_t size = 0; 160 FILE* out = open_memstream(&buf, &size); 161 ASSERT_NE(NULL, out); 162 163 print_percent_encoded(out, ""); 164 fclose(out); 165 166 EXPECT_STREQ("", buf); 167 168 free(buf); 169 } 170 171 UTEST(print_xml_encoded_len, FullEncoding) { 172 char* buf = NULL; 173 size_t size = 0; 174 FILE* out = open_memstream(&buf, &size); 175 ASSERT_NE(NULL, out); 176 177 const char* test_str = "<tag attr='value'> & \"text\""; 178 print_xml_encoded_len(out, test_str, -1, true); 179 fclose(out); 180 181 EXPECT_STREQ("<tag attr='value'> & "text"", buf); 182 183 free(buf); 184 } 185 186 UTEST(print_xml_encoded_len, PartialEncoding) { 187 char* buf = NULL; 188 size_t size = 0; 189 FILE* out = open_memstream(&buf, &size); 190 ASSERT_NE(NULL, out); 191 192 const char* test_str = "<tag>hello</tag>"; 193 print_xml_encoded_len(out, test_str, 5, true); 194 fclose(out); 195 196 EXPECT_STREQ("<tag>", buf); 197 198 free(buf); 199 } 200 201 UTEST(print_xml_encoded_len, WithCrlf) { 202 char* buf = NULL; 203 size_t size = 0; 204 FILE* out = open_memstream(&buf, &size); 205 ASSERT_NE(NULL, out); 206 207 const char* test_str = "line1\r\nline2"; 208 print_xml_encoded_len(out, test_str, -1, true); 209 fclose(out); 210 211 EXPECT_STREQ("line1\r\nline2", buf); 212 213 free(buf); 214 } 215 216 UTEST(print_xml_encoded_len, WithoutCrlf) { 217 char* buf = NULL; 218 size_t size = 0; 219 FILE* out = open_memstream(&buf, &size); 220 ASSERT_NE(NULL, out); 221 222 const char* test_str = "line1\r\nline2"; 223 print_xml_encoded_len(out, test_str, -1, false); 224 fclose(out); 225 226 EXPECT_STREQ("line1line2", buf); 227 228 free(buf); 229 } 230 231 UTEST(print_xml_encoded_len, EmptyString) { 232 char* buf = NULL; 233 size_t size = 0; 234 FILE* out = open_memstream(&buf, &size); 235 ASSERT_NE(NULL, out); 236 237 print_xml_encoded_len(out, "", -1, true); 238 fclose(out); 239 240 EXPECT_STREQ("", buf); 241 242 free(buf); 243 } 244 245 UTEST(print_xml_encoded_len, ZeroLength) { 246 char* buf = NULL; 247 size_t size = 0; 248 FILE* out = open_memstream(&buf, &size); 249 ASSERT_NE(NULL, out); 250 251 print_xml_encoded_len(out, "some text", 0, true); 252 fclose(out); 253 254 EXPECT_STREQ("", buf); 255 256 free(buf); 257 } 258 259 UTEST(print_gopher_text_len, BasicWithLf) { 260 char* buf = NULL; 261 size_t size = 0; 262 FILE* out = open_memstream(&buf, &size); 263 ASSERT_NE(NULL, out); 264 265 print_gopher_text_len(out, "hello\nworld", -1, true); 266 fclose(out); 267 268 EXPECT_STREQ("hello\nworld", buf); 269 270 free(buf); 271 } 272 273 UTEST(print_gopher_text_len, BasicNoLf) { 274 char* buf = NULL; 275 size_t size = 0; 276 FILE* out = open_memstream(&buf, &size); 277 ASSERT_NE(NULL, out); 278 279 print_gopher_text_len(out, "hello\nworld\r", -1, false); 280 fclose(out); 281 282 EXPECT_STREQ("helloworld", buf); 283 284 free(buf); 285 } 286 287 UTEST(print_gopher_text_len, EscapesWithLf) { 288 char* buf = NULL; 289 size_t size = 0; 290 FILE* out = open_memstream(&buf, &size); 291 ASSERT_NE(NULL, out); 292 293 print_gopher_text_len(out, "[hello]\n[world]", -1, true); 294 fclose(out); 295 296 EXPECT_STREQ("[|hello]\n[|world]", buf); 297 298 free(buf); 299 } 300 301 UTEST(print_gopher_text_len, DoesNotEscapeIfBracketNotImmediatelyAfterLf) { 302 char* buf = NULL; 303 size_t size = 0; 304 FILE* out = open_memstream(&buf, &size); 305 ASSERT_NE(NULL, out); 306 307 print_gopher_text_len(out, "[hello]\n\t[world]", -1, true); 308 fclose(out); 309 310 EXPECT_STREQ("[|hello]\n [world]", buf); 311 312 free(buf); 313 } 314 315 UTEST(print_gopher_text_len, NoEscapesWithoutLf) { 316 char* buf = NULL; 317 size_t size = 0; 318 FILE* out = open_memstream(&buf, &size); 319 ASSERT_NE(NULL, out); 320 321 print_gopher_text_len(out, "[hello]\n\t[world]", -1, false); 322 fclose(out); 323 324 EXPECT_STREQ("[hello] [world]", buf); 325 326 free(buf); 327 } 328 329 UTEST(print_gopher_text_len, PartialLen) { 330 char* buf = NULL; 331 size_t size = 0; 332 FILE* out = open_memstream(&buf, &size); 333 ASSERT_NE(NULL, out); 334 335 print_gopher_text_len(out, "[hello]\n\t[world]", 8, true); 336 fclose(out); 337 338 EXPECT_STREQ("[|hello]\n", buf); 339 340 free(buf); 341 } 342 343 UTEST(print_gopher_text_len, EmptyString) { 344 char* buf = NULL; 345 size_t size = 0; 346 FILE* out = open_memstream(&buf, &size); 347 ASSERT_NE(NULL, out); 348 349 print_gopher_text_len(out, "", -1, true); 350 fclose(out); 351 352 EXPECT_STREQ("", buf); 353 354 free(buf); 355 } 356 357 UTEST(print_gopher_link, SpecialChars) { 358 char* buf = NULL; 359 size_t size = 0; 360 FILE* out = open_memstream(&buf, &size); 361 ASSERT_NE(NULL, out); 362 363 print_gopher_link(out, "|\t\r\n"); 364 fclose(out); 365 366 EXPECT_STREQ("\\| ", buf); 367 368 free(buf); 369 } 370 371 UTEST(print_gopher_link, MixedContent) { 372 char* buf = NULL; 373 size_t size = 0; 374 FILE* out = open_memstream(&buf, &size); 375 ASSERT_NE(NULL, out); 376 377 print_gopher_link(out, "hello|world\t"); 378 fclose(out); 379 380 EXPECT_STREQ("hello\\|world ", buf); 381 382 free(buf); 383 } 384 385 UTEST(print_gopher_link, EmptyString) { 386 char* buf = NULL; 387 size_t size = 0; 388 FILE* out = open_memstream(&buf, &size); 389 ASSERT_NE(NULL, out); 390 391 print_gopher_link(out, ""); 392 fclose(out); 393 394 EXPECT_STREQ("", buf); 395 396 free(buf); 397 } 398 399 UTEST(print_gopher_link_padded, BasicPadding) { 400 char* buf = NULL; 401 size_t size = 0; 402 FILE* out = open_memstream(&buf, &size); 403 ASSERT_NE(NULL, out); 404 405 print_gopher_link_padded(out, "hello", 10, ' '); 406 fclose(out); 407 408 EXPECT_STREQ("hello ", buf); 409 410 free(buf); 411 } 412 413 UTEST(print_gopher_link_padded, NoPadding) { 414 char* buf = NULL; 415 size_t size = 0; 416 FILE* out = open_memstream(&buf, &size); 417 ASSERT_NE(NULL, out); 418 419 print_gopher_link_padded(out, "hello", 5, ' '); 420 fclose(out); 421 422 EXPECT_STREQ("hello", buf); 423 424 free(buf); 425 } 426 427 UTEST(print_gopher_link_padded, Truncation) { 428 char* buf = NULL; 429 size_t size = 0; 430 FILE* out = open_memstream(&buf, &size); 431 ASSERT_NE(NULL, out); 432 433 print_gopher_link_padded(out, "hello world", 10, ' '); 434 fclose(out); 435 436 EXPECT_STREQ("hello wor…", buf); 437 438 free(buf); 439 } 440 441 UTEST(print_gopher_link_padded, SpecialChars) { 442 char* buf = NULL; 443 size_t size = 0; 444 FILE* out = open_memstream(&buf, &size); 445 ASSERT_NE(NULL, out); 446 447 print_gopher_link_padded(out, "a|\t\r\nb", 20, '.'); 448 fclose(out); 449 450 EXPECT_STREQ("a\\| b.........", buf); 451 452 free(buf); 453 } 454 455 UTEST(print_gopher_link_padded, MultiByte) { 456 char* buf = NULL; 457 size_t size = 0; 458 FILE* out = open_memstream(&buf, &size); 459 ASSERT_NE(NULL, out); 460 461 print_gopher_link_padded(out, "こんにちは", 10, ' '); 462 fclose(out); 463 464 EXPECT_STREQ("こんにちは ", buf); 465 466 free(buf); 467 } 468 469 UTEST(print_gopher_link_padded, ZeroWidth) { 470 char* buf = NULL; 471 size_t size = 0; 472 FILE* out = open_memstream(&buf, &size); 473 ASSERT_NE(NULL, out); 474 475 print_gopher_link_padded(out, "hello", 0, ' '); 476 fclose(out); 477 478 EXPECT_STREQ("", buf); 479 480 free(buf); 481 } 482 483 UTEST(print_gopher_link_padded, NoPadChar) { 484 char* buf = NULL; 485 size_t size = 0; 486 FILE* out = open_memstream(&buf, &size); 487 ASSERT_NE(NULL, out); 488 489 print_gopher_link_padded(out, "hello", 10, '\0'); 490 fclose(out); 491 492 EXPECT_STREQ("hello", buf); 493 494 free(buf); 495 } 496 497 UTEST(print_gopher_link_padded, ComplexEmoji) { 498 char* buf = NULL; 499 size_t size = 0; 500 FILE* out = open_memstream(&buf, &size); 501 ASSERT_NE(NULL, out); 502 503 /* UTF-8 encoding of Unicode extended grapheme cluster for woman health worker 504 with medium-dark skin tone. This emoji is a Unicode emoji ZWJ sequence 505 composed of 5 code points. */ 506 const char* emoji = // 👩🏾⚕️ 507 "\xF0\x9F\x91\xA9" // U+1F469: Woman 👩 508 "\xF0\x9F\x8F\xBE" // U+1F3FE: Emoji modifier Fitzpatrick type 5 🏾 509 "\xE2\x80\x8D" // U+200D: Zero-width joiner 510 "\xE2\x9A\x95" // U+2695: Staff of Aesculapius ⚕ 511 "\xEF\xB8\x8F"; // U+FE0F: Variation selector 16 (colour emoji) 512 print_gopher_link_padded(out, emoji, 10, ' '); 513 fclose(out); 514 515 /* Expect 1 emoji, 9 spaces. */ 516 EXPECT_STREQ("👩🏾⚕️ ", buf); 517 518 free(buf); 519 }