1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30
31#include <qpoint.h>
32
33class tst_QPointF : public QObject
34{
35 Q_OBJECT
36
37public:
38 tst_QPointF();
39
40private slots:
41 void isNull();
42
43 void manhattanLength_data();
44 void manhattanLength();
45
46 void getSet_data();
47 void getSet();
48
49 void transposed();
50
51 void rx();
52 void ry();
53
54 void operator_add_data();
55 void operator_add();
56
57 void operator_subtract_data();
58 void operator_subtract();
59
60 void operator_multiply_data();
61 void operator_multiply();
62
63 void operator_divide_data();
64 void operator_divide();
65 void division();
66
67 void dotProduct_data();
68 void dotProduct();
69
70 void operator_unary_plus_data();
71 void operator_unary_plus();
72
73 void operator_unary_minus_data();
74 void operator_unary_minus();
75
76 void operator_eq_data();
77 void operator_eq();
78
79 void toPoint_data();
80 void toPoint();
81
82 void compare();
83
84#ifndef QT_NO_DATASTREAM
85 void stream_data();
86 void stream();
87#endif
88
89private:
90 const qreal QREAL_MIN;
91 const qreal QREAL_MAX;
92};
93
94tst_QPointF::tst_QPointF()
95: QREAL_MIN(std::numeric_limits<qreal>::min()),
96QREAL_MAX(std::numeric_limits<qreal>::max())
97{
98}
99
100void tst_QPointF::isNull()
101{
102 QPointF point(0, 0);
103 QVERIFY(point.isNull());
104 ++point.rx();
105 QVERIFY(!point.isNull());
106 point.rx() -= 2;
107 QVERIFY(!point.isNull());
108
109 QPointF nullNegativeZero(qreal(-0.0), qreal(-0.0));
110 QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f);
111 QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f);
112 QVERIFY(nullNegativeZero.isNull());
113}
114
115void tst_QPointF::manhattanLength_data()
116{
117 QTest::addColumn<QPointF>(name: "point");
118 QTest::addColumn<qreal>(name: "expected");
119
120 QTest::newRow(dataTag: "(0, 0)") << QPointF(0, 0) << qreal(0);
121 QTest::newRow(dataTag: "(10, 0)") << QPointF(10, 0) << qreal(10);
122 QTest::newRow(dataTag: "(0, 10)") << QPointF(0, 10) << qreal(10);
123 QTest::newRow(dataTag: "(10, 20)") << QPointF(10, 20) << qreal(30);
124 QTest::newRow(dataTag: "(10.1, 20.2)") << QPointF(10.1, 20.2) << qreal(30.3);
125 QTest::newRow(dataTag: "(-10.1, -20.2)") << QPointF(-10.1, -20.2) << qreal(30.3);
126}
127
128void tst_QPointF::manhattanLength()
129{
130 QFETCH(QPointF, point);
131 QFETCH(qreal, expected);
132
133 QCOMPARE(point.manhattanLength(), expected);
134}
135
136void tst_QPointF::getSet_data()
137{
138 QTest::addColumn<qreal>(name: "r");
139
140 QTest::newRow(dataTag: "0") << qreal(0);
141 QTest::newRow(dataTag: "-1") << qreal(-1);
142 QTest::newRow(dataTag: "1") << qreal(1);
143 QTest::newRow(dataTag: "QREAL_MAX") << qreal(QREAL_MAX);
144 QTest::newRow(dataTag: "QREAL_MIN") << qreal(QREAL_MIN);
145}
146
147void tst_QPointF::getSet()
148{
149 QFETCH(qreal, r);
150
151 QPointF point;
152 point.setX(r);
153 QCOMPARE(point.x(), r);
154
155 point.setY(r);
156 QCOMPARE(point.y(), r);
157}
158
159void tst_QPointF::transposed()
160{
161 QCOMPARE(QPointF(1, 2).transposed(), QPointF(2, 1));
162}
163
164void tst_QPointF::rx()
165{
166 const QPointF originalPoint(-1, 0);
167 QPointF point(originalPoint);
168 ++point.rx();
169 QCOMPARE(point.x(), originalPoint.x() + 1);
170}
171
172void tst_QPointF::ry()
173{
174 const QPointF originalPoint(0, -1);
175 QPointF point(originalPoint);
176 ++point.ry();
177 QCOMPARE(point.y(), originalPoint.y() + 1);
178}
179
180void tst_QPointF::operator_add_data()
181{
182 QTest::addColumn<QPointF>(name: "point1");
183 QTest::addColumn<QPointF>(name: "point2");
184 QTest::addColumn<QPointF>(name: "expected");
185
186 QTest::newRow(dataTag: "(0, 0) + (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << QPointF(0, 0);
187 QTest::newRow(dataTag: "(0, 9) + (1, 0)") << QPointF(0, 9) << QPointF(1, 0) << QPointF(1, 9);
188 QTest::newRow(dataTag: "(QREAL_MIN, 0) + (1, 0)") << QPointF(QREAL_MIN, 0) << QPointF(1, 0) << QPointF(QREAL_MIN + 1, 0);
189 QTest::newRow(dataTag: "(QREAL_MAX, 0) + (-1, 0)") << QPointF(QREAL_MAX, 0) << QPointF(-1, 0) << QPointF(QREAL_MAX - 1, 0);
190}
191
192void tst_QPointF::operator_add()
193{
194 QFETCH(QPointF, point1);
195 QFETCH(QPointF, point2);
196 QFETCH(QPointF, expected);
197
198 QCOMPARE(point1 + point2, expected);
199 point1 += point2;
200 QCOMPARE(point1, expected);
201}
202
203void tst_QPointF::operator_subtract_data()
204{
205 QTest::addColumn<QPointF>(name: "point1");
206 QTest::addColumn<QPointF>(name: "point2");
207 QTest::addColumn<QPointF>(name: "expected");
208
209 QTest::newRow(dataTag: "(0, 0) - (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << QPointF(0, 0);
210 QTest::newRow(dataTag: "(0, 9) - (1, 0)") << QPointF(0, 9) << QPointF(1, 0) << QPointF(-1, 9);
211 QTest::newRow(dataTag: "(QREAL_MAX, 0) - (1, 0)") << QPointF(QREAL_MAX, 0) << QPointF(1, 0) << QPointF(QREAL_MAX - 1, 0);
212 QTest::newRow(dataTag: "(QREAL_MIN, 0) - (-1, 0)") << QPointF(QREAL_MIN, 0) << QPointF(-1, 0) << QPointF(QREAL_MIN - -1, 0);
213}
214
215void tst_QPointF::operator_subtract()
216{
217 QFETCH(QPointF, point1);
218 QFETCH(QPointF, point2);
219 QFETCH(QPointF, expected);
220
221 QCOMPARE(point1 - point2, expected);
222 point1 -= point2;
223 QCOMPARE(point1, expected);
224}
225
226void tst_QPointF::operator_multiply_data()
227{
228 QTest::addColumn<QPointF>(name: "point");
229 QTest::addColumn<qreal>(name: "factor");
230 QTest::addColumn<QPointF>(name: "expected");
231
232 QTest::newRow(dataTag: "(0, 0) * 0.0") << QPointF(0, 0) << qreal(0) << QPointF(0, 0);
233 QTest::newRow(dataTag: "(QREAL_MIN, 1) * 0.5") << QPointF(QREAL_MIN, 1) << qreal(0.5) << QPointF(QREAL_MIN * 0.5, 0.5);
234 QTest::newRow(dataTag: "(QREAL_MAX, 2) * 0.5") << QPointF(QREAL_MAX, 2) << qreal(0.5) << QPointF(QREAL_MAX * 0.5, 1);
235}
236
237void tst_QPointF::operator_multiply()
238{
239 QFETCH(QPointF, point);
240 QFETCH(qreal, factor);
241 QFETCH(QPointF, expected);
242
243 QCOMPARE(point * factor, expected);
244 // Test with reversed argument version.
245 QCOMPARE(factor * point, expected);
246 point *= factor;
247 QCOMPARE(point, expected);
248}
249
250void tst_QPointF::operator_divide_data()
251{
252 QTest::addColumn<QPointF>(name: "point");
253 QTest::addColumn<qreal>(name: "divisor");
254 QTest::addColumn<QPointF>(name: "expected");
255
256 QTest::newRow(dataTag: "(0, 0) / 1") << QPointF(0, 0) << qreal(1) << QPointF(0, 0);
257 QTest::newRow(dataTag: "(0, 9) / 2") << QPointF(0, 9) << qreal(2) << QPointF(0, 4.5);
258 QTest::newRow(dataTag: "(QREAL_MAX, 0) / 2") << QPointF(QREAL_MAX, 0) << qreal(2) << QPointF(QREAL_MAX / qreal(2), 0);
259 QTest::newRow(dataTag: "(QREAL_MIN, 0) / -1.5") << QPointF(QREAL_MIN, 0) << qreal(-1.5) << QPointF(QREAL_MIN / qreal(-1.5), 0);
260}
261
262void tst_QPointF::operator_divide()
263{
264 QFETCH(QPointF, point);
265 QFETCH(qreal, divisor);
266 QFETCH(QPointF, expected);
267
268 QCOMPARE(point / divisor, expected);
269 point /= divisor;
270 QCOMPARE(point, expected);
271}
272
273static inline qreal dot(const QPointF &a, const QPointF &b)
274{
275 return a.x() * b.x() + a.y() * b.y();
276}
277
278void tst_QPointF::division()
279{
280 {
281 QPointF p(1e-14, 1e-14);
282 p = p / std::sqrt(x: dot(a: p, b: p));
283 QCOMPARE(dot(p, p), qreal(1.0));
284 }
285 {
286 QPointF p(1e-14, 1e-14);
287 p /= std::sqrt(x: dot(a: p, b: p));
288 QCOMPARE(dot(p, p), qreal(1.0));
289 }
290}
291
292void tst_QPointF::dotProduct_data()
293{
294 QTest::addColumn<QPointF>(name: "point1");
295 QTest::addColumn<QPointF>(name: "point2");
296 QTest::addColumn<qreal>(name: "expected");
297
298 QTest::newRow(dataTag: "(0, 0) dot (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << qreal(0);
299 QTest::newRow(dataTag: "(10, 0) dot (0, 10)") << QPointF(10, 0) << QPointF(0, 10)<< qreal(0);
300 QTest::newRow(dataTag: "(0, 10) dot (10, 0)") << QPointF(0, 10) << QPointF(10, 0) << qreal(0);
301 QTest::newRow(dataTag: "(10, 20) dot (-10, -20)") << QPointF(10, 20) << QPointF(-10, -20) << qreal(-500);
302 QTest::newRow(dataTag: "(10.1, 20.2) dot (-10.1, -20.2)") << QPointF(10.1, 20.2) << QPointF(-10.1, -20.2) << qreal(-510.05);
303 QTest::newRow(dataTag: "(-10.1, -20.2) dot (10.1, 20.2)") << QPointF(-10.1, -20.2) << QPointF(10.1, 20.2) << qreal(-510.05);
304}
305
306void tst_QPointF::dotProduct()
307{
308 QFETCH(QPointF, point1);
309 QFETCH(QPointF, point2);
310 QFETCH(qreal, expected);
311
312 QCOMPARE(QPointF::dotProduct(point1, point2), expected);
313}
314
315void tst_QPointF::operator_unary_plus_data()
316{
317 operator_unary_minus_data();
318}
319
320void tst_QPointF::operator_unary_plus()
321{
322 QFETCH(QPointF, point);
323 // Should be a NOOP.
324 QCOMPARE(+point, point);
325}
326
327void tst_QPointF::operator_unary_minus_data()
328{
329 QTest::addColumn<QPointF>(name: "point");
330 QTest::addColumn<QPointF>(name: "expected");
331
332 QTest::newRow(dataTag: "-(0, 0)") << QPointF(0, 0) << QPointF(0, 0);
333 QTest::newRow(dataTag: "-(-1, 0)") << QPointF(-1, 0) << QPointF(1, 0);
334 QTest::newRow(dataTag: "-(0, -1)") << QPointF(0, -1) << QPointF(0, 1);
335 QTest::newRow(dataTag: "-(1.2345, 0)") << QPointF(1.2345, 0) << QPointF(-1.2345, 0);
336 QTest::newRow(dataTag: "-(-QREAL_MAX, QREAL_MAX)")
337 << QPointF(-QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, -QREAL_MAX);
338}
339
340void tst_QPointF::operator_unary_minus()
341{
342 QFETCH(QPointF, point);
343 QFETCH(QPointF, expected);
344
345 QCOMPARE(-point, expected);
346}
347
348void tst_QPointF::operator_eq_data()
349{
350 QTest::addColumn<QPointF>(name: "point1");
351 QTest::addColumn<QPointF>(name: "point2");
352 QTest::addColumn<bool>(name: "expectEqual");
353
354 QTest::newRow(dataTag: "(0, 0) == (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << true;
355 QTest::newRow(dataTag: "(-1, 0) == (-1, 0)") << QPointF(-1, 0) << QPointF(-1, 0) << true;
356 QTest::newRow(dataTag: "(-1, 0) != (0, 0)") << QPointF(-1, 0) << QPointF(0, 0) << false;
357 QTest::newRow(dataTag: "(-1, 0) != (0, -1)") << QPointF(-1, 0) << QPointF(0, -1) << false;
358 QTest::newRow(dataTag: "(-1.125, 0.25) == (-1.125, 0.25)") << QPointF(-1.125, 0.25) << QPointF(-1.125, 0.25) << true;
359 QTest::newRow(dataTag: "(QREAL_MIN, QREAL_MIN) == (QREAL_MIN, QREAL_MIN)")
360 << QPointF(QREAL_MIN, QREAL_MIN) << QPointF(QREAL_MIN, QREAL_MIN) << true;
361 QTest::newRow(dataTag: "(QREAL_MAX, QREAL_MAX) == (QREAL_MAX, QREAL_MAX)")
362 << QPointF(QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, QREAL_MAX) << true;
363}
364
365void tst_QPointF::operator_eq()
366{
367 QFETCH(QPointF, point1);
368 QFETCH(QPointF, point2);
369 QFETCH(bool, expectEqual);
370
371 bool equal = point1 == point2;
372 QCOMPARE(equal, expectEqual);
373 bool notEqual = point1 != point2;
374 QCOMPARE(notEqual, !expectEqual);
375}
376
377void tst_QPointF::toPoint_data()
378{
379 QTest::addColumn<QPointF>(name: "pointf");
380 QTest::addColumn<QPoint>(name: "expected");
381
382 QTest::newRow(dataTag: "(0.0, 0.0) ==> (0, 0)") << QPointF(0, 0) << QPoint(0, 0);
383 QTest::newRow(dataTag: "(0.5, 0.5) ==> (1, 1)") << QPointF(0.5, 0.5) << QPoint(1, 1);
384 QTest::newRow(dataTag: "(-0.5, -0.5) ==> (0, 0)") << QPointF(-0.5, -0.5) << QPoint(0, 0);
385}
386
387void tst_QPointF::toPoint()
388{
389 QFETCH(QPointF, pointf);
390 QFETCH(QPoint, expected);
391
392 QCOMPARE(pointf.toPoint(), expected);
393}
394
395#ifndef QT_NO_DATASTREAM
396void tst_QPointF::stream_data()
397{
398 QTest::addColumn<QPointF>(name: "point");
399
400 QTest::newRow(dataTag: "(0, 0.5)") << QPointF(0, 0.5);
401 QTest::newRow(dataTag: "(-1, 1)") << QPointF(-1, 1);
402 QTest::newRow(dataTag: "(1, -1)") << QPointF(1, -1);
403 QTest::newRow(dataTag: "(INT_MIN, INT_MAX)") << QPointF(INT_MIN, INT_MAX);
404}
405
406void tst_QPointF::stream()
407{
408 QFETCH(QPointF, point);
409
410 QBuffer tmp;
411 QVERIFY(tmp.open(QBuffer::ReadWrite));
412 QDataStream stream(&tmp);
413 // Ensure that stream returned is the same stream we inserted into.
414 QDataStream& insertionStreamRef(stream << point);
415 QVERIFY(&insertionStreamRef == &stream);
416
417 tmp.seek(off: 0);
418 QPointF pointFromStream;
419 QDataStream& extractionStreamRef(stream >> pointFromStream);
420 QVERIFY(&extractionStreamRef == &stream);
421 QCOMPARE(pointFromStream, point);
422}
423#endif
424
425void tst_QPointF::compare()
426{
427 // First test we can scale and maintain difference.
428 QPointF p1(2.0, 2.0);
429 QPointF p2(3.0, 3.0);
430
431 QVERIFY(p1 != p2);
432
433 p1 /= 1e5;
434 p2 /= 1e5;
435
436 QVERIFY(!(p1 == p2));
437
438 p1 /= 1e5;
439 p2 /= 1e5;
440
441 QVERIFY(p1 != p2);
442
443 p1 /= 1e5;
444 p2 /= 1e5;
445
446 QVERIFY(!(p1 == p2));
447
448 p1 /= 2;
449 p2 /= 3;
450
451 QVERIFY(p1 == p2);
452
453 // Test we can compare with zero after inexact math
454 QPointF p3(3.0, 3.0);
455 p3 *= 0.1;
456 p3 /= 3;
457 p3 -= QPointF(0.1, 0.1);
458
459 QVERIFY(p3 == QPointF());
460
461 // Test we can compare one dimension with hard zero
462 QVERIFY(QPointF(1.9543e-14, -32.0) == QPointF(0.0, -32.0));
463}
464
465QTEST_MAIN(tst_QPointF)
466#include "tst_qpointf.moc"
467

source code of qtbase/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp