summaryrefslogtreecommitdiff
path: root/absl/strings/charset_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/charset_test.cc')
-rw-r--r--absl/strings/charset_test.cc181
1 files changed, 181 insertions, 0 deletions
diff --git a/absl/strings/charset_test.cc b/absl/strings/charset_test.cc
new file mode 100644
index 00000000..fff943ae
--- /dev/null
+++ b/absl/strings/charset_test.cc
@@ -0,0 +1,181 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/charset.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string>
+#include <vector>
+
+#include "gtest/gtest.h"
+#include "absl/strings/ascii.h"
+#include "absl/strings/string_view.h"
+
+namespace {
+
+constexpr absl::CharSet everything_map = ~absl::CharSet();
+constexpr absl::CharSet nothing_map = absl::CharSet();
+
+TEST(Charmap, AllTests) {
+ const absl::CharSet also_nothing_map("");
+ EXPECT_TRUE(everything_map.contains('\0'));
+ EXPECT_FALSE(nothing_map.contains('\0'));
+ EXPECT_FALSE(also_nothing_map.contains('\0'));
+ for (unsigned char ch = 1; ch != 0; ++ch) {
+ SCOPED_TRACE(ch);
+ EXPECT_TRUE(everything_map.contains(ch));
+ EXPECT_FALSE(nothing_map.contains(ch));
+ EXPECT_FALSE(also_nothing_map.contains(ch));
+ }
+
+ const absl::CharSet symbols(absl::string_view("&@#@^!@?", 5));
+ EXPECT_TRUE(symbols.contains('&'));
+ EXPECT_TRUE(symbols.contains('@'));
+ EXPECT_TRUE(symbols.contains('#'));
+ EXPECT_TRUE(symbols.contains('^'));
+ EXPECT_FALSE(symbols.contains('!'));
+ EXPECT_FALSE(symbols.contains('?'));
+ int cnt = 0;
+ for (unsigned char ch = 1; ch != 0; ++ch) cnt += symbols.contains(ch);
+ EXPECT_EQ(cnt, 4);
+
+ const absl::CharSet lets(absl::string_view("^abcde", 3));
+ const absl::CharSet lets2(absl::string_view("fghij\0klmnop", 10));
+ const absl::CharSet lets3("fghij\0klmnop");
+ EXPECT_TRUE(lets2.contains('k'));
+ EXPECT_FALSE(lets3.contains('k'));
+
+ EXPECT_FALSE((symbols & lets).empty());
+ EXPECT_TRUE((lets2 & lets).empty());
+ EXPECT_FALSE((lets & symbols).empty());
+ EXPECT_TRUE((lets & lets2).empty());
+
+ EXPECT_TRUE(nothing_map.empty());
+ EXPECT_FALSE(lets.empty());
+}
+
+std::string Members(const absl::CharSet& m) {
+ std::string r;
+ for (size_t i = 0; i < 256; ++i)
+ if (m.contains(i)) r.push_back(i);
+ return r;
+}
+
+std::string ClosedRangeString(unsigned char lo, unsigned char hi) {
+ // Don't depend on lo<hi. Just increment until lo==hi.
+ std::string s;
+ while (true) {
+ s.push_back(lo);
+ if (lo == hi) break;
+ ++lo;
+ }
+ return s;
+}
+
+TEST(Charmap, Constexpr) {
+ constexpr absl::CharSet kEmpty = absl::CharSet();
+ EXPECT_EQ(Members(kEmpty), "");
+ constexpr absl::CharSet kA = absl::CharSet::Char('A');
+ EXPECT_EQ(Members(kA), "A");
+ constexpr absl::CharSet kAZ = absl::CharSet::Range('A', 'Z');
+ EXPECT_EQ(Members(kAZ), "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ constexpr absl::CharSet kIdentifier =
+ absl::CharSet::Range('0', '9') | absl::CharSet::Range('A', 'Z') |
+ absl::CharSet::Range('a', 'z') | absl::CharSet::Char('_');
+ EXPECT_EQ(Members(kIdentifier),
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ "abcdefghijklmnopqrstuvwxyz");
+ constexpr absl::CharSet kAll = ~absl::CharSet();
+ for (size_t i = 0; i < 256; ++i) {
+ SCOPED_TRACE(i);
+ EXPECT_TRUE(kAll.contains(i));
+ }
+ constexpr absl::CharSet kHello = absl::CharSet("Hello, world!");
+ EXPECT_EQ(Members(kHello), " !,Hdelorw");
+
+ // test negation and intersection
+ constexpr absl::CharSet kABC =
+ absl::CharSet::Range('A', 'Z') & ~absl::CharSet::Range('D', 'Z');
+ EXPECT_EQ(Members(kABC), "ABC");
+
+ // contains
+ constexpr bool kContainsA = absl::CharSet("abc").contains('a');
+ EXPECT_TRUE(kContainsA);
+ constexpr bool kContainsD = absl::CharSet("abc").contains('d');
+ EXPECT_FALSE(kContainsD);
+
+ // empty
+ constexpr bool kEmptyIsEmpty = absl::CharSet().empty();
+ EXPECT_TRUE(kEmptyIsEmpty);
+ constexpr bool kNotEmptyIsEmpty = absl::CharSet("abc").empty();
+ EXPECT_FALSE(kNotEmptyIsEmpty);
+}
+
+TEST(Charmap, Range) {
+ // Exhaustive testing takes too long, so test some of the boundaries that
+ // are perhaps going to cause trouble.
+ std::vector<size_t> poi = {0, 1, 2, 3, 4, 7, 8, 9, 15,
+ 16, 17, 30, 31, 32, 33, 63, 64, 65,
+ 127, 128, 129, 223, 224, 225, 254, 255};
+ for (auto lo = poi.begin(); lo != poi.end(); ++lo) {
+ SCOPED_TRACE(*lo);
+ for (auto hi = lo; hi != poi.end(); ++hi) {
+ SCOPED_TRACE(*hi);
+ EXPECT_EQ(Members(absl::CharSet::Range(*lo, *hi)),
+ ClosedRangeString(*lo, *hi));
+ }
+ }
+}
+
+TEST(Charmap, NullByteWithStringView) {
+ char characters[5] = {'a', 'b', '\0', 'd', 'x'};
+ absl::string_view view(characters, 5);
+ absl::CharSet tester(view);
+ EXPECT_TRUE(tester.contains('a'));
+ EXPECT_TRUE(tester.contains('b'));
+ EXPECT_TRUE(tester.contains('\0'));
+ EXPECT_TRUE(tester.contains('d'));
+ EXPECT_TRUE(tester.contains('x'));
+ EXPECT_FALSE(tester.contains('c'));
+}
+
+TEST(CharmapCtype, Match) {
+ for (int c = 0; c < 256; ++c) {
+ SCOPED_TRACE(c);
+ SCOPED_TRACE(static_cast<char>(c));
+ EXPECT_EQ(absl::ascii_isupper(c),
+ absl::CharSet::AsciiUppercase().contains(c));
+ EXPECT_EQ(absl::ascii_islower(c),
+ absl::CharSet::AsciiLowercase().contains(c));
+ EXPECT_EQ(absl::ascii_isdigit(c), absl::CharSet::AsciiDigits().contains(c));
+ EXPECT_EQ(absl::ascii_isalpha(c),
+ absl::CharSet::AsciiAlphabet().contains(c));
+ EXPECT_EQ(absl::ascii_isalnum(c),
+ absl::CharSet::AsciiAlphanumerics().contains(c));
+ EXPECT_EQ(absl::ascii_isxdigit(c),
+ absl::CharSet::AsciiHexDigits().contains(c));
+ EXPECT_EQ(absl::ascii_isprint(c),
+ absl::CharSet::AsciiPrintable().contains(c));
+ EXPECT_EQ(absl::ascii_isspace(c),
+ absl::CharSet::AsciiWhitespace().contains(c));
+ EXPECT_EQ(absl::ascii_ispunct(c),
+ absl::CharSet::AsciiPunctuation().contains(c));
+ }
+}
+
+} // namespace