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>10
namespace str = cheatah::string;12
TEST(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");18
}20
TEST(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");24
}26
TEST(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 035
EXPECT_EQ(str::find("meow meow", "meow", 6), -1); // no match at/after 636
EXPECT_EQ(str::find("meow", "m", -3), 0); // negative start clamps to 037
EXPECT_EQ(str::find("meow", "m", 99), -1); // start past end -> not found38
EXPECT_EQ(str::count("meow meow meow", "meow"), 3);39
}41
TEST(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 elem49
}51
TEST(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");57
}59
TEST(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"));67
}69
TEST(CheatahString, ClassificationAlnumAndSpace) {70
EXPECT_TRUE(str::isalnum("abc123"));71
EXPECT_FALSE(str::isalnum("abc 123"));72
EXPECT_FALSE(str::isalnum("")); // empty → false73
EXPECT_TRUE(str::isspace(" \t\n"));74
EXPECT_FALSE(str::isspace("a b"));75
EXPECT_FALSE(str::isspace(""));76
}78
TEST(CheatahString, SplitEmptySeparator) {79
const std::vector<std::string> parts = str::split("abc", ""); // whole string, one element80
ASSERT_EQ(parts.size(), 1u);81
EXPECT_EQ(parts[0], "abc");82
}84
// contains() with a single character (the char overload, distinct from substring contains).85
TEST(CheatahString, ContainsChar) {86
EXPECT_TRUE(str::contains("hello", 'e'));87
EXPECT_FALSE(str::contains("hello", 'z'));88
EXPECT_FALSE(str::contains("", 'a'));89
}