blob: 87497b93c7538e4517cdce0630fa4752235295d5 [file] [edit]
//===- TestKmpStr.cpp - Tests for kmp_str utilities ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "kmp_str.h"
#include "gtest/gtest.h"
#include <cstring>
namespace {
// Test basic string buffer initialization
TEST(KmpStrTest, BufferInit) {
kmp_str_buf_t buffer;
__kmp_str_buf_init(&buffer);
EXPECT_NE(buffer.str, nullptr);
EXPECT_GT(buffer.size, 0u);
EXPECT_EQ(buffer.used, 0);
EXPECT_EQ(buffer.str[0], '\0');
}
// Test string buffer clear
TEST(KmpStrTest, BufferClear) {
kmp_str_buf_t buffer;
__kmp_str_buf_init(&buffer);
__kmp_str_buf_print(&buffer, "test string");
EXPECT_GT(buffer.used, 0);
__kmp_str_buf_clear(&buffer);
EXPECT_EQ(buffer.used, 0);
EXPECT_EQ(buffer.str[0], '\0');
__kmp_str_buf_free(&buffer);
}
// Test string buffer print
TEST(KmpStrTest, BufferPrint) {
kmp_str_buf_t buffer;
__kmp_str_buf_init(&buffer);
__kmp_str_buf_print(&buffer, "Hello, %s!", "World");
EXPECT_STREQ(buffer.str, "Hello, World!");
EXPECT_EQ(buffer.used, 13);
__kmp_str_buf_free(&buffer);
}
// Test string buffer concatenation
TEST(KmpStrTest, BufferCat) {
kmp_str_buf_t buffer;
__kmp_str_buf_init(&buffer);
__kmp_str_buf_cat(&buffer, "Hello", 5);
__kmp_str_buf_cat(&buffer, " ", 1);
__kmp_str_buf_cat(&buffer, "World", 5);
EXPECT_STREQ(buffer.str, "Hello World");
__kmp_str_buf_free(&buffer);
}
// Test string buffer reservation
TEST(KmpStrTest, BufferReserve) {
kmp_str_buf_t buffer;
__kmp_str_buf_init(&buffer);
size_t large_size = 2048;
__kmp_str_buf_reserve(&buffer, large_size);
EXPECT_GE(buffer.size, large_size);
__kmp_str_buf_free(&buffer);
}
// Test basic string to int conversion
TEST(KmpStrTest, BasicStrToInt) {
EXPECT_EQ(__kmp_basic_str_to_int("0"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("1"), 1);
EXPECT_EQ(__kmp_basic_str_to_int("42"), 42);
EXPECT_EQ(__kmp_basic_str_to_int("123"), 123);
}
// Test basic string to int conversion with invalid inputs
TEST(KmpStrTest, BasicStrToIntInvalid) {
// Empty string returns 0
EXPECT_EQ(__kmp_basic_str_to_int(""), 0);
// Strings starting with non-digits return 0
EXPECT_EQ(__kmp_basic_str_to_int("abc"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("hello"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("xyz123"), 0);
// Special characters return 0
EXPECT_EQ(__kmp_basic_str_to_int("!@#"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("+42"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("-42"), 0);
// Leading whitespace causes early stop (returns 0)
EXPECT_EQ(__kmp_basic_str_to_int(" 42"), 0);
EXPECT_EQ(__kmp_basic_str_to_int("\t42"), 0);
// Mixed content: parses digits until first non-digit
EXPECT_EQ(__kmp_basic_str_to_int("123abc"), 123);
EXPECT_EQ(__kmp_basic_str_to_int("42 "), 42);
EXPECT_EQ(__kmp_basic_str_to_int("7.5"), 7);
}
// Test string match
TEST(KmpStrTest, StrMatch) {
const char *data = "Hello World";
// Test exact match (len == 0)
EXPECT_TRUE(__kmp_str_match("Hello World", 0, data));
EXPECT_FALSE(__kmp_str_match("Hello", 0, data)); // Not exact (data is longer)
// Test prefix match (len < 0)
EXPECT_TRUE(
__kmp_str_match("Hello", -1, data)); // "Hello" is prefix of "Hello World"
EXPECT_FALSE(__kmp_str_match("World", -1, data)); // "World" is not a prefix
// Test minimum length match (len > 0)
EXPECT_TRUE(__kmp_str_match("Hello", 5, data)); // At least 5 chars match
EXPECT_TRUE(__kmp_str_match("Hello", 3, data)); // At least 3 chars match
EXPECT_FALSE(__kmp_str_match("World", 5, data)); // First chars don't match
}
// Test string contains
TEST(KmpStrTest, StrContains) {
const char *data = "Hello World";
EXPECT_TRUE(__kmp_str_contains("Hello", 5, data));
EXPECT_TRUE(__kmp_str_contains("World", 5, data));
EXPECT_TRUE(__kmp_str_contains("lo Wo", 5, data));
EXPECT_FALSE(__kmp_str_contains("Goodbye", 7, data));
}
// Test string match for true/false values
TEST(KmpStrTest, MatchBool) {
// Test true values
EXPECT_TRUE(__kmp_str_match_true("true"));
EXPECT_TRUE(__kmp_str_match_true("TRUE"));
EXPECT_TRUE(__kmp_str_match_true("on"));
EXPECT_TRUE(__kmp_str_match_true("ON"));
EXPECT_TRUE(__kmp_str_match_true("1"));
EXPECT_TRUE(__kmp_str_match_true("yes"));
EXPECT_TRUE(__kmp_str_match_true("YES"));
// Test false values
EXPECT_TRUE(__kmp_str_match_false("false"));
EXPECT_TRUE(__kmp_str_match_false("FALSE"));
EXPECT_TRUE(__kmp_str_match_false("off"));
EXPECT_TRUE(__kmp_str_match_false("OFF"));
EXPECT_TRUE(__kmp_str_match_false("0"));
EXPECT_TRUE(__kmp_str_match_false("no"));
EXPECT_TRUE(__kmp_str_match_false("NO"));
// Note: Trailing characters after a valid prefix still match due to
// minimum-length prefix matching (e.g., "true" uses len=1, "yes" uses len=1)
EXPECT_TRUE(__kmp_str_match_true("true "));
EXPECT_TRUE(__kmp_str_match_false("false "));
EXPECT_TRUE(__kmp_str_match_true("truex"));
EXPECT_TRUE(__kmp_str_match_false("falsex"));
// Partial prefixes also match due to minimum-length matching
EXPECT_TRUE(__kmp_str_match_true("t"));
EXPECT_TRUE(__kmp_str_match_true("tru"));
EXPECT_TRUE(__kmp_str_match_false("f"));
EXPECT_TRUE(__kmp_str_match_false("fals"));
EXPECT_TRUE(__kmp_str_match_true("y"));
EXPECT_TRUE(__kmp_str_match_true("yess"));
EXPECT_TRUE(__kmp_str_match_false("n"));
EXPECT_TRUE(__kmp_str_match_false("noo"));
// "on" and "off" require at least 2 characters
EXPECT_TRUE(__kmp_str_match_true("on"));
EXPECT_TRUE(__kmp_str_match_false("of"));
EXPECT_TRUE(__kmp_str_match_false("off"));
// "enabled" and "disabled" require exact match (len=0)
EXPECT_TRUE(__kmp_str_match_true("enabled"));
EXPECT_TRUE(__kmp_str_match_false("disabled"));
}
// Test string match for invalid bool values
TEST(KmpStrTest, MatchBoolInvalid) {
// Empty string is neither true nor false
EXPECT_FALSE(__kmp_str_match_true(""));
EXPECT_FALSE(__kmp_str_match_false(""));
// Random strings are neither true nor false
EXPECT_FALSE(__kmp_str_match_true("hello"));
EXPECT_FALSE(__kmp_str_match_false("hello"));
EXPECT_FALSE(__kmp_str_match_true("abc"));
EXPECT_FALSE(__kmp_str_match_false("abc"));
// Numbers other than 0/1 are neither true nor false
EXPECT_FALSE(__kmp_str_match_true("2"));
EXPECT_FALSE(__kmp_str_match_false("2"));
EXPECT_FALSE(__kmp_str_match_true("42"));
EXPECT_FALSE(__kmp_str_match_false("42"));
EXPECT_FALSE(__kmp_str_match_true("-1"));
EXPECT_FALSE(__kmp_str_match_false("-1"));
// Leading whitespace prevents matching
EXPECT_FALSE(__kmp_str_match_true(" true"));
EXPECT_FALSE(__kmp_str_match_false(" false"));
// "on" and "off" require at least 2 characters
EXPECT_FALSE(__kmp_str_match_true("o"));
EXPECT_FALSE(__kmp_str_match_false("o"));
// "enabled" and "disabled" require exact match (len=0)
EXPECT_FALSE(__kmp_str_match_true("enable"));
EXPECT_FALSE(__kmp_str_match_false("disable"));
// True values don't match as false and vice versa
EXPECT_FALSE(__kmp_str_match_false("true"));
EXPECT_FALSE(__kmp_str_match_false("1"));
EXPECT_FALSE(__kmp_str_match_false("yes"));
EXPECT_FALSE(__kmp_str_match_true("false"));
EXPECT_FALSE(__kmp_str_match_true("0"));
EXPECT_FALSE(__kmp_str_match_true("no"));
}
// Test string replace
TEST(KmpStrTest, StrReplace) {
char str[] = "Hello World";
__kmp_str_replace(str, ' ', '_');
EXPECT_STREQ(str, "Hello_World");
__kmp_str_replace(str, 'o', '0');
EXPECT_STREQ(str, "Hell0_W0rld");
}
// Test string split
TEST(KmpStrTest, StrSplit) {
char str[] = "key=value";
char *head = nullptr;
char *tail = nullptr;
__kmp_str_split(str, '=', &head, &tail);
EXPECT_STREQ(head, "key");
EXPECT_STREQ(tail, "value");
}
// Test file name parsing
TEST(KmpStrTest, FileNameInit) {
const char *path = "/path/to/file.txt";
kmp_str_fname_t fname;
__kmp_str_fname_init(&fname, path);
EXPECT_NE(fname.path, nullptr);
EXPECT_STREQ(fname.path, path);
EXPECT_NE(fname.base, nullptr);
EXPECT_STREQ(fname.base, "file.txt");
__kmp_str_fname_free(&fname);
}
// Test string format
TEST(KmpStrTest, StrFormat) {
char *result = __kmp_str_format("Number: %d, String: %s", 42, "test");
EXPECT_NE(result, nullptr);
EXPECT_STREQ(result, "Number: 42, String: test");
__kmp_str_free(&result);
EXPECT_EQ(result, nullptr);
}
// Test string buffer concatenate buffers
TEST(KmpStrTest, BufferCatBuf) {
kmp_str_buf_t buf1, buf2;
__kmp_str_buf_init(&buf1);
__kmp_str_buf_init(&buf2);
__kmp_str_buf_print(&buf1, "Hello");
__kmp_str_buf_print(&buf2, " World");
__kmp_str_buf_catbuf(&buf1, &buf2);
EXPECT_STREQ(buf1.str, "Hello World");
__kmp_str_buf_free(&buf1);
__kmp_str_buf_free(&buf2);
}
// Test size string parsing
TEST(KmpStrTest, StrToSize) {
size_t result;
const char *error = nullptr;
__kmp_str_to_size("100", &result, 1, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 100u);
__kmp_str_to_size("1K", &result, 1024, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 1024u);
__kmp_str_to_size("2M", &result, 1024, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 2u * 1024u * 1024u);
}
// Test uint string parsing
TEST(KmpStrTest, StrToUint) {
kmp_uint64 result;
const char *error = nullptr;
__kmp_str_to_uint("0", &result, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 0u);
__kmp_str_to_uint("42", &result, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 42u);
__kmp_str_to_uint("1234567890", &result, &error);
EXPECT_EQ(error, nullptr);
EXPECT_EQ(result, 1234567890u);
}
} // namespace