Files
RedBear-OS/local/recipes/kde/kwin/source/autotests/test_region.cpp
T

649 lines
24 KiB
C++

/*
SPDX-FileCopyrightText: 2025 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <QTest>
#include "core/region.h"
using namespace KWin;
template<typename T>
static constexpr int bitCount()
{
return sizeof(T) * 8;
}
static int xyToPow2(int x, int y, int stride)
{
return std::pow(2, y * stride + x);
}
static QMap<int, Rect> enumerateRects(const QSize &gridSize, const QSize &unit = QSize(5, 5))
{
Q_ASSERT(gridSize.width() * gridSize.height() <= bitCount<int>());
QList<int> sumAreaTable;
sumAreaTable.resize((gridSize.width() + 1) * (gridSize.height() + 1));
const int satStride = gridSize.width() + 1;
for (int x = 0; x <= gridSize.width(); ++x) {
sumAreaTable[x] = 0;
}
for (int y = 0; y < gridSize.height(); ++y) {
sumAreaTable[(y + 1) * satStride] = 0;
for (int x = 0; x < gridSize.width(); ++x) {
sumAreaTable[(y + 1) * satStride + x + 1] = sumAreaTable[(y + 1) * satStride + x]
- sumAreaTable[y * satStride + x] + sumAreaTable[y * satStride + x + 1] + xyToPow2(x, y, gridSize.width());
}
}
QMap<int, Rect> rects;
rects.insert(0, Rect());
for (int y1 = 0; y1 < gridSize.height(); ++y1) {
for (int y2 = y1 + 1; y2 <= gridSize.height(); ++y2) {
for (int x1 = 0; x1 < gridSize.width(); ++x1) {
for (int x2 = x1 + 1; x2 <= gridSize.width(); ++x2) {
const int a = y1 * satStride + x1;
const int b = y1 * satStride + x2;
const int c = y2 * satStride + x1;
const int d = y2 * satStride + x2;
const int variant = sumAreaTable[d] + sumAreaTable[a] - sumAreaTable[b] - sumAreaTable[c];
rects.insert(variant, Rect(QPoint(x1 * unit.width(), y1 * unit.height()), QPoint(x2 * unit.width(), y2 * unit.height())));
}
}
}
}
return rects;
}
static int coalesce(QList<Rect> &rects, int previousStart, int currentStart)
{
const int previousCount = currentStart - previousStart;
const int currentCount = rects.size() - currentStart;
if (!currentCount || previousCount != currentCount) {
return currentStart;
}
if (rects[previousStart].bottom() != rects[currentStart].top()) {
return currentStart;
}
for (int i = 0; i < currentCount; ++i) {
const Rect &a = rects[previousStart + i];
const Rect &b = rects[currentStart + i];
if (a.left() != b.left() || a.right() != b.right()) {
return currentStart;
}
}
const int currentBottom = rects[currentStart].bottom();
for (int i = 0; i < previousCount; ++i) {
rects[previousStart + i].setBottom(currentBottom);
}
rects.remove(currentStart, currentCount);
return previousStart;
}
/**
* Returns a region that corresponds to the pattern indicated by the @a bits argument.
*
* The regions are sampled from a two dimensional grid of size @a xSize by @a ySize. For example,
* consider a 3x3 grid:
*
* a b c
* d e f
* g h i
*
* Every item in the grid has a bit assigned to it, "a" is assigned to bit 0, "b" is assigned to
* bit 1, and so on. Then numbers between 0 and 2 ^ (xSize * ySize) describe all possible combinations
* of rectangles that can be used to construct a region.
*
* Also note that bit operations such as OR, XOR, and AND on bit patterns directly map to the
* corresponding region operations.
*/
static Region bitsToRegion(int bits, const QSize &gridSize, const QSize &unit = QSize(5, 5))
{
QList<Rect> rects;
rects.reserve(gridSize.width() * gridSize.height());
int current = 0;
for (int i = 0; i < gridSize.height(); ++i) {
std::optional<Rect> currentRect;
const int previous = current;
current = rects.size();
for (int j = 0; j < gridSize.width(); ++j) {
const int bitIndex = i * gridSize.width() + j;
const int bitValue = bits & (1 << bitIndex);
if (bitValue) {
if (currentRect) {
currentRect->setRight((j + 1) * unit.width());
} else {
currentRect = Rect(j * unit.width(), i * unit.height(), unit.width(), unit.height());
}
} else if (currentRect) {
rects.append(*currentRect);
currentRect = std::nullopt;
}
}
if (currentRect) {
rects.append(*currentRect);
}
current = coalesce(rects, previous, current);
}
return Region::fromSortedRects(rects);
}
static QList<Region> enumerateRegions(const QSize &gridSize, const QSize &unit = QSize(5, 5))
{
Q_ASSERT(gridSize.width() * gridSize.height() <= bitCount<int>());
const int maxVariations = std::pow(2, gridSize.width() * gridSize.height());
QList<Region> regions;
regions.reserve(maxVariations);
for (int i = 0; i < maxVariations; ++i) {
regions.append(bitsToRegion(i, gridSize, unit));
}
return regions;
}
static QSize testGridSize()
{
const QString text = qEnvironmentVariable("KWIN_TEST_REGION_GRID_SIZE");
if (text.isEmpty()) {
return QSize(3, 3);
}
const qsizetype x = text.indexOf('x');
Q_ASSERT(x != -1);
return QSize(text.left(x).toInt(), text.mid(x + 1).toInt());
}
class TestRegion : public QObject
{
Q_OBJECT
public:
TestRegion() = default;
private Q_SLOTS:
void equals_data();
void equals();
void notEquals_data();
void notEquals();
void empty_data();
void empty();
void boundingRect_data();
void boundingRect();
void containsRect();
void containsPoint_data();
void containsPoint();
void intersectsRect();
void intersectsRegion();
void united();
void unitedRect();
void subtracted();
void subtractedRect();
void xored();
void xoredRect();
void intersected();
void intersectedRect();
void translated_data();
void translated();
void scaledAndRoundedOut_data();
void scaledAndRoundedOut();
void fromSortedRects();
void fromUnsortedRects();
void fromRectsSortedByY();
void fromAndToQRegion_data();
void fromAndToQRegion();
private:
const QSize gridSize = testGridSize();
const QList<Region> m_regions = enumerateRegions(gridSize);
const QMap<int, Rect> m_rects = enumerateRects(gridSize);
};
void TestRegion::equals_data()
{
QTest::addColumn<Region>("region1");
QTest::addColumn<Region>("region2");
QTest::addColumn<bool>("expected");
QTest::addRow("default and default") << Region() << Region() << true;
QTest::addRow("(1,2 3x4) and default") << Region(Rect(1, 2, 3, 4)) << Region() << false;
QTest::addRow("(1,2 3x4) and (1,2 3x4)") << Region(Rect(1, 2, 3, 4)) << Region(Rect(1, 2, 3, 4)) << true;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and (1,2 3x4)") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << Region(Rect(1, 2, 3, 4)) << false;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and (5,6 7x8)") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << Region(Rect(5, 6, 7, 8)) << false;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and [(1,2 3x4), (5,6 7x8)]") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << true;
}
void TestRegion::equals()
{
QFETCH(Region, region1);
QFETCH(Region, region2);
QFETCH(bool, expected);
QCOMPARE(region1 == region2, expected);
QCOMPARE(region2 == region1, expected);
}
void TestRegion::notEquals_data()
{
QTest::addColumn<Region>("region1");
QTest::addColumn<Region>("region2");
QTest::addColumn<bool>("expected");
QTest::addRow("default and default") << Region() << Region() << false;
QTest::addRow("(1,2 3x4) and default") << Region(Rect(1, 2, 3, 4)) << Region() << true;
QTest::addRow("(1,2 3x4) and (1,2 3x4)") << Region(Rect(1, 2, 3, 4)) << Region(Rect(1, 2, 3, 4)) << false;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and (1,2 3x4)") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << Region(Rect(1, 2, 3, 4)) << true;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and (5,6 7x8)") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << Region(Rect(5, 6, 7, 8)) << true;
QTest::addRow("[(1,2 3x4), (5,6 7x8)] and [(1,2 3x4), (5,6 7x8)]") << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << (Region(Rect(1, 2, 3, 4)) | Region(Rect(5, 6, 7, 8))) << false;
}
void TestRegion::notEquals()
{
QFETCH(Region, region1);
QFETCH(Region, region2);
QFETCH(bool, expected);
QCOMPARE(region1 != region2, expected);
QCOMPARE(region2 != region1, expected);
}
void TestRegion::empty_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<bool>("empty");
QTest::addRow("default") << Region() << true;
QTest::addRow("0,0 0x0") << Region(0, 0, 0, 0) << true;
QTest::addRow("0,0 1x0") << Region(0, 0, 1, 0) << true;
QTest::addRow("0,0 0x1") << Region(0, 0, 0, 1) << true;
QTest::addRow("0,0 1x1") << Region(0, 0, 1, 1) << false;
}
void TestRegion::empty()
{
QFETCH(Region, region);
QTEST(region.isEmpty(), "empty");
}
void TestRegion::boundingRect_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<Rect>("boundingRect");
QTest::addRow("default") << Region() << Rect();
QTest::addRow("(1,2 0x0)") << Region(1, 2, 0, 0) << Rect(1, 2, 0, 0);
QTest::addRow("(1,2 3x4)") << Region(1, 2, 3, 4) << Rect(1, 2, 3, 4);
QTest::addRow("[(1,2 3x4), (5,6 7x8)]") << (Region(1, 2, 3, 4) | Region(5, 6, 7, 8)) << Rect(1, 2, 11, 12);
}
void TestRegion::boundingRect()
{
QFETCH(Region, region);
QTEST(region.boundingRect(), "boundingRect");
}
void TestRegion::containsRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
QCOMPARE(m_regions[i].contains(rect), j && (i & j) == j);
}
}
}
void TestRegion::containsPoint_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<QPoint>("point");
QTest::addColumn<bool>("contains");
QTest::addRow("empty region contains 0,0") << Region() << QPoint(0, 0) << false;
QTest::addRow("empty region contains 1,1") << Region() << QPoint(1, 1) << false;
const Region simpleRegion = Region(0, 0, 5, 5);
{
QTest::addRow("above the simple region") << simpleRegion << QPoint(0, -1) << false;
QTest::addRow("below the simple region") << simpleRegion << QPoint(0, 6) << false;
QTest::addRow("to the left of the simple region") << simpleRegion << QPoint(-1, 0) << false;
QTest::addRow("to the right of the simple region") << simpleRegion << QPoint(6, 0) << false;
QTest::addRow("at the top edge of the simple region") << simpleRegion << QPoint(2, 0) << true;
QTest::addRow("at the bottom edge of the simple region") << simpleRegion << QPoint(2, 5) << false;
QTest::addRow("at the left edge of the simple region") << simpleRegion << QPoint(0, 2) << true;
QTest::addRow("at the right edge of the simple region") << simpleRegion << QPoint(5, 2) << false;
QTest::addRow("inside the simple region") << simpleRegion << QPoint(2, 2) << true;
}
const Region complexRegion = Region(0, 0, 10, 6) | Region(20, 0, 10, 6) | Region(0, 12, 10, 6) | Region(20, 12, 10, 6);
{
QTest::addRow("above the top-left rect in the complex region") << complexRegion << QPoint(5, -1) << false;
QTest::addRow("below the top-left rect in the complex region") << complexRegion << QPoint(5, 7) << false;
QTest::addRow("to the left of the top-left rect in the complex region") << complexRegion << QPoint(-1, 3) << false;
QTest::addRow("to the right of the top-left rect in the complex region") << complexRegion << QPoint(11, 3) << false;
QTest::addRow("at the top edge of the top-left rect in the complex region") << complexRegion << QPoint(5, 0) << true;
QTest::addRow("at the bottom edge of the top-left rect in the complex region") << complexRegion << QPoint(5, 6) << false;
QTest::addRow("at the left edge of the top-left rect in the complex region") << complexRegion << QPoint(0, 3) << true;
QTest::addRow("at the right edge of the top-left rect in the complex region") << complexRegion << QPoint(10, 3) << false;
QTest::addRow("inside the top-left rect in the complex region") << complexRegion << QPoint(5, 3) << true;
}
{
QTest::addRow("above the top-right rect in the complex region") << complexRegion << QPoint(25, -1) << false;
QTest::addRow("below the top-right rect in the complex region") << complexRegion << QPoint(25, 7) << false;
QTest::addRow("to the left of the top-right rect in the complex region") << complexRegion << QPoint(19, 3) << false;
QTest::addRow("to the right of the top-right rect in the complex region") << complexRegion << QPoint(31, 3) << false;
QTest::addRow("at the top edge of the top-right rect in the complex region") << complexRegion << QPoint(25, 0) << true;
QTest::addRow("at the bottom edge of the top-right rect in the complex region") << complexRegion << QPoint(25, 6) << false;
QTest::addRow("at the left edge of the top-right rect in the complex region") << complexRegion << QPoint(20, 3) << true;
QTest::addRow("at the right edge of the top-right rect in the complex region") << complexRegion << QPoint(30, 3) << false;
QTest::addRow("inside the top-right rect in the complex region") << complexRegion << QPoint(25, 3) << true;
}
{
QTest::addRow("above the bottom-left rect in the complex region") << complexRegion << QPoint(5, 11) << false;
QTest::addRow("below the bottom-left rect in the complex region") << complexRegion << QPoint(5, 19) << false;
QTest::addRow("to the left of the bottom-left rect in the complex region") << complexRegion << QPoint(-1, 15) << false;
QTest::addRow("to the right of the bottom-left rect in the complex region") << complexRegion << QPoint(11, 15) << false;
QTest::addRow("at the top edge of the bottom-left rect in the complex region") << complexRegion << QPoint(5, 12) << true;
QTest::addRow("at the bottom edge of the bottom-left rect in the complex region") << complexRegion << QPoint(5, 18) << false;
QTest::addRow("at the left edge of the bottom-left rect in the complex region") << complexRegion << QPoint(0, 15) << true;
QTest::addRow("at the right edge of the bottom-left rect in the complex region") << complexRegion << QPoint(10, 15) << false;
QTest::addRow("inside the bottom-left rect in the complex region") << complexRegion << QPoint(5, 15) << true;
}
{
QTest::addRow("above the bottom-right rect in the complex region") << complexRegion << QPoint(25, 11) << false;
QTest::addRow("below the bottom-right rect in the complex region") << complexRegion << QPoint(25, 19) << false;
QTest::addRow("to the left of the bottom-right rect in the complex region") << complexRegion << QPoint(19, 15) << false;
QTest::addRow("to the right of the bottom-right rect in the complex region") << complexRegion << QPoint(31, 15) << false;
QTest::addRow("at the top edge of the bottom-right rect in the complex region") << complexRegion << QPoint(25, 12) << true;
QTest::addRow("at the bottom edge of the bottom-right rect in the complex region") << complexRegion << QPoint(25, 18) << false;
QTest::addRow("at the left edge of the bottom-right rect in the complex region") << complexRegion << QPoint(20, 15) << true;
QTest::addRow("at the right edge of the bottom-right rect in the complex region") << complexRegion << QPoint(30, 15) << false;
QTest::addRow("inside the bottom-right rect in the complex region") << complexRegion << QPoint(25, 15) << true;
}
QTest::addRow("above the gap between top-left and top-right rects in the complex region") << complexRegion << QPoint(15, -1) << false;
QTest::addRow("below the gap between bottom-left and bottom-right rects in the complex region") << complexRegion << QPoint(15, 19) << false;
QTest::addRow("to the left of the gap between top-left and bottom-left rects in the complex region") << complexRegion << QPoint(-1, 9) << false;
QTest::addRow("to the right of the gap between top-right and bottom-right rects in the complex region") << complexRegion << QPoint(31, 9) << false;
QTest::addRow("inside gap between four rects in the complex region") << complexRegion << QPoint(15, 9) << false;
}
void TestRegion::containsPoint()
{
QFETCH(Region, region);
QFETCH(QPoint, point);
QTEST(region.contains(point), "contains");
}
void TestRegion::intersectsRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
QCOMPARE(m_regions[i].intersects(rect), bool(i & j));
}
}
}
void TestRegion::intersectsRegion()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j <= i; ++j) {
QCOMPARE(m_regions[i].intersects(m_regions[j]), bool(i & j));
QCOMPARE(m_regions[j].intersects(m_regions[i]), bool(i & j));
}
}
}
void TestRegion::united()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j <= i; ++j) {
const Region expected = m_regions[i | j];
QCOMPARE(m_regions[i].united(m_regions[j]), expected);
QCOMPARE(m_regions[j].united(m_regions[i]), expected);
}
}
}
void TestRegion::unitedRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
const Region expected = m_regions[i | j];
QCOMPARE(m_regions[i].united(rect), expected);
}
}
}
void TestRegion::subtracted()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j <= i; ++j) {
QCOMPARE(m_regions[i].subtracted(m_regions[j]), m_regions[i & ~j]);
QCOMPARE(m_regions[j].subtracted(m_regions[i]), m_regions[j & ~i]);
}
}
}
void TestRegion::subtractedRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
const Region expected = m_regions[i & ~j];
QCOMPARE(m_regions[i].subtracted(rect), expected);
}
}
}
void TestRegion::xored()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j <= i; ++j) {
const Region expected = m_regions[i ^ j];
QCOMPARE(m_regions[i].xored(m_regions[j]), expected);
QCOMPARE(m_regions[j].xored(m_regions[i]), expected);
}
}
}
void TestRegion::xoredRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
const Region expected = m_regions[i ^ j];
QCOMPARE(m_regions[i].xored(rect), expected);
}
}
}
void TestRegion::intersected()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j <= i; ++j) {
const Region expected = m_regions[i & j];
QCOMPARE(m_regions[i].intersected(m_regions[j]), expected);
QCOMPARE(m_regions[j].intersected(m_regions[i]), expected);
}
}
}
void TestRegion::intersectedRect()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (const auto &[j, rect] : m_rects.asKeyValueRange()) {
const Region expected = m_regions[i & j];
QCOMPARE(m_regions[i].intersected(rect), expected);
}
}
}
void TestRegion::translated_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<QPoint>("translation");
QTest::addColumn<Region>("expected");
QTest::addRow("empty") << Region() << QPoint(1, 2) << Region();
QTest::addRow("simple") << Region(1, 2, 3, 4) << QPoint(10, 11) << Region(11, 13, 3, 4);
QTest::addRow("complex") << (Region(1, 2, 3, 4) | Region(5, 6, 7, 8)) << QPoint(10, 11) << (Region(11, 13, 3, 4) | Region(15, 17, 7, 8));
}
void TestRegion::translated()
{
QFETCH(Region, region);
QFETCH(QPoint, translation);
{
Region translated = region;
translated.translate(translation.x(), translation.y());
QTEST(translated, "expected");
}
{
Region translated = region;
translated.translate(translation);
QTEST(translated, "expected");
}
{
const Region translated = region.translated(translation.x(), translation.y());
QTEST(translated, "expected");
}
{
const Region translated = region.translated(translation);
QTEST(translated, "expected");
}
}
void TestRegion::scaledAndRoundedOut_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<qreal>("scale");
QTest::addColumn<Region>("expected");
QTest::addRow("empty @ 1.0") << Region() << 1.0 << Region();
QTest::addRow("empty @ 1.25") << Region() << 1.25 << Region();
QTest::addRow("empty @ 1.5") << Region() << 1.5 << Region();
QTest::addRow("empty @ 1.75") << Region() << 1.75 << Region();
QTest::addRow("empty @ 2.0") << Region() << 2.0 << Region();
const Region simple = Region(1, 2, 3, 4);
QTest::addRow("simple @ 1.0") << simple << 1.0 << simple;
QTest::addRow("simple @ 1.25") << simple << 1.25 << Region(1, 2, 4, 6);
QTest::addRow("simple @ 1.5") << simple << 1.5 << Region(1, 3, 5, 6);
QTest::addRow("simple @ 1.75") << simple << 1.75 << Region(1, 3, 6, 8);
QTest::addRow("simple @ 2.0") << simple << 2.0 << Region(2, 4, 6, 8);
const Region complex = Region(1, 2, 3, 4) | Region(5, 6, 7, 8);
QTest::addRow("complex @ 1.0") << complex << 1.0 << complex;
QTest::addRow("complex @ 1.25") << complex << 1.25 << (Region(1, 2, 4, 6) | Region(6, 7, 9, 11));
QTest::addRow("complex @ 1.5") << complex << 1.5 << (Region(1, 3, 5, 6) | Region(7, 9, 11, 12));
QTest::addRow("complex @ 1.75") << complex << 1.75 << (Region(1, 3, 6, 8) | Region(8, 10, 13, 15));
QTest::addRow("complex @ 2.0") << complex << 2.0 << (Region(2, 4, 6, 8) | Region(10, 12, 14, 16));
}
void TestRegion::scaledAndRoundedOut()
{
QFETCH(Region, region);
QFETCH(qreal, scale);
QTEST(region.scaledAndRoundedOut(scale), "expected");
}
template<typename T>
static QList<T> spanToList(const QSpan<const T> &span)
{
QList<T> list;
list.assign(span.begin(), span.end());
return list;
}
void TestRegion::fromSortedRects()
{
for (int i = 0; i < m_regions.size(); ++i) {
QCOMPARE(Region::fromSortedRects(spanToList(m_regions[i].rects())), m_regions[i]);
}
}
void TestRegion::fromUnsortedRects()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j < m_regions.size(); ++j) {
const QList<Rect> rects = spanToList(m_regions[i].rects()) + spanToList(m_regions[j].rects());
QCOMPARE(Region::fromUnsortedRects(rects), m_regions[i | j]);
}
}
}
void TestRegion::fromRectsSortedByY()
{
for (int i = 0; i < m_regions.size(); ++i) {
for (int j = 0; j < m_regions.size(); ++j) {
QList<Rect> rects = spanToList(m_regions[i].rects()) + spanToList(m_regions[j].rects());
std::sort(rects.begin(), rects.end(), [](const Rect &a, const Rect &b) {
return a.top() < b.top();
});
QCOMPARE(Region::fromRectsSortedByY(rects), m_regions[i | j]);
}
}
}
void TestRegion::fromAndToQRegion_data()
{
QTest::addColumn<Region>("region");
QTest::addColumn<QRegion>("qtRegion");
QTest::addRow("empty") << Region() << QRegion();
QTest::addRow("simple") << Region(1, 2, 3, 4) << QRegion(1, 2, 3, 4);
QTest::addRow("complex") << (Region(1, 2, 3, 4) | Region(5, 6, 7, 8)) << (QRegion(1, 2, 3, 4) | QRegion(5, 6, 7, 8));
}
void TestRegion::fromAndToQRegion()
{
QFETCH(Region, region);
QFETCH(QRegion, qtRegion);
QCOMPARE(Region(qtRegion), region);
QCOMPARE(QRegion(region), qtRegion);
}
QTEST_MAIN(TestRegion)
#include "test_region.moc"