1 | //===-- Tests for str{,r}chr and {,r}index functions ------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "test/UnitTest/Test.h" |
10 | |
11 | template <auto Func> struct StrchrTest : public LIBC_NAMESPACE::testing::Test { |
12 | void findsFirstCharacter() { |
13 | const char *src = "abcde"; |
14 | |
15 | // Should return original string since 'a' is the first character. |
16 | ASSERT_STREQ(Func(src, 'a'), "abcde"); |
17 | // Source string should not change. |
18 | ASSERT_STREQ(src, "abcde"); |
19 | } |
20 | |
21 | void findsMiddleCharacter() { |
22 | const char *src = "abcde"; |
23 | |
24 | // Should return characters after (and including) 'c'. |
25 | ASSERT_STREQ(Func(src, 'c'), "cde"); |
26 | // Source string should not change. |
27 | ASSERT_STREQ(src, "abcde"); |
28 | } |
29 | |
30 | void findsLastCharacterThatIsNotNullTerminator() { |
31 | const char *src = "abcde"; |
32 | |
33 | // Should return 'e' and null-terminator. |
34 | ASSERT_STREQ(Func(src, 'e'), "e"); |
35 | // Source string should not change. |
36 | ASSERT_STREQ(src, "abcde"); |
37 | } |
38 | |
39 | void findsNullTerminator() { |
40 | const char *src = "abcde"; |
41 | |
42 | // Should return null terminator. |
43 | const char *nul_terminator = Func(src, '\0'); |
44 | ASSERT_NE(nul_terminator, nullptr); |
45 | ASSERT_STREQ(nul_terminator, ""); |
46 | // Source string should not change. |
47 | ASSERT_STREQ(src, "abcde"); |
48 | } |
49 | |
50 | void characterNotWithinStringShouldReturnNullptr() { |
51 | // Since 'z' is not within the string, should return nullptr. |
52 | ASSERT_EQ(Func("123?", 'z'), nullptr); |
53 | } |
54 | |
55 | void theSourceShouldNotChange() { |
56 | const char *src = "abcde"; |
57 | // When the character is found, the source string should not change. |
58 | Func(src, 'd'); |
59 | ASSERT_STREQ(src, "abcde"); |
60 | // Same case for when the character is not found. |
61 | Func(src, 'z'); |
62 | ASSERT_STREQ(src, "abcde"); |
63 | // Same case for when looking for nullptr. |
64 | Func(src, '\0'); |
65 | ASSERT_STREQ(src, "abcde"); |
66 | } |
67 | |
68 | void shouldFindFirstOfDuplicates() { |
69 | // '1' is duplicated in the string, but it should find the first copy. |
70 | ASSERT_STREQ(Func("abc1def1ghi", '1'), "1def1ghi"); |
71 | |
72 | const char *dups = "XXXXX"; |
73 | // Should return original string since 'X' is the first character. |
74 | ASSERT_STREQ(Func(dups, 'X'), dups); |
75 | } |
76 | |
77 | void emptyStringShouldOnlyMatchNullTerminator() { |
78 | // Null terminator should match. |
79 | const char empty_string[] = ""; |
80 | ASSERT_EQ(static_cast<const char *>(Func(empty_string, '\0')), |
81 | empty_string); |
82 | // All other characters should not match. |
83 | ASSERT_EQ(Func("", 'Z'), nullptr); |
84 | ASSERT_EQ(Func("", '3'), nullptr); |
85 | ASSERT_EQ(Func("", '*'), nullptr); |
86 | } |
87 | }; |
88 | |
89 | template <auto Func> struct StrrchrTest : public LIBC_NAMESPACE::testing::Test { |
90 | void findsFirstCharacter() { |
91 | const char *src = "abcde"; |
92 | |
93 | // Should return original string since 'a' is the first character. |
94 | ASSERT_STREQ(Func(src, 'a'), "abcde"); |
95 | // Source string should not change. |
96 | ASSERT_STREQ(src, "abcde"); |
97 | } |
98 | |
99 | void findsMiddleCharacter() { |
100 | const char *src = "abcde"; |
101 | |
102 | // Should return characters after (and including) 'c'. |
103 | ASSERT_STREQ(Func(src, 'c'), "cde"); |
104 | // Source string should not change. |
105 | ASSERT_STREQ(src, "abcde"); |
106 | } |
107 | |
108 | void findsLastCharacterThatIsNotNullTerminator() { |
109 | const char *src = "abcde"; |
110 | |
111 | // Should return 'e' and null-terminator. |
112 | ASSERT_STREQ(Func(src, 'e'), "e"); |
113 | // Source string should not change. |
114 | ASSERT_STREQ(src, "abcde"); |
115 | } |
116 | |
117 | void findsNullTerminator() { |
118 | const char *src = "abcde"; |
119 | |
120 | // Should return null terminator. |
121 | const char *nul_terminator = Func(src, '\0'); |
122 | ASSERT_NE(nul_terminator, nullptr); |
123 | ASSERT_STREQ(nul_terminator, ""); |
124 | // Source string should not change. |
125 | ASSERT_STREQ(src, "abcde"); |
126 | } |
127 | |
128 | void findsLastBehindFirstNullTerminator() { |
129 | static const char src[6] = {'a', 'a', '\0', 'b', '\0', 'c'}; |
130 | // 'b' is behind a null terminator, so should not be found. |
131 | ASSERT_EQ(Func(src, 'b'), nullptr); |
132 | // Same goes for 'c'. |
133 | ASSERT_EQ(Func(src, 'c'), nullptr); |
134 | |
135 | // Should find the second of the two a's. |
136 | ASSERT_STREQ(Func(src, 'a'), "a"); |
137 | } |
138 | |
139 | void characterNotWithinStringShouldReturnNullptr() { |
140 | // Since 'z' is not within the string, should return nullptr. |
141 | ASSERT_EQ(Func("123?", 'z'), nullptr); |
142 | } |
143 | |
144 | void shouldFindLastOfDuplicates() { |
145 | // '1' is duplicated in the string, but it should find the last copy. |
146 | ASSERT_STREQ(Func("abc1def1ghi", '1'), "1ghi"); |
147 | |
148 | const char *dups = "XXXXX"; |
149 | // Should return the last occurrence of 'X'. |
150 | ASSERT_STREQ(Func(dups, 'X'), "X"); |
151 | } |
152 | |
153 | void emptyStringShouldOnlyMatchNullTerminator() { |
154 | // Null terminator should match. |
155 | const char empty_string[] = ""; |
156 | ASSERT_EQ(static_cast<const char *>(Func(empty_string, '\0')), |
157 | empty_string); |
158 | // All other characters should not match. |
159 | ASSERT_EQ(Func("", 'A'), nullptr); |
160 | ASSERT_EQ(Func("", '2'), nullptr); |
161 | ASSERT_EQ(Func("", '*'), nullptr); |
162 | } |
163 | }; |
164 | |
165 | #define STRCHR_TEST(name, func) \ |
166 | using LlvmLibc##name##Test = StrchrTest<func>; \ |
167 | TEST_F(LlvmLibc##name##Test, FindsFirstCharacter) { findsFirstCharacter(); } \ |
168 | TEST_F(LlvmLibc##name##Test, FindsMiddleCharacter) { \ |
169 | findsMiddleCharacter(); \ |
170 | } \ |
171 | TEST_F(LlvmLibc##name##Test, FindsLastCharacterThatIsNotNullTerminator) { \ |
172 | findsLastCharacterThatIsNotNullTerminator(); \ |
173 | } \ |
174 | TEST_F(LlvmLibc##name##Test, FindsNullTerminator) { findsNullTerminator(); } \ |
175 | TEST_F(LlvmLibc##name##Test, CharacterNotWithinStringShouldReturnNullptr) { \ |
176 | characterNotWithinStringShouldReturnNullptr(); \ |
177 | } \ |
178 | TEST_F(LlvmLibc##name##Test, TheSourceShouldNotChange) { \ |
179 | theSourceShouldNotChange(); \ |
180 | } \ |
181 | TEST_F(LlvmLibc##name##Test, ShouldFindFirstOfDuplicates) { \ |
182 | shouldFindFirstOfDuplicates(); \ |
183 | } \ |
184 | TEST_F(LlvmLibc##name##Test, EmptyStringShouldOnlyMatchNullTerminator) { \ |
185 | emptyStringShouldOnlyMatchNullTerminator(); \ |
186 | } |
187 | |
188 | #define STRRCHR_TEST(name, func) \ |
189 | using LlvmLibc##name##Test = StrrchrTest<func>; \ |
190 | TEST_F(LlvmLibc##name##Test, FindsFirstCharacter) { findsFirstCharacter(); } \ |
191 | TEST_F(LlvmLibc##name##Test, FindsMiddleCharacter) { \ |
192 | findsMiddleCharacter(); \ |
193 | } \ |
194 | TEST_F(LlvmLibc##name##Test, FindsLastCharacterThatIsNotNullTerminator) { \ |
195 | findsLastCharacterThatIsNotNullTerminator(); \ |
196 | } \ |
197 | TEST_F(LlvmLibc##name##Test, FindsNullTerminator) { findsNullTerminator(); } \ |
198 | TEST_F(LlvmLibc##name##Test, FindsLastBehindFirstNullTerminator) { \ |
199 | findsLastBehindFirstNullTerminator(); \ |
200 | } \ |
201 | TEST_F(LlvmLibc##name##Test, CharacterNotWithinStringShouldReturnNullptr) { \ |
202 | characterNotWithinStringShouldReturnNullptr(); \ |
203 | } \ |
204 | TEST_F(LlvmLibc##name##Test, ShouldFindLastOfDuplicates) { \ |
205 | shouldFindLastOfDuplicates(); \ |
206 | } \ |
207 | TEST_F(LlvmLibc##name##Test, EmptyStringShouldOnlyMatchNullTerminator) { \ |
208 | emptyStringShouldOnlyMatchNullTerminator(); \ |
209 | } |
210 |
Definitions
- StrchrTest
- findsFirstCharacter
- findsMiddleCharacter
- findsLastCharacterThatIsNotNullTerminator
- findsNullTerminator
- characterNotWithinStringShouldReturnNullptr
- theSourceShouldNotChange
- shouldFindFirstOfDuplicates
- emptyStringShouldOnlyMatchNullTerminator
- StrrchrTest
- findsFirstCharacter
- findsMiddleCharacter
- findsLastCharacterThatIsNotNullTerminator
- findsNullTerminator
- findsLastBehindFirstNullTerminator
- characterNotWithinStringShouldReturnNullptr
- shouldFindLastOfDuplicates
Improve your Profiling and Debugging skills
Find out more