262 lines
5.1 KiB
C++
262 lines
5.1 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <catch2/catch_all.hpp>
|
|
|
|
#include <vector>
|
|
#include <stdexcept>
|
|
|
|
#include "Data/Containers/Array.hpp"
|
|
|
|
class NonTrivial
|
|
{
|
|
public:
|
|
static int destructorCount;
|
|
|
|
NonTrivial() = default;
|
|
~NonTrivial() { destructorCount++; }
|
|
};
|
|
|
|
int NonTrivial::destructorCount = 0;
|
|
|
|
using namespace OpenVulkano;
|
|
|
|
TEST_CASE("Default constructor", "[Array]")
|
|
{
|
|
Array<int> array;
|
|
REQUIRE(array.Size() == 0);
|
|
REQUIRE(array.Empty());
|
|
}
|
|
|
|
TEST_CASE("Constructor with size", "[Array]")
|
|
{
|
|
Array<int> array(5);
|
|
REQUIRE(array.Size() == 5);
|
|
|
|
Array<int> arr(5, 42);
|
|
REQUIRE(arr.Size() == 5);
|
|
for (size_t i = 0; i < arr.Size(); ++i)
|
|
{
|
|
REQUIRE(arr[i] == 42);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Constructor with initializer list", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
REQUIRE(array.Size() == 3);
|
|
REQUIRE(array[0] == 1);
|
|
REQUIRE(array[1] == 2);
|
|
REQUIRE(array[2] == 3);
|
|
}
|
|
|
|
TEST_CASE("Copy constructor", "[Array]")
|
|
{
|
|
Array<int> array1 { 1, 2, 3 };
|
|
Array<int> array2(array1);
|
|
REQUIRE(array2.Size() == 3);
|
|
REQUIRE(array2 == array1);
|
|
}
|
|
|
|
TEST_CASE("Move constructor", "[Array]")
|
|
{
|
|
Array<int> array1 { 1, 2, 3 };
|
|
Array<int> array2(std::move(array1));
|
|
REQUIRE(array2.Size() == 3);
|
|
REQUIRE(array1.Size() == 0);
|
|
REQUIRE(array1.Empty());
|
|
}
|
|
|
|
TEST_CASE("Constructor from std::vector", "[Array]")
|
|
{
|
|
std::vector<int> vec { 4, 5, 6 };
|
|
Array<int> array(vec);
|
|
REQUIRE(array.Size() == 3);
|
|
REQUIRE(array[0] == 4);
|
|
REQUIRE(array[1] == 5);
|
|
REQUIRE(array[2] == 6);
|
|
}
|
|
|
|
TEST_CASE("Constructor with default value", "[Array]")
|
|
{
|
|
Array<int> array(3, 7);
|
|
REQUIRE(array.Size() == 3);
|
|
for (size_t i = 0; i < 3; ++i)
|
|
{
|
|
REQUIRE(array[i] == 7);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Resize method", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
array = { 4, 5 };
|
|
REQUIRE(array.Size() == 2);
|
|
REQUIRE(array[0] == 4);
|
|
REQUIRE(array[1] == 5);
|
|
}
|
|
|
|
TEST_CASE("Destructor for non-trivially destructible types", "[Array]")
|
|
{
|
|
{
|
|
NonTrivial::destructorCount = 0;
|
|
Array<NonTrivial> array(3);
|
|
}
|
|
REQUIRE(NonTrivial::destructorCount == 3);
|
|
}
|
|
|
|
TEST_CASE("At() method with bounds checking", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
REQUIRE(array.At(1) == 2);
|
|
REQUIRE_THROWS_AS(array.At(5), std::out_of_range);
|
|
}
|
|
|
|
TEST_CASE("Assignment operator", "[Array]")
|
|
{
|
|
Array<int> array1 { 1, 2, 3 };
|
|
Array<int> array2;
|
|
array2 = array1;
|
|
REQUIRE(array2 == array1);
|
|
}
|
|
|
|
TEST_CASE("Move assignment operator", "[Array]")
|
|
{
|
|
Array<int> array1 { 1, 2, 3 };
|
|
Array<int> array2;
|
|
array2 = std::move(array1);
|
|
REQUIRE(array2.Size() == 3);
|
|
REQUIRE(array1.Size() == 0);
|
|
}
|
|
|
|
TEST_CASE("Comparison operators", "[Array]")
|
|
{
|
|
Array<int> array1 { 1, 2, 3 };
|
|
Array<int> array2 { 1, 2, 3 };
|
|
Array<int> array3 { 4, 5, 6 };
|
|
|
|
REQUIRE(array1 == array2);
|
|
REQUIRE(array1 != array3);
|
|
REQUIRE(array1 < array3);
|
|
REQUIRE(array3 > array1);
|
|
REQUIRE(array1 <= array2);
|
|
REQUIRE(array1 >= array2);
|
|
}
|
|
|
|
TEST_CASE("Fill method", "[Array]")
|
|
{
|
|
Array<int> array(5);
|
|
array.Fill(42);
|
|
for (size_t i = 0; i < 5; ++i)
|
|
{
|
|
REQUIRE(array[i] == 42);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Front and Back methods", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
REQUIRE(array.Front() == 1);
|
|
REQUIRE(array.Back() == 3);
|
|
}
|
|
|
|
TEST_CASE("Iterators", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
int sum = 0;
|
|
for (auto it = array.Begin(); it != array.End(); ++it)
|
|
{
|
|
sum += *it;
|
|
}
|
|
REQUIRE(sum == 6);
|
|
|
|
sum = 0;
|
|
for (auto it = array.ReverseBegin(); it != array.ReverseEnd(); ++it)
|
|
{
|
|
sum += *it;
|
|
}
|
|
REQUIRE(sum == 6);
|
|
|
|
Array<int> arr = { 1, 2, 3, 4, 5 };
|
|
{
|
|
int sum = 0;
|
|
for (auto it = arr.Begin(); it != arr.End(); ++it)
|
|
{
|
|
sum += *it;
|
|
}
|
|
REQUIRE(sum == 15);
|
|
}
|
|
|
|
{
|
|
std::vector<int> reversedElements;
|
|
for (auto it = arr.ReverseBegin(); it != arr.ReverseEnd(); ++it)
|
|
{
|
|
reversedElements.push_back(*it);
|
|
}
|
|
REQUIRE(reversedElements == std::vector<int>({ 5, 4, 3, 2, 1 }));
|
|
}
|
|
|
|
{
|
|
const Array<int> constArr = { 1, 2, 3, 4, 5 };
|
|
int sum = 0;
|
|
for (auto it = constArr.Begin(); it != constArr.End(); ++it)
|
|
{
|
|
sum += *it;
|
|
}
|
|
REQUIRE(sum == 15);
|
|
}
|
|
|
|
{
|
|
const Array<int> constArr = { 1, 2, 3, 4, 5 };
|
|
std::vector<int> reversedElements;
|
|
for (auto it = constArr.ReverseBegin(); it != constArr.ReverseEnd(); ++it)
|
|
{
|
|
reversedElements.push_back(*it);
|
|
}
|
|
REQUIRE(reversedElements == std::vector<int>({ 5, 4, 3, 2, 1 }));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Data method", "[Array]")
|
|
{
|
|
Array<int> array { 1, 2, 3 };
|
|
int* data = array.Data();
|
|
REQUIRE(data[0] == 1);
|
|
REQUIRE(data[1] == 2);
|
|
REQUIRE(data[2] == 3);
|
|
}
|
|
|
|
|
|
TEST_CASE("Swap method", "[Array]")
|
|
{
|
|
Array<int> arr1 = { 1, 2, 3 };
|
|
Array<int> arr2 = { 4, 5, 6 };
|
|
arr1.Swap(arr2);
|
|
REQUIRE(arr1[0] == 4);
|
|
REQUIRE(arr2[0] == 1);
|
|
}
|
|
|
|
TEST_CASE("Iterator constructor", "[Array]")
|
|
{
|
|
{
|
|
char data[] = "Hello world";
|
|
Array<char> arr(data, data + sizeof(data));
|
|
REQUIRE(arr.Data() != data);
|
|
for (int i = 0; i < sizeof(data); i++)
|
|
{
|
|
REQUIRE(data[i] == arr[i]);
|
|
}
|
|
}
|
|
|
|
{
|
|
Array<int> arr = { 1, 2, 3, 4, 5 };
|
|
Array<double> arr2(arr.begin(), arr.end());
|
|
for (int i = 0; i < arr.Size(); i++)
|
|
{
|
|
REQUIRE(arr[i] == arr2[i]);
|
|
}
|
|
}
|
|
} |