blob: a40e70ae7320514140c0a0640fa9ee5d2b0a959b [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h"
#include "base/memory/ptr_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/wtf_test_helper.h"
namespace WTF {
TEST(VectorBackedLinkedListTest, Insert) {
using List = VectorBackedLinkedList<int>;
List list;
EXPECT_TRUE(list.empty());
EXPECT_TRUE(list.begin() == list.end());
list.insert(list.end(), 1);
list.insert(list.begin(), -2);
list.insert(list.end(), 2);
List::iterator it = list.begin();
EXPECT_EQ(*it, -2);
++it;
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
it = list.insert(++list.begin(), 0);
list.insert(it, -1);
EXPECT_EQ(list.front(), -2);
EXPECT_EQ(list.back(), 2);
EXPECT_EQ(list.size(), 5u);
int i = -2;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
}
TEST(VectorBackedLinkedListTest, PushFront) {
using List = VectorBackedLinkedList<int>;
List list;
EXPECT_TRUE(list.empty());
list.push_front(3);
EXPECT_EQ(list.front(), 3);
list.push_front(2);
EXPECT_EQ(list.front(), 2);
list.push_front(1);
EXPECT_EQ(list.front(), 1);
int i = 1;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
}
TEST(VectorBackedLinkedListTest, PushBack) {
using List = VectorBackedLinkedList<int>;
List list;
EXPECT_TRUE(list.empty());
list.push_back(1);
EXPECT_EQ(list.back(), 1);
list.push_back(2);
EXPECT_EQ(list.back(), 2);
list.push_back(3);
EXPECT_EQ(list.back(), 3);
int i = 1;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
}
TEST(VectorBackedLinkedListTest, MoveTo) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.MoveTo(list.begin(), list.end());
List::iterator it = list.begin();
EXPECT_EQ(*it, 1);
list.push_back(2);
list.push_back(3);
List::iterator target = list.begin();
list.MoveTo(target, list.end()); // {2, 3, 1}
it = list.begin();
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
--it;
target = it;
list.MoveTo(target, list.begin()); // {3, 2, 1}
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 1);
target = it;
list.MoveTo(target, --it); // {3, 1, 2}
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
list.MoveTo(list.begin(), list.begin());
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
target = list.begin();
List::iterator position = ++list.begin();
list.MoveTo(target, position);
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
}
TEST(VectorBackedLinkedListTest, Erase) {
using List = VectorBackedLinkedList<int>;
List list;
List::iterator it = list.insert(list.end(), 1);
EXPECT_EQ(*it, 1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
EXPECT_EQ(list.size(), 5u);
int i = 1;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
List::iterator target = list.begin();
++target;
it = list.erase(target); // list = {1, 3, 4, 5}
EXPECT_EQ(*it, 3);
EXPECT_EQ(list.size(), 4u);
it = list.erase(++it); // list = {1, 3, 5}
EXPECT_EQ(*it, 5);
EXPECT_EQ(list.size(), 3u);
it = list.erase(list.begin()); // list = {3, 5}
EXPECT_EQ(*it, 3);
EXPECT_EQ(list.size(), 2u);
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 5);
++it;
EXPECT_TRUE(it == list.end());
list.push_back(6);
EXPECT_EQ(list.front(), 3);
EXPECT_EQ(list.back(), 6);
}
TEST(VectorBackedLinkedListTest, PopFront) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
int i = 1;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
list.pop_front();
EXPECT_EQ(list.front(), 2);
EXPECT_EQ(list.back(), 3);
EXPECT_EQ(list.size(), 2u);
list.pop_front();
EXPECT_EQ(list.front(), 3);
EXPECT_EQ(list.back(), 3);
EXPECT_EQ(list.size(), 1u);
list.pop_front();
EXPECT_TRUE(list.empty());
}
TEST(VectorBackedLinkedListTest, PopBack) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.pop_back();
EXPECT_EQ(list.front(), 1);
EXPECT_EQ(list.back(), 2);
EXPECT_EQ(list.size(), 2u);
list.pop_back();
EXPECT_EQ(list.front(), 1);
EXPECT_EQ(list.back(), 1);
EXPECT_EQ(list.size(), 1u);
list.pop_back();
EXPECT_TRUE(list.empty());
}
TEST(VectorBackedLinkedListTest, Clear) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
EXPECT_EQ(list.size(), 3u);
list.clear();
EXPECT_EQ(list.size(), 0u);
EXPECT_TRUE(list.empty());
EXPECT_TRUE(list.begin() == list.end());
list.push_back(1);
EXPECT_EQ(list.front(), 1);
EXPECT_EQ(list.back(), 1);
EXPECT_EQ(list.size(), 1u);
}
TEST(VectorBackedLinkedListTest, Iterator) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
List::iterator it = list.begin();
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 3);
*it = 4; // list: {1, 2, 4}
EXPECT_EQ(list.back(), 4);
++it;
EXPECT_TRUE(it == list.end());
--it;
--it;
--it;
EXPECT_TRUE(it == list.begin());
EXPECT_EQ(list.front(), 1);
*it = 0;
EXPECT_EQ(list.front(), 0); // list: {0, 2, 4}
List::reverse_iterator rit = list.rbegin();
EXPECT_EQ(*rit, 4);
++rit;
EXPECT_EQ(*rit, 2);
++rit;
EXPECT_EQ(*rit, 0);
EXPECT_FALSE(rit == list.rend());
*rit = 1; // list: {1, 2, 4}
EXPECT_EQ(list.front(), 1);
++rit;
EXPECT_TRUE(rit == list.rend());
--rit;
EXPECT_EQ(*rit, 1);
}
TEST(VectorBackedLinkedListTest, ConstIterator) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
List::const_iterator cit = list.cbegin();
EXPECT_EQ(*cit, 1);
++cit;
EXPECT_EQ(*cit, 2);
++cit;
EXPECT_EQ(*cit, 3);
++cit;
EXPECT_TRUE(cit == list.cend());
--cit;
--cit;
--cit;
EXPECT_TRUE(cit == list.cbegin());
EXPECT_EQ(list.front(), 1);
List::const_reverse_iterator crit = list.crbegin();
EXPECT_EQ(*crit, 3);
++crit;
EXPECT_EQ(*crit, 2);
++crit;
EXPECT_EQ(*crit, 1);
++crit;
EXPECT_TRUE(crit == list.crend());
--crit;
EXPECT_EQ(*crit, 1);
}
TEST(VectorBackedLinkedListTest, String) {
using List = VectorBackedLinkedList<String>;
List list;
EXPECT_TRUE(list.empty());
list.push_back("b");
list.push_front("a");
list.push_back("c");
EXPECT_EQ(list.front(), "a");
EXPECT_EQ(list.back(), "c");
EXPECT_EQ(list.size(), 3u);
List::iterator it = list.begin();
EXPECT_EQ(*it, "a");
++it;
EXPECT_EQ(*it, "b");
List::iterator target = it;
++it;
EXPECT_EQ(*it, "c");
++it;
EXPECT_TRUE(it == list.end());
--it;
EXPECT_EQ(*it, "c");
--it;
--it;
EXPECT_TRUE(it == list.begin());
list.erase(target);
it = list.begin();
EXPECT_EQ(*it, "a");
++it;
EXPECT_EQ(*it, "c");
++it;
EXPECT_TRUE(it == list.end());
list.pop_back();
EXPECT_EQ(list.front(), "a");
EXPECT_EQ(list.back(), "a");
EXPECT_EQ(list.size(), 1u);
list.push_front("c");
it = list.begin();
EXPECT_EQ(*it, "c");
++it;
EXPECT_EQ(*it, "a");
++it;
EXPECT_TRUE(it == list.end());
list.clear();
EXPECT_TRUE(list.empty());
EXPECT_TRUE(list.begin() == list.end());
list.push_front("a");
EXPECT_EQ(list.size(), 1u);
EXPECT_EQ(list.front(), "a");
list.pop_back();
EXPECT_TRUE(list.empty());
}
TEST(VectorBackedLinkedListTest, UniquePtr) {
using List = VectorBackedLinkedList<std::unique_ptr<Dummy>>;
List list;
bool deleted1 = false, deleted2 = false, deleted3 = false;
std::unique_ptr<Dummy> ptr1 = std::make_unique<Dummy>(deleted1);
std::unique_ptr<Dummy> ptr2 = std::make_unique<Dummy>(deleted2);
std::unique_ptr<Dummy> ptr3 = std::make_unique<Dummy>(deleted3);
Dummy* raw_ptr1 = ptr1.get();
Dummy* raw_ptr2 = ptr2.get();
Dummy* raw_ptr3 = ptr3.get();
list.push_front(std::move(ptr1));
list.push_back(std::move(ptr3));
List::iterator it = list.begin();
++it;
it = list.insert(it, std::move(ptr2));
EXPECT_EQ(it->get(), raw_ptr2);
EXPECT_EQ(list.size(), 3u);
EXPECT_EQ((list.front()).get(), raw_ptr1);
EXPECT_EQ((list.back()).get(), raw_ptr3);
it = list.begin();
EXPECT_EQ(it->get(), raw_ptr1);
++it;
EXPECT_EQ(it->get(), raw_ptr2);
List::iterator target = it;
++it;
EXPECT_EQ(it->get(), raw_ptr3);
++it;
EXPECT_TRUE(it == list.end());
--it;
EXPECT_EQ(it->get(), raw_ptr3);
--it;
--it;
EXPECT_TRUE(it == list.begin());
list.erase(target);
EXPECT_FALSE(deleted1);
EXPECT_TRUE(deleted2);
EXPECT_FALSE(deleted3);
EXPECT_EQ(list.size(), 2u);
it = list.begin();
EXPECT_EQ(it->get(), raw_ptr1);
++it;
EXPECT_EQ(it->get(), raw_ptr3);
++it;
EXPECT_TRUE(it == list.end());
list.pop_front();
EXPECT_TRUE(deleted1);
EXPECT_TRUE(deleted2);
EXPECT_FALSE(deleted3);
EXPECT_EQ(list.size(), 1u);
it = list.begin();
EXPECT_EQ(it->get(), raw_ptr3);
++it;
EXPECT_TRUE(it == list.end());
list.pop_back();
EXPECT_TRUE(deleted1);
EXPECT_TRUE(deleted2);
EXPECT_TRUE(deleted3);
EXPECT_TRUE(list.empty());
bool deleted4 = false, deleted5 = false, deleted6 = false;
std::unique_ptr<Dummy> ptr4 = std::make_unique<Dummy>(deleted4);
std::unique_ptr<Dummy> ptr5 = std::make_unique<Dummy>(deleted5);
std::unique_ptr<Dummy> ptr6 = std::make_unique<Dummy>(deleted6);
Dummy* raw_ptr4 = ptr4.get();
Dummy* raw_ptr5 = ptr5.get();
Dummy* raw_ptr6 = ptr6.get();
list.push_back(std::move(ptr4));
list.push_back(std::move(ptr5));
list.push_back(std::move(ptr6));
it = list.end();
--it;
list.MoveTo(list.begin(), it);
it = list.begin();
EXPECT_EQ(it->get(), raw_ptr5);
++it;
EXPECT_EQ(it->get(), raw_ptr4);
++it;
EXPECT_EQ(it->get(), raw_ptr6);
list.MoveTo(list.begin(), list.begin());
it = list.begin();
EXPECT_EQ(it->get(), raw_ptr5);
++it;
EXPECT_EQ(it->get(), raw_ptr4);
++it;
EXPECT_EQ(it->get(), raw_ptr6);
EXPECT_FALSE(deleted4);
EXPECT_FALSE(deleted5);
EXPECT_FALSE(deleted6);
list.clear();
EXPECT_TRUE(list.empty());
EXPECT_EQ(list.size(), 0u);
EXPECT_TRUE(deleted4);
EXPECT_TRUE(deleted5);
EXPECT_TRUE(deleted6);
}
} // namespace WTF