VPiece to JSON.

Strict version to support Unit tests.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2019-08-29 15:01:27 +03:00
parent 0a28339963
commit df3684d2a1
25 changed files with 1143 additions and 355 deletions

View file

@ -28,6 +28,7 @@
#include "vgobject.h"
#include <QJsonObject>
#include <QLine>
#include <QLineF>
#include <QPoint>
@ -205,6 +206,18 @@ quint32 VGObject::getIdTool() const
}
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VGObject::ToJson() const
{
QJsonObject object
{
{"id", static_cast<qint64>(id())},
{"type", static_cast<int>(getType())},
};
return object;
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VGObject::BuildLine(const QPointF &p1, const qreal &length, const qreal &angle)
{

View file

@ -82,6 +82,8 @@ public:
quint32 getIdTool() const;
virtual QJsonObject ToJson() const;
static QLineF BuildLine(const QPointF &p1, const qreal& length, const qreal &angle);
static QPointF BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect);
static QLineF BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect);

View file

@ -28,6 +28,7 @@
#include "vpointf.h"
#include "vpointf_p.h"
#include <QJsonObject>
#include <QLineF>
#include <QPointF>
#include <QString>
@ -232,6 +233,18 @@ void VPointF::SetShowLabel(bool hide)
d->m_showLabel = hide;
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VPointF::ToJson() const
{
QJsonObject object = VGObject::ToJson();
object[QLatin1String("x")] = x();
object[QLatin1String("y")] = y();
object[QLatin1String("name")] = name();
object[QLatin1String("mx")] = mx();
object[QLatin1String("my")] = my();
return object;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VPointF::RotatePF(const QPointF &originPoint, const QPointF &point, qreal degrees)
{

View file

@ -85,6 +85,8 @@ public:
bool IsShowLabel() const;
void SetShowLabel(bool hide);
virtual QJsonObject ToJson() const override;
static QPointF RotatePF(const QPointF &originPoint, const QPointF &point, qreal degrees);
static QPointF FlipPF(const QLineF &axis, const QPointF &point);
static QPointF MovePF(const QPointF &originPoint, qreal length, qreal angle);

View file

@ -28,6 +28,7 @@
#include "vspline.h"
#include <QJsonObject>
#include <QLineF>
#include "vabstractcurve.h"
@ -548,6 +549,24 @@ qreal VSpline::ParamT (const QPointF &pBt) const
return tx;
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VSpline::ToJson() const
{
QJsonObject object = VAbstractCubicBezier::ToJson();
object[QLatin1String("aScale")] = GetApproximationScale();
object[QLatin1String("p1")] = GetP1().ToJson();
object[QLatin1String("p4")] = GetP4().ToJson();
object[QLatin1String("angle1")] = GetStartAngle();
object[QLatin1String("angle1Formula")] = GetStartAngleFormula();
object[QLatin1String("angle2")] = GetEndAngle();
object[QLatin1String("angle2Formula")] = GetEndAngleFormula();
object[QLatin1String("c1Length")] = GetC1Length();
object[QLatin1String("c1LengthFormula")] = GetC1LengthFormula();
object[QLatin1String("c2Length")] = GetC2Length();
object[QLatin1String("c2LengthFormula")] = GetC2LengthFormula();
return object;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VSpline::GetControlPoint1() const
{

View file

@ -114,6 +114,8 @@ public:
qreal kAsm2, qreal kCurve, qreal approximationScale);
qreal ParamT(const QPointF &pBt) const;
virtual QJsonObject ToJson() const override;
protected:
virtual QPointF GetControlPoint1() const override;
virtual QPointF GetControlPoint2() const override;

View file

@ -28,6 +28,8 @@
#include "vsplinepath.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QPoint>
#include "../ifc/exception/vexception.h"
@ -323,6 +325,22 @@ const VSplinePoint &VSplinePath::at(int indx) const
return d->path[indx];
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VSplinePath::ToJson() const
{
QJsonObject object = VAbstractCubicBezierPath::ToJson();
object[QLatin1String("aScale")] = GetApproximationScale();
QJsonArray nodesArray;
for (auto &node: d->path)
{
nodesArray.append(node.ToJson());
}
object[QLatin1String("nodes")] = nodesArray;
return object;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePath::GetStartAngle() const
{

View file

@ -93,6 +93,9 @@ public:
VSplinePoint GetSplinePoint(qint32 indexSpline, SplinePointPosition pos) const;
const VSplinePoint &at(int indx) const;
virtual QJsonObject ToJson() const override;
protected:
virtual VPointF FirstPoint() const override;
virtual VPointF LastPoint() const override;

View file

@ -28,6 +28,7 @@
#include "vsplinepoint.h"
#include <QJsonObject>
#include <QLineF>
#include "../qmuparser/qmutokenparser.h"
@ -332,3 +333,21 @@ bool VSplinePoint::IsMovable() const
return qmu::QmuTokenParser::IsSingle(d->angle1F) && qmu::QmuTokenParser::IsSingle(d->angle2F) &&
qmu::QmuTokenParser::IsSingle(d->length1F) && qmu::QmuTokenParser::IsSingle(d->length2F);
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VSplinePoint::ToJson() const
{
QJsonObject object
{
{"point", d->pSpline.ToJson()},
{"angle1", d->angle1},
{"angle1Formula", d->angle1F},
{"angle2", d->angle2},
{"angle2Formula", d->angle2F},
{"length1", d->length1},
{"length1Formula", d->length1F},
{"length2", d->length2},
{"length2Formula", d->length2F},
};
return object;
}

View file

@ -119,6 +119,8 @@ public:
void SetLength2(const qreal &value, const QString &length2F);
bool IsMovable() const;
QJsonObject ToJson() const;
protected:
QSharedDataPointer<VSplinePointData> d;
};

View file

@ -0,0 +1,72 @@
/************************************************************************
**
** @file testpath.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 28 8, 2019
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2019 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "testpath.h"
#include <QVector>
#include <QJsonArray>
#include <QTemporaryFile>
#include <QJsonObject>
#include <QTextStream>
#include <QJsonDocument>
#include <QPointF>
//---------------------------------------------------------------------------------------------------------------------
#if !defined(V_NO_ASSERT)
// Use for writing tests
void VectorToJson(const QVector<QPointF> &points, QJsonObject &json)
{
QJsonArray pointsArray;
for (auto point: points)
{
QJsonObject pointObject;
pointObject[QLatin1String("type")] = "QPointF";
pointObject[QLatin1String("x")] = point.x();
pointObject[QLatin1String("y")] = point.y();
pointsArray.append(pointObject);
}
json[QLatin1String("vector")] = pointsArray;
}
//---------------------------------------------------------------------------------------------------------------------
void DumpVector(const QVector<QPointF> &points)
{
QTemporaryFile temp; // Go to tmp folder to find dump
temp.setAutoRemove(false); // Remove dump manually
if (temp.open())
{
QJsonObject vectorObject;
VectorToJson(points, vectorObject);
QJsonDocument vector(vectorObject);
QTextStream out(&temp);
out << vector.toJson();
out.flush();
}
}
#endif // !defined(V_NO_ASSERT)

View file

@ -0,0 +1,40 @@
/************************************************************************
**
** @file testpath.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 28 8, 2019
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2019 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef TESTPATH_H
#define TESTPATH_H
class QPointF;
class QJsonObject;
template <class T> class QVector;
#if !defined(V_NO_ASSERT)
void VectorToJson(const QVector<QPointF> &points, QJsonObject &json);
void DumpVector(const QVector<QPointF> &points);
#endif // !defined(V_NO_ASSERT)
#endif // TESTPATH_H

View file

@ -35,6 +35,7 @@
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/vcontainer.h"
#include "../vpatterndb/calculator.h"
#include "testpath.h"
#include <QLineF>
#include <QSet>
@ -535,21 +536,6 @@ qreal AngleBetweenBisectors(const QLineF &b1, const QLineF &b2)
//---------------------------------------------------------------------------------------------------------------------
#if !defined(V_NO_ASSERT)
// Use for writing tests
void VectorToJson(const QVector<QPointF> &points, QJsonObject &json)
{
QJsonArray pointsArray;
for (auto point: points)
{
QJsonObject pointObject;
pointObject[QLatin1String("type")] = "QPointF";
pointObject[QLatin1String("x")] = point.x();
pointObject[QLatin1String("y")] = point.y();
pointsArray.append(pointObject);
}
json[QLatin1String("vector")] = pointsArray;
}
//---------------------------------------------------------------------------------------------------------------------
void VectorToJson(const QVector<VSAPoint> &points, QJsonObject &json)
{
@ -561,23 +547,6 @@ void VectorToJson(const QVector<VSAPoint> &points, QJsonObject &json)
json[QLatin1String("vector")] = pointsArray;
}
//---------------------------------------------------------------------------------------------------------------------
void DumpVector(const QVector<QPointF> &points)
{
QTemporaryFile temp; // Go to tmp folder to find dump
temp.setAutoRemove(false); // Remove dump manually
if (temp.open())
{
QJsonObject vectorObject;
VectorToJson(points, vectorObject);
QJsonDocument vector(vectorObject);
QTextStream out(&temp);
out << vector.toJson();
out.flush();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DumpVector(const QVector<VSAPoint> &points)
{

View file

@ -3,6 +3,7 @@
HEADERS += \
$$PWD/stable.h \
$$PWD/testpath.h \
$$PWD/vlayoutgenerator.h \
$$PWD/vlayoutdef.h \
$$PWD/vlayoutpaper.h \
@ -24,6 +25,7 @@ HEADERS += \
$$PWD/vbestsquare_p.h
SOURCES += \
$$PWD/testpath.cpp \
$$PWD/vlayoutgenerator.cpp \
$$PWD/vlayoutpaper.cpp \
$$PWD/vbank.cpp \

View file

@ -36,10 +36,15 @@
#include "vcontainer.h"
#include "../vmisc/vabstractapplication.h"
#include "../ifc/exception/vexceptioninvalidnotch.h"
#include "../vlayout/testpath.h"
#include <QSharedPointer>
#include <QDebug>
#include <QPainterPath>
#include <QTemporaryFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
namespace
{
@ -150,8 +155,12 @@ void VPiece::SetPath(const VPiecePath &path)
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::MainPathPoints(const VContainer *data) const
{
// DumpPiece(*this, data); // Uncomment for dumping test data
QVector<QPointF> points = GetPath().PathPoints(data);
points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops
// DumpVector(points); // Uncomment for dumping test data
return points;
}
@ -1077,3 +1086,77 @@ int VPiece::IsCSAStart(const QVector<CustomSARecord> &records, quint32 id)
return -1;
}
//---------------------------------------------------------------------------------------------------------------------
#if !defined(V_NO_ASSERT)
// Use for writing tests
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VPiece::MainPathToJson() const
{
QJsonObject pieceObject
{
{"seamAllowance", IsSeamAllowance()},
{"saWidth", GetSAWidth()},
};
QJsonArray nodesArray;
for (qint32 i = 0; i < d->m_path.CountNodes(); ++i)
{
QJsonObject nodeObject
{
{"id", static_cast<qint64>(d->m_path.at(i).GetId())},
{"type", static_cast<int>(d->m_path.at(i).GetTypeTool())},
{"reverse", d->m_path.at(i).GetReverse()},
};
nodesArray.append(nodeObject);
}
pieceObject[QLatin1String("nodes")] = nodesArray;
return pieceObject;
}
//---------------------------------------------------------------------------------------------------------------------
QJsonObject VPiece::DBToJson(const VContainer *data) const
{
QJsonArray itemsArray;
for (qint32 i = 0; i < d->m_path.CountNodes(); ++i)
{
itemsArray.append(data->GetGObject(d->m_path.at(i).GetId())->ToJson());
}
QJsonObject dbObject
{
{"items", itemsArray}
};
return dbObject;
}
//---------------------------------------------------------------------------------------------------------------------
void VPiece::DumpPiece(const VPiece &piece, const VContainer *data)
{
SCASSERT(data != nullptr)
QTemporaryFile temp; // Go to tmp folder to find dump
temp.setAutoRemove(false); // Remove dump manually
if (temp.open())
{
QJsonObject testCase
{
{"bd", piece.DBToJson(data)},
{"piece", piece.MainPathToJson()},
};
QJsonObject json
{
{"testCase", testCase},
};
QJsonDocument document(json);
QTextStream out(&temp);
out << document.toJson();
out.flush();
}
}
#endif // !defined(V_NO_ASSERT)

View file

@ -136,6 +136,8 @@ public:
QVector<VPieceNode> GetUnitedPath(const VContainer *data) const;
QVector<QPointF> SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const;
static void DumpPiece(const VPiece &piece, const VContainer *data);
private:
QSharedDataPointer<VPieceData> d;
@ -156,6 +158,9 @@ private:
const VContainer *data) const;
static int IsCSAStart(const QVector<CustomSARecord> &records, quint32 id);
QJsonObject MainPathToJson() const;
QJsonObject DBToJson(const VContainer *data) const;
};
Q_DECLARE_TYPEINFO(VPiece, Q_MOVABLE_TYPE);

View file

@ -52,7 +52,13 @@
#include "vsysexits.h"
#include "../vgeometry/vgobject.h"
#include "../vgeometry/vpointf.h"
#include "../vgeometry/vspline.h"
#include "../vgeometry/vsplinepath.h"
#include "../vlayout/vabstractpiece.h"
#include "../vpatterndb/vcontainer.h"
#include "../vpatterndb/vpiece.h"
#include "../vpatterndb/vpiecenode.h"
//---------------------------------------------------------------------------------------------------------------------
AbstractTest::AbstractTest(QObject *parent) :
@ -63,41 +69,25 @@ AbstractTest::AbstractTest(QObject *parent) :
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VectorFromJson(const QString &json, QVector<QPointF>& vector)
{
QFile loadFile(json);
if (not loadFile.open(QIODevice::ReadOnly))
{
const QString error = QStringLiteral("Couldn't open json file. %1").arg(loadFile.errorString());
QFAIL(qUtf8Printable(error));
}
QByteArray saveData = loadFile.readAll();
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString vectorKey = QStringLiteral("vector");
const QString typeKey = QStringLiteral("type");
const QString xKey = QStringLiteral("x");
const QString yKey = QStringLiteral("y");
QJsonObject vectorObject = loadDoc.object();
if (not vectorObject.contains(vectorKey))
{
const QString error = QStringLiteral("Invalid json file '%1'. File doesn't contain root object.").arg(json);
QFAIL(qUtf8Printable(error));
}
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = loadDoc.object()[vectorKey].toArray();
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i)
{
QJsonObject pointObject = vectorArray[i].toObject();
if (not pointObject.contains(typeKey))
{
const QString error = QStringLiteral("Invalid json file '%1'. Json object doesn't provide class type.")
.arg(json);
QFAIL(qUtf8Printable(error));
}
QString type;
AbstractTest::ReadStringValue(pointObject, typeKey, type);
if (pointObject[typeKey].toString() != QLatin1String("QPointF"))
if (type != QLatin1String("QPointF"))
{
const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.")
.arg(json, pointObject[typeKey].toString());
@ -106,43 +96,13 @@ void AbstractTest::VectorFromJson(const QString &json, QVector<QPointF>& vector)
QPointF point;
if (pointObject.contains(xKey))
{
QJsonValue xValue = pointObject[xKey];
if (xValue.isDouble())
{
point.setX(xValue.toDouble());
}
else
{
const QString error = QStringLiteral("X coordinate is not double '%1'.").arg(xValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
const QString error = QStringLiteral("Json object does not contain X coordinate.");
QFAIL(qUtf8Printable(error));
}
qreal x = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("x"), x);
point.setX(x);
if (pointObject.contains(yKey))
{
QJsonValue yValue = pointObject[yKey];
if (yValue.isDouble())
{
point.setY(yValue.toDouble());
}
else
{
const QString error = QStringLiteral("Y coordinate is not double '%1'.").arg(yValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
const QString error = QStringLiteral("Json object does not contain Y coordinate.");
QFAIL(qUtf8Printable(error));
}
qreal y = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("y"), y);
point.setY(y);
vector.append(point);
}
@ -151,44 +111,28 @@ void AbstractTest::VectorFromJson(const QString &json, QVector<QPointF>& vector)
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VectorFromJson(const QString &json, QVector<VSAPoint> &vector)
{
QFile loadFile(json);
if (not loadFile.open(QIODevice::ReadOnly))
{
const QString error = QStringLiteral("Couldn't open json file. %1").arg(loadFile.errorString());
QFAIL(qUtf8Printable(error));
}
QByteArray saveData = loadFile.readAll();
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const int defaultAngle = static_cast<int>(PieceNodeAngle::ByLength);
const QString vectorKey = QStringLiteral("vector");
const QString typeKey = QStringLiteral("type");
const QString xKey = QStringLiteral("x");
const QString yKey = QStringLiteral("y");
const QString saBeforeKey = QStringLiteral("saBefore");
const QString saAfterKey = QStringLiteral("saAfter");
const QString angleKey = QStringLiteral("angle");
QJsonObject vectorObject = loadDoc.object();
if (not vectorObject.contains(vectorKey))
{
const QString error = QStringLiteral("Invalid json file '%1'. File doesn't contain root object.").arg(json);
QFAIL(qUtf8Printable(error));
}
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = loadDoc.object()[vectorKey].toArray();
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i)
{
QJsonObject pointObject = vectorArray[i].toObject();
if (not pointObject.contains(typeKey))
{
const QString error = QStringLiteral("Invalid json file '%1'. Json object doesn't provide class type.")
.arg(json);
QFAIL(qUtf8Printable(error));
}
QString type;
AbstractTest::ReadStringValue(pointObject, typeKey, type);
if (pointObject[typeKey].toString() != QLatin1String("VSAPoint"))
{
@ -199,43 +143,15 @@ void AbstractTest::VectorFromJson(const QString &json, QVector<VSAPoint> &vector
VSAPoint point;
if (pointObject.contains(xKey))
{
QJsonValue xValue = pointObject[xKey];
if (xValue.isDouble())
{
point.setX(xValue.toDouble());
}
else
{
const QString error = QStringLiteral("X coordinate is not double '%1'.").arg(xValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
const QString error = QStringLiteral("Json object does not contain X coordinate.");
QFAIL(qUtf8Printable(error));
}
qreal x = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("x"), x);
point.setX(x);
qreal y = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("y"), y);
point.setY(y);
if (pointObject.contains(yKey))
{
QJsonValue yValue = pointObject[yKey];
if (yValue.isDouble())
{
point.setY(yValue.toDouble());
}
else
{
const QString error = QStringLiteral("Y coordinate is not double '%1'.").arg(yValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
const QString error = QStringLiteral("Json object does not contain Y coordinate.");
QFAIL(qUtf8Printable(error));
}
if (pointObject.contains(saBeforeKey))
{
@ -284,6 +200,43 @@ void AbstractTest::VectorFromJson(const QString &json, QVector<VSAPoint> &vector
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data)
{
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString testCaseKey = QStringLiteral("testCase");
const QString bdKey = QStringLiteral("bd");
const QString pieceKey = QStringLiteral("piece");
QJsonObject testCaseObject = loadDoc.object();
TestRoot(testCaseObject, testCaseKey, json);
QJsonObject testCase = testCaseObject[testCaseKey].toObject();
if (testCase.contains(bdKey))
{
DBFromJson(testCase[bdKey].toObject(), data);
}
else
{
const QString error = QStringLiteral("Test case json object does not contain db data.");
QFAIL(qUtf8Printable(error));
}
if (testCase.contains(pieceKey))
{
MainPathFromJson(testCase[pieceKey].toObject(), piece);
}
else
{
const QString error = QStringLiteral("Test case json object does not contain piece data.");
QFAIL(qUtf8Printable(error));
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const
{
@ -294,7 +247,7 @@ void AbstractTest::Comparison(const QVector<QPointF> &ekv, const QVector<QPointF
{
const QPointF p1 = ekv.at(i);
const QPointF p2 = ekvOrig.at(i);
const QString msg = QString("Index: %1. Got '%2;%3', Expected '%4;%5'.")
const QString msg = QStringLiteral("Index: %1. Got '%2;%3', Expected '%4;%5'.")
.arg(i).arg(p1.x()).arg(p1.y()).arg(p2.x()).arg(p2.y());
// Check each point. Don't use comparison float values
QVERIFY2(VFuzzyComparePoints(p1, p2), qUtf8Printable(msg));
@ -370,12 +323,13 @@ QString AbstractTest::TranslationsPath() const
//---------------------------------------------------------------------------------------------------------------------
int AbstractTest::Run(int exit, const QString &program, const QStringList &arguments, QString &error, int msecs)
{
const QString parameters = QString("Program: %1 \nArguments: %2.").arg(program, arguments.join(", "));
const QString parameters = QStringLiteral("Program: %1 \nArguments: %2.")
.arg(program, arguments.join(QStringLiteral(", ")));
QFileInfo info(program);
if (not info.exists())
{
error = QString("Can't find binary.\n%1").arg(parameters);
error = QStringLiteral("Can't find binary.\n%1").arg(parameters);
return TST_EX_BIN;
}
@ -426,7 +380,7 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
const QString dirName = QFileInfo(tgtFilePath).fileName();
if (not targetDir.mkdir(dirName))
{
const QString msg = QString("Can't create dir '%1'.").arg(dirName);
const QString msg = QStringLiteral("Can't create dir '%1'.").arg(dirName);
QWARN(qUtf8Printable(msg));
return false;
}
@ -447,7 +401,7 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
{
if (QFileInfo::exists(tgtFilePath))
{
const QString msg = QString("File '%1' exists.").arg(srcFilePath);
const QString msg = QStringLiteral("File '%1' exists.").arg(srcFilePath);
QWARN(qUtf8Printable(msg));
if (QFile::remove(tgtFilePath))
@ -465,7 +419,8 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
QFile srcFile(srcFilePath);
if (not srcFile.open(QFile::ReadOnly))
{
const QString msg = QString("Can't copy file '%1'. Error: %2").arg(srcFilePath, srcFile.errorString());
const QString msg = QStringLiteral("Can't copy file '%1'. Error: %2")
.arg(srcFilePath, srcFile.errorString());
QWARN(qUtf8Printable(msg));
return false;
}
@ -473,7 +428,7 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
if (not srcFile.copy(tgtFilePath))
{
const QString msg = QString("Can't copy file '%1' to '%2'. Error: %3")
const QString msg = QStringLiteral("Can't copy file '%1' to '%2'. Error: %3")
.arg(srcFilePath, tgtFilePath, srcFile.errorString());
QWARN(qUtf8Printable(msg));
return false;
@ -481,3 +436,399 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::PrepareDocument(const QString &json, QByteArray &data) const
{
QFile loadFile(json);
if (not loadFile.open(QIODevice::ReadOnly))
{
const QString error = QStringLiteral("Couldn't open json file. %1").arg(loadFile.errorString());
QFAIL(qUtf8Printable(error));
}
data = loadFile.readAll();
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::TestRoot(const QJsonObject &root, const QString &attribute, const QString &file)
{
if (not root.contains(attribute))
{
const QString error = QStringLiteral("Invalid json file '%1'. File doesn't contain root object.").arg(file);
QFAIL(qUtf8Printable(error));
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue)
{
if (itemObject.contains(attribute))
{
QJsonValue attributeValue = itemObject[attribute];
if (attributeValue.isString())
{
value = attributeValue.toString();
}
else
{
const QString error = QStringLiteral("%1 is not string '%2'.").arg(attribute, attributeValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
if (not defaultValue.isEmpty())
{
value = defaultValue;
}
else
{
const QString error = QStringLiteral("Json object does not contain attribute '%1'.").arg(attribute);
QFAIL(qUtf8Printable(error));
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue)
{
if (itemObject.contains(attribute))
{
QJsonValue attributeValue = itemObject[attribute];
if (attributeValue.isBool())
{
value = attributeValue.toBool();
}
else
{
const QString error = QStringLiteral("%1 is not boolean value '%2'.").arg(attribute,
attributeValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
if (not defaultValue.isEmpty())
{
bool ok = false;
int defVal = defaultValue.toInt(&ok);
if (not ok)
{
const QString error = QStringLiteral("Cannot convert default value '%1' to int.").arg(defaultValue);
QFAIL(qUtf8Printable(error));
}
value = static_cast<bool>(defVal);
}
else
{
const QString error = QStringLiteral("Json object does not contain attribute '%1'.").arg(attribute);
QFAIL(qUtf8Printable(error));
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadPointValue(const QJsonObject &itemObject, const QString &attribute, VPointF &value)
{
if (itemObject.contains(attribute))
{
QJsonObject p1Object = itemObject[attribute].toObject();
PointFromJson(p1Object, value);
}
else
{
const QString error = QStringLiteral("Json object does not contain attribute '%1'.").arg(attribute);
QFAIL(qUtf8Printable(error));
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadSplinePointValues(const QJsonObject &itemObject, const QString &attribute,
QVector<VSplinePoint> &points)
{
points.clear();
if (itemObject.contains(attribute))
{
QJsonArray nodes = itemObject[attribute].toArray();
for (int i = 0; i < nodes.size(); ++i)
{
QJsonObject item = nodes[i].toObject();
VSplinePoint point;
ReadSplinePointValue(item, point);
points.append(point);
}
}
else
{
const QString error = QStringLiteral("Json object does not contain attribute '%1'.").arg(attribute);
QFAIL(qUtf8Printable(error));
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadSplinePointValue(const QJsonObject &itemObject, VSplinePoint &point)
{
qreal angle1 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("angle1"), angle1);
QString angle1Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("angle1Formula"), angle1Formula);
qreal angle2 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("angle2"), angle2);
QString angle2Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("angle2Formula"), angle2Formula);
qreal length1 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("length1"), length1);
QString length1Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("length1Formula"), length1Formula);
qreal length2 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("length2"), length2);
QString length2Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("length2Formula"), length2Formula);
VPointF pSpline;
ReadPointValue(itemObject, QStringLiteral("point"), pSpline);
point = VSplinePoint(pSpline, angle1, angle1Formula, angle2, angle2Formula, length1, length1Formula, length2,
length2Formula);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode &node)
{
vidtype id = NULL_ID;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id);
Tool typeTool = Tool::LAST_ONE_DO_NOT_USE;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("type"), typeTool);
bool reverse = false;
AbstractTest::ReadBooleanValue(itemObject, QStringLiteral("reverse"), reverse, QChar('0'));
node = VPieceNode(id, typeTool, reverse);
}
//---------------------------------------------------------------------------------------------------------------------
template<typename T>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue)
{
if (itemObject.contains(attribute))
{
QJsonValue attributeValue = itemObject[attribute];
if (attributeValue.isDouble())
{
value = static_cast<T>(attributeValue.toDouble());
}
else
{
const QString error = QStringLiteral("%1 is not double '%2'.").arg(attribute, attributeValue.toString());
QFAIL(qUtf8Printable(error));
}
}
else
{
if (not defaultValue.isEmpty())
{
bool ok = false;
qreal defVal = defaultValue.toDouble(&ok);
if (not ok)
{
const QString error = QStringLiteral("Cannot convert default value '%1' to double.").arg(defaultValue);
QFAIL(qUtf8Printable(error));
}
value = static_cast<T>(defVal);
}
else
{
const QString error = QStringLiteral("Json object does not contain attribute '%1'.").arg(attribute);
QFAIL(qUtf8Printable(error));
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::PointFromJson(const QJsonObject &itemObject, VPointF &value)
{
vidtype id = NULL_ID;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id);
qreal mx = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("mx"), mx);
qreal my = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("my"), my);
QString name;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("name"), name);
qreal x = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("x"), x);
qreal y = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("y"), y);
value = VPointF(x, y, name, mx, my);
value.setId(id);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::SplineFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data)
{
vidtype id = NULL_ID;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id);
qreal aScale = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("aScale"), aScale);
qreal angle1 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("angle1"), angle1);
QString angle1Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("angle1Formula"), angle1Formula);
qreal angle2 = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("angle2"), angle2);
QString angle2Formula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("angle2Formula"), angle2Formula);
qreal c1Length = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("c1Length"), c1Length);
QString c1LengthFormula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("c1LengthFormula"), c1LengthFormula);
qreal c2Length = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("c2Length"), c2Length);
QString c2LengthFormula;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("c2LengthFormula"), c2LengthFormula);
VPointF p1;
ReadPointValue(itemObject, QStringLiteral("p1"), p1);
data->UpdateGObject(p1.id(), new VPointF(p1));
VPointF p4;
ReadPointValue(itemObject, QStringLiteral("p4"), p4);
data->UpdateGObject(p4.id(), new VPointF(p4));
VSpline *spl = new VSpline(p1, p4, angle1, angle1Formula, angle2, angle2Formula, c1Length, c1LengthFormula,
c2Length, c2LengthFormula);
spl->SetApproximationScale(aScale);
data->UpdateGObject(id, spl);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::SplinePathFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data)
{
vidtype id = NULL_ID;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id);
qreal aScale = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("aScale"), aScale);
QVector<VSplinePoint> points;
AbstractTest::ReadSplinePointValues(itemObject, QStringLiteral("nodes"), points);
for (auto &point : points)
{
data->UpdateGObject(point.P().id(), new VPointF(point.P()));
}
VSplinePath *path = new VSplinePath(points);
path->SetApproximationScale(aScale);
data->UpdateGObject(id, path);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::DBFromJson(const QJsonObject &dbObject, QSharedPointer<VContainer> &data)
{
const QString itemsKey = QStringLiteral("items");
if (dbObject.contains(itemsKey))
{
QJsonArray items = dbObject[itemsKey].toArray();
for (int i = 0; i < items.size(); ++i)
{
QJsonObject itemObject = items[i].toObject();
GOType objectType;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("type"), objectType);
switch(objectType)
{
case GOType::Point:
{
VPointF point;
PointFromJson(itemObject, point);
data->UpdateGObject(point.id(), new VPointF(point));
break;
}
case GOType::Spline:
SplineFromJson(itemObject, data);
break;
case GOType::SplinePath:
SplinePathFromJson(itemObject, data);
break;
default:
{
const QString error = QStringLiteral("Not supported item type '%1'.")
.arg(static_cast<int>(objectType));
QFAIL(qUtf8Printable(error));
}
}
}
}
else
{
const QString error = QStringLiteral("DB json object does not contain items.");
QFAIL(qUtf8Printable(error));
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::MainPathFromJson(const QJsonObject &pieceObject, VPiece &piece)
{
qreal saWidth = 0;
AbstractTest::ReadDoubleValue(pieceObject, QStringLiteral("saWidth"), saWidth);
bool seamAllowance = false;
AbstractTest::ReadBooleanValue(pieceObject, QStringLiteral("seamAllowance"), seamAllowance);
piece.SetSeamAllowance(seamAllowance);
piece.SetSAWidth(saWidth);
piece.GetPath().Clear();
const QString nodesKey = QStringLiteral("nodes");
if (pieceObject.contains(nodesKey))
{
QJsonArray nodes = pieceObject[nodesKey].toArray();
for (int i = 0; i < nodes.size(); ++i)
{
QJsonObject itemObject = nodes[i].toObject();
VPieceNode node;
ReadPieceNodeValue(itemObject, node);
piece.GetPath().Append(node);
}
}
else
{
const QString error = QStringLiteral("Piece json object does not contain nodes.");
QFAIL(qUtf8Printable(error));
}
}

View file

@ -54,6 +54,13 @@ static const auto V_UNUSED TST_EX_CRASH = -4; // Program crashed.
enum ErrorState {ErrorLoad = 0, ErrorInstall, ErrorSize, NoError};
class VPiece;
class VContainer;
class VPointF;
class VSplinePoint;
class VPieceNode;
enum class GOType : char;
class AbstractTest : public QObject
{
Q_OBJECT
@ -63,6 +70,8 @@ public:
void VectorFromJson(const QString &json, QVector<QPointF>& vector);
void VectorFromJson(const QString &json, QVector<VSAPoint>& vector);
void PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data);
protected:
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
void Comparison(const QPointF &result, const QPointF &expected) const;
@ -74,6 +83,28 @@ protected:
int Run(int exit, const QString &program, const QStringList &arguments, QString &error, int msecs = 120000);
bool CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const;
void PrepareDocument(const QString &json, QByteArray &data) const;
void TestRoot(const QJsonObject &root, const QString &attribute, const QString &file);
template <typename T>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString());
void ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue = QString());
void ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue = QString());
void ReadPointValue(const QJsonObject &itemObject, const QString &attribute, VPointF &value);
void ReadSplinePointValues(const QJsonObject &itemObject, const QString &attribute, QVector<VSplinePoint> &points);
void ReadSplinePointValue(const QJsonObject &itemObject, VSplinePoint &point);
void ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode &node);
void PointFromJson(const QJsonObject &itemObject, VPointF &value);
void SplineFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data);
void SplinePathFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data);
void DBFromJson(const QJsonObject &dbObject, QSharedPointer<VContainer> &data);
void MainPathFromJson(const QJsonObject &pieceObject, VPiece &piece);
};
#endif // ABSTRACTTEST_H

View file

@ -4,7 +4,7 @@
#
#-------------------------------------------------
QT += testlib widgets printsupport concurrent
QT += testlib widgets printsupport concurrent xml
QT -= gui
@ -90,6 +90,15 @@ CONFIG(release, debug|release){
}
}
#VTest static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtest/$${DESTDIR} -lvtest
INCLUDEPATH += $$PWD/../../libs/vtest
DEPENDPATH += $$PWD/../../libs/vtest
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/vtest.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/libvtest.a
#VTools static library (depend on VWidgets, VMisc, VPatternDB)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtools/$${DESTDIR}/ -lvtools
@ -126,15 +135,6 @@ DEPENDPATH += $$PWD/../../libs/vpatterndb
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/vpatterndb.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/libvpatterndb.a
#VTest static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtest/$${DESTDIR} -lvtest
INCLUDEPATH += $$PWD/../../libs/vtest
DEPENDPATH += $$PWD/../../libs/vtest
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/vtest.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/libvtest.a
# VGeometry static library (depend on ifc)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vgeometry/$${DESTDIR} -lvgeometry

View file

@ -102,15 +102,6 @@ CONFIG(release, debug|release){
}
}
#VPatternDB static library (depend on vgeometry, vmisc, VLayout)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vpatterndb/$${DESTDIR} -lvpatterndb
INCLUDEPATH += $$PWD/../../libs/vpatterndb
DEPENDPATH += $$PWD/../../libs/vpatterndb
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/vpatterndb.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/libvpatterndb.a
#VTest static library (depend on VGeometry)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtest/$${DESTDIR} -lvtest
@ -120,6 +111,15 @@ DEPENDPATH += $$PWD/../../libs/vtest
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/vtest.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/libvtest.a
#VPatternDB static library (depend on vgeometry, vmisc, VLayout)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vpatterndb/$${DESTDIR} -lvpatterndb
INCLUDEPATH += $$PWD/../../libs/vpatterndb
DEPENDPATH += $$PWD/../../libs/vpatterndb
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/vpatterndb.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/libvpatterndb.a
#VMisc static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vmisc/$${DESTDIR} -lvmisc
@ -129,6 +129,15 @@ DEPENDPATH += $$PWD/../../libs/vmisc
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/vmisc.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/libvmisc.a
# VLayout static library (depend on IFC, VGeometry)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vlayout/$${DESTDIR}/ -lvlayout
INCLUDEPATH += $$PWD/../../libs/vlayout
DEPENDPATH += $$PWD/../../libs/vlayout
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vlayout/$${DESTDIR}/vlayout.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vlayout/$${DESTDIR}/libvlayout.a
## VGeometry static library (depend on ifc)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vgeometry/$${DESTDIR} -lvgeometry

View file

@ -128,6 +128,15 @@ CONFIG(release, debug|release){
}
}
#VTest static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtest/$${DESTDIR} -lvtest
INCLUDEPATH += $$PWD/../../libs/vtest
DEPENDPATH += $$PWD/../../libs/vtest
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/vtest.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/libvtest.a
#VTools static library (depend on VWidgets, VMisc, VPatternDB)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtools/$${DESTDIR}/ -lvtools
@ -173,15 +182,6 @@ DEPENDPATH += $$PWD/../../libs/ifc
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/ifc/$${DESTDIR}/ifc.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/ifc/$${DESTDIR}/libifc.a
#VTest static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vtest/$${DESTDIR} -lvtest
INCLUDEPATH += $$PWD/../../libs/vtest
DEPENDPATH += $$PWD/../../libs/vtest
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/vtest.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vtest/$${DESTDIR}/libvtest.a
#VMisc static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vmisc/$${DESTDIR}/ -lvmisc

View file

@ -0,0 +1,175 @@
{
"testCase": {
"bd": {
"items": [
{
"id": 9,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A",
"type": 0,
"x": 30,
"y": 39.999874015748034
},
{
"id": 10,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A1",
"type": 0,
"x": 333.80102715408316,
"y": 37.24215812551862
},
{
"id": 11,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A2",
"type": 0,
"x": 345.43524385831233,
"y": 572.5727590471123
},
{
"id": 12,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A3",
"type": 0,
"x": -43.77068412991713,
"y": 567.8446507439608
},
{
"aScale": 0,
"angle1": 59.9325,
"angle1Formula": "59.9325",
"angle2": 257.57,
"angle2Formula": "257.57",
"c1Length": 170.46425196850396,
"c1LengthFormula": "4.5102",
"c2Length": 150.6164409448819,
"c2LengthFormula": "3.98506",
"id": 13,
"p1": {
"id": 4,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A3",
"type": 0,
"x": -43.77068412991713,
"y": 567.8446507439608
},
"p4": {
"id": 5,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A4",
"type": 0,
"x": 101.73836126698214,
"y": 289.83563666815587
},
"type": 3
},
{
"aScale": 0,
"id": 14,
"nodes": [
{
"angle1": 239.377,
"angle1Formula": "239.377",
"angle2": 59.377,
"angle2Formula": "59.377",
"length1": 0.03779527559055119,
"length1Formula": "0",
"length2": 109.55943307086613,
"length2Formula": "2.89876",
"point": {
"id": 6,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A5",
"type": 0,
"x": 34.07050146772224,
"y": 568.7902724045911
}
},
{
"angle1": 273.972,
"angle1Formula": "273.972",
"angle2": 93.97199999999995,
"angle2Formula": "93.972",
"length1": 88.16163779527558,
"length1Formula": "2.33261",
"length2": 56.13505511811023,
"length2Formula": "1.48524",
"point": {
"id": 5,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A4",
"type": 0,
"x": 101.73836126698214,
"y": 289.83563666815587
}
},
{
"angle1": 337.326,
"angle1Formula": "337.326",
"angle2": 157.326,
"angle2Formula": "157.326",
"length1": 71.18966929133859,
"length1Formula": "1.88356",
"length2": 50.093858267716534,
"length2Formula": "1.3254",
"point": {
"id": 1,
"mx": 5.000012598425196,
"my": 9.999987401574804,
"name": "A",
"type": 0,
"x": 30,
"y": 39.999874015748034
}
}
],
"type": 4
}
]
},
"piece": {
"nodes": [
{
"id": 9,
"reverse": false,
"type": 26
},
{
"id": 10,
"reverse": false,
"type": 26
},
{
"id": 11,
"reverse": false,
"type": 26
},
{
"id": 12,
"reverse": false,
"type": 26
},
{
"id": 13,
"reverse": false,
"type": 29
},
{
"id": 14,
"reverse": false,
"type": 30
}
],
"saWidth": 1,
"seamAllowance": false
}
}
}

View file

@ -0,0 +1,124 @@
{
"vector": [
{
"type": "QPointF",
"x": 30,
"y": 39.999874015748034
},
{
"type": "QPointF",
"x": 333.80102715408316,
"y": 37.24215812551862
},
{
"type": "QPointF",
"x": 345.43524385831233,
"y": 572.5727590471123
},
{
"type": "QPointF",
"x": -43.77068412991713,
"y": 567.8446507439608
},
{
"type": "QPointF",
"x": -28.208019859282338,
"y": 541.465807361293
},
{
"type": "QPointF",
"x": -1.2263002196735067,
"y": 499.6098664070548
},
{
"type": "QPointF",
"x": 31.788999578643004,
"y": 453.18888409938205
},
{
"type": "QPointF",
"x": 56.76511631570957,
"y": 416.4234789439902
},
{
"type": "QPointF",
"x": 67.46387337253643,
"y": 396.85702763809593
},
{
"type": "QPointF",
"x": 74.13118502881579,
"y": 382.4581709466848
},
{
"type": "QPointF",
"x": 80.49778754648116,
"y": 366.38376506330246
},
{
"type": "QPointF",
"x": 92.69483546961426,
"y": 327.287500697207
},
{
"type": "QPointF",
"x": 101.73836126698214,
"y": 289.83563666815587
},
{
"type": "QPointF",
"x": 96.68026149584162,
"y": 212.73003048920287
},
{
"type": "QPointF",
"x": 92.2665801456707,
"y": 173.83095999929157
},
{
"type": "QPointF",
"x": 87.25149211813451,
"y": 144.48122290748523
},
{
"type": "QPointF",
"x": 83.01539723892088,
"y": 125.48779016127347
},
{
"type": "QPointF",
"x": 77.91171792586823,
"y": 107.37688780476154
},
{
"type": "QPointF",
"x": 71.84487099607841,
"y": 90.51376394967542
},
{
"type": "QPointF",
"x": 64.71927326665323,
"y": 75.2636667077411
},
{
"type": "QPointF",
"x": 56.4393415546946,
"y": 61.99184419068451
},
{
"type": "QPointF",
"x": 46.90949267730432,
"y": 51.06354451023162
},
{
"type": "QPointF",
"x": 38.84006150425045,
"y": 44.71818577337716
},
{
"type": "QPointF",
"x": 30,
"y": 39.999874015748034
}
]
}

View file

@ -2,5 +2,7 @@
<qresource prefix="/">
<file>input_loop_by_intersection.json</file>
<file>output_loop_by_intersection.json</file>
<file>Issue_620/input.json</file>
<file>Issue_620/output.json</file>
</qresource>
</RCC>

View file

@ -679,184 +679,16 @@ void TST_VPiece::Issue620()
// See file <root>/src/app/share/collection/bugs/Issue_#620.vit
// Check main path
const Unit unit = Unit::Cm;
QScopedPointer<VContainer> data(new VContainer(nullptr, &unit, VContainer::UniqueNamespace()));
QSharedPointer<VContainer> data(new VContainer(nullptr, &unit, VContainer::UniqueNamespace()));
qApp->setPatternUnit(unit);
data->UpdateGObject(1, new VPointF(30, 39.999874015748034, "A", 5.0000125984251973, 9.9999874015748045));
data->UpdateGObject(2, new VPointF(333.80102715408322, 37.242158125518621, "A1", 5.0000125984251973,
9.9999874015748045));
data->UpdateGObject(3, new VPointF(345.43524385831239, 572.57275904711241, "A2", 5.0000125984251973,
9.9999874015748045));
VPointF *p4 = new VPointF(-43.770684129917051, 567.84465074396087, "A3", 5.0000125984251973,
9.9999874015748045);
data->UpdateGObject(4, p4);
VPointF *p5 = new VPointF(101.73836126698214, 289.83563666815587, "A4", 5.0000125984251973, 9.9999874015748045);
data->UpdateGObject(5, p5);
data->UpdateGObject(6, new VPointF(34.070501467722302, 568.79027240459118, "A5", 5.0000125984251973,
9.9999874015748045));
QVector<VSplinePoint> points;
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(6);
VSplinePoint p(*point.data(), 239.37700000000001, "239.377", 419.37700000000001, "59.3765",
0, QChar('0'), 109.55943307086613, "2.89876");
points.append(p);
}
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(5);
VSplinePoint p(*point.data(), 273.97199999999998, "273.972", 453.97199999999998, "93.9724",
88.161637795275595, "2.33261", 56.135055118110238, "1.48524");
points.append(p);
}
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(1);
VSplinePoint p(*point.data(), 337.32600000000002, "337.326", 157.32599999999999, "157.326",
71.189669291338589, "1.88356", 50.093858267716534, "1.3254");
points.append(p);
}
{
VSplinePath *path = new VSplinePath(points);
path->SetApproximationScale(10);
data->UpdateGObject(7, path);
}
{
VSpline *spl = new VSpline(*p4, *p5, 59.932499999999997, "59.9325", 257.56999999999999,
"257.57", 170.46425196850396, "4.5102", 150.6164409448819, "3.98506");
spl->SetApproximationScale(10);
data->UpdateGObject(8, spl);
}
VPiece detail;
detail.SetSeamAllowance(false);
detail.SetSAWidth(7);
detail.GetPath().Append(VPieceNode(1, Tool::NodePoint));
detail.GetPath().Append(VPieceNode(2, Tool::NodePoint));
detail.GetPath().Append(VPieceNode(3, Tool::NodePoint));
detail.GetPath().Append(VPieceNode(4, Tool::NodePoint));
detail.GetPath().Append(VPieceNode(8, Tool::NodeSpline));
detail.GetPath().Append(VPieceNode(7, Tool::NodeSplinePath));
AbstractTest::PieceFromJson(QStringLiteral("://Issue_620/input.json"), detail, data);
const QVector<QPointF> pointsEkv = detail.MainPathPoints(data.data());
QVector<QPointF> origPoints;
origPoints.append(QPointF(30.0, 39.999874015748034));
origPoints.append(QPointF(333.8010271540832, 37.24215812551862));
origPoints.append(QPointF(345.4352438583124, 572.5727590471124));
origPoints.append(QPointF(-43.77068412991705, 567.8446507439609));
origPoints.append(QPointF(-41.776027573529674, 564.4070486713748));
origPoints.append(QPointF(-37.85646185008852, 557.7284453106807));
origPoints.append(QPointF(-34.019306379498914, 551.2790100611998));
origPoints.append(QPointF(-30.263131590262248, 545.0512397783091));
origPoints.append(QPointF(-26.586507910879927, 539.0376313173863));
origPoints.append(QPointF(-22.98800576985332, 533.2306815338081));
origPoints.append(QPointF(-19.466195595683825, 527.6228872829522));
origPoints.append(QPointF(-16.019647816872833, 522.2067454201957));
origPoints.append(QPointF(-10.978854893973825, 514.4038559090675));
origPoints.append(QPointF(-4.520178850519514, 504.6314487766784));
origPoints.append(QPointF(1.6631798984757897, 495.490594593478));
origPoints.append(QPointF(7.58265792500097, 486.92126820248467));
origPoints.append(QPointF(13.249691801044914, 478.8634444467164));
origPoints.append(QPointF(18.67571809859651, 471.25709816919147));
origPoints.append(QPointF(26.41443785504145, 460.525117170489));
origPoints.append(QPointF(33.62211724018606, 450.5466726362586));
origPoints.append(QPointF(38.19847894365711, 444.14598470188895));
origPoints.append(QPointF(42.591015928580234, 437.89664846085356));
origPoints.append(QPointF(46.811164766944344, 431.73863875617076));
origPoints.append(QPointF(50.87036203073829, 425.6119304308587));
origPoints.append(QPointF(53.81161102143449, 420.9990273759227));
origPoints.append(QPointF(55.73121775864344, 417.9028756631243));
origPoints.append(QPointF(57.61701967395359, 414.7807851443662));
origPoints.append(QPointF(59.47044633886358, 411.6252526750258));
origPoints.append(QPointF(61.292927324872, 408.42877511048044));
origPoints.append(QPointF(63.085892203477464, 405.18384930610733));
origPoints.append(QPointF(64.85077054617858, 401.88297211728377));
origPoints.append(QPointF(66.58899192447396, 398.5186403993869));
origPoints.append(QPointF(68.30198590986222, 395.0833510077942));
origPoints.append(QPointF(69.99118207384197, 391.5696007978828));
origPoints.append(QPointF(71.65800998791181, 387.96988662503003));
origPoints.append(QPointF(73.30389922357037, 384.2767053446131));
origPoints.append(QPointF(74.93027935231623, 380.48255381200937));
origPoints.append(QPointF(76.53857994564802, 376.57992888259605));
origPoints.append(QPointF(78.13023057506439, 372.56132741175054));
origPoints.append(QPointF(79.70666081206386, 368.4192462548499));
origPoints.append(QPointF(81.26930022814513, 364.14618226727157));
origPoints.append(QPointF(82.81957839480675, 359.7346323043928));
origPoints.append(QPointF(84.35892488354736, 355.1770932215909));
origPoints.append(QPointF(85.88876926586558, 350.466061874243));
origPoints.append(QPointF(87.41054111325998, 345.59403511772655));
origPoints.append(QPointF(88.92566999722922, 340.55350980741866));
origPoints.append(QPointF(90.43558548927187, 335.33698279869674));
origPoints.append(QPointF(91.94171716088657, 329.93695094693794));
origPoints.append(QPointF(93.44549458357191, 324.34591110751967));
origPoints.append(QPointF(94.94834732882651, 318.55636013581915));
origPoints.append(QPointF(96.45170496814899, 312.56079488721366));
origPoints.append(QPointF(97.95699707303794, 306.35171221708043));
origPoints.append(QPointF(99.46565321499199, 299.92160898079675));
origPoints.append(QPointF(100.97910296550974, 293.26298203373995));
origPoints.append(QPointF(101.73836126698214, 289.83563666815587));
origPoints.append(QPointF(101.37719348141695, 284.37000549925995));
origPoints.append(QPointF(100.64077948858204, 271.46526165758365));
origPoints.append(QPointF(99.80144652509331, 256.5210633117996));
origPoints.append(QPointF(99.03846354637537, 244.15048365420762));
origPoints.append(QPointF(98.45199860267363, 235.49121370797783));
origPoints.append(QPointF(97.78603837592823, 226.52753219856694));
origPoints.append(QPointF(97.02863496827689, 217.3050951399407));
origPoints.append(QPointF(96.16784048185737, 207.86955854606484));
origPoints.append(QPointF(95.19170701880736, 198.26657843090516));
origPoints.append(QPointF(94.08828668126463, 188.54181080842733));
origPoints.append(QPointF(92.8456315713669, 178.7409116925971));
origPoints.append(QPointF(91.8100755249774, 171.36785871320973));
origPoints.append(QPointF(91.07312073651642, 166.45311304837324));
origPoints.append(QPointF(90.29463656241913, 161.54501601805435));
origPoints.append(QPointF(89.4731295154528, 156.6492746239989));
origPoints.append(QPointF(88.60710610838458, 151.77159586795244));
origPoints.append(QPointF(87.69507285398177, 146.91768675166082));
origPoints.append(QPointF(86.73553626501155, 142.0932542768697));
origPoints.append(QPointF(85.7270028542411, 137.3040054453248));
origPoints.append(QPointF(84.6679791344377, 132.55564725877187));
origPoints.append(QPointF(83.55697161836854, 127.85388671895657));
origPoints.append(QPointF(82.39248681880082, 123.20443082762469));
origPoints.append(QPointF(81.17303124850177, 118.61298658652187));
origPoints.append(QPointF(79.8971114202386, 114.08526099739389));
origPoints.append(QPointF(78.56323384677853, 109.62696106198644));
origPoints.append(QPointF(77.1699050408888, 105.24379378204526));
origPoints.append(QPointF(75.71563151533661, 100.94146615931604));
origPoints.append(QPointF(74.19891978288913, 96.72568519554451));
origPoints.append(QPointF(72.61827635631366, 92.60215789247638));
origPoints.append(QPointF(70.97220774837734, 88.5765912518574));
origPoints.append(QPointF(69.25922047184744, 84.65469227543325));
origPoints.append(QPointF(67.47782103949115, 80.84216796494968));
origPoints.append(QPointF(65.62651596407568, 77.14472532215238));
origPoints.append(QPointF(63.703811758368275, 73.56807134878709));
origPoints.append(QPointF(61.70821493513614, 70.11791304659951));
origPoints.append(QPointF(59.63823200714647, 66.79995741733536));
origPoints.append(QPointF(57.49236948716651, 63.61991146274037));
origPoints.append(QPointF(55.8298252766917, 61.333435118024795));
origPoints.append(QPointF(54.698584178428256, 59.852194710865774));
origPoints.append(QPointF(53.5475330955988, 58.408641910856005));
origPoints.append(QPointF(52.37648534229922, 57.00349009321371));
origPoints.append(QPointF(51.18525423262544, 55.63745263315711));
origPoints.append(QPointF(49.973653080673344, 54.31124290590439));
origPoints.append(QPointF(48.741495200538836, 53.025574286673795));
origPoints.append(QPointF(47.48859390631783, 51.78116015068352));
origPoints.append(QPointF(46.21476251210622, 50.5787138731518));
origPoints.append(QPointF(44.919814331999916, 49.41894882929684));
origPoints.append(QPointF(43.60356268009479, 48.30257839433685));
origPoints.append(QPointF(42.26582087048678, 47.23031594349004));
origPoints.append(QPointF(40.906402217271776, 46.20287485197463));
origPoints.append(QPointF(39.525120034545665, 45.22096849500884));
origPoints.append(QPointF(38.12178763640438, 44.285310247810884));
origPoints.append(QPointF(36.69621833694379, 43.39661348559898));
origPoints.append(QPointF(35.24822545025982, 42.55559158359132));
origPoints.append(QPointF(33.77762229044836, 41.76295791700616));
origPoints.append(QPointF(32.28422217160532, 41.01942586106168));
origPoints.append(QPointF(30.7678384078266, 40.32570879097611));
AbstractTest::VectorFromJson(QStringLiteral("://Issue_620/output.json"), origPoints);
// Begin comparison
Comparison(pointsEkv, origPoints);