Serenity Operating System
1/*
2 * Copyright (c) 2021, Max Wipfli <mail@maxwipfli.ch>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <AK/CharacterTypes.h>
10#include <ctype.h>
11
12#define ASCII 0x80
13#define UNICODE 0x10FFFF + 100
14
15void compare_bool_output_over(u32 range, auto& old_function, auto& new_function)
16{
17 bool result1 = false;
18 bool result2 = false;
19 for (u32 i = 0; i < range; ++i) {
20 EXPECT_EQ(result1 = (old_function(i) > 0), result2 = (new_function(i) > 0));
21 if (result1 != result2)
22 dbgln("Function input value was {}.", i);
23 }
24}
25
26void compare_value_output_over(u32 range, auto& old_function, auto& new_function)
27{
28 i64 result1 = 0;
29 i64 result2 = 0;
30 for (u32 i = 0; i < range; ++i) {
31 EXPECT_EQ(result1 = old_function(i), result2 = new_function(i));
32 if (result1 != result2)
33 dbgln("Function input value was {}.", i);
34 }
35}
36
37// NOTE: Avoid comparing over UNICODE in "TEST_CASE" due to test runtime becoming too long.
38
39TEST_CASE(is_ascii_alphanumeric)
40{
41 compare_bool_output_over(ASCII, isalnum, is_ascii_alphanumeric);
42}
43
44TEST_CASE(is_ascii_blank)
45{
46 compare_bool_output_over(ASCII, isblank, is_ascii_blank);
47}
48
49TEST_CASE(is_ascii_c0_control)
50{
51 compare_bool_output_over(ASCII - 1, iscntrl, is_ascii_c0_control);
52}
53
54TEST_CASE(is_ascii_control)
55{
56 compare_bool_output_over(ASCII, iscntrl, is_ascii_control);
57}
58
59TEST_CASE(is_ascii_digit)
60{
61 compare_bool_output_over(ASCII, isdigit, is_ascii_digit);
62}
63
64TEST_CASE(is_ascii_graphical)
65{
66 compare_bool_output_over(ASCII, isgraph, is_ascii_graphical);
67}
68
69TEST_CASE(is_ascii_hex_digit)
70{
71 compare_bool_output_over(ASCII, isxdigit, is_ascii_hex_digit);
72}
73
74TEST_CASE(is_ascii_lower_alpha)
75{
76 compare_bool_output_over(ASCII, islower, is_ascii_lower_alpha);
77}
78
79TEST_CASE(is_ascii_printable)
80{
81 compare_bool_output_over(ASCII, isprint, is_ascii_printable);
82}
83
84TEST_CASE(is_ascii_punctuation)
85{
86 compare_bool_output_over(ASCII, ispunct, is_ascii_punctuation);
87}
88
89TEST_CASE(is_ascii_space)
90{
91 compare_bool_output_over(ASCII, isspace, is_ascii_space);
92}
93
94TEST_CASE(is_ascii_upper_alpha)
95{
96 compare_bool_output_over(ASCII, isupper, is_ascii_upper_alpha);
97}
98
99TEST_CASE(to_ascii_lowercase)
100{
101 compare_value_output_over(ASCII, tolower, to_ascii_lowercase);
102}
103
104TEST_CASE(to_ascii_uppercase)
105{
106 compare_value_output_over(ASCII, toupper, to_ascii_uppercase);
107}
108
109TEST_CASE(parse_ascii_digit)
110{
111 EXPECT_EQ(parse_ascii_digit('0'), 0u);
112 EXPECT_EQ(parse_ascii_digit('9'), 9u);
113 EXPECT_CRASH("parsing invalid ASCII digit", [] {
114 parse_ascii_digit('a');
115 return Test::Crash::Failure::DidNotCrash;
116 });
117 EXPECT_CRASH("parsing invalid unicode digit", [] {
118 parse_ascii_digit(0x00A9);
119 return Test::Crash::Failure::DidNotCrash;
120 });
121}
122
123TEST_CASE(parse_ascii_hex_digit)
124{
125 EXPECT_EQ(parse_ascii_hex_digit('0'), 0u);
126 EXPECT_EQ(parse_ascii_hex_digit('F'), 15u);
127 EXPECT_EQ(parse_ascii_hex_digit('f'), 15u);
128 EXPECT_CRASH("parsing invalid ASCII hex digit", [] {
129 parse_ascii_hex_digit('g');
130 return Test::Crash::Failure::DidNotCrash;
131 });
132}
133
134BENCHMARK_CASE(is_ascii)
135{
136 compare_bool_output_over(UNICODE, isascii, is_ascii);
137}
138
139BENCHMARK_CASE(to_ascii_lowercase_unicode)
140{
141 compare_value_output_over(UNICODE, tolower, to_ascii_lowercase);
142}
143
144BENCHMARK_CASE(to_ascii_uppercase_unicode)
145{
146 compare_value_output_over(UNICODE, toupper, to_ascii_uppercase);
147}