Add unit tests instead of main; more implementations
This commit is contained in:
parent
2efd3407ac
commit
d313d0ce63
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -5,7 +5,7 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"name": "Test",
|
||||
"type": "gdb",
|
||||
"request": "launch",
|
||||
"target": "./vector.out",
|
||||
|
@ -6,4 +6,7 @@ Run `scons` in the root directory.
|
||||
## Developing
|
||||
The `scons` command also generates a `compile_commands.json` which can be used by the VSCodium extension `clangd` for autocompletion, debugging, etc.
|
||||
|
||||
Build and run scripts for VSCodium are provided as well.
|
||||
Build and run scripts for VSCodium are provided as well.
|
||||
|
||||
## Credits
|
||||
Catch2 for unit tests: https://github.com/catchorg/Catch2
|
||||
|
45
Vector.h
45
Vector.h
@ -9,7 +9,6 @@ class Vector {
|
||||
// Constructor
|
||||
Vector(unsigned int capacity = 10)
|
||||
: capacity(capacity), element_count(0), data(new T[capacity]) {
|
||||
std::cout << "Vector created" << std::endl;
|
||||
}
|
||||
|
||||
// Copy Constructor
|
||||
@ -30,6 +29,9 @@ class Vector {
|
||||
// Copy Assignment Operator using the copy-and-swap-idiom
|
||||
// Since this takes a value rather than a const reference due to
|
||||
// copy-and-swap, this is also the Move Assignment Operator
|
||||
// This works because we pass-by-value, causing the copy constructor (which
|
||||
// does the actual copying) to be called, and then we swap the resulting
|
||||
// temporary into `this`.
|
||||
Vector &operator=(Vector other) {
|
||||
swap(*this, other);
|
||||
|
||||
@ -39,8 +41,6 @@ class Vector {
|
||||
// Destructor
|
||||
~Vector() {
|
||||
delete[] data;
|
||||
|
||||
std::cout << "Vector deleted" << std::endl;
|
||||
}
|
||||
|
||||
// Bracket Operator
|
||||
@ -48,6 +48,19 @@ class Vector {
|
||||
return at(position);
|
||||
}
|
||||
|
||||
// Equals Operator
|
||||
bool operator==(const Vector &other) {
|
||||
if (size() != other.size()) return false;
|
||||
|
||||
for (unsigned int i = 0; i < size(); i++) {
|
||||
if (at(i) != other[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Swap function for the copy-and-swap idiom.
|
||||
// See also:
|
||||
// https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
|
||||
@ -93,9 +106,31 @@ class Vector {
|
||||
return data[position];
|
||||
}
|
||||
|
||||
void reserve(unsigned int);
|
||||
// Expand the capacity (length) of the vector by the given addition
|
||||
void reserve(unsigned int addition) {
|
||||
// TODO: Actual reserve
|
||||
capacity += addition;
|
||||
}
|
||||
|
||||
void resize(unsigned int);
|
||||
// Resize the size of the vector to the given new_size
|
||||
// If this decreases the size, some elements are deleted
|
||||
// If this increases the size, some default-constructed elements are added
|
||||
void resize(unsigned int new_size) {
|
||||
// TODO: Reserve if needed
|
||||
int difference = new_size - size();
|
||||
|
||||
if (difference > 0) {
|
||||
for (int i = 0; i < difference; i++) {
|
||||
data[element_count + i] = T();
|
||||
}
|
||||
} else if (difference < 0) {
|
||||
for (int i = -1; i > difference; i--) {
|
||||
data[element_count + i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
element_count += difference;
|
||||
}
|
||||
|
||||
private:
|
||||
T *data;
|
||||
|
9430
catch_amalgamated.cpp
Normal file
9430
catch_amalgamated.cpp
Normal file
File diff suppressed because it is too large
Load Diff
10987
catch_amalgamated.hpp
Normal file
10987
catch_amalgamated.hpp
Normal file
File diff suppressed because it is too large
Load Diff
46
main.cpp
46
main.cpp
@ -1,46 +0,0 @@
|
||||
#include "Vector.h"
|
||||
#include <iostream>
|
||||
|
||||
void print_float_vector(const Vector<float> &v) {
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
std::cout << v[i] << ", ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Vector<float> vector1;
|
||||
|
||||
vector1.push_back(0.5);
|
||||
vector1.push_back(0.7);
|
||||
vector1.push_back(1.2);
|
||||
vector1.push_back(2.0);
|
||||
vector1.push_back(3.0);
|
||||
|
||||
std::cout << "Before erase at 2" << std::endl;
|
||||
print_float_vector(vector1);
|
||||
|
||||
vector1.erase(2);
|
||||
|
||||
std::cout << "After erase at 2" << std::endl;
|
||||
print_float_vector(vector1);
|
||||
|
||||
Vector<float> vector2 = std::move(vector1);
|
||||
|
||||
std::cout << "After std::move" << std::endl;
|
||||
print_float_vector(vector2);
|
||||
|
||||
Vector<float> vector3 = vector2;
|
||||
|
||||
std::cout << "After copy construction" << std::endl;
|
||||
print_float_vector(vector2);
|
||||
print_float_vector(vector3);
|
||||
|
||||
Vector<float> vector4;
|
||||
vector4.push_back(7353.0);
|
||||
vector4 = vector3;
|
||||
|
||||
std::cout << "After copy assignment" << std::endl;
|
||||
print_float_vector(vector3);
|
||||
print_float_vector(vector4);
|
||||
}
|
229
test.cpp
Normal file
229
test.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#include "Vector.h"
|
||||
#include <iostream>
|
||||
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this
|
||||
// in one cpp file
|
||||
#include "catch_amalgamated.hpp"
|
||||
|
||||
SCENARIO("Vector size and length are correct", "[vector]") {
|
||||
Vector<int> v(20);
|
||||
v.push_back(1);
|
||||
|
||||
REQUIRE(v.size() == 1);
|
||||
REQUIRE(v.length() == 20);
|
||||
}
|
||||
|
||||
SCENARIO("The bracket operator returns the correct element", "[vector]") {
|
||||
Vector<int> v(20);
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
v.push_back(3);
|
||||
|
||||
REQUIRE(v[1] == 2);
|
||||
}
|
||||
|
||||
SCENARIO("Equality is returned correctly", "[vector]") {
|
||||
GIVEN("Two vectors with the same items") {
|
||||
Vector<int> v1;
|
||||
Vector<int> v2;
|
||||
|
||||
v1.push_back(1);
|
||||
v2.push_back(1);
|
||||
|
||||
v1.push_back(5);
|
||||
v2.push_back(5);
|
||||
|
||||
REQUIRE(v1.size() == 2);
|
||||
REQUIRE(v2.size() == 2);
|
||||
|
||||
WHEN("Comparing them") {
|
||||
bool equals = v1 == v2;
|
||||
|
||||
THEN("The result should be true") {
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Two vectors with different items") {
|
||||
Vector<int> v1;
|
||||
Vector<int> v2;
|
||||
|
||||
v1.push_back(1);
|
||||
v2.push_back(2);
|
||||
|
||||
v1.push_back(5);
|
||||
v2.push_back(5);
|
||||
|
||||
REQUIRE(v1.size() == 2);
|
||||
REQUIRE(v2.size() == 2);
|
||||
|
||||
WHEN("Comparing them") {
|
||||
bool equals = v1 == v2;
|
||||
|
||||
THEN("The result should be false") {
|
||||
REQUIRE_FALSE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Erasing an item removes it and moves the following ones forward",
|
||||
"[vector]") {
|
||||
GIVEN("Two vectors with almost identical items") {
|
||||
Vector<int> v1;
|
||||
Vector<int> v2;
|
||||
|
||||
v1.push_back(1);
|
||||
v2.push_back(1);
|
||||
|
||||
v1.push_back(2);
|
||||
v2.push_back(5);
|
||||
|
||||
v1.push_back(5);
|
||||
|
||||
v1.push_back(10);
|
||||
v2.push_back(10);
|
||||
|
||||
REQUIRE(v1.size() == 4);
|
||||
REQUIRE(v2.size() == 3);
|
||||
|
||||
WHEN("Comparing them") {
|
||||
bool equals = v1 == v2;
|
||||
|
||||
THEN("The result should be false") {
|
||||
REQUIRE_FALSE(equals);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("Erasing the different item") {
|
||||
v1.erase(1);
|
||||
bool equals = v1 == v2;
|
||||
|
||||
THEN("The result should be true") {
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Copy Assignment", "[vector]") {
|
||||
GIVEN("Two vectors with identical items") {
|
||||
Vector<int> v1;
|
||||
Vector<int> v2;
|
||||
|
||||
v1.push_back(1);
|
||||
v2.push_back(1);
|
||||
|
||||
v1.push_back(5);
|
||||
v2.push_back(5);
|
||||
|
||||
REQUIRE(v1.size() == 2);
|
||||
REQUIRE(v2.size() == 2);
|
||||
|
||||
WHEN("Copy assigning the second vector to a third vector") {
|
||||
Vector<int> v3;
|
||||
v3 = v2;
|
||||
|
||||
THEN("All vectors should be identical") {
|
||||
bool equals = v1 == v2 && v2 == v3 && v1 == v3;
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Move Assignment", "[vector]") {
|
||||
GIVEN("Two vectors with identical items") {
|
||||
Vector<int> v1;
|
||||
Vector<int> v2;
|
||||
|
||||
v1.push_back(1);
|
||||
v2.push_back(1);
|
||||
|
||||
v1.push_back(5);
|
||||
v2.push_back(5);
|
||||
|
||||
REQUIRE(v1.size() == 2);
|
||||
REQUIRE(v2.size() == 2);
|
||||
|
||||
WHEN("Move assigning the second vector to a third vector") {
|
||||
Vector<int> v3;
|
||||
v3 = std::move(v2);
|
||||
|
||||
THEN("The first and third vector should be identical") {
|
||||
bool equals = v1 == v3;
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Reserve additional space", "[vector]") {
|
||||
GIVEN("A vector with a given capacity") {
|
||||
Vector<int> v(5);
|
||||
|
||||
REQUIRE(v.length() == 5);
|
||||
|
||||
WHEN("Reserving additional space") {
|
||||
v.reserve(10);
|
||||
|
||||
THEN("The capacity has increased accordingly") {
|
||||
REQUIRE(v.length() == 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Resizing a vector", "[vector]") {
|
||||
GIVEN("A vector with 3 items") {
|
||||
Vector<int> v;
|
||||
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
v.push_back(3);
|
||||
|
||||
Vector<int> target;
|
||||
|
||||
target.push_back(1);
|
||||
target.push_back(2);
|
||||
target.push_back(3);
|
||||
target.push_back(0);
|
||||
target.push_back(0);
|
||||
|
||||
WHEN("Resizing to 5") {
|
||||
v.resize(5);
|
||||
|
||||
THEN("The size should be 5") {
|
||||
REQUIRE(v.size() == 5);
|
||||
}
|
||||
|
||||
THEN("2 new default items should've been added") {
|
||||
bool equals = v == target;
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("Resizing to 1") {
|
||||
v.resize(1);
|
||||
|
||||
THEN("The size should be 1") {
|
||||
REQUIRE(v.size() == 1);
|
||||
}
|
||||
|
||||
THEN("The remaining element should be correct") {
|
||||
REQUIRE(v[0] == 1);
|
||||
}
|
||||
|
||||
THEN("Adding the elements again produces the same result again") {
|
||||
v.push_back(2);
|
||||
v.push_back(3);
|
||||
v.push_back(0);
|
||||
v.push_back(0);
|
||||
|
||||
bool equals = v == target;
|
||||
REQUIRE(equals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user