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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxy, 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, &paramProxyTwo, 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, &paramProxyTwo, 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, &paramProxyTwo, 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, &paramProxyTwo, 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, &paramProxyTwo, 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, &paramPoint, 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( &paramPointTwo, 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( &paramPointThree, 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