1 /*
2 Copyright (C) 2012 <hanna.et.scott@gmail.com>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18 */
19
20 #include "TestSnapStrategy.h"
21 #include <QPainterPath>
22 #include <QTest>
23 #include "KoSnapStrategy.h"
24 #include "KoPathShape.h"
25 #include "KoSnapProxy.h"
26 #include "KoShapeControllerBase.h"
27 #include "MockShapes.h"
28 #include "KoPathPoint.h"
29 #include "KoViewConverter.h"
30 #include <sdk/tests/kistest.h>
31 //#include <PointProperties.h>
32 #include <KoSnapData.h>
33
testOrthogonalSnap()34 void TestSnapStrategy::testOrthogonalSnap()
35 {
36 //Test case one - expected not to snap
37
38 OrthogonalSnapStrategy toTest;
39 const QPointF paramMousePosition;
40 MockShapeController fakeShapeControllerBase;
41 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase); //the shapeManager() function of this will be called
42 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase); //the call that will be made to the snap guide created is m_snapGuide->canvas()->shapeManager()->shapes();
43 KoSnapProxy paramProxy(&aKoSnapGuide); //param proxy will have no shapes hence it will not snap
44 qreal paramSnapDistance = 0;
45
46 bool didSnap = toTest.snap(paramMousePosition, ¶mProxy, paramSnapDistance);
47 QVERIFY(!didSnap);
48
49
50 //Second test case - makes sure the there are shapes in the fakeShapeControllerBase thus it should snap
51 OrthogonalSnapStrategy toTestTwo;
52 //paramMousePosition must be within paramSnapDistance of the points in firstSnapPointList
53 const QPointF paramMousePositionTwo(3,3);
54 MockShapeController fakeShapeControllerBaseTwo;
55
56 //This call will be made on the paramProxy: proxy->pointsFromShape(shape) which in turn
57 //will make this call shape->snapData().snapPoints(); so the shapes have to have snapPoints
58 //In order to have snapPoints we have to use the call
59 //shape->snapData().setSnapPoints() for each fakeShape, where we send in a const
60 //QList<QPointF> &snapPoints in order to have snapPoints to iterate - which is the only
61 //way to change the value of minHorzDist and minVertDist in KoSnapStrategy.cpp so it
62 //differs from HUGE_VAL - i.e. gives us the true value for the snap function.
63
64 //creating the lists of points
65 //example QList<QPointF> pts; pts.push_back(QPointF(0.2, 0.3)); pts.push_back(QPointF(0.5, 0.7));
66
67
68 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo); //the shapeManager() function of this will be called
69
70 KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
71 MockShape fakeShapeOne;
72 QList<QPointF> firstSnapPointList;
73 firstSnapPointList.push_back(QPointF(1,2));
74 firstSnapPointList.push_back(QPointF(2,2));
75 firstSnapPointList.push_back(QPointF(3,2));
76 firstSnapPointList.push_back(QPointF(4,2));
77
78 fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
79 fakeShapeOne.isVisible(true);
80 fakeShapeManager->addShape(&fakeShapeOne);
81 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo); //the call that will be made to the snap guide created is m_snapGuide->canvas()->shapeManager()->shapes();
82 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo); //param proxy will have shapes now
83
84 //Make sure at least one point in firstSnapPointList is within this distance of
85 //paramMousePoint to trigger the branches if (dx < minHorzDist && dx < maxSnapDistance)
86 //and if (dy < minVertDist && dy < maxSnapDistance) WHICH IS WHERE minVertDist and minHorzDist
87 //ARE CHANGED FROM HUGE_VAL
88 qreal paramSnapDistanceTwo = 4;
89 bool didSnapTwo = toTestTwo.snap(paramMousePositionTwo, ¶mProxyTwo, paramSnapDistanceTwo);
90 QVERIFY(didSnapTwo);
91
92 // don't forget to remove the shape from the shape manager before exiting!
93 fakeShapeManager->remove(&fakeShapeOne);
94 }
testNodeSnap()95 void TestSnapStrategy::testNodeSnap()
96 {
97
98 //Test case one - expected to not snap
99 NodeSnapStrategy toTest;
100 const QPointF paramMousePos;
101 MockShapeController fakeShapeControllerBase;
102 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
103 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
104 KoSnapProxy paramProxy(&aKoSnapGuide);
105 qreal paramSnapDistance = 0;
106
107 bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
108 QVERIFY(!didSnap);
109
110 //Test case two - exercising the branches by putting a shape and snap points into the ShapeManager
111 NodeSnapStrategy toTestTwo;
112 const QPointF paramMousePosTwo;
113 MockShapeController fakeShapeControllerBaseTwo;
114 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
115 KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
116 MockShape fakeShapeOne;
117 QList<QPointF> firstSnapPointList;
118 firstSnapPointList.push_back(QPointF(1,2));
119 firstSnapPointList.push_back(QPointF(2,2));
120 firstSnapPointList.push_back(QPointF(3,2));
121 firstSnapPointList.push_back(QPointF(4,2));
122
123 qreal paramSnapDistanceTwo = 4;
124
125 fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
126 fakeShapeOne.isVisible(true);
127 fakeShapeManager->addShape(&fakeShapeOne);
128 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
129 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
130
131 bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
132 QVERIFY(didSnapTwo);
133
134 // don't forget to remove the shape from the shape manager before exiting!
135 fakeShapeManager->remove(&fakeShapeOne);
136 }
testExtensionSnap()137 void TestSnapStrategy::testExtensionSnap()
138 {
139 //bool ExtensionSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
140 ExtensionSnapStrategy toTest;
141 const QPointF paramMousePos;
142 MockShapeController fakeShapeControllerBase;
143 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
144 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
145 KoSnapProxy paramProxy(&aKoSnapGuide);
146 qreal paramSnapDistance = 0;
147 bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
148 QVERIFY(!didSnap);
149
150 //Second test case - testing the snap by providing ShapeManager with a shape that has snap points and a path
151 //fakeShapeOne needs at least one subpath that is open in order to change the values of minDistances
152 //which in turn opens the path where it is possible to get a true bool value back from the snap function
153 // KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); in KoPathShape needs to be called
154 ExtensionSnapStrategy toTestTwo;
155 const QPointF paramMousePosTwo;
156 MockShapeController fakeShapeControllerBaseTwo;
157 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
158 KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
159 KoPathShape fakeShapeOne;
160 QList<QPointF> firstSnapPointList;
161 firstSnapPointList.push_back(QPointF(1,2));
162 firstSnapPointList.push_back(QPointF(2,2));
163 firstSnapPointList.push_back(QPointF(3,2));
164 firstSnapPointList.push_back(QPointF(4,2));
165
166 qreal paramSnapDistanceTwo = 4;
167 fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
168 fakeShapeOne.isVisible(true);
169
170 QPointF firstPoint(0,2);
171 QPointF secondPoint(1,2);
172 QPointF thirdPoint(2,3);
173 QPointF fourthPoint(3,4);
174
175 fakeShapeOne.moveTo(firstPoint);
176 fakeShapeOne.lineTo(secondPoint);
177 fakeShapeOne.lineTo(thirdPoint);
178 fakeShapeOne.lineTo(fourthPoint);
179
180 fakeShapeManager->addShape(&fakeShapeOne);
181 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
182 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
183
184 bool didSnapTwo = toTest.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
185 QVERIFY(didSnapTwo);
186
187 // don't forget to remove the shape from the shape manager before exiting!
188 fakeShapeManager->remove(&fakeShapeOne);
189 }
testIntersectionSnap()190 void TestSnapStrategy::testIntersectionSnap()
191 {
192 //Testing so it does not work without a path
193 IntersectionSnapStrategy toTest;
194 const QPointF paramMousePos;
195 MockShapeController fakeShapeControllerBase;
196 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
197 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
198 KoSnapProxy paramProxy(&aKoSnapGuide);
199 qreal paramSnapDistance = 0;
200 bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
201 QVERIFY(!didSnap);
202
203 //Exercising the working snap by providing the shape manager with three path shapes
204 //In order for this test to work the shapeManager has to have more than one fakeShape in it
205 //(requirement in QList<KoShape *> KoShapeManager::shapesAt(const QRectF &rect, bool omitHiddenShapes)
206 //And both shapes have to be not-visible
207 IntersectionSnapStrategy toTestTwo;
208 const QPointF paramMousePosTwo;
209 MockShapeController fakeShapeControllerBaseTwo;
210 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
211 KoShapeManager *ShapeManager = fakeKoCanvasBaseTwo.shapeManager();
212
213 qreal paramSnapDistanceTwo = 8;
214 KoPathShape pathShapeOne;
215 QList<QPointF> firstSnapPointList;
216
217 pathShapeOne.moveTo(QPointF(1,2));
218 pathShapeOne.lineTo(QPointF(2,2));
219 pathShapeOne.lineTo(QPointF(3,2));
220 pathShapeOne.lineTo(QPointF(4,2));
221
222 //pathShapeOne.snapData().setSnapPoints(firstSnapPointList);
223
224 pathShapeOne.isVisible(true);
225 ShapeManager->addShape(&pathShapeOne);
226
227 KoPathShape pathShapeTwo;
228 QList<QPointF> secondSnapPointList;
229
230 pathShapeTwo.moveTo(QPointF(1,1));
231 pathShapeTwo.lineTo(QPointF(2,2));
232 pathShapeTwo.lineTo(QPointF(3,3));
233 pathShapeTwo.lineTo(QPointF(4,4));
234
235 //pathShapeTwo.snapData().setSnapPoints(secondSnapPointList);
236
237 pathShapeTwo.isVisible(true);
238 ShapeManager->addShape(&pathShapeTwo);
239
240 KoPathShape pathShapeThree;
241 QList<QPointF> thirdSnapPointList;
242 pathShapeThree.moveTo(QPointF(5,5));
243 pathShapeThree.lineTo(QPointF(6,6));
244 pathShapeThree.lineTo(QPointF(7,7));
245 pathShapeThree.lineTo(QPointF(8,8));
246
247 pathShapeThree.isVisible(true);
248 ShapeManager->addShape(&pathShapeThree);
249
250 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
251 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
252 bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
253 QVERIFY(didSnapTwo);
254
255 // don't forget to remove the shape from the shape manager before exiting!
256 ShapeManager->remove(&pathShapeOne);
257 ShapeManager->remove(&pathShapeTwo);
258 ShapeManager->remove(&pathShapeThree);
259 }
testGridSnap()260 void TestSnapStrategy::testGridSnap()
261 {
262 //This test is the default case - meant to fail since the grid of the SnapGuide is not set
263 GridSnapStrategy toTest;
264 const QPointF paramMousePos;
265 MockShapeController fakeShapeControllerBase;
266 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
267 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
268 KoSnapProxy paramProxy(&aKoSnapGuide);
269 qreal paramSnapDistance = 0;
270 bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
271 QVERIFY(!didSnap);
272
273 //This test tests the snapping by providing the SnapGuide with a grid to snap against
274 GridSnapStrategy toTestTwo;
275 const QPointF paramMousePosTwo(40,60);
276 MockShapeController fakeShapeControllerBaseTwo;
277 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
278 fakeKoCanvasBaseTwo.setHorz(10);
279 fakeKoCanvasBaseTwo.setVert(8);
280 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
281 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
282 qreal paramSnapDistanceTwo = 8;
283 bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
284 QVERIFY(didSnapTwo);
285
286 }
testBoundingBoxSnap()287 void TestSnapStrategy::testBoundingBoxSnap()
288 {
289 //Tests so the snap does not work when there is no shape with a path
290 BoundingBoxSnapStrategy toTest;
291 const QPointF paramMousePos;
292 MockShapeController fakeShapeControllerBase;
293 MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
294 KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
295 KoSnapProxy paramProxy(&aKoSnapGuide);
296 qreal paramSnapDistance = 0;
297 bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
298 QVERIFY(!didSnap);
299
300 //tests the snap by providing three path shapes to the shape manager
301 BoundingBoxSnapStrategy toTestTwo;
302 const QPointF paramMousePosTwo;
303 MockShapeController fakeShapeControllerBaseTwo;
304 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
305 KoShapeManager *ShapeManager = fakeKoCanvasBaseTwo.shapeManager();
306
307 qreal paramSnapDistanceTwo = 8;
308 KoPathShape pathShapeOne;
309 QList<QPointF> firstSnapPointList;
310
311 pathShapeOne.moveTo(QPointF(1,2));
312 pathShapeOne.lineTo(QPointF(2,2));
313 pathShapeOne.lineTo(QPointF(3,2));
314 pathShapeOne.lineTo(QPointF(4,2));
315
316 pathShapeOne.isVisible(true);
317 ShapeManager->addShape(&pathShapeOne);
318
319 KoPathShape pathShapeTwo;
320 QList<QPointF> secondSnapPointList;
321
322 pathShapeTwo.moveTo(QPointF(1,1));
323 pathShapeTwo.lineTo(QPointF(2,2));
324 pathShapeTwo.lineTo(QPointF(3,3));
325 pathShapeTwo.lineTo(QPointF(4,4));
326
327 pathShapeTwo.isVisible(true);
328 ShapeManager->addShape(&pathShapeTwo);
329
330 KoPathShape pathShapeThree;
331 QList<QPointF> thirdSnapPointList;
332 pathShapeThree.moveTo(QPointF(5,5));
333 pathShapeThree.lineTo(QPointF(6,6));
334 pathShapeThree.lineTo(QPointF(7,7));
335 pathShapeThree.lineTo(QPointF(8,8));
336
337 pathShapeThree.isVisible(true);
338 ShapeManager->addShape(&pathShapeThree);
339
340 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
341 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
342 bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
343 QVERIFY(didSnapTwo);
344
345 // don't forget to remove the shape from the shape manager before exiting!
346 ShapeManager->remove(&pathShapeOne);
347 ShapeManager->remove(&pathShapeTwo);
348 ShapeManager->remove(&pathShapeThree);
349 }
testLineGuideSnap()350 void TestSnapStrategy::testLineGuideSnap()
351 {
352 // KoGuides data has been moved into Krita
353 //
354 // //Testing so the snap does not work without horizontal and vertial lines
355 // LineGuideSnapStrategy toTest;
356 // const QPointF paramMousePos;
357 // MockShapeController fakeShapeControllerBase;
358 // MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
359 // KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
360 // KoSnapProxy paramProxy(&aKoSnapGuide);
361 // qreal paramSnapDistance = 0;
362 // bool didSnap = toTest.snap(paramMousePos, ¶mProxy, paramSnapDistance);
363 // QVERIFY(!didSnap);
364
365 // //Test case that covers the path of the snap by providing horizontal and vertical lines for the GuidesData
366 // LineGuideSnapStrategy toTestTwo;
367 // const QPointF paramMousePosTwo;
368 // MockShapeController fakeShapeControllerBaseTwo;
369 // MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
370
371 // KoGuidesData guidesData;
372
373 // QList<qreal> horzLines;
374 // horzLines.push_back(2);
375 // horzLines.push_back(3);
376 // horzLines.push_back(4);
377 // horzLines.push_back(5);
378
379 // QList<qreal> vertLines;
380 // vertLines.push_back(1);
381 // vertLines.push_back(2);
382 // vertLines.push_back(3);
383 // vertLines.push_back(4);
384
385 // guidesData.setHorizontalGuideLines(horzLines);
386 // guidesData.setVerticalGuideLines(vertLines);
387 // fakeKoCanvasBaseTwo.setGuidesData(&guidesData);
388 // qreal paramSnapDistanceTwo = 8;
389 // KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
390 // KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
391 // bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
392 // QVERIFY(didSnapTwo);
393 }
394
testOrhogonalDecoration()395 void TestSnapStrategy::testOrhogonalDecoration()
396 {
397 //Making sure the decoration is created but is empty
398 OrthogonalSnapStrategy toTestTwo;
399 const QPointF paramMousePositionTwo(3,3);
400 MockShapeController fakeShapeControllerBaseTwo;
401 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
402
403 KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
404 MockShape fakeShapeOne;
405 QList<QPointF> firstSnapPointList;
406 firstSnapPointList.push_back(QPointF(1,2));
407 firstSnapPointList.push_back(QPointF(2,2));
408 firstSnapPointList.push_back(QPointF(3,2));
409 firstSnapPointList.push_back(QPointF(4,2));
410
411 fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
412 fakeShapeOne.isVisible(true);
413 fakeShapeManager->addShape(&fakeShapeOne);
414 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
415 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
416
417 //Make sure at least one point in firstSnapPointList is within this distance of
418 //paramMousePoint to trigger the branches if (dx < minHorzDist && dx < maxSnapDistance)
419 //and if (dy < minVertDist && dy < maxSnapDistance) WHICH IS WHERE minVertDist and minHorzDist
420 //ARE CHANGED FROM HUGE_VAL
421 qreal paramSnapDistanceTwo = 4;
422 toTestTwo.snap(paramMousePositionTwo, ¶mProxyTwo, paramSnapDistanceTwo);
423
424 KoViewConverter irrelevantParameter;
425 QPainterPath resultingDecoration = toTestTwo.decoration(irrelevantParameter);
426
427 QVERIFY( resultingDecoration.isEmpty() );
428
429 // don't forget to remove the shape from the shape manager before exiting!
430 fakeShapeManager->remove(&fakeShapeOne);
431
432 }
testNodeDecoration()433 void TestSnapStrategy::testNodeDecoration()
434 {
435 //Tests so the decoration returns a rect which is inside the "standard outer rect"
436 NodeSnapStrategy toTest;
437 KoViewConverter irrelevantParameter;
438 QRectF originalRect = QRectF(-5.5, -5.5, 11, 11);
439 QPainterPath resultingDecoration = toTest.decoration(irrelevantParameter);
440 QRectF rectInsidePath = resultingDecoration.boundingRect();
441 QVERIFY(originalRect==rectInsidePath);
442 }
testExtensionDecoration()443 void TestSnapStrategy::testExtensionDecoration()
444 {
445 //Tests the decoration is exercised by providing it with path
446 //fakeShapeOne needs at least one subpath that is open in order to change the values of minDistances
447 //which in turn opens the path where it is possible to get a true bool value back from the snap function
448 // KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); in KoPathShape needs to be called
449
450 ExtensionSnapStrategy toTestTwo;
451 const QPointF paramMousePosTwo;
452 MockShapeController fakeShapeControllerBaseTwo;
453 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
454 KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
455 KoPathShape fakeShapeOne;
456 QList<QPointF> firstSnapPointList;
457 firstSnapPointList.push_back(QPointF(1,2));
458 firstSnapPointList.push_back(QPointF(2,2));
459 firstSnapPointList.push_back(QPointF(3,2));
460 firstSnapPointList.push_back(QPointF(4,2));
461
462 qreal paramSnapDistanceTwo = 4;
463 fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
464 fakeShapeOne.isVisible(true);
465
466 QPointF firstPoint(0,2);
467 QPointF secondPoint(1,2);
468 QPointF thirdPoint(2,3);
469 QPointF fourthPoint(3,4);
470
471 fakeShapeOne.moveTo(firstPoint);
472 fakeShapeOne.lineTo(secondPoint);
473 fakeShapeOne.lineTo(thirdPoint);
474 fakeShapeOne.lineTo(fourthPoint);
475
476 fakeShapeManager->addShape(&fakeShapeOne);
477 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
478 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
479
480 toTestTwo.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
481
482 const KoViewConverter aConverter;
483 QPainterPath resultingDecoration = toTestTwo.decoration(aConverter);
484 QPointF resultDecorationLastPoint = resultingDecoration.currentPosition();
485
486 QVERIFY( resultDecorationLastPoint == QPointF(0,2) );
487
488 // don't forget to remove the shape from the shape manager before exiting!
489 fakeShapeManager->remove(&fakeShapeOne);
490 }
testIntersectionDecoration()491 void TestSnapStrategy::testIntersectionDecoration()
492 {
493 //Tests the decoration by making sure that the returned rect is within the "standard outer rect"
494 IntersectionSnapStrategy toTest;
495 KoViewConverter irrelevantParameter;
496 QRectF originalRect = QRectF(-5.5,-5.5,11,11); //std outer rect
497 QPainterPath resultingDecoration = toTest.decoration(irrelevantParameter);
498 QRectF rectInsidePath = resultingDecoration.boundingRect();
499 QVERIFY(originalRect==rectInsidePath);
500 }
testGridDecoration()501 void TestSnapStrategy::testGridDecoration()
502 {
503 //Tests the decoration by making sure the path returned has the calculated endpoint
504 GridSnapStrategy toTest;
505 const QPointF paramMousePosTwo(40,60);
506 MockShapeController fakeShapeControllerBaseTwo;
507 MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
508 fakeKoCanvasBaseTwo.setHorz(10);
509 fakeKoCanvasBaseTwo.setVert(8);
510 KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
511 KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
512 qreal paramSnapDistanceTwo = 8;
513 toTest.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
514
515 KoViewConverter viewConverter;
516 QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
517 QPointF snappedPos(40, 56); //the snapped position is 40, 56 because horz 10 - so 40 is right on the gridline, and 56 because 7*8 = 56 which is within 8 of 60
518 QPointF originalEndPoint(snappedPos + QPointF(0, unzoomedSize.height()));
519 QPainterPath resultingDecoration = toTest.decoration(viewConverter);
520
521 QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
522 }
testBoundingBoxDecoration()523 void TestSnapStrategy::testBoundingBoxDecoration()
524 {
525 //tests the decoration by making sure the returned path has the pre-calculated end point
526 BoundingBoxSnapStrategy toTest;
527
528 KoViewConverter viewConverter;
529 QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
530 QPointF snappedPos(0,0);
531 QPointF originalEndPoint(snappedPos + QPointF(unzoomedSize.width(), -unzoomedSize.height()));
532 QPainterPath resultingDecoration = toTest.decoration(viewConverter);
533
534 QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
535 }
536
testLineGuideDecoration()537 void TestSnapStrategy::testLineGuideDecoration()
538 {
539 // KoGuides data has been moved into Krita
540 //
541 // //tests the decoration by making sure there are horizontal and vertical lines in the guidesData
542 // LineGuideSnapStrategy toTest;
543
544 // const QPointF paramMousePosTwo;
545 // MockShapeController fakeShapeControllerBaseTwo;
546 // MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
547
548 // KoGuidesData guidesData;
549 // //firstSnapPointList.push_back(
550 // QList<qreal> horzLines;
551 // horzLines.push_back(2);
552 // horzLines.push_back(3);
553 // horzLines.push_back(4);
554 // horzLines.push_back(5);
555
556 // QList<qreal> vertLines;
557 // vertLines.push_back(1);
558 // vertLines.push_back(2);
559 // vertLines.push_back(3);
560 // vertLines.push_back(4);
561
562 // guidesData.setHorizontalGuideLines(horzLines);
563 // guidesData.setVerticalGuideLines(vertLines);
564 // fakeKoCanvasBaseTwo.setGuidesData(&guidesData);
565 // qreal paramSnapDistanceTwo = 8;
566 // KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
567 // KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
568 // toTest.snap(paramMousePosTwo, ¶mProxyTwo, paramSnapDistanceTwo);
569
570 // KoViewConverter parameterConverter;
571 // QSizeF unzoomedSize = parameterConverter.viewToDocument(QSizeF(5, 5));
572 // QPointF snappedPos(1,2);
573 // QPointF originalEndPointOne(snappedPos + QPointF(unzoomedSize.width(), 0));
574 // QPointF originalEndPointTwo(snappedPos + QPointF(0, unzoomedSize.height()));
575 // QPainterPath resultingDecoration = toTest.decoration(parameterConverter);
576
577 // QVERIFY( (resultingDecoration.currentPosition() == originalEndPointOne) || (resultingDecoration.currentPosition() == originalEndPointTwo ) );
578 }
579
testSquareDistance()580 void TestSnapStrategy::testSquareDistance()
581 {
582 //tests that it does not work without setting the points
583 OrthogonalSnapStrategy toTest;
584
585 QPointF p1;
586 QPointF p2;
587
588 qreal resultingRealOne = toTest.squareDistance(p1, p2);
589 QVERIFY(resultingRealOne == 0);
590 //tests that the returned value is as expected for positive values
591 OrthogonalSnapStrategy toTestTwo;
592
593 QPointF p1_2(2,2);
594 QPointF p2_2(1,1);
595
596 qreal resultingRealTwo = toTestTwo.squareDistance(p1_2, p2_2);
597 QVERIFY(resultingRealTwo == 2);
598 //tests that the returned value is as expected for positive and negative values
599 OrthogonalSnapStrategy toTestThree;
600
601 QPointF p1_3(2,2);
602 QPointF p2_3(-2,-2);
603
604 qreal resultingRealThree = toTestThree.squareDistance(p1_3, p2_3);
605 QVERIFY(resultingRealThree == 32);
606
607 //tests that the returned value is 0 when the points are the same
608 OrthogonalSnapStrategy toTestFour;
609
610 QPointF p1_4(2,2);
611 QPointF p2_4(2,2);
612
613 qreal resultingRealFour = toTestFour.squareDistance(p1_4, p2_4);
614 QVERIFY(resultingRealFour == 0);
615 }
testScalarProduct()616 void TestSnapStrategy::testScalarProduct()
617 {
618 //Tests so the scalarProduct cannot be calculated unless the points are set
619 OrthogonalSnapStrategy toTest;
620
621 QPointF p1_5;
622 QPointF p2_5;
623
624 qreal resultingRealOne = toTest.squareDistance(p1_5, p2_5);
625 QVERIFY(resultingRealOne == 0 );
626 //tests that the product is correctly calculated for positive point values
627 OrthogonalSnapStrategy toTestTwo;
628
629 QPointF p1_6(2,2);
630 QPointF p2_6(3,3);
631
632 qreal resultingRealTwo = toTestTwo.squareDistance(p1_6, p2_6);
633 QVERIFY(resultingRealTwo == 2 );
634 //tests that the product is correctly calculated for positive and negative point values
635 OrthogonalSnapStrategy toTestThree;
636
637 QPointF p1_7(2,2);
638 QPointF p2_7(-2,-2);
639
640 qreal resultingRealThree = toTestThree.squareDistance(p1_7, p2_7);
641 QVERIFY(resultingRealThree == 32);
642 //tests so the product is 0 when the points are the same
643 OrthogonalSnapStrategy toTestFour;
644
645 QPointF p1_8(1,1);
646 QPointF p2_8(1,1);
647
648 qreal resultingRealFour = toTestFour.squareDistance(p1_8, p2_8);
649 QVERIFY(resultingRealFour == 0);
650 //tests so there is nothing fishy when using origo
651 OrthogonalSnapStrategy toTestFive;
652
653 QPointF p1_9(1,1);
654 QPointF p2_9(0,0);
655
656 qreal resultingRealFive = toTestFive.squareDistance(p1_9, p2_9);
657 QVERIFY(resultingRealFive == 2);
658 }
659
660
661
662 //------------------------------------------------------------------
663
664
665
testSnapToExtension()666 void TestSnapStrategy::testSnapToExtension()
667 {
668 /*
669
670 toTest.snapToExtension(paramPosition, ¶mPoint, paramMatrix);
671
672 qDebug() << direction << " is the returned direction for this point in TestSnapStrategy::testSnapToExtension()";
673 QCOMPARE(direction, );
674 */
675 }
testProject()676 void TestSnapStrategy::testProject()
677 {
678 //tests for positive point values but backwards leaning line
679 ExtensionSnapStrategy toTestOne;
680 qreal toCompWithOne = -1;
681 QPointF lineStart(4,4);
682 QPointF lineEnd(2,2);
683 QPointF comparisonPoint(6,6);
684
685 qreal resultingRealOne = toTestOne.project(lineStart, lineEnd, comparisonPoint);
686 QCOMPARE(resultingRealOne, toCompWithOne);
687 //testing for for negative point values
688 ExtensionSnapStrategy toTestTwo;
689 qreal toCompWithTwo = -4;
690 QPointF lineStart_2(-2,-2);
691 QPointF lineEnd_2(-4,-4);
692 QPointF comparisonPoint_2(6,6);
693
694 qreal resultingRealTwo = toTestTwo.project(lineStart_2, lineEnd_2, comparisonPoint_2);
695 QCOMPARE(resultingRealTwo, toCompWithTwo);
696 //testing for negative and positive point values
697 ExtensionSnapStrategy toTestThree;
698 qreal toCompWithThree = (10*(6/sqrt(72.0)) + 10*(6/sqrt(72.0))) / sqrt(72.0); //diffLength = sqrt(72), scalar = (10*(6/sqrt(72)) + 10*(6/sqrt(72)))
699 QPointF lineStart_3(-2,-2);
700 QPointF lineEnd_3(4, 4);
701 QPointF comparisonPoint_3(8,8);
702
703 qreal resultingRealThree = toTestThree.project(lineStart_3, lineEnd_3, comparisonPoint_3);
704 QCOMPARE(resultingRealThree, toCompWithThree);
705
706 //Below we test the formula itself for the dot-product by using values we know return t=0.5
707 //Formula for how to use the t value is:
708 //ProjectionPoint = lineStart*(1-resultingReal) + resultingReal*lineEnd; (this is the formula used in BoundingBoxSnapStrategy::squareDistanceToLine())
709 //Note: The angle of the line from projection point to comparison point is always 90 degrees
710
711 ExtensionSnapStrategy toTestFour;
712 qreal toCompWithFour = 0.5;
713 QPointF lineStart_4(2,1);
714 QPointF lineEnd_4(6,3);
715 QPointF comparisonPoint_4(3,4);
716
717 qreal resultingRealFour = toTestFour.project(lineStart_4, lineEnd_4, comparisonPoint_4);
718 QCOMPARE(resultingRealFour, toCompWithFour);
719 }
720
testExtensionDirection()721 void TestSnapStrategy::testExtensionDirection()
722 {
723 /* TEST CASE 0
724 Supposed to return null
725 */
726 ExtensionSnapStrategy toTestOne;
727 KoPathShape uninitiatedPathShape;
728 KoPathPoint::PointProperties normal = KoPathPoint::Normal;
729 const QPointF initiatedPoint0(0,0);
730 KoPathPoint initiatedPoint(&uninitiatedPathShape, initiatedPoint0, normal);
731 QMatrix initiatedMatrixParam(1,1,1,1,1,1);
732 const QTransform initiatedMatrix(initiatedMatrixParam);
733 QPointF direction2 = toTestOne.extensionDirection( &initiatedPoint, initiatedMatrix);
734 QVERIFY(direction2.isNull());
735
736 /* TEST CASE 1
737 tests a point that:
738 - is the first in a subpath,
739 - does not have the firstSubpath property set,
740 - it has no activeControlPoint1,
741 - is has no previous point
742
743 = expected returning an empty QPointF
744 */
745 ExtensionSnapStrategy toTestTwo;
746 QPointF expectedPointTwo(0,0);
747 KoPathShape shapeOne;
748
749 QPointF firstPoint(0,1);
750 QPointF secondPoint(1,2);
751 QPointF thirdPoint(2,3);
752 QPointF fourthPoint(3,4);
753
754 shapeOne.moveTo(firstPoint);
755 shapeOne.lineTo(secondPoint);
756 shapeOne.lineTo(thirdPoint);
757 shapeOne.lineTo(fourthPoint);
758
759 QPointF paramPositionTwo(0,1);
760 KoPathPoint paramPointTwo;
761 paramPointTwo.setPoint(paramPositionTwo);
762 paramPointTwo.setParent(&shapeOne);
763
764 const QTransform paramTransMatrix(1,2,3,4,5,6);
765 QPointF directionTwo = toTestTwo.extensionDirection( ¶mPointTwo, paramTransMatrix);
766 QCOMPARE(directionTwo, expectedPointTwo);
767
768 /* TEST CASE 2
769 tests a point that:
770 - is the second in a subpath,
771 - does not have the firstSubpath property set,
772 - it has no activeControlPoint1,
773 - is has a previous point
774
775 = expected returning an
776 */
777 ExtensionSnapStrategy toTestThree;
778 QPointF expectedPointThree(0,0);
779 QPointF paramPositionThree(1,1);
780 KoPathPoint paramPointThree;
781 paramPointThree.setPoint(paramPositionThree);
782 paramPointThree.setParent(&shapeOne);
783 QPointF directionThree = toTestThree.extensionDirection( ¶mPointThree, paramTransMatrix);
784 QCOMPARE(directionThree, expectedPointThree);
785
786 }
787
testSquareDistanceToLine()788 void TestSnapStrategy::testSquareDistanceToLine()
789 {
790 BoundingBoxSnapStrategy toTestOne;
791
792 const QPointF lineA(4,1);
793 const QPointF lineB(6,3);
794 const QPointF point(5,8);
795 QPointF pointOnLine(0,0);
796
797 qreal result = toTestOne.squareDistanceToLine(lineA, lineB, point, pointOnLine);
798 //Should be HUGE_VAL because scalar > diffLength
799 QVERIFY(result == HUGE_VAL);
800
801 BoundingBoxSnapStrategy toTestTwo;
802 QPointF lineA2(4,4);
803 QPointF lineB2(4,4);
804 QPointF point2(5,8);
805 QPointF pointOnLine2(0,0);
806
807 qreal result2 = toTestTwo.squareDistanceToLine(lineA2, lineB2, point2, pointOnLine2);
808 //Should be HUGE_VAL because lineA2 == lineB2
809 QVERIFY(result2 == HUGE_VAL);
810
811 BoundingBoxSnapStrategy toTestThree;
812 QPointF lineA3(6,4);
813 QPointF lineB3(8,6);
814 QPointF point3(2,2);
815 QPointF pointOnLine3(0,0);
816
817 qreal result3 = toTestThree.squareDistanceToLine(lineA3, lineB3, point3, pointOnLine3);
818 //Should be HUGE_VAL because scalar < 0.0
819 QVERIFY(result3 == HUGE_VAL);
820
821 BoundingBoxSnapStrategy toTestFour;
822 QPointF lineA4(2,2);
823 QPointF lineB4(8,6);
824 QPointF point4(3,4);
825 QPointF pointOnLine4(0,0);
826
827 QPointF diff(6,4);
828 //diff = lineB3 - point3 = 6,4
829 //diffLength = sqrt(52)
830 //scalar = (1*(6/sqrt(52)) + 2*(4/sqrt(52)));
831
832 //pointOnLine = lineA + scalar / diffLength * diff; lineA + ((1*(6/sqrt(52)) + 2*(4/sqrt(52))) / sqrt(52)) * 6,4;
833 QPointF distToPointOnLine = (lineA4 + ((1*(6/sqrt(52.0)) + 2*(4/sqrt(52.0))) / sqrt(52.0)) * diff)-point4;
834 qreal toCompWithFour = distToPointOnLine.x()*distToPointOnLine.x()+distToPointOnLine.y()*distToPointOnLine.y();
835
836 qreal result4 = toTestFour.squareDistanceToLine(lineA4, lineB4, point4, pointOnLine4);
837 //Normal case with example data
838 QVERIFY(qFuzzyCompare(result4, toCompWithFour));
839
840 }
841 KISTEST_MAIN(TestSnapStrategy)
842