Share Model merge; Merge initializers; undo/redo descs (#65)
- use "shared" pointer between Model and undo/redo instances - adds missing initializers to Merge and Text classes - adds checkpoints for mouse resize, barcode, and image reset. - renames the position dialog checkpoint from Move -> Position to differentiate it from a mouse move. - adds the Undo/Redo action descriptions to the menu items. - adds unit tests for the Merge and Model change, and for ColorNode, RawText and TextNode.
This commit is contained in:
@@ -31,7 +31,7 @@ namespace glabels
|
|||||||
///
|
///
|
||||||
/// Constructor
|
/// Constructor
|
||||||
///
|
///
|
||||||
Merge::Merge( const Merge* merge ) : mSource(merge->mSource)
|
Merge::Merge( const Merge* merge ) : mId(merge->mId), mSource(merge->mSource)
|
||||||
{
|
{
|
||||||
foreach ( Record* record, merge->mRecordList )
|
foreach ( Record* record, merge->mRecordList )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace glabels
|
|||||||
Text::Text( const Text* merge )
|
Text::Text( const Text* merge )
|
||||||
: Merge( merge ),
|
: Merge( merge ),
|
||||||
mDelimeter(merge->mDelimeter), mLine1HasKeys(merge->mLine1HasKeys),
|
mDelimeter(merge->mDelimeter), mLine1HasKeys(merge->mLine1HasKeys),
|
||||||
mNFieldsMax(merge->mNFieldsMax)
|
mKeys(merge->mKeys), mNFieldsMax(merge->mNFieldsMax)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -661,6 +661,7 @@ namespace glabels
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ArrowResize:
|
case ArrowResize:
|
||||||
|
mUndoRedoModel->checkpoint( tr("Resize") );
|
||||||
handleResizeMotion( xWorld, yWorld );
|
handleResizeMotion( xWorld, yWorld );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
+43
-5
@@ -62,7 +62,7 @@ namespace glabels
|
|||||||
///
|
///
|
||||||
/// Constructor
|
/// Constructor
|
||||||
///
|
///
|
||||||
MainWindow::MainWindow() : mModel(nullptr)
|
MainWindow::MainWindow() : mModel(nullptr), mUndoRedoModel(nullptr)
|
||||||
{
|
{
|
||||||
setWindowIcon( Icons::Glabels() );
|
setWindowIcon( Icons::Glabels() );
|
||||||
|
|
||||||
@@ -194,7 +194,15 @@ namespace glabels
|
|||||||
///
|
///
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
// empty
|
if ( mUndoRedoModel )
|
||||||
|
{
|
||||||
|
delete mUndoRedoModel;
|
||||||
|
}
|
||||||
|
if ( mModel )
|
||||||
|
{
|
||||||
|
delete mModel->merge(); // Ownership of final Merge instance is ours
|
||||||
|
delete mModel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -212,7 +220,7 @@ namespace glabels
|
|||||||
///
|
///
|
||||||
void MainWindow::setModel( model::Model* model )
|
void MainWindow::setModel( model::Model* model )
|
||||||
{
|
{
|
||||||
mModel = model;
|
mModel = model; // Ownership passes to us
|
||||||
mUndoRedoModel = new UndoRedoModel( mModel );
|
mUndoRedoModel = new UndoRedoModel( mModel );
|
||||||
|
|
||||||
mPropertiesView->setModel( mModel, mUndoRedoModel );
|
mPropertiesView->setModel( mModel, mUndoRedoModel );
|
||||||
@@ -882,8 +890,38 @@ namespace glabels
|
|||||||
fileExitAction->setEnabled( true );
|
fileExitAction->setEnabled( true );
|
||||||
|
|
||||||
// Edit actions
|
// Edit actions
|
||||||
editUndoAction->setEnabled( hasModel && mUndoRedoModel->canUndo() );
|
if ( hasModel )
|
||||||
editRedoAction->setEnabled( hasModel && mUndoRedoModel->canRedo() );
|
{
|
||||||
|
if ( mUndoRedoModel->canUndo() )
|
||||||
|
{
|
||||||
|
editUndoAction->setEnabled( true );
|
||||||
|
/* Translators: %1 is the action description to undo. */
|
||||||
|
editUndoAction->setText( QString( tr("Undo %1") ).arg( mUndoRedoModel->undoDescription() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
editUndoAction->setEnabled( false );
|
||||||
|
editUndoAction->setText( tr("Undo") );
|
||||||
|
}
|
||||||
|
if ( mUndoRedoModel->canRedo() )
|
||||||
|
{
|
||||||
|
editRedoAction->setEnabled( true );
|
||||||
|
/* Translators: %1 is the action description to redo. */
|
||||||
|
editRedoAction->setText( QString( tr("Redo %1") ).arg( mUndoRedoModel->redoDescription() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
editRedoAction->setEnabled( false );
|
||||||
|
editRedoAction->setText( tr("Redo") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
editUndoAction->setEnabled( false );
|
||||||
|
editUndoAction->setText( tr("Undo") );
|
||||||
|
editRedoAction->setEnabled( false );
|
||||||
|
editRedoAction->setText( tr("Redo") );
|
||||||
|
}
|
||||||
editCutAction->setEnabled( isEditorPage && hasSelection );
|
editCutAction->setEnabled( isEditorPage && hasSelection );
|
||||||
editCopyAction->setEnabled( isEditorPage && hasSelection );
|
editCopyAction->setEnabled( isEditorPage && hasSelection );
|
||||||
editPasteAction->setEnabled( isEditorPage && canPaste );
|
editPasteAction->setEnabled( isEditorPage && canPaste );
|
||||||
|
|||||||
@@ -631,7 +631,7 @@ namespace glabels
|
|||||||
{
|
{
|
||||||
mBlocked = true;
|
mBlocked = true;
|
||||||
|
|
||||||
mUndoRedoModel->checkpoint( tr("Move") );
|
mUndoRedoModel->checkpoint( tr("Position") );
|
||||||
|
|
||||||
model::Distance x = model::Distance(posXSpin->value(), mUnits);
|
model::Distance x = model::Distance(posXSpin->value(), mUnits);
|
||||||
model::Distance y = model::Distance(posYSpin->value(), mUnits);
|
model::Distance y = model::Distance(posYSpin->value(), mUnits);
|
||||||
@@ -744,6 +744,8 @@ namespace glabels
|
|||||||
{
|
{
|
||||||
mBlocked = true;
|
mBlocked = true;
|
||||||
|
|
||||||
|
mUndoRedoModel->checkpoint( tr("Barcode") );
|
||||||
|
|
||||||
barcode::Style bcStyle = barcodeStyleButton->bcStyle();
|
barcode::Style bcStyle = barcodeStyleButton->bcStyle();
|
||||||
|
|
||||||
barcodeShowTextCheck->setEnabled( bcStyle.textOptional() );
|
barcodeShowTextCheck->setEnabled( bcStyle.textOptional() );
|
||||||
@@ -778,6 +780,8 @@ namespace glabels
|
|||||||
|
|
||||||
void ObjectEditor::onResetImageSize()
|
void ObjectEditor::onResetImageSize()
|
||||||
{
|
{
|
||||||
|
mUndoRedoModel->checkpoint( tr("Reset") );
|
||||||
|
|
||||||
mObject->setSize( mObject->naturalSize() );
|
mObject->setSize( mObject->naturalSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-8
@@ -61,12 +61,19 @@ namespace glabels
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Model::Model( merge::Merge* merge )
|
||||||
|
: mUntitledInstance(0), mModified(true), mRotate(false)
|
||||||
|
{
|
||||||
|
mMerge = merge; // Shared
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor.
|
/// Destructor.
|
||||||
///
|
///
|
||||||
Model::~Model()
|
Model::~Model()
|
||||||
{
|
{
|
||||||
delete mMerge;
|
// Final instance of mMerge to be deleted by Model owner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -75,7 +82,13 @@ namespace glabels
|
|||||||
///
|
///
|
||||||
Model* Model::save() const
|
Model* Model::save() const
|
||||||
{
|
{
|
||||||
auto* savedModel = new Model;
|
auto* savedModel = new Model( mMerge ); // mMerge shared between models
|
||||||
|
|
||||||
|
if ( mFileName.isEmpty() && mUntitledInstance == 0 )
|
||||||
|
{
|
||||||
|
qDebug() << "Model::save: Warning: called before mUntitledInstance has been initialized: untitled names will differ";
|
||||||
|
}
|
||||||
|
|
||||||
savedModel->restore( this );
|
savedModel->restore( this );
|
||||||
|
|
||||||
return savedModel;
|
return savedModel;
|
||||||
@@ -112,18 +125,12 @@ namespace glabels
|
|||||||
connect( object, SIGNAL(moved()), this, SLOT(onObjectMoved()) );
|
connect( object, SIGNAL(moved()), this, SLOT(onObjectMoved()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
delete mMerge;
|
|
||||||
mMerge = savedModel->mMerge->clone();
|
|
||||||
|
|
||||||
// Emit signals based on potential changes
|
// Emit signals based on potential changes
|
||||||
emit changed();
|
emit changed();
|
||||||
emit selectionChanged();
|
emit selectionChanged();
|
||||||
emit modifiedChanged();
|
emit modifiedChanged();
|
||||||
emit nameChanged();
|
emit nameChanged();
|
||||||
emit sizeChanged();
|
emit sizeChanged();
|
||||||
emit mergeChanged();
|
|
||||||
emit mergeSourceChanged();
|
|
||||||
emit mergeSelectionChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace glabels
|
|||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
public:
|
public:
|
||||||
Model();
|
Model();
|
||||||
|
Model( merge::Merge* merge );
|
||||||
~Model();
|
~Model();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,44 @@ if (Qt5Test_FOUND)
|
|||||||
target_link_libraries (TestXmlLabel Model Qt5::Test)
|
target_link_libraries (TestXmlLabel Model Qt5::Test)
|
||||||
add_test (NAME XmlLabel COMMAND TestXmlLabel)
|
add_test (NAME XmlLabel COMMAND TestXmlLabel)
|
||||||
|
|
||||||
|
#=======================================
|
||||||
|
# Test ColorNode class
|
||||||
|
#=======================================
|
||||||
|
qt5_wrap_cpp (TestColorNode_moc_sources TestColorNode.h)
|
||||||
|
add_executable (TestColorNode TestColorNode.cpp ${TestColorNode_moc_sources})
|
||||||
|
target_link_libraries (TestColorNode Model Qt5::Test)
|
||||||
|
add_test (NAME ColorNode COMMAND TestColorNode)
|
||||||
|
|
||||||
|
#=======================================
|
||||||
|
# Test Merge classes
|
||||||
|
#=======================================
|
||||||
|
qt5_wrap_cpp (TestMerge_moc_sources TestMerge.h)
|
||||||
|
add_executable (TestMerge TestMerge.cpp ${TestMerge_moc_sources})
|
||||||
|
target_link_libraries (TestMerge Model Qt5::Test)
|
||||||
|
add_test (NAME Merge COMMAND TestMerge)
|
||||||
|
|
||||||
|
#=======================================
|
||||||
|
# Test Model class
|
||||||
|
#=======================================
|
||||||
|
qt5_wrap_cpp (TestModel_moc_sources TestModel.h)
|
||||||
|
add_executable (TestModel TestModel.cpp ${TestModel_moc_sources})
|
||||||
|
target_link_libraries (TestModel Model Qt5::Test)
|
||||||
|
add_test (NAME Model COMMAND TestModel)
|
||||||
|
|
||||||
|
#=======================================
|
||||||
|
# Test RawText class
|
||||||
|
#=======================================
|
||||||
|
qt5_wrap_cpp (TestRawText_moc_sources TestRawText.h)
|
||||||
|
add_executable (TestRawText TestRawText.cpp ${TestRawText_moc_sources})
|
||||||
|
target_link_libraries (TestRawText Model Qt5::Test)
|
||||||
|
add_test (NAME RawText COMMAND TestRawText)
|
||||||
|
|
||||||
|
#=======================================
|
||||||
|
# Test TextNode class
|
||||||
|
#=======================================
|
||||||
|
qt5_wrap_cpp (TestTextNode_moc_sources TestTextNode.h)
|
||||||
|
add_executable (TestTextNode TestTextNode.cpp ${TestTextNode_moc_sources})
|
||||||
|
target_link_libraries (TestTextNode Model Qt5::Test)
|
||||||
|
add_test (NAME TextNode COMMAND TestTextNode)
|
||||||
|
|
||||||
endif (Qt5Test_FOUND)
|
endif (Qt5Test_FOUND)
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/* TestColorNode.cpp
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestColorNode.h"
|
||||||
|
|
||||||
|
#include "model/ColorNode.h"
|
||||||
|
|
||||||
|
#include "merge/Record.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(TestColorNode)
|
||||||
|
|
||||||
|
using namespace glabels::model;
|
||||||
|
using namespace glabels::merge;
|
||||||
|
|
||||||
|
|
||||||
|
void TestColorNode::colorNode()
|
||||||
|
{
|
||||||
|
uint32_t rgbaBlackTransparent = 0;
|
||||||
|
uint32_t rgbaWhite = 0xFFFFFFFF;
|
||||||
|
uint32_t rgbaRed = 0xFF0000FF; // ColorNode uses RGBA. QColor set alpha to opaque 0xFF by default
|
||||||
|
uint32_t qRgbaRed = 0xFFFF0000; // QColor uses ARGB, ie alpha at top
|
||||||
|
uint32_t qRgbaGreen80 = 0x8000FF00;
|
||||||
|
|
||||||
|
QColor blackTransparent = QColor::fromRgba( rgbaBlackTransparent );
|
||||||
|
QColor white = QColor::fromRgba( rgbaWhite );
|
||||||
|
QColor red = QColor::fromRgba( qRgbaRed );
|
||||||
|
QColor green80 = QColor::fromRgba( qRgbaGreen80 );
|
||||||
|
|
||||||
|
Record record;
|
||||||
|
|
||||||
|
ColorNode colorNode;
|
||||||
|
QVERIFY( !colorNode.isField() );
|
||||||
|
QCOMPARE( colorNode.color(), blackTransparent );
|
||||||
|
QCOMPARE( colorNode.key(), QString( "" ) );
|
||||||
|
QCOMPARE( colorNode.rgba(), rgbaBlackTransparent );
|
||||||
|
QCOMPARE( colorNode.color( nullptr ), blackTransparent );
|
||||||
|
QCOMPARE( colorNode.color( &record ), blackTransparent );
|
||||||
|
|
||||||
|
colorNode.setField( true );
|
||||||
|
QVERIFY( colorNode.isField() );
|
||||||
|
colorNode.setField( false );
|
||||||
|
QVERIFY( !colorNode.isField() );
|
||||||
|
|
||||||
|
colorNode.setColor( white );
|
||||||
|
QCOMPARE( colorNode.color(), white );
|
||||||
|
QCOMPARE( colorNode.rgba(), rgbaWhite );
|
||||||
|
QCOMPARE( colorNode.color( nullptr ), white );
|
||||||
|
QCOMPARE( colorNode.color( &record ), white );
|
||||||
|
|
||||||
|
colorNode.setKey( "key1" );
|
||||||
|
QCOMPARE( colorNode.key(), QString( "key1" ) );
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructors
|
||||||
|
///
|
||||||
|
ColorNode colorNode2( true, white, QString( "key2" ) );
|
||||||
|
QVERIFY( colorNode2.isField() );
|
||||||
|
QCOMPARE( colorNode2.key(), QString( "key2" ) );
|
||||||
|
QCOMPARE( colorNode2.color(), white );
|
||||||
|
|
||||||
|
QVERIFY( colorNode2 != colorNode );
|
||||||
|
colorNode.setField( true );
|
||||||
|
QVERIFY( colorNode2 != colorNode );
|
||||||
|
colorNode.setKey( "key2" );
|
||||||
|
QVERIFY( colorNode2 == colorNode );
|
||||||
|
|
||||||
|
ColorNode colorNode3( red );
|
||||||
|
QVERIFY( !colorNode3.isField() );
|
||||||
|
QCOMPARE( colorNode3.key(), QString( "" ) );
|
||||||
|
QCOMPARE( colorNode3.color(), red );
|
||||||
|
QCOMPARE( colorNode3.rgba(), rgbaRed );
|
||||||
|
|
||||||
|
QVERIFY( colorNode3 != colorNode );
|
||||||
|
colorNode.setField( false );
|
||||||
|
QVERIFY( colorNode3 != colorNode );
|
||||||
|
colorNode.setKey( "" );
|
||||||
|
QVERIFY( colorNode3 != colorNode );
|
||||||
|
colorNode.setColor( red );
|
||||||
|
QVERIFY( colorNode3 == colorNode );
|
||||||
|
|
||||||
|
colorNode = ColorNode( QString( "key1" ) );
|
||||||
|
QVERIFY( colorNode.isField() ); // Defaults to true if given key only
|
||||||
|
QCOMPARE( colorNode.key(), QString( "key1" ) );
|
||||||
|
QCOMPARE( colorNode.color(), blackTransparent );
|
||||||
|
QCOMPARE( colorNode.color( &record ), blackTransparent );
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Record
|
||||||
|
///
|
||||||
|
record["key1"] = "white";
|
||||||
|
QCOMPARE( colorNode.color( &record ), white );
|
||||||
|
|
||||||
|
record["key1"] = "red";
|
||||||
|
QCOMPARE( colorNode.color( &record ), red );
|
||||||
|
|
||||||
|
record["key1"] = "#FF0000";
|
||||||
|
QCOMPARE( colorNode.color( &record ), red );
|
||||||
|
|
||||||
|
record["key1"] = "#FFFF0000"; // ARGB
|
||||||
|
QCOMPARE( colorNode.color( &record ), red );
|
||||||
|
|
||||||
|
record["key1"] = "#8000FF00";
|
||||||
|
QCOMPARE( colorNode.color( &record ), green80 );
|
||||||
|
|
||||||
|
colorNode.setKey( "key2" );
|
||||||
|
QCOMPARE( colorNode.color( &record ), blackTransparent );
|
||||||
|
record["key2"] = "#8000FF00";
|
||||||
|
QCOMPARE( colorNode.color( &record ), green80 );
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* TestColorNode.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
|
||||||
|
class TestColorNode : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void colorNode();
|
||||||
|
};
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
/* TestMerge.cpp
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestMerge.h"
|
||||||
|
|
||||||
|
#include "merge/Factory.h"
|
||||||
|
#include "merge/None.h"
|
||||||
|
#include "merge/TextCsv.h"
|
||||||
|
#include "merge/TextCsvKeys.h"
|
||||||
|
#include "merge/TextTsv.h"
|
||||||
|
#include "merge/TextTsvKeys.h"
|
||||||
|
#include "merge/TextColon.h"
|
||||||
|
#include "merge/TextColonKeys.h"
|
||||||
|
#include "merge/TextSemicolon.h"
|
||||||
|
#include "merge/TextSemicolonKeys.h"
|
||||||
|
|
||||||
|
#include "merge/Record.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(TestMerge)
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(glabels::merge::Factory::SourceType)
|
||||||
|
|
||||||
|
using namespace glabels::merge;
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::initTestCase()
|
||||||
|
{
|
||||||
|
Factory::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::factory_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>( "id" );
|
||||||
|
QTest::addColumn<QString>( "name" );
|
||||||
|
QTest::addColumn<Factory::SourceType>( "type" );
|
||||||
|
QTest::addColumn<int>( "index" );
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
QTest::newRow( "None" ) << None::id() << "None" << Factory::NONE << index++;
|
||||||
|
QTest::newRow( "TextCsv" ) << TextCsv::id() << "Text: Comma Separated Values (CSV)" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextCsvKeys" ) << TextCsvKeys::id() << "Text: Comma Separated Values (CSV), keys on line 1" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextTsv" ) << TextTsv::id() << "Text: Tab Separated Values (TSV)" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextTsvKeys" ) << TextTsvKeys::id() << "Text: Tab Separated Values (TSV), keys on line 1" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextColon" ) << TextColon::id() << "Text: Colon Separated Values" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextColonKeys" ) << TextColonKeys::id() << "Text: Colon Separated Values, keys on line 1" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextSemicolon" ) << TextSemicolon::id() << "Text: Semicolon Separated Values" << Factory::FILE << index++;
|
||||||
|
QTest::newRow( "TextSemicolonKeys" ) << TextSemicolonKeys::id() << "Text: Semicolon Separated Values, keys on line 1" << Factory::FILE << index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::factory()
|
||||||
|
{
|
||||||
|
QFETCH( QString, id );
|
||||||
|
QFETCH( QString, name );
|
||||||
|
QFETCH( Factory::SourceType, type );
|
||||||
|
QFETCH( int, index );
|
||||||
|
|
||||||
|
QVERIFY( Factory::nameList().contains( name ) );
|
||||||
|
|
||||||
|
QString outName = Factory::idToName( id );
|
||||||
|
QCOMPARE( outName, name );
|
||||||
|
|
||||||
|
QString outId = Factory::nameToId( name );
|
||||||
|
QCOMPARE( outId, id );
|
||||||
|
|
||||||
|
Factory::SourceType outType = Factory::idToType( id );
|
||||||
|
QCOMPARE( outType, type );
|
||||||
|
|
||||||
|
outId = Factory::indexToId( index );
|
||||||
|
QCOMPARE( outId, id );
|
||||||
|
|
||||||
|
Merge* merge = Factory::createMerge( id );
|
||||||
|
QVERIFY( merge );
|
||||||
|
QCOMPARE( merge->id(), id );
|
||||||
|
|
||||||
|
Merge* cloneMerge = merge->clone();
|
||||||
|
QCOMPARE( cloneMerge->id(), merge->id() );
|
||||||
|
delete cloneMerge;
|
||||||
|
delete merge;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::factoryNotRegistered()
|
||||||
|
{
|
||||||
|
QString id( "unregistered" );
|
||||||
|
Merge* merge = Factory::createMerge( id );
|
||||||
|
QVERIFY( merge );
|
||||||
|
QVERIFY( merge->id() != id );
|
||||||
|
QCOMPARE( merge->id(), None::id() );
|
||||||
|
delete merge;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::text_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>( "id" );
|
||||||
|
QTest::addColumn<bool>( "keyed" );
|
||||||
|
QTest::addColumn<char>( "delim" );
|
||||||
|
|
||||||
|
QTest::newRow( "TextCsv" ) << TextCsv::id() << false << ',';
|
||||||
|
QTest::newRow( "TextCsvKeys" ) << TextCsvKeys::id() << true << ',';
|
||||||
|
QTest::newRow( "TextTsv" ) << TextTsv::id() << false << '\t';
|
||||||
|
QTest::newRow( "TextTsvKeys" ) << TextTsvKeys::id() << true << '\t';
|
||||||
|
QTest::newRow( "TextColon" ) << TextColon::id() << false << ':';
|
||||||
|
QTest::newRow( "TextColonKeys" ) << TextColonKeys::id() << true << ':';
|
||||||
|
QTest::newRow( "TextSemicolon" ) << TextSemicolon::id() << false << ';';
|
||||||
|
QTest::newRow( "TextSemicolonKeys" ) << TextSemicolonKeys::id() << true << ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::text()
|
||||||
|
{
|
||||||
|
QFETCH( QString, id );
|
||||||
|
QFETCH( bool, keyed );
|
||||||
|
QFETCH( char, delim );
|
||||||
|
|
||||||
|
QTemporaryFile file;
|
||||||
|
file.open();
|
||||||
|
if ( keyed )
|
||||||
|
{
|
||||||
|
file.write( "header1" );
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"header 2\"" );
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "header3\r\n" );
|
||||||
|
}
|
||||||
|
file.write( " val11" ); // Leading spaces in SIMPLE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"\"\"val 12\"\"\"" ); // 2DQUOTE at beginning and end of DQUOTE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( " \"val 13\"\n" ); // Leading spaces before DQUOTE entry, end line with LF only
|
||||||
|
|
||||||
|
file.write( "\" val21\"\"\"" ); // Leading spaces within DQUOTE entry, 2DQUOTE at end
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"\"\"val 22\"" ); // 2DQUOTE at beginning of DQUOTE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\r\n" ); // Last field blank
|
||||||
|
|
||||||
|
file.write( "\"\"\"\"\"\"" ); // 2 2DQUOTES alone in DQUOTE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "val \"32" ); // DQUOTE in SIMPLE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "val \"\\\"33\r\n" ); // DQUOTE backslashed-DQUOTE in SIMPLE entry
|
||||||
|
|
||||||
|
file.putChar( delim ); file.putChar( delim ); // All fields blank
|
||||||
|
file.write( "\r\n" );
|
||||||
|
|
||||||
|
file.write( "val\\n \\t \\r \\\\ \\x51" ); // Backslashed-n/-t/-r/-backslash/-x in SIMPLE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"val\\n \\t \\r \\\\ \\x52\"" ); // Backslashed-n/-t/-r/-backslash/-x in QUOTE entry
|
||||||
|
file.write( "\r\n" ); // No last delim
|
||||||
|
|
||||||
|
file.write( "\"val \"\"61\"" ); // 2DQUOTE in middle of DQUOTE entry
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"val\"\"" ); file.putChar( delim ); file.write( "\r\n\\\"\u2019\\\\52\"" ); // 2DQUOTE delim CRLF backslashed-DQUOTE U+2019 backslashed-backslash
|
||||||
|
file.putChar( delim );
|
||||||
|
file.write( "\"val63\"" ); // End without CRLF
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
Merge* merge = Factory::createMerge( id );
|
||||||
|
QCOMPARE( merge->id(), id );
|
||||||
|
|
||||||
|
merge->setSource( file.fileName() );
|
||||||
|
QCOMPARE( merge->source(), file.fileName() );
|
||||||
|
|
||||||
|
const QList<Record*>& recordList = merge->recordList();
|
||||||
|
QCOMPARE( recordList.size(), 6 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Records
|
||||||
|
//
|
||||||
|
const char* h1 = keyed ? "header1" : "1";
|
||||||
|
const char* h2 = keyed ? "header 2" : "2";
|
||||||
|
const char* h3 = keyed ? "header3" : "3";
|
||||||
|
const Record* record;
|
||||||
|
|
||||||
|
record = recordList[0];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( " val11" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "\"val 12\"" ) );
|
||||||
|
QVERIFY( record->contains( h3 ) );
|
||||||
|
QCOMPARE( record->value( h3 ), QString( " \"val 13\"" ) ); // NOTE: Treats as unquoted due to leading spaces
|
||||||
|
|
||||||
|
record = recordList[1];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( " val21\"" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "\"val 22" ) );
|
||||||
|
QVERIFY( record->contains( h3 ) );
|
||||||
|
QCOMPARE( record->value( h3 ), QString( "" ) );
|
||||||
|
|
||||||
|
record = recordList[2];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( "\"\"" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "val \"32" ) );
|
||||||
|
QVERIFY( record->contains( h3 ) );
|
||||||
|
QCOMPARE( record->value( h3 ), QString( "val \"\"33" ) );
|
||||||
|
|
||||||
|
record = recordList[3];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( "" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "" ) );
|
||||||
|
QVERIFY( record->contains( h3 ) );
|
||||||
|
QCOMPARE( record->value( h3 ), QString( "" ) );
|
||||||
|
|
||||||
|
record = recordList[4];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( "val\n \t r \\ x51" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "val\n \t r \\ x52" ) );
|
||||||
|
QVERIFY( !record->contains( h3 ) );
|
||||||
|
|
||||||
|
record = recordList[5];
|
||||||
|
QVERIFY( record->contains( h1 ) );
|
||||||
|
QCOMPARE( record->value( h1 ), QString( "val \"61" ) );
|
||||||
|
QVERIFY( record->contains( h2 ) );
|
||||||
|
QCOMPARE( record->value( h2 ), QString( "val\"" ).append( delim ).append( "\n\"\u2019\\52" ) ); // NOTE: CR missing (QIODevice::Text strips all CRs from stream)
|
||||||
|
QVERIFY( record->contains( h3 ) );
|
||||||
|
QCOMPARE( record->value( h3 ), QString( "val63" ) );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selection
|
||||||
|
//
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 6 ); // Initially all selected
|
||||||
|
merge->unselectAll();
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 0 );
|
||||||
|
|
||||||
|
record = recordList[1];
|
||||||
|
merge->select( (Record*)record );
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 1 );
|
||||||
|
QCOMPARE( merge->selectedRecords().size(), 1 );
|
||||||
|
QCOMPARE( merge->selectedRecords().first(), record ); // Pointers same
|
||||||
|
|
||||||
|
merge->unselect( (Record*)record );
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 0 );
|
||||||
|
QCOMPARE( merge->selectedRecords().size(), 0 );
|
||||||
|
|
||||||
|
merge->setSelected( 0 );
|
||||||
|
merge->setSelected( 3 );
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 2 );
|
||||||
|
QCOMPARE( merge->selectedRecords().size(), 2 );
|
||||||
|
QCOMPARE( merge->selectedRecords().first(), recordList[0] );
|
||||||
|
QCOMPARE( merge->selectedRecords().last(), recordList[3] );
|
||||||
|
|
||||||
|
merge->setSelected( 0, false );
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 1 );
|
||||||
|
QCOMPARE( merge->selectedRecords().size(), 1 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Keys
|
||||||
|
//
|
||||||
|
QStringList keys = merge->keys();
|
||||||
|
QCOMPARE( keys.size(), 3 );
|
||||||
|
QCOMPARE( keys[0], QString( h1 ) );
|
||||||
|
QCOMPARE( keys[1], QString( h2 ) );
|
||||||
|
QCOMPARE( keys[2], QString( h3 ) );
|
||||||
|
QCOMPARE( merge->primaryKey(), QString( h1 ) );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clone
|
||||||
|
//
|
||||||
|
merge->unselectAll();
|
||||||
|
merge->setSelected( 0 );
|
||||||
|
QCOMPARE( merge->nSelectedRecords(), 1 );
|
||||||
|
|
||||||
|
Merge* cloneMerge = merge->clone();
|
||||||
|
QCOMPARE( cloneMerge->id(), merge->id() );
|
||||||
|
QCOMPARE( cloneMerge->source(), merge->source() );
|
||||||
|
QCOMPARE( cloneMerge->recordList().size(), merge->recordList().size() );
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[0]), *(merge->recordList()[0]) ); // Pointers different
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[1]), *(merge->recordList()[1]) );
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[2]), *(merge->recordList()[2]) );
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[3]), *(merge->recordList()[3]) );
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[4]), *(merge->recordList()[4]) );
|
||||||
|
QCOMPARE( *(cloneMerge->recordList()[5]), *(merge->recordList()[5]) );
|
||||||
|
QCOMPARE( cloneMerge->nSelectedRecords(), merge->nSelectedRecords() );
|
||||||
|
QCOMPARE( cloneMerge->selectedRecords().size(), merge->selectedRecords().size() );
|
||||||
|
QCOMPARE( *(cloneMerge->selectedRecords()[0]), *(merge->selectedRecords()[0]) );
|
||||||
|
QCOMPARE( cloneMerge->keys(), merge->keys() );
|
||||||
|
QCOMPARE( cloneMerge->primaryKey(), merge->primaryKey() );
|
||||||
|
delete cloneMerge;
|
||||||
|
delete merge;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::none()
|
||||||
|
{
|
||||||
|
None none;
|
||||||
|
QCOMPARE( none.id(), QString( "None" ) );
|
||||||
|
|
||||||
|
None* cloneNone = none.clone();
|
||||||
|
QCOMPARE( cloneNone->id(), none.id() );
|
||||||
|
QCOMPARE( cloneNone->keys(), none.keys() );
|
||||||
|
QCOMPARE( cloneNone->primaryKey(), none.primaryKey() );
|
||||||
|
delete cloneNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestMerge::record()
|
||||||
|
{
|
||||||
|
Record record;
|
||||||
|
QCOMPARE( record.isSelected(), true );
|
||||||
|
record.setSelected( false );
|
||||||
|
QCOMPARE( record.isSelected(), false );
|
||||||
|
record.setSelected( true );
|
||||||
|
QCOMPARE( record.isSelected(), true );
|
||||||
|
|
||||||
|
record["key"] = "val";
|
||||||
|
QVERIFY( record.contains( "key" ) );
|
||||||
|
QCOMPARE( record["key"], QString( "val" ) );
|
||||||
|
|
||||||
|
Record* cloneRecord = record.clone();
|
||||||
|
QCOMPARE( cloneRecord->isSelected(), true );
|
||||||
|
QVERIFY( cloneRecord->contains( "key" ) );
|
||||||
|
QCOMPARE( cloneRecord->value( "key" ), QString( "val" ) );
|
||||||
|
delete cloneRecord;
|
||||||
|
|
||||||
|
record.setSelected( false );
|
||||||
|
Record record2( &record );
|
||||||
|
QCOMPARE( record2.isSelected(), false );
|
||||||
|
QVERIFY( record2.contains( "key" ) );
|
||||||
|
QCOMPARE( record2["key"], QString( "val" ) );
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* TestMerge.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
|
||||||
|
class TestMerge : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void factory_data();
|
||||||
|
void factory();
|
||||||
|
void factoryNotRegistered();
|
||||||
|
void text_data();
|
||||||
|
void text();
|
||||||
|
void none();
|
||||||
|
void record();
|
||||||
|
};
|
||||||
@@ -0,0 +1,475 @@
|
|||||||
|
/* TestModel.cpp
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestModel.h"
|
||||||
|
|
||||||
|
#include "model/Model.h"
|
||||||
|
#include "model/ModelBoxObject.h"
|
||||||
|
#include "model/ModelEllipseObject.h"
|
||||||
|
#include "model/ModelLineObject.h"
|
||||||
|
#include "model/ModelTextObject.h"
|
||||||
|
#include "model/FrameRect.h"
|
||||||
|
#include "model/FrameContinuous.h"
|
||||||
|
#include "model/Region.h"
|
||||||
|
#include "model/Settings.h"
|
||||||
|
|
||||||
|
#include "merge/Factory.h"
|
||||||
|
#include "merge/Merge.h"
|
||||||
|
#include "merge/None.h"
|
||||||
|
#include "merge/TextCsv.h"
|
||||||
|
#include "merge/TextCsvKeys.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(TestModel)
|
||||||
|
|
||||||
|
using namespace glabels::model;
|
||||||
|
using namespace glabels::merge;
|
||||||
|
|
||||||
|
|
||||||
|
void TestModel::initTestCase()
|
||||||
|
{
|
||||||
|
Factory::init();
|
||||||
|
Settings::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestModel::model()
|
||||||
|
{
|
||||||
|
Model model;
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
QVERIFY( model.shortName().contains( QRegExp( "^Untitled[1-9][0-9]*$" ) ) );
|
||||||
|
model.setFileName( "dir/file1.ext" );
|
||||||
|
QCOMPARE( model.fileName(), QString( "dir/file1.ext" ) );
|
||||||
|
QCOMPARE( model.shortName(), QString( "file1" ) );
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
QCOMPARE( model.w(), Distance( 0 ) );
|
||||||
|
QCOMPARE( model.h(), Distance( 0 ) );
|
||||||
|
|
||||||
|
Template tmplate( "Test Brand", "part", "desc", "testPaperId", 100, 400 );
|
||||||
|
FrameRect* frame = new FrameRect( 100, 200, 5, 0, 0, "rect1" );
|
||||||
|
QVERIFY( frame->w() != frame->h() );
|
||||||
|
tmplate.addFrame( frame );
|
||||||
|
model.setTmplate( &tmplate ); // Copies
|
||||||
|
QCOMPARE( model.tmplate()->brand(), QString( "Test Brand" ) );
|
||||||
|
QCOMPARE( model.tmplate()->part(), QString( "part" ) );
|
||||||
|
QCOMPARE( model.tmplate()->description(), QString( "desc" ) );
|
||||||
|
QCOMPARE( model.tmplate()->paperId(), QString( "testPaperId" ) );
|
||||||
|
QCOMPARE( model.tmplate()->pageWidth(), Distance( 100 ) );
|
||||||
|
QCOMPARE( model.tmplate()->pageHeight(), Distance( 400 ) );
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
|
||||||
|
QVERIFY( model.frame()->id() == frame->id() );
|
||||||
|
QCOMPARE( model.w(), Distance( 100 ) );
|
||||||
|
QCOMPARE( model.h(), Distance( 200 ) );
|
||||||
|
QCOMPARE( model.w(), frame->w() );
|
||||||
|
QCOMPARE( model.h(), frame->h() );
|
||||||
|
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
QVERIFY( !model.rotate() );
|
||||||
|
model.setRotate( false );
|
||||||
|
QVERIFY( !model.rotate() );
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
model.setRotate( true );
|
||||||
|
QVERIFY( model.rotate() );
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
|
||||||
|
QCOMPARE( model.w(), frame->h() );
|
||||||
|
QCOMPARE( model.h(), frame->w() );
|
||||||
|
|
||||||
|
model.setRotate( false );
|
||||||
|
QVERIFY( !model.rotate() );
|
||||||
|
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
model.setH( 300 ); // Default does nothing
|
||||||
|
QCOMPARE( model.h(), Distance( 200 ) );
|
||||||
|
QVERIFY( model.isModified() ); // Set anyway
|
||||||
|
|
||||||
|
// Continuous frame implements setH()
|
||||||
|
Template tmplate2( "Test Brand2", "part2", "desc2", "testPaperId2", 100, 400 );
|
||||||
|
FrameContinuous* frame2 = new FrameContinuous( 100, 0, 500, 200, "continuous1" );
|
||||||
|
QCOMPARE( frame2->h(), Distance( 200 ) );
|
||||||
|
tmplate2.addFrame( frame2 );
|
||||||
|
model.setTmplate( &tmplate2 );
|
||||||
|
QVERIFY( model.frame()->id() == frame2->id() );
|
||||||
|
QCOMPARE( model.w(), Distance( 100 ) );
|
||||||
|
QCOMPARE( model.h(), Distance( 200 ) );
|
||||||
|
QCOMPARE( model.w(), frame2->w() );
|
||||||
|
QCOMPARE( model.h(), frame2->h() );
|
||||||
|
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
model.setH( 300 );
|
||||||
|
QCOMPARE( model.h(), Distance( 300 ) );
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Objects
|
||||||
|
//
|
||||||
|
ColorNode black( Qt::black );
|
||||||
|
ModelObject* ellipse = new ModelEllipseObject( 1, 0, 100, 100, false, 1, black, black );
|
||||||
|
ModelObject* box = new ModelBoxObject( 1, 100, 100, 100, false, 1, black, black );
|
||||||
|
ModelObject* line = new ModelLineObject( 1, 200, 99 /*dx*/, 1 /*dy*/, 1.0, black );
|
||||||
|
ModelObject* text = new ModelTextObject( 1, 201, 100, 30, false, "", "Sans", 10, QFont::Normal, false, false, black, Qt::AlignLeft, Qt::AlignTop, QTextOption::WordWrap, 1, false );
|
||||||
|
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
model.addObject( ellipse );
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
model.addObject( box );
|
||||||
|
model.addObject( line );
|
||||||
|
model.addObject( text );
|
||||||
|
|
||||||
|
QCOMPARE( model.objectList().size(), 4 );
|
||||||
|
|
||||||
|
ModelObject* line2 = new ModelLineObject( 1, 231, 100 /*dx*/, 1 /*dy*/, 1.0, black );
|
||||||
|
model.addObject( line2 );
|
||||||
|
QCOMPARE( model.objectList().size(), 5 );
|
||||||
|
|
||||||
|
model.clearModified();
|
||||||
|
QVERIFY( !model.isModified() );
|
||||||
|
|
||||||
|
model.deleteObject( line2 );
|
||||||
|
QCOMPARE( model.objectList().size(), 4 );
|
||||||
|
QVERIFY( model.isModified() );
|
||||||
|
|
||||||
|
ModelObject* object;
|
||||||
|
|
||||||
|
object = model.objectAt( 1 /*scale*/, 1, 200 );
|
||||||
|
QVERIFY( object );
|
||||||
|
QVERIFY( dynamic_cast<ModelLineObject*>(object) );
|
||||||
|
QCOMPARE( object->id(), line->id() );
|
||||||
|
|
||||||
|
object = model.objectAt( 1 /*scale*/, 100, 150 );
|
||||||
|
QVERIFY( object );
|
||||||
|
QVERIFY( dynamic_cast<ModelBoxObject*>(object) );
|
||||||
|
QCOMPARE( object->id(), box->id() );
|
||||||
|
|
||||||
|
object = model.objectAt( 1 /*scale*/, 50, 0 );
|
||||||
|
QVERIFY( object );
|
||||||
|
QVERIFY( dynamic_cast<ModelEllipseObject*>(object) );
|
||||||
|
QCOMPARE( object->id(), ellipse->id() );
|
||||||
|
|
||||||
|
object = model.objectAt( 1 /*scale*/, 1 + 3, 201 + 3 ); // Allow for text offset
|
||||||
|
QVERIFY( object );
|
||||||
|
QVERIFY( dynamic_cast<ModelTextObject*>(object) );
|
||||||
|
QCOMPARE( object->id(), text->id() );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selection
|
||||||
|
//
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
QVERIFY( !model.isSelectionAtomic() );
|
||||||
|
QVERIFY( model.getSelection().isEmpty() );
|
||||||
|
QVERIFY( !model.getFirstSelectedObject() );
|
||||||
|
|
||||||
|
QVERIFY( !model.canSelectionText() );
|
||||||
|
QVERIFY( !model.canSelectionFill() );
|
||||||
|
QVERIFY( !model.canSelectionLineColor() );
|
||||||
|
QVERIFY( !model.canSelectionLineWidth() );
|
||||||
|
|
||||||
|
model.selectAll();
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( !model.isSelectionAtomic() );
|
||||||
|
QVERIFY( !model.getSelection().isEmpty() );
|
||||||
|
QCOMPARE( model.getSelection().size(), 4 );
|
||||||
|
QCOMPARE( model.getSelection().first()->id(), ellipse->id() );
|
||||||
|
QCOMPARE( model.getSelection().at(1)->id(), box->id() );
|
||||||
|
QCOMPARE( model.getSelection().at(2)->id(), line->id() );
|
||||||
|
QCOMPARE( model.getSelection().at(3)->id(), text->id() );
|
||||||
|
QVERIFY( model.getFirstSelectedObject() );
|
||||||
|
QCOMPARE( model.getFirstSelectedObject()->id(), ellipse->id() );
|
||||||
|
|
||||||
|
QVERIFY( model.canSelectionText() );
|
||||||
|
QVERIFY( model.canSelectionFill() );
|
||||||
|
QVERIFY( model.canSelectionLineColor() );
|
||||||
|
QVERIFY( model.canSelectionLineWidth() );
|
||||||
|
|
||||||
|
model.unselectAll();
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
QVERIFY( !model.isSelectionAtomic() );
|
||||||
|
QVERIFY( model.getSelection().isEmpty() );
|
||||||
|
QVERIFY( !model.getFirstSelectedObject() );
|
||||||
|
|
||||||
|
model.selectObject( text );
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( model.isSelectionAtomic() );
|
||||||
|
QCOMPARE( model.getSelection().size(), 1 );
|
||||||
|
QCOMPARE( model.getFirstSelectedObject()->id(), text->id() );
|
||||||
|
|
||||||
|
QVERIFY( model.canSelectionText() );
|
||||||
|
QVERIFY( !model.canSelectionFill() );
|
||||||
|
QVERIFY( !model.canSelectionLineColor() );
|
||||||
|
QVERIFY( !model.canSelectionLineWidth() );
|
||||||
|
|
||||||
|
model.unselectObject( text );
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
|
||||||
|
model.selectObject( line );
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( model.isSelectionAtomic() );
|
||||||
|
QCOMPARE( model.getSelection().size(), 1 );
|
||||||
|
QCOMPARE( model.getFirstSelectedObject()->id(), line->id() );
|
||||||
|
|
||||||
|
QVERIFY( !model.canSelectionText() );
|
||||||
|
QVERIFY( !model.canSelectionFill() );
|
||||||
|
QVERIFY( model.canSelectionLineColor() );
|
||||||
|
QVERIFY( model.canSelectionLineWidth() );
|
||||||
|
|
||||||
|
model.unselectAll();
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
|
||||||
|
double margin = 0.5; // Allow 0.5pt margin
|
||||||
|
Region region( 1 - margin, 302 - margin, 101 + margin /*x2*/, 302 + margin /*y2*/ ); // Outside all objects
|
||||||
|
model.selectRegion( region );
|
||||||
|
QVERIFY( model.getSelection().isEmpty() );
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
|
||||||
|
region.setY1( 0 - margin ); // Ellipse
|
||||||
|
region.setY2( 100 + margin );
|
||||||
|
model.selectRegion( region );
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( model.isSelectionAtomic() );
|
||||||
|
QCOMPARE( model.getSelection().size(), 1 );
|
||||||
|
QCOMPARE( model.getFirstSelectedObject()->id(), ellipse->id() );
|
||||||
|
|
||||||
|
QVERIFY( !model.canSelectionText() );
|
||||||
|
QVERIFY( model.canSelectionFill() );
|
||||||
|
QVERIFY( model.canSelectionLineColor() );
|
||||||
|
QVERIFY( model.canSelectionLineWidth() );
|
||||||
|
|
||||||
|
region.setY1( 200 - margin ); // Line
|
||||||
|
region.setY2( 201 + margin );
|
||||||
|
model.selectRegion( region );
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( !model.isSelectionAtomic() ); // Accumulative
|
||||||
|
QCOMPARE( model.getSelection().size(), 2 );
|
||||||
|
QCOMPARE( model.getSelection().at(0)->id(), ellipse->id() );
|
||||||
|
QCOMPARE( model.getSelection().at(1)->id(), line->id() );
|
||||||
|
|
||||||
|
model.unselectObject( ellipse );
|
||||||
|
QVERIFY( !model.isSelectionEmpty() );
|
||||||
|
QVERIFY( model.isSelectionAtomic() );
|
||||||
|
QCOMPARE( model.getSelection().size(), 1 );
|
||||||
|
QCOMPARE( model.getFirstSelectedObject()->id(), line->id() );
|
||||||
|
|
||||||
|
model.unselectAll();
|
||||||
|
QVERIFY( model.isSelectionEmpty() );
|
||||||
|
|
||||||
|
// TODO: Operations on selections etc
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestModel::saveRestore()
|
||||||
|
{
|
||||||
|
Model* model = new Model;
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
model->clearModified();
|
||||||
|
QVERIFY( !model->isModified() );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set template/frame
|
||||||
|
//
|
||||||
|
Template tmplate( "Test Brand", "part", "desc", "testPaperId", 110, 410 );
|
||||||
|
FrameRect* frame = new FrameRect( 120, 220, 5, 0, 0, "rect1" );
|
||||||
|
tmplate.addFrame( frame );
|
||||||
|
model->setTmplate( &tmplate ); // Copies
|
||||||
|
QCOMPARE( model->tmplate()->brand(), QString( "Test Brand" ) );
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
|
||||||
|
model->clearModified();
|
||||||
|
QVERIFY( !model->isModified() );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set merge
|
||||||
|
//
|
||||||
|
Merge* merge = Factory::createMerge( TextCsvKeys::id() );
|
||||||
|
QCOMPARE( merge->id(), TextCsvKeys::id() );
|
||||||
|
|
||||||
|
model->setMerge( merge );
|
||||||
|
QCOMPARE( model->merge(), merge );
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
|
||||||
|
model->clearModified();
|
||||||
|
QVERIFY( !model->isModified() );
|
||||||
|
|
||||||
|
QTemporaryFile csv;
|
||||||
|
csv.open();
|
||||||
|
csv.write( "id,text\n1,text1\n2,text2\n3,text3\n" );
|
||||||
|
csv.close();
|
||||||
|
|
||||||
|
merge->setSource( csv.fileName() );
|
||||||
|
QCOMPARE( merge->source(), csv.fileName() );
|
||||||
|
QCOMPARE( merge->recordList().size(), 3 );
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
|
||||||
|
model->clearModified();
|
||||||
|
QVERIFY( !model->isModified() );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add some objects
|
||||||
|
//
|
||||||
|
ColorNode black( Qt::black );
|
||||||
|
ModelObject* object1 = new ModelLineObject( 1, 1, 90, 80, 1.0, black );
|
||||||
|
model->addObject( object1 );
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
QCOMPARE( model->objectList().size(), 1 );
|
||||||
|
QCOMPARE( model->objectList().first(), object1 );
|
||||||
|
|
||||||
|
model->clearModified();
|
||||||
|
QVERIFY( !model->isModified() );
|
||||||
|
|
||||||
|
ModelObject* object2 = new ModelTextObject( 2, 2, 70, 30, false, "", "Sans", 10, QFont::Normal, false, false, black, Qt::AlignLeft, Qt::AlignTop, QTextOption::WordWrap, 1, false );
|
||||||
|
model->addObject( object2 );
|
||||||
|
QVERIFY( model->isModified() );
|
||||||
|
QCOMPARE( model->objectList().size(), 2 );
|
||||||
|
QCOMPARE( model->objectList().last(), object2 );
|
||||||
|
|
||||||
|
QString modelShortName = model->shortName(); // If no fileName set then model expects to have have this called before being saved/restored (otherwise get differing untitled names)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test
|
||||||
|
//
|
||||||
|
Model* saved = model->save();
|
||||||
|
QVERIFY( saved->isModified() );
|
||||||
|
QCOMPARE( saved->merge(), model->merge() ); // Shared
|
||||||
|
QCOMPARE( saved->isModified(), model->isModified() );
|
||||||
|
QCOMPARE( saved->shortName(), modelShortName );
|
||||||
|
QCOMPARE( saved->shortName(), model->shortName() );
|
||||||
|
QCOMPARE( saved->fileName(), model->fileName() );
|
||||||
|
QCOMPARE( saved->rotate(), model->rotate() );
|
||||||
|
QCOMPARE( saved->objectList().size(), model->objectList().size() );
|
||||||
|
QVERIFY( saved->objectList().at(0) != object1 ); // Objects copied
|
||||||
|
QVERIFY( saved->objectList().at(1) != object2 ); // Objects copied
|
||||||
|
QCOMPARE( saved->objectList().at(0)->x0(), model->objectList().at(0)->x0() );
|
||||||
|
QCOMPARE( saved->objectList().at(0)->y0(), model->objectList().at(0)->y0() );
|
||||||
|
QCOMPARE( saved->objectList().at(1)->x0(), model->objectList().at(1)->x0() );
|
||||||
|
QCOMPARE( saved->objectList().at(1)->y0(), model->objectList().at(1)->y0() );
|
||||||
|
|
||||||
|
// Modify original
|
||||||
|
Template tmplate2( "Test Brand2", "part2", "desc2", "testPaperId2", 230, 630 );
|
||||||
|
FrameRect* frame2 = new FrameRect( 240, 340, 5, 0, 0, "rect2" );
|
||||||
|
tmplate2.addFrame( frame2 );
|
||||||
|
model->setTmplate( &tmplate2 );
|
||||||
|
QCOMPARE( model->tmplate()->brand(), QString( "Test Brand2" ) );
|
||||||
|
QCOMPARE( model->w(), Distance( 240 ) );
|
||||||
|
QCOMPARE( model->h(), Distance( 340 ) );
|
||||||
|
|
||||||
|
model->setFileName( "dir/file1.ext" );
|
||||||
|
QCOMPARE( model->shortName(), QString( "file1" ) );
|
||||||
|
|
||||||
|
model->setRotate( true );
|
||||||
|
QVERIFY( model->rotate() );
|
||||||
|
QCOMPARE( model->w(), Distance( 340 ) );
|
||||||
|
QCOMPARE( model->h(), Distance( 240 ) );
|
||||||
|
|
||||||
|
model->deleteObject( model->objectList().first() );
|
||||||
|
QCOMPARE( model->objectList().size(), 1 );
|
||||||
|
QCOMPARE( model->objectList().first(), object2 );
|
||||||
|
|
||||||
|
model->objectList().first()->setY0( model->objectList().first()->y0() + 1 );
|
||||||
|
|
||||||
|
Merge* merge2 = Factory::createMerge( TextCsv::id() );
|
||||||
|
QCOMPARE( merge2->id(), TextCsv::id() );
|
||||||
|
QTemporaryFile csv2; csv2.open(); csv2.write( "21,text21\n22,text22\n23,text23\n24,text24\n" ); csv2.close();
|
||||||
|
merge2->setSource( csv2.fileName() );
|
||||||
|
QCOMPARE( merge2->source(), csv2.fileName() );
|
||||||
|
QCOMPARE( merge2->recordList().size(), 4 );
|
||||||
|
|
||||||
|
model->setMerge( merge2 ); // Deletes original so saved->merge() now invalid
|
||||||
|
QCOMPARE( model->merge(), merge2 );
|
||||||
|
|
||||||
|
Model* modified = model->save();
|
||||||
|
QCOMPARE( modified->merge(), merge2 ); // Shared
|
||||||
|
|
||||||
|
// Verify differences
|
||||||
|
QVERIFY( model->shortName() != modelShortName );
|
||||||
|
QVERIFY( model->shortName() != saved->shortName() );
|
||||||
|
QVERIFY( model->fileName() != saved->fileName() );
|
||||||
|
QVERIFY( model->tmplate()->brand() != saved->tmplate()->brand() );
|
||||||
|
QVERIFY( model->rotate() != saved->rotate() );
|
||||||
|
QVERIFY( model->w() != saved->w() );
|
||||||
|
QVERIFY( model->h() != saved->h() );
|
||||||
|
QVERIFY( model->objectList().size() != saved->objectList().size() );
|
||||||
|
QVERIFY( model->objectList().at(0)->x0() != saved->objectList().at(0)->x0() );
|
||||||
|
QVERIFY( model->objectList().at(0)->y0() != saved->objectList().at(0)->y0() );
|
||||||
|
QCOMPARE( model->objectList().at(0)->x0(), saved->objectList().at(1)->x0() ); // Unchanged
|
||||||
|
QVERIFY( model->objectList().at(0)->y0() != saved->objectList().at(1)->y0() );
|
||||||
|
|
||||||
|
// Restore
|
||||||
|
model->restore( saved );
|
||||||
|
QCOMPARE( model->shortName(), modelShortName );
|
||||||
|
QCOMPARE( model->shortName(), saved->shortName() );
|
||||||
|
QCOMPARE( model->fileName(), saved->fileName() );
|
||||||
|
QCOMPARE( model->tmplate()->brand(), saved->tmplate()->brand() );
|
||||||
|
QCOMPARE( model->rotate(), saved->rotate() );
|
||||||
|
QCOMPARE( model->w(), saved->w() );
|
||||||
|
QCOMPARE( model->h(), saved->h() );
|
||||||
|
QCOMPARE( model->objectList().size(), saved->objectList().size() );
|
||||||
|
QCOMPARE( model->objectList().size(), 2 );
|
||||||
|
QCOMPARE( model->objectList().at(0)->x0(), saved->objectList().at(0)->x0() );
|
||||||
|
QCOMPARE( model->objectList().at(0)->y0(), saved->objectList().at(0)->y0() );
|
||||||
|
QCOMPARE( model->objectList().at(1)->x0(), saved->objectList().at(1)->x0() );
|
||||||
|
QCOMPARE( model->objectList().at(1)->y0(), saved->objectList().at(1)->y0() );
|
||||||
|
|
||||||
|
QCOMPARE( model->merge(), merge2 ); // Unchanged
|
||||||
|
QVERIFY( model->merge() != saved->merge() ); // NOTE saved->merge() now points to deleted object
|
||||||
|
|
||||||
|
// Unrestore
|
||||||
|
model->restore( modified );
|
||||||
|
QVERIFY( model->shortName() != modelShortName );
|
||||||
|
QVERIFY( model->shortName() != saved->shortName() );
|
||||||
|
QVERIFY( model->fileName() != saved->fileName() );
|
||||||
|
QVERIFY( model->tmplate()->brand() != saved->tmplate()->brand() );
|
||||||
|
QVERIFY( model->rotate() != saved->rotate() );
|
||||||
|
QVERIFY( model->w() != saved->w() );
|
||||||
|
QVERIFY( model->h() != saved->h() );
|
||||||
|
QCOMPARE( model->objectList().size(), 1 );
|
||||||
|
QVERIFY( model->objectList().size() != saved->objectList().size() );
|
||||||
|
QVERIFY( model->objectList().at(0)->x0() != saved->objectList().at(0)->x0() );
|
||||||
|
QVERIFY( model->objectList().at(0)->y0() != saved->objectList().at(0)->y0() );
|
||||||
|
QCOMPARE( model->merge(), merge2 ); // Same
|
||||||
|
|
||||||
|
QCOMPARE( model->shortName(), modified->shortName() );
|
||||||
|
QCOMPARE( model->fileName(), modified->fileName() );
|
||||||
|
QCOMPARE( model->tmplate()->brand(), modified->tmplate()->brand() );
|
||||||
|
QCOMPARE( model->rotate(), modified->rotate() );
|
||||||
|
QCOMPARE( model->w(), modified->w() );
|
||||||
|
QCOMPARE( model->h(), modified->h() );
|
||||||
|
QCOMPARE( model->objectList().size(), modified->objectList().size() );
|
||||||
|
QCOMPARE( model->objectList().at(0)->x0(), modified->objectList().at(0)->x0() );
|
||||||
|
QCOMPARE( model->objectList().at(0)->y0(), modified->objectList().at(0)->y0() );
|
||||||
|
|
||||||
|
delete model->merge(); // Final instance owned by us
|
||||||
|
delete model;
|
||||||
|
delete saved;
|
||||||
|
delete modified;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/* TestModel.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
|
||||||
|
class TestModel : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void model();
|
||||||
|
void saveRestore();
|
||||||
|
};
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/* TestRawText.cpp
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestRawText.h"
|
||||||
|
|
||||||
|
#include "model/RawText.h"
|
||||||
|
|
||||||
|
#include "merge/Record.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(TestRawText)
|
||||||
|
|
||||||
|
using namespace glabels::model;
|
||||||
|
using namespace glabels::merge;
|
||||||
|
|
||||||
|
|
||||||
|
void TestRawText::rawText()
|
||||||
|
{
|
||||||
|
RawText rawText;
|
||||||
|
Record record;
|
||||||
|
|
||||||
|
QVERIFY( rawText.isEmpty() );
|
||||||
|
QVERIFY( !rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.toString(), QString( "" ) );
|
||||||
|
QCOMPARE( rawText.toStdString(), std::string( "" ) );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "" ) );
|
||||||
|
|
||||||
|
rawText = "text";
|
||||||
|
QVERIFY( !rawText.isEmpty() );
|
||||||
|
QVERIFY( !rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.toString(), QString( "text" ) );
|
||||||
|
QCOMPARE( rawText.toStdString(), std::string( "text" ) );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "text" ) );
|
||||||
|
|
||||||
|
RawText rawText2( "text" );
|
||||||
|
QVERIFY( !rawText2.isEmpty() );
|
||||||
|
QVERIFY( !rawText2.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText2.toString(), QString( "text" ) );
|
||||||
|
|
||||||
|
rawText = "${key1}";
|
||||||
|
QVERIFY( !rawText.isEmpty() );
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.toString(), QString( "${key1}" ) );
|
||||||
|
QCOMPARE( rawText.toStdString(), std::string( "${key1}" ) );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "" ) );
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Record
|
||||||
|
///
|
||||||
|
record["key1"] = "val1";
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val1" ) );
|
||||||
|
|
||||||
|
rawText = "${key1}${key2}";
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val1" ) );
|
||||||
|
|
||||||
|
record["key2"] = "val2";
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val1val2" ) );
|
||||||
|
|
||||||
|
rawText = "${key1}text${key2}";
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val1textval2" ) );
|
||||||
|
|
||||||
|
rawText = "text1${key1}text2${key2}text3";
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "text1val1text2val2text3" ) );
|
||||||
|
|
||||||
|
rawText = "${key1}text${key2}${key3}";
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val1textval2" ) );
|
||||||
|
|
||||||
|
rawText = "${key2}${key3}${key1}";
|
||||||
|
QVERIFY( rawText.hasPlaceHolders() );
|
||||||
|
QCOMPARE( rawText.expand( &record ), QString( "val2val1" ) );
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* TestRawText.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
|
||||||
|
class TestRawText : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void rawText();
|
||||||
|
};
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/* TestTextNode.cpp
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestTextNode.h"
|
||||||
|
|
||||||
|
#include "model/TextNode.h"
|
||||||
|
|
||||||
|
#include "merge/Record.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(TestTextNode)
|
||||||
|
|
||||||
|
using namespace glabels::model;
|
||||||
|
using namespace glabels::merge;
|
||||||
|
|
||||||
|
|
||||||
|
void TestTextNode::textNode()
|
||||||
|
{
|
||||||
|
Record record;
|
||||||
|
|
||||||
|
TextNode textNode;
|
||||||
|
QVERIFY( !textNode.isField() );
|
||||||
|
QCOMPARE( textNode.data(), QString( "" ) );
|
||||||
|
QVERIFY( textNode == TextNode() );
|
||||||
|
QVERIFY( !(textNode != TextNode()) );
|
||||||
|
QCOMPARE( textNode.text( nullptr ), QString( "" ) );
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
textNode.setField( true );
|
||||||
|
QVERIFY( textNode.isField() );
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
textNode.setField( false );
|
||||||
|
QVERIFY( !textNode.isField() );
|
||||||
|
|
||||||
|
textNode.setData( QString( "data1" ) );
|
||||||
|
QCOMPARE( textNode.data(), QString( "data1" ) );
|
||||||
|
QCOMPARE( textNode.text( nullptr ), QString( "data1" ) );
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "data1" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
textNode.setField( true );
|
||||||
|
QCOMPARE( textNode.text( nullptr ), QString( "${data1}" ) );
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructors
|
||||||
|
///
|
||||||
|
TextNode textNode2( true, "data2" );
|
||||||
|
QVERIFY( textNode2.isField() );
|
||||||
|
QCOMPARE( textNode2.data(), QString( "data2" ) );
|
||||||
|
textNode.setField( false );
|
||||||
|
QVERIFY( !(textNode2 == textNode) );
|
||||||
|
QVERIFY( textNode2 != textNode );
|
||||||
|
textNode.setField( true );
|
||||||
|
QVERIFY( !(textNode2 == textNode) );
|
||||||
|
QVERIFY( textNode2 != textNode );
|
||||||
|
textNode.setData( QString( "data2" ) );
|
||||||
|
QVERIFY( textNode2 == textNode );
|
||||||
|
QVERIFY( !(textNode2 != textNode) );
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Record
|
||||||
|
///
|
||||||
|
record["key1"] = "";
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
textNode.setData( QString( "key1" ) );
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( textNode.isEmptyField( &record ) );
|
||||||
|
|
||||||
|
record["key1"] = "val1";
|
||||||
|
QCOMPARE( textNode.text( &record ), QString( "val1" ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( nullptr ) );
|
||||||
|
QVERIFY( !textNode.isEmptyField( &record ) );
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* TestTextNode.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Jim Evins <evins@snaught.com>
|
||||||
|
*
|
||||||
|
* This file is part of gLabels-qt.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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.
|
||||||
|
*
|
||||||
|
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
|
||||||
|
class TestTextNode : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void textNode();
|
||||||
|
};
|
||||||
@@ -1209,6 +1209,10 @@
|
|||||||
<source>Delete</source>
|
<source>Delete</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Resize</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>glabels::MainWindow</name>
|
<name>glabels::MainWindow</name>
|
||||||
@@ -1740,6 +1744,14 @@
|
|||||||
<source>Quick Access Toolbar</source>
|
<source>Quick Access Toolbar</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Undo %1</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Redo %1</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>glabels::MergeView</name>
|
<name>glabels::MergeView</name>
|
||||||
@@ -1898,10 +1910,6 @@
|
|||||||
<source>Set image</source>
|
<source>Set image</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Move</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Size</source>
|
<source>Size</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@@ -1914,6 +1922,18 @@
|
|||||||
<source>Shadow</source>
|
<source>Shadow</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Position</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Barcode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reset</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>glabels::PrintView</name>
|
<name>glabels::PrintView</name>
|
||||||
|
|||||||
Reference in New Issue
Block a user