File indexing completed on 2024-05-26 04:26:30

0001 /*
0002     Copyright (C) 2012 <hanna.et.scott@gmail.com> 
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 
0006 */
0007 
0008 #include "TestSnapStrategy.h"
0009 #include "KoPathPoint.h"
0010 #include "KoPathShape.h"
0011 #include "KoShapeControllerBase.h"
0012 #include "KoSnapProxy.h"
0013 #include "KoSnapStrategy.h"
0014 #include "KoViewConverter.h"
0015 #include "MockShapes.h"
0016 #include <QPainterPath>
0017 #include <simpletest.h>
0018 #include <testflake.h>
0019 
0020 //#include <PointProperties.h>
0021 #include <KoSnapData.h>
0022 
0023 void TestSnapStrategy::testOrthogonalSnap()
0024 {
0025     //Test case one - expected not to snap
0026 
0027     OrthogonalSnapStrategy toTest;
0028     const QPointF paramMousePosition;
0029     MockShapeController fakeShapeControllerBase;
0030     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase); //the shapeManager() function of this will be called
0031     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase); //the call that will be made to the snap guide created is m_snapGuide->canvas()->shapeManager()->shapes();
0032     KoSnapProxy paramProxy(&aKoSnapGuide);  //param proxy will have no shapes hence it will not snap
0033     qreal paramSnapDistance = 0;
0034 
0035     bool didSnap = toTest.snap(paramMousePosition, &paramProxy, paramSnapDistance);
0036     QVERIFY(!didSnap);
0037 
0038 
0039     //Second test case - makes sure the there are shapes in the fakeShapeControllerBase thus it should snap
0040     OrthogonalSnapStrategy toTestTwo;
0041     //paramMousePosition must be within paramSnapDistance of the points in firstSnapPointList
0042     const QPointF paramMousePositionTwo(3,3);
0043     MockShapeController fakeShapeControllerBaseTwo;
0044 
0045     //This call will be made on the paramProxy: proxy->pointsFromShape(shape) which in turn
0046     //will make this call shape->snapData().snapPoints(); so the shapes have to have snapPoints
0047     //In order to have snapPoints we have to use the call
0048     //shape->snapData().setSnapPoints() for each fakeShape, where we send in a const
0049     //QList<QPointF> &snapPoints in order to have snapPoints to iterate - which is the only
0050     //way to change the value of minHorzDist and minVertDist in KoSnapStrategy.cpp so it
0051     //differs from HUGE_VAL - i.e. gives us the true value for the snap function.
0052 
0053     //creating the lists of points
0054     //example QList<QPointF> pts; pts.push_back(QPointF(0.2, 0.3)); pts.push_back(QPointF(0.5, 0.7));
0055 
0056 
0057     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo); //the shapeManager() function of this will be called
0058 
0059     KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0060     MockShape fakeShapeOne;
0061     QList<QPointF> firstSnapPointList;
0062     firstSnapPointList.push_back(QPointF(1,2));
0063     firstSnapPointList.push_back(QPointF(2,2));
0064     firstSnapPointList.push_back(QPointF(3,2));
0065     firstSnapPointList.push_back(QPointF(4,2));
0066 
0067     fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
0068     fakeShapeOne.isVisible(true);
0069     fakeShapeManager->addShape(&fakeShapeOne);
0070     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo); //the call that will be made to the snap guide created is m_snapGuide->canvas()->shapeManager()->shapes();
0071     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);  //param proxy will have shapes now
0072 
0073     //Make sure at least one point in firstSnapPointList is within this distance of
0074     //paramMousePoint to trigger the branches if (dx < minHorzDist && dx < maxSnapDistance)
0075     //and if (dy < minVertDist && dy < maxSnapDistance) WHICH IS WHERE minVertDist and minHorzDist
0076     //ARE CHANGED FROM HUGE_VAL
0077     qreal paramSnapDistanceTwo = 4;
0078     bool didSnapTwo = toTestTwo.snap(paramMousePositionTwo, &paramProxyTwo, paramSnapDistanceTwo);
0079     QVERIFY(didSnapTwo);
0080 
0081     // don't forget to remove the shape from the shape manager before exiting!
0082     fakeShapeManager->remove(&fakeShapeOne);
0083 }
0084 void TestSnapStrategy::testNodeSnap()
0085 {
0086 
0087     //Test case one - expected to not snap
0088     NodeSnapStrategy toTest;
0089     const QPointF paramMousePos;
0090     MockShapeController fakeShapeControllerBase;
0091     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0092     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0093     KoSnapProxy paramProxy(&aKoSnapGuide);
0094     qreal paramSnapDistance = 0;
0095 
0096     bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0097     QVERIFY(!didSnap);
0098 
0099     //Test case two - exercising the branches by putting a shape and snap points into the ShapeManager
0100     NodeSnapStrategy toTestTwo;
0101     const QPointF paramMousePosTwo;
0102     MockShapeController fakeShapeControllerBaseTwo;
0103     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0104     KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0105     MockShape fakeShapeOne;
0106     QList<QPointF> firstSnapPointList;
0107     firstSnapPointList.push_back(QPointF(1,2));
0108     firstSnapPointList.push_back(QPointF(2,2));
0109     firstSnapPointList.push_back(QPointF(3,2));
0110     firstSnapPointList.push_back(QPointF(4,2));
0111 
0112     qreal paramSnapDistanceTwo = 4;
0113 
0114     fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
0115     fakeShapeOne.isVisible(true);
0116     fakeShapeManager->addShape(&fakeShapeOne);
0117     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0118     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0119 
0120     bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0121     QVERIFY(didSnapTwo);
0122 
0123     // don't forget to remove the shape from the shape manager before exiting!
0124     fakeShapeManager->remove(&fakeShapeOne);
0125 }
0126 void TestSnapStrategy::testExtensionSnap()
0127 {
0128     //bool ExtensionSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
0129     ExtensionSnapStrategy toTest;
0130     const QPointF paramMousePos;
0131     MockShapeController fakeShapeControllerBase;
0132     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0133     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0134     KoSnapProxy paramProxy(&aKoSnapGuide);
0135     qreal paramSnapDistance = 0;
0136     bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0137     QVERIFY(!didSnap);
0138 
0139     //Second test case - testing the snap by providing ShapeManager with a shape that has snap points and a path
0140     //fakeShapeOne needs at least one subpath that is open in order to change the values of minDistances
0141     //which in turn opens the path where it is possible to get a true bool value back from the snap function
0142     // KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); in KoPathShape needs to be called
0143     ExtensionSnapStrategy toTestTwo;
0144     const QPointF paramMousePosTwo;
0145     MockShapeController fakeShapeControllerBaseTwo;
0146     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0147     KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0148     KoPathShape fakeShapeOne;
0149     QList<QPointF> firstSnapPointList;
0150     firstSnapPointList.push_back(QPointF(1,2));
0151     firstSnapPointList.push_back(QPointF(2,2));
0152     firstSnapPointList.push_back(QPointF(3,2));
0153     firstSnapPointList.push_back(QPointF(4,2));
0154 
0155     qreal paramSnapDistanceTwo = 4;
0156     fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
0157     fakeShapeOne.isVisible(true);
0158 
0159     QPointF firstPoint(0,2);
0160     QPointF secondPoint(1,2);
0161     QPointF thirdPoint(2,3);
0162     QPointF fourthPoint(3,4);
0163 
0164     fakeShapeOne.moveTo(firstPoint);
0165     fakeShapeOne.lineTo(secondPoint);
0166     fakeShapeOne.lineTo(thirdPoint);
0167     fakeShapeOne.lineTo(fourthPoint);
0168 
0169     fakeShapeManager->addShape(&fakeShapeOne);
0170     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0171     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0172 
0173     bool didSnapTwo = toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0174     QVERIFY(didSnapTwo);
0175 
0176     // don't forget to remove the shape from the shape manager before exiting!
0177     fakeShapeManager->remove(&fakeShapeOne);
0178 }
0179 void TestSnapStrategy::testIntersectionSnap()
0180 {
0181     //Testing so it does not work without a path
0182     IntersectionSnapStrategy toTest;
0183     const QPointF paramMousePos;
0184     MockShapeController fakeShapeControllerBase;
0185     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0186     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0187     KoSnapProxy paramProxy(&aKoSnapGuide);
0188     qreal paramSnapDistance = 0;
0189     bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0190     QVERIFY(!didSnap);
0191 
0192     //Exercising the working snap by providing the shape manager with three path shapes
0193     //In order for this test to work the shapeManager has to have more than one fakeShape in it
0194     //(requirement in QList<KoShape *> KoShapeManager::shapesAt(const QRectF &rect, bool omitHiddenShapes)
0195     //And both shapes have to be not-visible
0196     IntersectionSnapStrategy toTestTwo;
0197     const QPointF paramMousePosTwo;
0198     MockShapeController fakeShapeControllerBaseTwo;
0199     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0200     KoShapeManager *ShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0201 
0202     qreal paramSnapDistanceTwo = 8;
0203     KoPathShape pathShapeOne;
0204     QList<QPointF> firstSnapPointList;
0205 
0206     pathShapeOne.moveTo(QPointF(1,2));
0207     pathShapeOne.lineTo(QPointF(2,2));
0208     pathShapeOne.lineTo(QPointF(3,2));
0209     pathShapeOne.lineTo(QPointF(4,2));
0210 
0211     //pathShapeOne.snapData().setSnapPoints(firstSnapPointList);
0212 
0213     pathShapeOne.isVisible(true);
0214     ShapeManager->addShape(&pathShapeOne);
0215 
0216     KoPathShape pathShapeTwo;
0217     QList<QPointF> secondSnapPointList;
0218 
0219     pathShapeTwo.moveTo(QPointF(1,1));
0220     pathShapeTwo.lineTo(QPointF(2,2));
0221     pathShapeTwo.lineTo(QPointF(3,3));
0222     pathShapeTwo.lineTo(QPointF(4,4));
0223 
0224     //pathShapeTwo.snapData().setSnapPoints(secondSnapPointList);
0225 
0226     pathShapeTwo.isVisible(true);
0227     ShapeManager->addShape(&pathShapeTwo);
0228 
0229     KoPathShape pathShapeThree;
0230     QList<QPointF> thirdSnapPointList;
0231     pathShapeThree.moveTo(QPointF(5,5));
0232     pathShapeThree.lineTo(QPointF(6,6));
0233     pathShapeThree.lineTo(QPointF(7,7));
0234     pathShapeThree.lineTo(QPointF(8,8));
0235 
0236     pathShapeThree.isVisible(true);
0237     ShapeManager->addShape(&pathShapeThree);
0238 
0239     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0240     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0241     bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0242     QVERIFY(didSnapTwo);
0243 
0244     // don't forget to remove the shape from the shape manager before exiting!
0245     ShapeManager->remove(&pathShapeOne);
0246     ShapeManager->remove(&pathShapeTwo);
0247     ShapeManager->remove(&pathShapeThree);
0248 }
0249 void TestSnapStrategy::testGridSnap()
0250 {
0251     //This test is the default case - meant to fail since the grid of the SnapGuide is not set
0252     GridSnapStrategy toTest;
0253     const QPointF paramMousePos;
0254     MockShapeController fakeShapeControllerBase;
0255     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0256     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0257     KoSnapProxy paramProxy(&aKoSnapGuide);
0258     qreal paramSnapDistance = 0;
0259     bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0260     QVERIFY(!didSnap);
0261 
0262     //This test tests the snapping by providing the SnapGuide with a grid to snap against
0263     GridSnapStrategy toTestTwo;
0264     const QPointF paramMousePosTwo(40,60);
0265     MockShapeController fakeShapeControllerBaseTwo;
0266     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0267     fakeKoCanvasBaseTwo.setHorz(10);
0268     fakeKoCanvasBaseTwo.setVert(8);
0269     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0270     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0271     qreal paramSnapDistanceTwo = 8;
0272     bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0273     QVERIFY(didSnapTwo);
0274 
0275 }
0276 void TestSnapStrategy::testBoundingBoxSnap()
0277 {
0278     //Tests so the snap does not work when there is no shape with a path
0279     BoundingBoxSnapStrategy toTest;
0280     const QPointF paramMousePos;
0281     MockShapeController fakeShapeControllerBase;
0282     MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0283     KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0284     KoSnapProxy paramProxy(&aKoSnapGuide);
0285     qreal paramSnapDistance = 0;
0286     bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0287     QVERIFY(!didSnap);
0288 
0289     //tests the snap by providing three path shapes to the shape manager
0290     BoundingBoxSnapStrategy toTestTwo;
0291     const QPointF paramMousePosTwo;
0292     MockShapeController fakeShapeControllerBaseTwo;
0293     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0294     KoShapeManager *ShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0295 
0296     qreal paramSnapDistanceTwo = 8;
0297     KoPathShape pathShapeOne;
0298     QList<QPointF> firstSnapPointList;
0299 
0300     pathShapeOne.moveTo(QPointF(1,2));
0301     pathShapeOne.lineTo(QPointF(2,2));
0302     pathShapeOne.lineTo(QPointF(3,2));
0303     pathShapeOne.lineTo(QPointF(4,2));
0304 
0305     pathShapeOne.isVisible(true);
0306     ShapeManager->addShape(&pathShapeOne);
0307 
0308     KoPathShape pathShapeTwo;
0309     QList<QPointF> secondSnapPointList;
0310 
0311     pathShapeTwo.moveTo(QPointF(1,1));
0312     pathShapeTwo.lineTo(QPointF(2,2));
0313     pathShapeTwo.lineTo(QPointF(3,3));
0314     pathShapeTwo.lineTo(QPointF(4,4));
0315 
0316     pathShapeTwo.isVisible(true);
0317     ShapeManager->addShape(&pathShapeTwo);
0318 
0319     KoPathShape pathShapeThree;
0320     QList<QPointF> thirdSnapPointList;
0321     pathShapeThree.moveTo(QPointF(5,5));
0322     pathShapeThree.lineTo(QPointF(6,6));
0323     pathShapeThree.lineTo(QPointF(7,7));
0324     pathShapeThree.lineTo(QPointF(8,8));
0325 
0326     pathShapeThree.isVisible(true);
0327     ShapeManager->addShape(&pathShapeThree);
0328 
0329     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0330     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0331     bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0332     QVERIFY(didSnapTwo);
0333 
0334     // don't forget to remove the shape from the shape manager before exiting!
0335     ShapeManager->remove(&pathShapeOne);
0336     ShapeManager->remove(&pathShapeTwo);
0337     ShapeManager->remove(&pathShapeThree);
0338 }
0339 void TestSnapStrategy::testLineGuideSnap()
0340 {
0341     // KoGuides data has been moved into Krita
0342     // 
0343     // //Testing so the snap does not work without horizontal and vertical lines
0344     // LineGuideSnapStrategy toTest;
0345     // const QPointF paramMousePos;
0346     // MockShapeController fakeShapeControllerBase;
0347     // MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
0348     // KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
0349     // KoSnapProxy paramProxy(&aKoSnapGuide);
0350     // qreal paramSnapDistance = 0;
0351     // bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
0352     // QVERIFY(!didSnap);
0353 
0354     // //Test case that covers the path of the snap by providing horizontal and vertical lines for the GuidesData
0355     // LineGuideSnapStrategy toTestTwo;
0356     // const QPointF paramMousePosTwo;
0357     // MockShapeController fakeShapeControllerBaseTwo;
0358     // MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0359 
0360     // KoGuidesData guidesData;
0361 
0362     // QList<qreal> horzLines;
0363     // horzLines.push_back(2);
0364     // horzLines.push_back(3);
0365     // horzLines.push_back(4);
0366     // horzLines.push_back(5);
0367 
0368     // QList<qreal> vertLines;
0369     // vertLines.push_back(1);
0370     // vertLines.push_back(2);
0371     // vertLines.push_back(3);
0372     // vertLines.push_back(4);
0373 
0374     // guidesData.setHorizontalGuideLines(horzLines);
0375     // guidesData.setVerticalGuideLines(vertLines);
0376     // fakeKoCanvasBaseTwo.setGuidesData(&guidesData);
0377     // qreal paramSnapDistanceTwo = 8;
0378     // KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0379     // KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0380     // bool didSnapTwo = toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0381     // QVERIFY(didSnapTwo);
0382 }
0383 
0384 void TestSnapStrategy::testOrthogonalDecoration()
0385 {
0386     //Making sure the decoration is created but is empty
0387     OrthogonalSnapStrategy toTestTwo;
0388     const QPointF paramMousePositionTwo(3,3);
0389     MockShapeController fakeShapeControllerBaseTwo;
0390     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0391 
0392     KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0393     MockShape fakeShapeOne;
0394     QList<QPointF> firstSnapPointList;
0395     firstSnapPointList.push_back(QPointF(1,2));
0396     firstSnapPointList.push_back(QPointF(2,2));
0397     firstSnapPointList.push_back(QPointF(3,2));
0398     firstSnapPointList.push_back(QPointF(4,2));
0399 
0400     fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
0401     fakeShapeOne.isVisible(true);
0402     fakeShapeManager->addShape(&fakeShapeOne);
0403     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0404     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0405 
0406     //Make sure at least one point in firstSnapPointList is within this distance of
0407     //paramMousePoint to trigger the branches if (dx < minHorzDist && dx < maxSnapDistance)
0408     //and if (dy < minVertDist && dy < maxSnapDistance) WHICH IS WHERE minVertDist and minHorzDist
0409     //ARE CHANGED FROM HUGE_VAL
0410     qreal paramSnapDistanceTwo = 4;
0411     toTestTwo.snap(paramMousePositionTwo, &paramProxyTwo, paramSnapDistanceTwo);
0412 
0413     KoViewConverter irrelevantParameter;
0414     QPainterPath resultingDecoration = toTestTwo.decoration(irrelevantParameter);
0415 
0416     QVERIFY( resultingDecoration.isEmpty() );
0417 
0418     // don't forget to remove the shape from the shape manager before exiting!
0419     fakeShapeManager->remove(&fakeShapeOne);
0420 
0421 }
0422 void TestSnapStrategy::testNodeDecoration()
0423 {
0424     //Tests so the decoration returns a rect which is inside the "standard outer rect"
0425     NodeSnapStrategy toTest;
0426     KoViewConverter irrelevantParameter;
0427     QRectF originalRect = QRectF(-5.5, -5.5, 11, 11);
0428     QPainterPath resultingDecoration = toTest.decoration(irrelevantParameter);
0429     QRectF rectInsidePath = resultingDecoration.boundingRect();
0430     QVERIFY(originalRect==rectInsidePath);
0431 }
0432 void TestSnapStrategy::testExtensionDecoration()
0433 {
0434     //Tests the decoration is exercised by providing it with path
0435     //fakeShapeOne needs at least one subpath that is open in order to change the values of minDistances
0436     //which in turn opens the path where it is possible to get a true bool value back from the snap function
0437     // KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); in KoPathShape needs to be called
0438 
0439     ExtensionSnapStrategy toTestTwo;
0440     const QPointF paramMousePosTwo;
0441     MockShapeController fakeShapeControllerBaseTwo;
0442     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0443     KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
0444     KoPathShape fakeShapeOne;
0445     QList<QPointF> firstSnapPointList;
0446     firstSnapPointList.push_back(QPointF(1,2));
0447     firstSnapPointList.push_back(QPointF(2,2));
0448     firstSnapPointList.push_back(QPointF(3,2));
0449     firstSnapPointList.push_back(QPointF(4,2));
0450 
0451     qreal paramSnapDistanceTwo = 4;
0452     fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
0453     fakeShapeOne.isVisible(true);
0454 
0455     QPointF firstPoint(0,2);
0456     QPointF secondPoint(1,2);
0457     QPointF thirdPoint(2,3);
0458     QPointF fourthPoint(3,4);
0459 
0460     fakeShapeOne.moveTo(firstPoint);
0461     fakeShapeOne.lineTo(secondPoint);
0462     fakeShapeOne.lineTo(thirdPoint);
0463     fakeShapeOne.lineTo(fourthPoint);
0464 
0465     fakeShapeManager->addShape(&fakeShapeOne);
0466     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0467     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0468 
0469     toTestTwo.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0470 
0471     const KoViewConverter aConverter;
0472     QPainterPath resultingDecoration = toTestTwo.decoration(aConverter);
0473     QPointF resultDecorationLastPoint = resultingDecoration.currentPosition();
0474 
0475     QVERIFY( resultDecorationLastPoint == QPointF(0,2) );
0476 
0477     // don't forget to remove the shape from the shape manager before exiting!
0478     fakeShapeManager->remove(&fakeShapeOne);
0479 }
0480 void TestSnapStrategy::testIntersectionDecoration()
0481 {
0482     //Tests the decoration by making sure that the returned rect is within the "standard outer rect"
0483     IntersectionSnapStrategy toTest;
0484     KoViewConverter irrelevantParameter;
0485     QRectF originalRect = QRectF(-5.5,-5.5,11,11); //std outer rect
0486     QPainterPath resultingDecoration = toTest.decoration(irrelevantParameter);
0487     QRectF rectInsidePath = resultingDecoration.boundingRect();
0488     QVERIFY(originalRect==rectInsidePath);
0489 }
0490 void TestSnapStrategy::testGridDecoration()
0491 {
0492     //Tests the decoration by making sure the path returned has the calculated endpoint
0493     GridSnapStrategy toTest;
0494     const QPointF paramMousePosTwo(40,60);
0495     MockShapeController fakeShapeControllerBaseTwo;
0496     MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0497     fakeKoCanvasBaseTwo.setHorz(10);
0498     fakeKoCanvasBaseTwo.setVert(8);
0499     KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0500     KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0501     qreal paramSnapDistanceTwo = 8;
0502     toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0503 
0504     KoViewConverter viewConverter;
0505     QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
0506     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
0507     QPointF originalEndPoint(snappedPos + QPointF(0, unzoomedSize.height()));
0508     QPainterPath resultingDecoration = toTest.decoration(viewConverter);
0509 
0510     QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
0511 }
0512 void TestSnapStrategy::testBoundingBoxDecoration()
0513 {
0514     //tests the decoration by making sure the returned path has the pre-calculated end point
0515     BoundingBoxSnapStrategy toTest;
0516 
0517     KoViewConverter viewConverter;
0518     QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
0519     QPointF snappedPos(0,0);
0520     QPointF originalEndPoint(snappedPos + QPointF(unzoomedSize.width(), -unzoomedSize.height()));
0521     QPainterPath resultingDecoration = toTest.decoration(viewConverter);
0522 
0523     QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
0524 }
0525 
0526 void TestSnapStrategy::testLineGuideDecoration()
0527 {
0528     // KoGuides data has been moved into Krita
0529     //
0530     // //tests the decoration by making sure there are horizontal and vertical lines in the guidesData
0531     // LineGuideSnapStrategy toTest;
0532 
0533     // const QPointF paramMousePosTwo;
0534     // MockShapeController fakeShapeControllerBaseTwo;
0535     // MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
0536 
0537     // KoGuidesData guidesData;
0538     // //firstSnapPointList.push_back(
0539     // QList<qreal> horzLines;
0540     // horzLines.push_back(2);
0541     // horzLines.push_back(3);
0542     // horzLines.push_back(4);
0543     // horzLines.push_back(5);
0544 
0545     // QList<qreal> vertLines;
0546     // vertLines.push_back(1);
0547     // vertLines.push_back(2);
0548     // vertLines.push_back(3);
0549     // vertLines.push_back(4);
0550 
0551     // guidesData.setHorizontalGuideLines(horzLines);
0552     // guidesData.setVerticalGuideLines(vertLines);
0553     // fakeKoCanvasBaseTwo.setGuidesData(&guidesData);
0554     // qreal paramSnapDistanceTwo = 8;
0555     // KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
0556     // KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
0557     // toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
0558 
0559     // KoViewConverter parameterConverter;
0560     // QSizeF unzoomedSize = parameterConverter.viewToDocument(QSizeF(5, 5));
0561     // QPointF snappedPos(1,2);
0562     // QPointF originalEndPointOne(snappedPos + QPointF(unzoomedSize.width(), 0));
0563     // QPointF originalEndPointTwo(snappedPos + QPointF(0, unzoomedSize.height()));
0564     // QPainterPath resultingDecoration = toTest.decoration(parameterConverter);
0565 
0566     // QVERIFY( (resultingDecoration.currentPosition() == originalEndPointOne) || (resultingDecoration.currentPosition() == originalEndPointTwo ) );
0567 }
0568 
0569 void TestSnapStrategy::testSquareDistance()
0570 {
0571     //tests that it does not work without setting the points
0572     OrthogonalSnapStrategy toTest;
0573 
0574     QPointF p1;
0575     QPointF p2;
0576 
0577     qreal resultingRealOne = toTest.squareDistance(p1, p2);
0578     QVERIFY(resultingRealOne == 0);
0579     //tests that the returned value is as expected for positive values
0580     OrthogonalSnapStrategy toTestTwo;
0581 
0582     QPointF p1_2(2,2);
0583     QPointF p2_2(1,1);
0584 
0585     qreal resultingRealTwo = toTestTwo.squareDistance(p1_2, p2_2);
0586     QVERIFY(resultingRealTwo == 2);
0587     //tests that the returned value is as expected for positive and negative values
0588     OrthogonalSnapStrategy toTestThree;
0589 
0590     QPointF p1_3(2,2);
0591     QPointF p2_3(-2,-2);
0592 
0593     qreal resultingRealThree = toTestThree.squareDistance(p1_3, p2_3);
0594     QVERIFY(resultingRealThree == 32);
0595 
0596     //tests that the returned value is 0 when the points are the same
0597     OrthogonalSnapStrategy toTestFour;
0598 
0599     QPointF p1_4(2,2);
0600     QPointF p2_4(2,2);
0601 
0602     qreal resultingRealFour = toTestFour.squareDistance(p1_4, p2_4);
0603     QVERIFY(resultingRealFour == 0);
0604 }
0605 void TestSnapStrategy::testScalarProduct()
0606 {
0607     //Tests so the scalarProduct cannot be calculated unless the points are set
0608     OrthogonalSnapStrategy toTest;
0609 
0610     QPointF p1_5;
0611     QPointF p2_5;
0612 
0613     qreal resultingRealOne = toTest.squareDistance(p1_5, p2_5);
0614     QVERIFY(resultingRealOne == 0 );
0615     //tests that the product is correctly calculated for positive point values
0616     OrthogonalSnapStrategy toTestTwo;
0617 
0618     QPointF p1_6(2,2);
0619     QPointF p2_6(3,3);
0620 
0621     qreal resultingRealTwo = toTestTwo.squareDistance(p1_6, p2_6);
0622     QVERIFY(resultingRealTwo == 2 );
0623     //tests that the product is correctly calculated for positive and negative point values
0624     OrthogonalSnapStrategy toTestThree;
0625 
0626     QPointF p1_7(2,2);
0627     QPointF p2_7(-2,-2);
0628 
0629     qreal resultingRealThree = toTestThree.squareDistance(p1_7, p2_7);
0630     QVERIFY(resultingRealThree == 32);
0631     //tests so the product is 0 when the points are the same
0632     OrthogonalSnapStrategy toTestFour;
0633 
0634     QPointF p1_8(1,1);
0635     QPointF p2_8(1,1);
0636 
0637     qreal resultingRealFour = toTestFour.squareDistance(p1_8, p2_8);
0638     QVERIFY(resultingRealFour == 0);
0639     //tests so there is nothing fishy when using origin
0640     OrthogonalSnapStrategy toTestFive;
0641 
0642     QPointF p1_9(1,1);
0643     QPointF p2_9(0,0);
0644 
0645     qreal resultingRealFive = toTestFive.squareDistance(p1_9, p2_9);
0646     QVERIFY(resultingRealFive == 2);
0647 }
0648 
0649 
0650 
0651 //------------------------------------------------------------------
0652 
0653 
0654 
0655 void TestSnapStrategy::testSnapToExtension()
0656 {
0657     /*
0658 
0659     toTest.snapToExtension(paramPosition, &paramPoint, paramMatrix);
0660 
0661 qDebug() << direction << " is the returned direction for this point in TestSnapStrategy::testSnapToExtension()";
0662     QCOMPARE(direction, );
0663     */
0664 }
0665 void TestSnapStrategy::testProject()
0666 {
0667     //tests for positive point values but backwards leaning line
0668     ExtensionSnapStrategy toTestOne;
0669     qreal toCompWithOne = -1;
0670     QPointF lineStart(4,4);
0671     QPointF lineEnd(2,2);
0672     QPointF comparisonPoint(6,6);
0673 
0674     qreal resultingRealOne = toTestOne.project(lineStart, lineEnd, comparisonPoint);
0675     QCOMPARE(resultingRealOne, toCompWithOne);
0676     //testing for negative point values
0677     ExtensionSnapStrategy toTestTwo;
0678     qreal toCompWithTwo = -4;
0679     QPointF lineStart_2(-2,-2);
0680     QPointF lineEnd_2(-4,-4);
0681     QPointF comparisonPoint_2(6,6);
0682 
0683     qreal resultingRealTwo = toTestTwo.project(lineStart_2, lineEnd_2, comparisonPoint_2);
0684     QCOMPARE(resultingRealTwo, toCompWithTwo);
0685     //testing for negative and positive point values
0686     ExtensionSnapStrategy toTestThree;
0687     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)))
0688     QPointF lineStart_3(-2,-2);
0689     QPointF lineEnd_3(4, 4);
0690     QPointF comparisonPoint_3(8,8);
0691 
0692     qreal resultingRealThree = toTestThree.project(lineStart_3, lineEnd_3, comparisonPoint_3);
0693     QCOMPARE(resultingRealThree, toCompWithThree);
0694 
0695     //Below we test the formula itself for the dot-product by using values we know return t=0.5
0696     //Formula for how to use the t value is:
0697     //ProjectionPoint = lineStart*(1-resultingReal) + resultingReal*lineEnd; (this is the formula used in BoundingBoxSnapStrategy::squareDistanceToLine())
0698     //Note: The angle of the line from projection point to comparison point is always 90 degrees
0699 
0700     ExtensionSnapStrategy toTestFour;
0701     qreal toCompWithFour = 0.5;
0702     QPointF lineStart_4(2,1);
0703     QPointF lineEnd_4(6,3);
0704     QPointF comparisonPoint_4(3,4);
0705 
0706     qreal resultingRealFour = toTestFour.project(lineStart_4, lineEnd_4, comparisonPoint_4);
0707     QCOMPARE(resultingRealFour, toCompWithFour);
0708 }
0709 
0710 void TestSnapStrategy::testExtensionDirection()
0711 {
0712     /* TEST CASE 0
0713        Supposed to return null
0714     */
0715     ExtensionSnapStrategy toTestOne;
0716     KoPathShape uninitiatedPathShape;
0717     KoPathPoint::PointProperties normal = KoPathPoint::Normal;
0718     const QPointF initiatedPoint0(0,0);
0719     KoPathPoint initiatedPoint(&uninitiatedPathShape, initiatedPoint0, normal);
0720     QMatrix initiatedMatrixParam(1,1,1,1,1,1);
0721     const QTransform initiatedMatrix(initiatedMatrixParam);
0722     QPointF direction2 = toTestOne.extensionDirection( &initiatedPoint, initiatedMatrix);
0723     QVERIFY(direction2.isNull());
0724 
0725     /* TEST CASE 1
0726     tests a point that:
0727      - is the first in a subpath,
0728      - does not have the firstSubpath property set,
0729      - it has no activeControlPoint1,
0730      - is has no previous point
0731 
0732      = expected returning an empty QPointF
0733     */
0734     ExtensionSnapStrategy toTestTwo;
0735     QPointF expectedPointTwo(0,0);
0736     KoPathShape shapeOne;
0737 
0738     QPointF firstPoint(0,1);
0739     QPointF secondPoint(1,2);
0740     QPointF thirdPoint(2,3);
0741     QPointF fourthPoint(3,4);
0742 
0743     shapeOne.moveTo(firstPoint);
0744     shapeOne.lineTo(secondPoint);
0745     shapeOne.lineTo(thirdPoint);
0746     shapeOne.lineTo(fourthPoint);
0747 
0748     QPointF paramPositionTwo(0,1);
0749     KoPathPoint paramPointTwo;
0750     paramPointTwo.setPoint(paramPositionTwo);
0751     paramPointTwo.setParent(&shapeOne);
0752 
0753     const QTransform paramTransMatrix(1,2,3,4,5,6);
0754     QPointF directionTwo = toTestTwo.extensionDirection( &paramPointTwo, paramTransMatrix);
0755     QCOMPARE(directionTwo, expectedPointTwo);
0756 
0757     /* TEST CASE 2
0758     tests a point that:
0759      - is the second in a subpath,
0760      - does not have the firstSubpath property set,
0761      - it has no activeControlPoint1,
0762      - is has a previous point
0763 
0764      = expected returning an
0765     */
0766     ExtensionSnapStrategy toTestThree;
0767     QPointF expectedPointThree(0,0);
0768     QPointF paramPositionThree(1,1);
0769     KoPathPoint paramPointThree;
0770     paramPointThree.setPoint(paramPositionThree);
0771     paramPointThree.setParent(&shapeOne);
0772     QPointF directionThree = toTestThree.extensionDirection( &paramPointThree, paramTransMatrix);
0773     QCOMPARE(directionThree, expectedPointThree);
0774 
0775 }
0776 
0777 void TestSnapStrategy::testSquareDistanceToLine()
0778 {
0779     BoundingBoxSnapStrategy toTestOne;
0780 
0781     const QPointF lineA(4,1);
0782     const QPointF lineB(6,3);
0783     const QPointF point(5,8);
0784     QPointF pointOnLine(0,0);
0785 
0786     qreal result = toTestOne.squareDistanceToLine(lineA, lineB, point, pointOnLine);
0787     //Should be HUGE_VAL because scalar > diffLength
0788     QVERIFY(result == HUGE_VAL);
0789 
0790     BoundingBoxSnapStrategy toTestTwo;
0791     QPointF lineA2(4,4);
0792     QPointF lineB2(4,4);
0793     QPointF point2(5,8);
0794     QPointF pointOnLine2(0,0);
0795 
0796     qreal result2 = toTestTwo.squareDistanceToLine(lineA2, lineB2, point2, pointOnLine2);
0797     //Should be HUGE_VAL because lineA2 == lineB2
0798     QVERIFY(result2 == HUGE_VAL);
0799 
0800     BoundingBoxSnapStrategy toTestThree;
0801     QPointF lineA3(6,4);
0802     QPointF lineB3(8,6);
0803     QPointF point3(2,2);
0804     QPointF pointOnLine3(0,0);
0805 
0806     qreal result3 = toTestThree.squareDistanceToLine(lineA3, lineB3, point3, pointOnLine3);
0807     //Should be HUGE_VAL because scalar < 0.0
0808     QVERIFY(result3 == HUGE_VAL);
0809 
0810     BoundingBoxSnapStrategy toTestFour;
0811     QPointF lineA4(2,2);
0812     QPointF lineB4(8,6);
0813     QPointF point4(3,4);
0814     QPointF pointOnLine4(0,0);
0815 
0816     QPointF diff(6,4);
0817     //diff = lineB3 - point3 = 6,4
0818     //diffLength = sqrt(52)
0819     //scalar = (1*(6/sqrt(52)) + 2*(4/sqrt(52)));
0820 
0821     //pointOnLine = lineA + scalar / diffLength * diff;  lineA + ((1*(6/sqrt(52)) + 2*(4/sqrt(52))) / sqrt(52)) * 6,4;
0822     QPointF distToPointOnLine = (lineA4 + ((1*(6/sqrt(52.0)) + 2*(4/sqrt(52.0))) / sqrt(52.0)) * diff)-point4;
0823     qreal toCompWithFour = distToPointOnLine.x()*distToPointOnLine.x()+distToPointOnLine.y()*distToPointOnLine.y();
0824 
0825     qreal result4 = toTestFour.squareDistanceToLine(lineA4, lineB4, point4, pointOnLine4);
0826     //Normal case with example data
0827     QVERIFY(qFuzzyCompare(result4, toCompWithFour));
0828 
0829 }
0830 KISTEST_MAIN(TestSnapStrategy)