terminal/src/til/ut_til/SomeTests.cpp
Michael Niksa f5ab042939
til::rectangle (#4912)
## Summary of the Pull Request
Introduces convenience type `til::rectangle` which automatically implements our best practices for rectangle-related types and provides automatic conversions in/out of the relevant types.

## PR Checklist
* [x] In support of Differential Rendering #778
* [X] I work here.
* [x] Tests added/passed
* [x] I'm a core contributor.

## Detailed Description of the Pull Request / Additional comments
- Automatically converts in from anything with a Left/Top/Right/Bottom or left/top/right/bottom (Win32 `RECT`)
- Automatically converts Console type `SMALL_RECT` and shifts it from **inclusive** to **exclusive** on instantiation
- Automatically converts out to `SMALL_RECT` (converting back to **inclusive**), `RECT`, or `D2D1_RECT_F`.
- Constructs from bare integers written into source file
- Constructs from a single `til::point` as a 1x1 size rectangle with top-left corner (origin) at that point
- Constructs from a single `til::size` as a WxH size rectangle with top-left corner (origin) at 0,0
- Constructs from a `til::point` and a `til::size` representing the top-left corner and the width by height.
- Constructs from a `til::point` and another `til::point` representing the top-left corner and the **exclusive** bottom-right corner.
- Default constructs to empty
- Uses Chromium numerics for all basic math operations (+, -, *, /)
- Provides equality tests
- Provides `operator bool` to know when it's valid (has an area > 0) and `empty()` to know the contrary
- Accessors for left/top/right/bottom
- Type converting accessors (that use safe conversions and throw) for left/top/right/bottom
- Convenience methods for finding width/height (with Chromium numerics operations) and type-converting templates (with Chromium numerics conversions).
- Accessors for origin (top-left point) and the size/dimensions (as a `til::size`).
- Intersect operation on `operator &` to find where two `til::rectangle`s overlap, returned as a `til::rectangle`.
- Union operation on `operator |` to find the total area covered by two `til::rectangles`, returned as a `til::rectangle`.
- Subtract operation on `operator -` to find the area remaining after one `til::rectangle` is removed from another, returned as a `til::some<til::rectangle, 4>`.
- TAEF/WEX Output and Comparators so they will print very nicely with `VERIFY` and `Log` macros in our testing suite.
- Additional comparators, TAEF/WEX output, and tests written on `til::some` to support the Subtract operation.
- A natvis

## Validation Steps Performed
- See automated tests of functionality.
2020-03-14 17:27:47 +00:00

307 lines
7.2 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
using namespace WEX::Common;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
class SomeTests
{
TEST_CLASS(SomeTests);
TEST_METHOD(Construct)
{
Log::Comment(L"Default Constructor");
til::some<int, 2> s;
Log::Comment(L"Valid Initializer List Constructor");
til::some<int, 2> t{ 1 };
til::some<int, 2> u{ 1, 2 };
Log::Comment(L"Invalid Initializer List Constructor");
auto f = []() {
til::some<int, 2> v{ 1, 2, 3 };
};
VERIFY_THROWS(f(), std::invalid_argument);
}
TEST_METHOD(Equality)
{
til::some<int, 2> a{ 1, 2 };
til::some<int, 2> b{ 1, 2 };
VERIFY_IS_TRUE(a == b);
til::some<int, 2> c{ 3, 2 };
VERIFY_IS_FALSE(a == c);
til::some<int, 2> d{ 2, 3 };
VERIFY_IS_FALSE(a == d);
til::some<int, 2> e{ 1 };
VERIFY_IS_FALSE(a == e);
}
TEST_METHOD(Inequality)
{
til::some<int, 2> a{ 1, 2 };
til::some<int, 2> b{ 1, 2 };
VERIFY_IS_FALSE(a != b);
til::some<int, 2> c{ 3, 2 };
VERIFY_IS_TRUE(a != c);
til::some<int, 2> d{ 2, 3 };
VERIFY_IS_TRUE(a != d);
til::some<int, 2> e{ 1 };
VERIFY_IS_TRUE(a != e);
}
TEST_METHOD(Fill)
{
til::some<int, 4> s;
const auto val = 12;
s.fill(val);
VERIFY_ARE_EQUAL(s.max_size(), s.size());
for (const auto& i : s)
{
VERIFY_ARE_EQUAL(val, i);
}
}
TEST_METHOD(Swap)
{
til::some<int, 4> a;
til::some<int, 4> b;
const auto aVal = 900;
a.fill(900);
const auto bVal = 45;
b.push_back(45);
const auto aSize = a.size();
const auto bSize = b.size();
a.swap(b);
VERIFY_ARE_EQUAL(aSize, b.size());
VERIFY_ARE_EQUAL(bSize, a.size());
VERIFY_ARE_EQUAL(bVal, a[0]);
for (const auto& i : b)
{
VERIFY_ARE_EQUAL(aVal, i);
}
}
TEST_METHOD(Size)
{
til::some<int, 2> c;
VERIFY_ARE_EQUAL(0u, c.size());
c.push_back(3);
VERIFY_ARE_EQUAL(1u, c.size());
c.push_back(12);
VERIFY_ARE_EQUAL(2u, c.size());
c.pop_back();
VERIFY_ARE_EQUAL(1u, c.size());
c.pop_back();
VERIFY_ARE_EQUAL(0u, c.size());
}
TEST_METHOD(MaxSize)
{
til::some<int, 2> c;
VERIFY_ARE_EQUAL(2u, c.max_size());
c.push_back(3);
VERIFY_ARE_EQUAL(2u, c.max_size());
c.push_back(12);
VERIFY_ARE_EQUAL(2u, c.size());
c.pop_back();
VERIFY_ARE_EQUAL(2u, c.max_size());
c.pop_back();
VERIFY_ARE_EQUAL(2u, c.max_size());
}
TEST_METHOD(PushBack)
{
til::some<int, 1> s;
s.push_back(12);
VERIFY_THROWS(s.push_back(12), std::out_of_range);
}
TEST_METHOD(PopBack)
{
til::some<int, 1> s;
VERIFY_THROWS(s.pop_back(), std::out_of_range);
s.push_back(12);
VERIFY_THROWS(s.push_back(12), std::out_of_range);
}
TEST_METHOD(Empty)
{
til::some<int, 2> s;
VERIFY_IS_TRUE(s.empty());
s.push_back(12);
VERIFY_IS_FALSE(s.empty());
s.pop_back();
VERIFY_IS_TRUE(s.empty());
}
TEST_METHOD(Data)
{
til::some<int, 2> s;
const auto one = 1;
const auto two = 2;
s.push_back(one);
s.push_back(two);
auto data = s.data();
VERIFY_ARE_EQUAL(one, *data);
VERIFY_ARE_EQUAL(two, *(data + 1));
}
TEST_METHOD(FrontBack)
{
til::some<int, 2> s;
const auto one = 1;
const auto two = 2;
s.push_back(one);
s.push_back(two);
VERIFY_ARE_EQUAL(one, s.front());
VERIFY_ARE_EQUAL(two, s.back());
}
TEST_METHOD(Indexing)
{
const auto one = 14;
const auto two = 28;
til::some<int, 2> s;
VERIFY_THROWS(s.at(0), std::out_of_range);
VERIFY_THROWS(s.at(1), std::out_of_range);
auto a = s[0];
a = s[1];
s.push_back(one);
VERIFY_ARE_EQUAL(one, s.at(0));
VERIFY_ARE_EQUAL(one, s[0]);
VERIFY_THROWS(s.at(1), std::out_of_range);
a = s[1];
s.push_back(two);
VERIFY_ARE_EQUAL(one, s.at(0));
VERIFY_ARE_EQUAL(one, s[0]);
VERIFY_ARE_EQUAL(two, s.at(1));
VERIFY_ARE_EQUAL(two, s[1]);
s.pop_back();
VERIFY_ARE_EQUAL(one, s.at(0));
VERIFY_ARE_EQUAL(one, s[0]);
VERIFY_THROWS(s.at(1), std::out_of_range);
a = s[1];
s.pop_back();
VERIFY_THROWS(s.at(0), std::out_of_range);
VERIFY_THROWS(s.at(1), std::out_of_range);
a = s[0];
a = s[1];
}
TEST_METHOD(ForwardIter)
{
const int vals[] = { 17, 99 };
const int valLength = ARRAYSIZE(vals);
til::some<int, 2> s;
VERIFY_ARE_EQUAL(s.begin(), s.end());
VERIFY_ARE_EQUAL(s.cbegin(), s.cend());
VERIFY_ARE_EQUAL(s.begin(), s.cbegin());
VERIFY_ARE_EQUAL(s.end(), s.cend());
s.push_back(vals[0]);
s.push_back(vals[1]);
VERIFY_ARE_EQUAL(s.begin() + valLength, s.end());
VERIFY_ARE_EQUAL(s.cbegin() + valLength, s.cend());
auto count = 0;
for (const auto& i : s)
{
VERIFY_ARE_EQUAL(vals[count], i);
++count;
}
VERIFY_ARE_EQUAL(valLength, count);
count = 0;
for (auto i = s.cbegin(); i < s.cend(); ++i)
{
VERIFY_ARE_EQUAL(vals[count], *i);
++count;
}
VERIFY_ARE_EQUAL(valLength, count);
count = 0;
for (auto i = s.begin(); i < s.end(); ++i)
{
VERIFY_ARE_EQUAL(vals[count], *i);
++count;
}
VERIFY_ARE_EQUAL(valLength, count);
}
TEST_METHOD(ReverseIter)
{
const int vals[] = { 17, 99 };
const int valLength = ARRAYSIZE(vals);
til::some<int, 2> s;
VERIFY_ARE_EQUAL(s.rbegin(), s.rend());
VERIFY_ARE_EQUAL(s.crbegin(), s.crend());
VERIFY_ARE_EQUAL(s.rbegin(), s.crbegin());
VERIFY_ARE_EQUAL(s.rend(), s.crend());
s.push_back(vals[0]);
s.push_back(vals[1]);
VERIFY_ARE_EQUAL(s.rbegin() + valLength, s.rend());
VERIFY_ARE_EQUAL(s.crbegin() + valLength, s.crend());
auto count = 0;
for (auto i = s.crbegin(); i < s.crend(); ++i)
{
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
++count;
}
VERIFY_ARE_EQUAL(valLength, count);
count = 0;
for (auto i = s.rbegin(); i < s.rend(); ++i)
{
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
++count;
}
VERIFY_ARE_EQUAL(valLength, count);
}
};