diff options
Diffstat (limited to 'absl/strings/charset_test.cc')
-rw-r--r-- | absl/strings/charset_test.cc | 181 |
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 |