Skip to content

Commit

Permalink
move StrVec tests to StrVec_ut.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
kjk committed May 29, 2024
1 parent 0b76f5a commit 4e37a51
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 314 deletions.
1 change: 1 addition & 0 deletions src/tools/test_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ extern void TrivialHtmlParser_UnitTests();
extern void VecTest();
extern void WinUtilTest();
extern void StrFormatTest();
extern void StrVecTest();

int main(int, char**) {
printf("Running unit tests\n");
Expand Down
314 changes: 0 additions & 314 deletions src/utils/tests/StrUtil_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,314 +225,6 @@ void strWStrTest() {
}
}

static void assertStrEq(const char* s1, const char* s2) {
bool ok = str::Eq(s1, s2);
utassert(ok);
}

static void CheckRemoveAt(StrVec& v) {
while (v.Size() > 0) {
int n = v.Size();
int idx = v.Size() / 2;
auto exp = v[idx];
char* got;
if (n % 2 == 0) {
got = v.RemoveAt(idx);
} else {
got = v.RemoveAtFast(idx);
}
utassert(exp == got); // should be exact same pointer value
utassert(v.Size() == n - 1);
}
}

static void StrVecCheckIter(StrVec& v, const char** strings, int start = 0) {
int i = 0;
for (char* s : v) {
if (i < start) {
i++;
continue;
}
char* s2 = v[i];
utassert(str::Eq(s, s2));
if (strings) {
const char* s3 = strings[i - start];
utassert(str::Eq(s, s3));
}
i++;
}
if (!strings) {
return;
}

// test iterator + operator
auto it = v.begin() + start;
auto end = v.end();
i = 0;
for (; it != end; it++, i++) {
char* s = *it;
const char* s2 = strings[i];
utassert(str::Eq(s, s2));
}
}

static void AppendStrings(StrVec& v, const char** strings, int nStrings) {
int initialSize = v.Size();
for (int i = 0; i < nStrings; i++) {
v.Append(strings[i]);
utassert(v.Size() == initialSize + i + 1);
}
StrVecCheckIter(v, strings, initialSize);
}

const char* strs[] = {"foo", "bar", "Blast", nullptr, "this is a large string, my friend"};

static void StrVecTest() {
{
StrVec v;
const char* s = "lolda";
v.InsertAt(0, s);
utassert(v.Size() == 1);
utassert(str::Eq(v.At(0), s));
}
// order in strs
int unsortedOrder[] = {0, 1, 2, 3, 4};
int sortedOrder[]{3, 2, 1, 0, 4};
int sortedNoCaseOrder[]{3, 1, 2, 0, 4};

int n = dimofi(strs);
StrVec v;
utassert(v.Size() == 0);
AppendStrings(v, strs, n);
StrVecCheckIter(v, strs, 0);

StrVec sortedView = v;
Sort(sortedView);

for (int i = 0; i < n; i++) {
char* got = sortedView.At(i);
auto exp = strs[sortedOrder[i]];
assertStrEq(got, exp);
}

// allocate a bunch to test allocating
for (int i = 0; i < 1024; i++) {
v.Append(strs[4]);
}
utassert(v.Size() == 1024 + n);

for (int i = 0; i < n; i++) {
auto got = v.At(i);
auto exp = strs[unsortedOrder[i]];
assertStrEq(got, exp);
}

for (int i = 0; i < 1024; i++) {
auto got = v.At(i + n);
auto exp = strs[4];
assertStrEq(got, exp);
}
SortNoCase(sortedView);

for (int i = 0; i < n; i++) {
auto got = sortedView.At(i);
auto exp = strs[sortedNoCaseOrder[i]];
assertStrEq(got, exp);
}

Sort(v);
for (int i = 0; i < n; i++) {
char* got = v.At(i);
auto exp = strs[sortedOrder[i]];
assertStrEq(got, exp);
}
StrVecCheckIter(v, nullptr);
SortNoCase(v);
for (int i = 0; i < n; i++) {
char* got = v.At(i);
auto exp = strs[sortedNoCaseOrder[i]];
assertStrEq(got, exp);
}
v.SetAt(3, nullptr);
utassert(nullptr == v[3]);
CheckRemoveAt(v);
}

static void StrVecTest2() {
StrVec v;
v.Append("foo");
v.Append("bar");
char* s = Join(v);
utassert(v.Size() == 2);
utassert(str::Eq("foobar", s));
str::Free(s);

s = Join(v, ";");
utassert(v.Size() == 2);
utassert(str::Eq("foo;bar", s));
str::Free(s);

v.Append(nullptr);
utassert(v.Size() == 3);

v.Append("glee");
s = JoinTemp(v, "_ _");
utassert(v.Size() == 4);
utassert(str::Eq("foo_ _bar_ _glee", s));

StrVecCheckIter(v, nullptr);
Sort(v);
const char* strsSorted[] = {nullptr, "bar", "foo", "glee"};
StrVecCheckIter(v, strsSorted);

s = Join(v, "++");
utassert(v.Size() == 4);
utassert(str::Eq("bar++foo++glee", s));
str::Free(s);

s = Join(v);
utassert(str::Eq("barfooglee", s));
str::Free(s);

{
StrVec v2(v);
utassert(str::Eq(v2.At(2), "foo"));
v2.Append("nobar");
utassert(str::Eq(v2.At(4), "nobar"));
v2 = v;
utassert(v2.Size() == 4);
// copies should be same values but at different addresses
utassert(v2.At(1) != v.At(1));
utassert(str::Eq(v2.At(1), v.At(1)));
s = v2.At(2);
utassert(str::Eq(s, "foo"));
CheckRemoveAt(v2);
}

{
StrVec v2;
size_t count = Split(v2, "a,b,,c,", ",");
utassert(count == 5 && v2.Find("c") == 3);
utassert(v2.Find("") == 2);
utassert(v2.Find("", 3) == 4);
utassert(v2.Find("", 5) == -1);
utassert(v2.Find("B") == -1 && v2.FindI("B") == 1);
TempStr joined = JoinTemp(v2, ";");
utassert(str::Eq(joined, "a;b;;c;"));
CheckRemoveAt(v2);
}

{
StrVec v2;
size_t count = Split(v2, "a,b,,c,", ",", true);
utassert(count == 3 && v2.Find("c") == 2);
TempStr joined = JoinTemp(v2, ";");
utassert(str::Eq(joined, "a;b;c"));
StrVecCheckIter(v2, nullptr);

#if 0
AutoFreeWStr last(v2.Pop());
utassert(v2.size() == 2 && str::Eq(last, L"c"));
#endif
CheckRemoveAt(v2);
}
CheckRemoveAt(v);
}

static void StrVecTest3() {
StrVec v;
utassert(v.Size() == 0);
v.Append("one");
v.Append("two");
v.Append("One");
utassert(v.Size() == 3);
utassert(str::Eq(v.At(0), "one"));
utassert(str::EqI(v.At(2), "one"));
utassert(v.Find("One") == 2);
utassert(v.FindI("One") == 0);
utassert(v.Find("Two") == -1);
StrVecCheckIter(v, nullptr);
CheckRemoveAt(v);
}

static void StrVecTest4() {
StrVec v;
AppendStrings(v, strs, dimofi(strs));

int idx = 2;

utassert(str::Eq(strs[idx], v[idx]));
auto s = "new value of string, should be large to get results faster";
// StrVec: tests adding where can allocate new value inside a page
v.SetAt(idx, s);
utassert(str::Eq(s, v[idx]));
v.SetAt(idx, nullptr);
utassert(str::Eq(nullptr, v[idx]));
v.SetAt(idx, "");
utassert(str::Eq("", v[idx]));
// StrVec: force allocating in side strings
// first page is 256 bytes so this should force allocation in sideStrings
int n = 256 / str::Leni(s);
for (int i = 0; i < n; i++) {
v.SetAt(idx, s);
}
utassert(str::Eq(s, v[idx]));

auto prevAtIdx = strs[idx];
defer {
strs[idx] = prevAtIdx;
};
strs[idx] = s;
StrVecCheckIter(v, strs);

auto s2 = v.RemoveAt(idx);
utassert(str::Eq(s, s2));

// should be replaced by next value
s2 = v.At(idx);
utassert(str::Eq(s2, strs[idx + 1]));

// StrVec: test multiple side strings
n = v.Size();
for (int i = 0; i < n; i++) {
v.SetAt(i, s);
}
for (auto it = v.begin(); it != v.end(); it++) {
s2 = *it;
utassert(str::Eq(s, s2));
}
auto s3 = "hello";
v.SetAt(n / 2, s3);
s2 = v[n / 2];
utassert(str::Eq(s3, s2));
while (v.Size() > 0) {
n = v.Size();
s2 = v[0];
if (n % 2 == 0) {
s3 = v.RemoveAtFast(0);
} else {
s3 = v.RemoveAt(0);
}
utassert(str::Eq(s2, s3));
}
}

static void StrVecTest5() {
StrVec v;
AppendStrings(v, strs, dimofi(strs));
const char* s = "first";
v.InsertAt(0, s);
auto s2 = v.At(0);
utassert(str::Eq(s, s2));
s = strs[0];
s2 = v.At(1);
utassert(str::Eq(s2, s));
s = "middle";
v.InsertAt(3, s);
s2 = v.At(3);
utassert(str::Eq(s2, s));
}

void StrTest() {
WCHAR buf[32];
const WCHAR* str = L"a string";
Expand Down Expand Up @@ -959,10 +651,4 @@ void StrTest() {
StrConvTest();
StrUrlExtractTest();
// ParseUntilTest();

StrVecTest();
StrVecTest2();
StrVecTest3();
StrVecTest4();
StrVecTest5();
}

0 comments on commit 4e37a51

Please sign in to comment.