xref: /aosp_15_r20/external/abseil-cpp/absl/strings/charset_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1 // Copyright 2020 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/strings/charset.h"
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 #include <string>
21 #include <vector>
22 
23 #include "gtest/gtest.h"
24 #include "absl/strings/ascii.h"
25 #include "absl/strings/string_view.h"
26 
27 namespace {
28 
29 constexpr absl::CharSet everything_map = ~absl::CharSet();
30 constexpr absl::CharSet nothing_map = absl::CharSet();
31 
TEST(Charmap,AllTests)32 TEST(Charmap, AllTests) {
33   const absl::CharSet also_nothing_map("");
34   EXPECT_TRUE(everything_map.contains('\0'));
35   EXPECT_FALSE(nothing_map.contains('\0'));
36   EXPECT_FALSE(also_nothing_map.contains('\0'));
37   for (unsigned char ch = 1; ch != 0; ++ch) {
38     SCOPED_TRACE(ch);
39     EXPECT_TRUE(everything_map.contains(ch));
40     EXPECT_FALSE(nothing_map.contains(ch));
41     EXPECT_FALSE(also_nothing_map.contains(ch));
42   }
43 
44   const absl::CharSet symbols(absl::string_view("&@#@^!@?", 5));
45   EXPECT_TRUE(symbols.contains('&'));
46   EXPECT_TRUE(symbols.contains('@'));
47   EXPECT_TRUE(symbols.contains('#'));
48   EXPECT_TRUE(symbols.contains('^'));
49   EXPECT_FALSE(symbols.contains('!'));
50   EXPECT_FALSE(symbols.contains('?'));
51   int cnt = 0;
52   for (unsigned char ch = 1; ch != 0; ++ch) cnt += symbols.contains(ch);
53   EXPECT_EQ(cnt, 4);
54 
55   const absl::CharSet lets(absl::string_view("^abcde", 3));
56   const absl::CharSet lets2(absl::string_view("fghij\0klmnop", 10));
57   const absl::CharSet lets3("fghij\0klmnop");
58   EXPECT_TRUE(lets2.contains('k'));
59   EXPECT_FALSE(lets3.contains('k'));
60 
61   EXPECT_FALSE((symbols & lets).empty());
62   EXPECT_TRUE((lets2 & lets).empty());
63   EXPECT_FALSE((lets & symbols).empty());
64   EXPECT_TRUE((lets & lets2).empty());
65 
66   EXPECT_TRUE(nothing_map.empty());
67   EXPECT_FALSE(lets.empty());
68 }
69 
Members(const absl::CharSet & m)70 std::string Members(const absl::CharSet& m) {
71   std::string r;
72   for (size_t i = 0; i < 256; ++i)
73     if (m.contains(i)) r.push_back(i);
74   return r;
75 }
76 
ClosedRangeString(unsigned char lo,unsigned char hi)77 std::string ClosedRangeString(unsigned char lo, unsigned char hi) {
78   // Don't depend on lo<hi. Just increment until lo==hi.
79   std::string s;
80   while (true) {
81     s.push_back(lo);
82     if (lo == hi) break;
83     ++lo;
84   }
85   return s;
86 }
87 
TEST(Charmap,Constexpr)88 TEST(Charmap, Constexpr) {
89   constexpr absl::CharSet kEmpty = absl::CharSet();
90   EXPECT_EQ(Members(kEmpty), "");
91   constexpr absl::CharSet kA = absl::CharSet::Char('A');
92   EXPECT_EQ(Members(kA), "A");
93   constexpr absl::CharSet kAZ = absl::CharSet::Range('A', 'Z');
94   EXPECT_EQ(Members(kAZ), "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
95   constexpr absl::CharSet kIdentifier =
96       absl::CharSet::Range('0', '9') | absl::CharSet::Range('A', 'Z') |
97       absl::CharSet::Range('a', 'z') | absl::CharSet::Char('_');
98   EXPECT_EQ(Members(kIdentifier),
99             "0123456789"
100             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
101             "_"
102             "abcdefghijklmnopqrstuvwxyz");
103   constexpr absl::CharSet kAll = ~absl::CharSet();
104   for (size_t i = 0; i < 256; ++i) {
105     SCOPED_TRACE(i);
106     EXPECT_TRUE(kAll.contains(i));
107   }
108   constexpr absl::CharSet kHello = absl::CharSet("Hello, world!");
109   EXPECT_EQ(Members(kHello), " !,Hdelorw");
110 
111   // test negation and intersection
112   constexpr absl::CharSet kABC =
113       absl::CharSet::Range('A', 'Z') & ~absl::CharSet::Range('D', 'Z');
114   EXPECT_EQ(Members(kABC), "ABC");
115 
116   // contains
117   constexpr bool kContainsA = absl::CharSet("abc").contains('a');
118   EXPECT_TRUE(kContainsA);
119   constexpr bool kContainsD = absl::CharSet("abc").contains('d');
120   EXPECT_FALSE(kContainsD);
121 
122   // empty
123   constexpr bool kEmptyIsEmpty = absl::CharSet().empty();
124   EXPECT_TRUE(kEmptyIsEmpty);
125   constexpr bool kNotEmptyIsEmpty = absl::CharSet("abc").empty();
126   EXPECT_FALSE(kNotEmptyIsEmpty);
127 }
128 
TEST(Charmap,Range)129 TEST(Charmap, Range) {
130   // Exhaustive testing takes too long, so test some of the boundaries that
131   // are perhaps going to cause trouble.
132   std::vector<size_t> poi = {0,   1,   2,   3,   4,   7,   8,   9,  15,
133                              16,  17,  30,  31,  32,  33,  63,  64, 65,
134                              127, 128, 129, 223, 224, 225, 254, 255};
135   for (auto lo = poi.begin(); lo != poi.end(); ++lo) {
136     SCOPED_TRACE(*lo);
137     for (auto hi = lo; hi != poi.end(); ++hi) {
138       SCOPED_TRACE(*hi);
139       EXPECT_EQ(Members(absl::CharSet::Range(*lo, *hi)),
140                 ClosedRangeString(*lo, *hi));
141     }
142   }
143 }
144 
TEST(Charmap,NullByteWithStringView)145 TEST(Charmap, NullByteWithStringView) {
146   char characters[5] = {'a', 'b', '\0', 'd', 'x'};
147   absl::string_view view(characters, 5);
148   absl::CharSet tester(view);
149   EXPECT_TRUE(tester.contains('a'));
150   EXPECT_TRUE(tester.contains('b'));
151   EXPECT_TRUE(tester.contains('\0'));
152   EXPECT_TRUE(tester.contains('d'));
153   EXPECT_TRUE(tester.contains('x'));
154   EXPECT_FALSE(tester.contains('c'));
155 }
156 
TEST(CharmapCtype,Match)157 TEST(CharmapCtype, Match) {
158   for (int c = 0; c < 256; ++c) {
159     SCOPED_TRACE(c);
160     SCOPED_TRACE(static_cast<char>(c));
161     EXPECT_EQ(absl::ascii_isupper(c),
162               absl::CharSet::AsciiUppercase().contains(c));
163     EXPECT_EQ(absl::ascii_islower(c),
164               absl::CharSet::AsciiLowercase().contains(c));
165     EXPECT_EQ(absl::ascii_isdigit(c), absl::CharSet::AsciiDigits().contains(c));
166     EXPECT_EQ(absl::ascii_isalpha(c),
167               absl::CharSet::AsciiAlphabet().contains(c));
168     EXPECT_EQ(absl::ascii_isalnum(c),
169               absl::CharSet::AsciiAlphanumerics().contains(c));
170     EXPECT_EQ(absl::ascii_isxdigit(c),
171               absl::CharSet::AsciiHexDigits().contains(c));
172     EXPECT_EQ(absl::ascii_isprint(c),
173               absl::CharSet::AsciiPrintable().contains(c));
174     EXPECT_EQ(absl::ascii_isspace(c),
175               absl::CharSet::AsciiWhitespace().contains(c));
176     EXPECT_EQ(absl::ascii_ispunct(c),
177               absl::CharSet::AsciiPunctuation().contains(c));
178   }
179 }
180 
181 }  // namespace
182