cheatah
Source

stdlib/tests/string_test.cpp

1// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
2// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
3#include "string.hpp"
5#include <string>
6#include <vector>
8#include <gtest/gtest.h>
10namespace str = cheatah::string;
12TEST(CheatahString, Case) {
13 EXPECT_EQ(str::upper("meow"), "MEOW");
14 EXPECT_EQ(str::lower("MeOw"), "meow");
15 EXPECT_EQ(str::capitalize("hello world"), "Hello world");
16 EXPECT_EQ(str::title("hello world"), "Hello World");
17 EXPECT_EQ(str::swapcase("Meow"), "mEOW");
20TEST(CheatahString, Trimming) {
21 EXPECT_EQ(str::strip(" meow \t"), "meow");
22 EXPECT_EQ(str::lstrip("xxmeow", "x"), "meow");
23 EXPECT_EQ(str::rstrip("meowyy", "y"), "meow");
26TEST(CheatahString, SearchAndTest) {
27 EXPECT_TRUE(str::startswith("meow", "me"));
28 EXPECT_TRUE(str::endswith("meow", "ow"));
29 EXPECT_TRUE(str::contains("meow", "eo"));
30 EXPECT_EQ(str::find("meow meow", "meow"), 0);
31 EXPECT_EQ(str::rfind("meow meow", "meow"), 5);
32 EXPECT_EQ(str::find("meow", "z"), -1);
33 // 3-arg find(s, sub, start): search from an offset without slicing (O(n) repeated scans).
34 EXPECT_EQ(str::find("meow meow", "meow", 1), 5); // skips the match at 0
35 EXPECT_EQ(str::find("meow meow", "meow", 6), -1); // no match at/after 6
36 EXPECT_EQ(str::find("meow", "m", -3), 0); // negative start clamps to 0
37 EXPECT_EQ(str::find("meow", "m", 99), -1); // start past end -> not found
38 EXPECT_EQ(str::count("meow meow meow", "meow"), 3);
41TEST(CheatahString, Transform) {
42 EXPECT_EQ(str::replace("meow meow", "e", "3"), "m3ow m3ow");
43 EXPECT_EQ(str::split("a,b,c", ","), (std::vector<std::string>{"a", "b", "c"}));
44 EXPECT_EQ(str::split(" a b "), (std::vector<std::string>{"a", "b"}));
45 EXPECT_EQ(str::splitlines("a\nb\r\nc"), (std::vector<std::string>{"a", "b", "c"}));
46 EXPECT_EQ(str::capwords("the quick brown"), "The Quick Brown");
47 EXPECT_EQ(str::join("-", std::vector<std::string>{"a", "b", "c"}), "a-b-c");
48 EXPECT_EQ(str::join(", ", std::vector<const char*>{"x", "y"}), "x, y"); // any string-like elem
51TEST(CheatahString, Padding) {
52 EXPECT_EQ(str::ljust("cat", 5), "cat ");
53 EXPECT_EQ(str::rjust("cat", 5), " cat");
54 EXPECT_EQ(str::center("cat", 9, "*"), "***cat***");
55 EXPECT_EQ(str::zfill("42", 5), "00042");
56 EXPECT_EQ(str::zfill("-42", 5), "-0042");
59TEST(CheatahString, Classification) {
60 EXPECT_TRUE(str::isdigit("123"));
61 EXPECT_FALSE(str::isdigit("12a"));
62 EXPECT_FALSE(str::isdigit(""));
63 EXPECT_TRUE(str::isalpha("abc"));
64 EXPECT_TRUE(str::isupper("MEOW"));
65 EXPECT_TRUE(str::islower("meow"));
66 EXPECT_FALSE(str::isupper("Meow"));
69TEST(CheatahString, ClassificationAlnumAndSpace) {
70 EXPECT_TRUE(str::isalnum("abc123"));
71 EXPECT_FALSE(str::isalnum("abc 123"));
72 EXPECT_FALSE(str::isalnum("")); // empty → false
73 EXPECT_TRUE(str::isspace(" \t\n"));
74 EXPECT_FALSE(str::isspace("a b"));
75 EXPECT_FALSE(str::isspace(""));
78TEST(CheatahString, SplitEmptySeparator) {
79 const std::vector<std::string> parts = str::split("abc", ""); // whole string, one element
80 ASSERT_EQ(parts.size(), 1u);
81 EXPECT_EQ(parts[0], "abc");
84// contains() with a single character (the char overload, distinct from substring contains).
85TEST(CheatahString, ContainsChar) {
86 EXPECT_TRUE(str::contains("hello", 'e'));
87 EXPECT_FALSE(str::contains("hello", 'z'));
88 EXPECT_FALSE(str::contains("", 'a'));