blob: 935c5f36446a5daa029cb16ae2915b9374a805ea [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuzz-utils/string-list.h>
#include <unittest/unittest.h>
namespace fuzzing {
namespace testing {
namespace {
#define arraysize(x) sizeof(x) / sizeof(x[0])
// Helper function to find expected strings in a list
bool Match(StringList* list, const char** expected, size_t off, size_t len) {
BEGIN_HELPER;
EXPECT_EQ(list->length(), len);
const char* elem = list->first();
for (size_t i = 0; i < len; ++i) {
ASSERT_NONNULL(elem);
EXPECT_STR_EQ(elem, expected[off + i]);
elem = list->next();
}
EXPECT_NULL(elem);
END_HELPER;
}
bool TestEmpty() {
BEGIN_TEST;
StringList list;
EXPECT_TRUE(list.is_empty());
EXPECT_NULL(list.first());
EXPECT_NULL(list.next());
END_TEST;
}
bool TestPushFrontAndBack() {
BEGIN_TEST;
StringList list;
const char* expected[] = {"", "foo", "bar", "baz", ""};
// Strings can be pushed from either end
list.push_front("bar");
list.push_back("baz");
list.push_front("foo");
EXPECT_TRUE(Match(&list, expected, 1, 3));
// Empty strings are fine
list.push_front("");
list.push_back("");
EXPECT_TRUE(Match(&list, expected, 0, 5));
// Null strings are ignored
list.push_front(nullptr);
list.push_back(nullptr);
EXPECT_TRUE(Match(&list, expected, 0, 5));
// Test the new constructor
StringList list2(expected, arraysize(expected));
EXPECT_TRUE(Match(&list, expected, 0, 5));
END_TEST;
}
bool TestKeepIf() {
BEGIN_TEST;
StringList list;
const char* original[] = {"", "foo", "bar", "baz", "qux",
"quux", "corge", "grault", "garply", "waldo",
"fred", "plugh", "xyzzy", "thud", ""};
const char* expected1[] = {"bar", "corge", "grault", "garply", "plugh"};
const char* expected2[] = {"corge", "grault", "garply", "plugh"};
const char* expected3[] = {"garply"};
for (size_t i = 0; i < arraysize(original); ++i) {
list.push_back(original[i]);
}
// Null string has no effect
list.keep_if(nullptr);
EXPECT_TRUE(Match(&list, original, 0, arraysize(original)));
// Empty string matches everything
list.keep_if("");
EXPECT_TRUE(Match(&list, original, 0, arraysize(original)));
// Match a string
list.keep_if("g");
EXPECT_TRUE(Match(&list, expected2, 0, arraysize(expected2)));
// Match a string that would have matched elements in the original list
list.keep_if("ar");
EXPECT_TRUE(Match(&list, expected3, 0, arraysize(expected3)));
// Use a string that doesn't match anything
list.keep_if("zzz");
EXPECT_TRUE(list.is_empty());
// Reset and apply both matches at once with logical-or
StringList substrs;
substrs.push_back("g");
substrs.push_back("ar");
list.clear();
for (size_t i = 0; i < arraysize(original); ++i) {
list.push_back(original[i]);
}
list.keep_if_any(&substrs);
EXPECT_TRUE(Match(&list, expected1, 0, arraysize(expected1)));
// Reset and apply both matches at once with logical-and
list.clear();
for (size_t i = 0; i < arraysize(original); ++i) {
list.push_back(original[i]);
}
list.keep_if_all(&substrs);
EXPECT_TRUE(Match(&list, expected3, 0, arraysize(expected3)));
END_TEST;
}
bool TestEraseIf() {
BEGIN_TEST;
StringList list;
const char* original[] = {"", "foo", "bar", "baz", ""};
const char* expected1[] = {"", "foo", "baz", ""};
const char* expected2[] = {"foo", "baz"};
for (size_t i = 0; i < sizeof(original) / sizeof(original[0]); ++i) {
list.push_back(original[i]);
}
// Null and empty strings have no effect
list.erase_if(nullptr);
EXPECT_TRUE(Match(&list, original, 0, arraysize(original)));
// Use a string that doesn't match anything
list.erase_if("zzz");
EXPECT_TRUE(Match(&list, original, 0, arraysize(original)));
// Match a string
list.erase_if("bar");
EXPECT_TRUE(Match(&list, expected1, 0, arraysize(expected1)));
// Idempotent
list.erase_if("bar");
EXPECT_TRUE(Match(&list, expected1, 0, arraysize(expected1)));
// Able to erase empty strings
list.erase_if("");
EXPECT_TRUE(Match(&list, expected2, 0, arraysize(expected2)));
END_TEST;
}
bool TestClear() {
BEGIN_TEST;
StringList list;
list.push_front("bar");
EXPECT_NONNULL(list.first());
list.clear();
EXPECT_NULL(list.next());
EXPECT_NULL(list.first());
EXPECT_EQ(list.length(), 0);
END_TEST;
}
BEGIN_TEST_CASE(StringListTest)
RUN_TEST(TestEmpty)
RUN_TEST(TestPushFrontAndBack)
RUN_TEST(TestKeepIf)
RUN_TEST(TestEraseIf)
RUN_TEST(TestClear)
END_TEST_CASE(StringListTest)
} // namespace
} // namespace testing
} // namespace fuzzing