blob: 92a940ee089ccc162f8023ec0b2f19cd1cc823ad [file] [log] [blame]
/*
* Copyright (C) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "MoveOnly.h"
#include <wtf/RefCountedFixedVector.h>
namespace TestWebKitAPI {
TEST(WTF_RefCountedFixedVector, Empty)
{
auto vector = RefCountedFixedVector<unsigned>::create(0);
EXPECT_TRUE(vector->isEmpty());
EXPECT_EQ(0U, vector->size());
}
TEST(WTF_RefCountedFixedVector, Iterator)
{
auto intVector = RefCountedFixedVector<unsigned>::create(4);
intVector.get()[0] = 10;
intVector.get()[1] = 11;
intVector.get()[2] = 12;
intVector.get()[3] = 13;
auto it = intVector->begin();
auto end = intVector->end();
EXPECT_TRUE(end != it);
EXPECT_EQ(10U, *it);
++it;
EXPECT_EQ(11U, *it);
++it;
EXPECT_EQ(12U, *it);
++it;
EXPECT_EQ(13U, *it);
++it;
EXPECT_TRUE(end == it);
}
TEST(WTF_RefCountedFixedVector, OverloadedOperatorAmpersand)
{
struct Test {
private:
Test* operator&() = delete;
};
auto vector = RefCountedFixedVector<Test>::create(1);
vector.get()[0] = Test();
}
TEST(WTF_RefCountedFixedVector, Copy)
{
auto vec1 = RefCountedFixedVector<unsigned>::create(3);
vec1.get()[0] = 0;
vec1.get()[1] = 1;
vec1.get()[2] = 2;
auto vec2 = RefCountedFixedVector<unsigned>::create(vec1->begin(), vec1->end());
EXPECT_EQ(3U, vec1->size());
EXPECT_EQ(3U, vec2->size());
for (unsigned i = 0; i < vec1->size(); ++i) {
EXPECT_EQ(i, vec1.get()[i]);
EXPECT_EQ(i, vec2.get()[i]);
}
vec1.get()[2] = 42;
EXPECT_EQ(42U, vec1.get()[2]);
EXPECT_EQ(2U, vec2.get()[2]);
}
TEST(WTF_RefCountedFixedVector, CopyVector)
{
auto vec1 = Vector<unsigned>::from(0, 1, 2, 3);
EXPECT_EQ(4U, vec1.size());
auto vec2 = RefCountedFixedVector<unsigned>::createFromVector(vec1);
EXPECT_EQ(4U, vec1.size());
EXPECT_EQ(4U, vec2->size());
for (unsigned i = 0; i < vec1.size(); ++i) {
EXPECT_EQ(i, vec1[i]);
EXPECT_EQ(i, vec2.get()[i]);
}
vec1[2] = 42;
EXPECT_EQ(42U, vec1[2]);
EXPECT_EQ(2U, vec2.get()[2]);
}
TEST(WTF_RefCountedFixedVector, MoveVector)
{
auto vec1 = Vector<MoveOnly>::from(MoveOnly(0), MoveOnly(1), MoveOnly(2), MoveOnly(3));
EXPECT_EQ(4U, vec1.size());
auto vec2 = RefCountedFixedVector<MoveOnly>::createFromVector(WTFMove(vec1));
EXPECT_EQ(0U, vec1.size());
EXPECT_EQ(4U, vec2->size());
for (unsigned index = 0; index < vec2->size(); ++index)
EXPECT_EQ(index, vec2.get()[index].value());
}
TEST(WTF_RefCountedFixedVector, IteratorFor)
{
auto vec1 = RefCountedFixedVector<unsigned>::create(3);
vec1.get()[0] = 0;
vec1.get()[1] = 1;
vec1.get()[2] = 2;
unsigned index = 0;
for (auto iter = vec1->begin(); iter != vec1->end(); ++iter) {
EXPECT_EQ(index, *iter);
++index;
}
}
TEST(WTF_RefCountedFixedVector, Reverse)
{
auto vec1 = RefCountedFixedVector<unsigned>::create(3);
vec1.get()[0] = 0;
vec1.get()[1] = 1;
vec1.get()[2] = 2;
unsigned index = 0;
for (auto iter = vec1->rbegin(); iter != vec1->rend(); ++iter) {
++index;
EXPECT_EQ(3U - index, *iter);
}
}
TEST(WTF_RefCountedFixedVector, Fill)
{
auto vec1 = RefCountedFixedVector<unsigned>::create(3);
vec1->fill(42);
for (auto& value : vec1.get())
EXPECT_EQ(value, 42U);
}
struct DestructorObserver {
DestructorObserver() = default;
DestructorObserver(bool* destructed)
: destructed(destructed)
{
}
~DestructorObserver()
{
if (destructed)
*destructed = true;
}
DestructorObserver(DestructorObserver&& other)
: destructed(other.destructed)
{
other.destructed = nullptr;
}
DestructorObserver& operator=(DestructorObserver&& other)
{
destructed = other.destructed;
other.destructed = nullptr;
return *this;
}
bool* destructed { nullptr };
};
TEST(WTF_RefCountedFixedVector, Destructor)
{
Vector<bool> flags(3, false);
{
auto vector = RefCountedFixedVector<DestructorObserver>::create(flags.size());
for (unsigned i = 0; i < flags.size(); ++i)
vector.get()[i] = DestructorObserver(&flags[i]);
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_FALSE(flags[i]);
}
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_TRUE(flags[i]);
}
TEST(WTF_RefCountedFixedVector, DestructorAfterMove)
{
Vector<bool> flags(3, false);
{
RefPtr<RefCountedFixedVector<DestructorObserver>> outerVector;
{
RefPtr<RefCountedFixedVector<DestructorObserver>> outerVector2;
{
auto vector = RefCountedFixedVector<DestructorObserver>::create(flags.size());
for (unsigned i = 0; i < flags.size(); ++i)
vector.get()[i] = DestructorObserver(&flags[i]);
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_FALSE(flags[i]);
outerVector = vector.copyRef();
outerVector2 = vector.copyRef();
}
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_FALSE(flags[i]);
EXPECT_EQ(outerVector.get(), outerVector2.get());
}
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_FALSE(flags[i]);
}
for (unsigned i = 0; i < flags.size(); ++i)
EXPECT_TRUE(flags[i]);
}
TEST(WTF_RefCountedFixedVector, Basic)
{
std::array<unsigned, 4> array { {
0, 1, 2, 3
} };
{
auto vector = RefCountedFixedVector<unsigned>::create(array.begin(), array.end());
EXPECT_EQ(4U, vector->size());
EXPECT_EQ(0U, vector->at(0));
EXPECT_EQ(1U, vector->at(1));
EXPECT_EQ(2U, vector->at(2));
EXPECT_EQ(3U, vector->at(3));
}
}
TEST(WTF_RefCountedFixedVector, Clone)
{
std::array<unsigned, 4> array { {
0, 1, 2, 3
} };
{
auto vector = RefCountedFixedVector<unsigned>::create(array.begin(), array.end());
EXPECT_EQ(4U, vector->size());
EXPECT_EQ(0U, vector->at(0));
EXPECT_EQ(1U, vector->at(1));
EXPECT_EQ(2U, vector->at(2));
EXPECT_EQ(3U, vector->at(3));
auto cloned = vector->clone();
EXPECT_EQ(4U, cloned->size());
EXPECT_EQ(0U, cloned->at(0));
EXPECT_EQ(1U, cloned->at(1));
EXPECT_EQ(2U, cloned->at(2));
EXPECT_EQ(3U, cloned->at(3));
}
}
TEST(WTF_RefCountedFixedVector, Equal)
{
auto vec1 = RefCountedFixedVector<unsigned>::create(10);
auto vec2 = RefCountedFixedVector<unsigned>::create(10);
for (unsigned i = 0; i < 10; ++i) {
vec1.get()[i] = i;
vec2.get()[i] = i;
}
EXPECT_EQ(vec1.get(), vec2.get());
vec1.get()[0] = 42;
EXPECT_NE(vec1.get(), vec2.get());
}
}