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
11template <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
89template <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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libc/test/src/string/StrchrTest.h