File indexing completed on 2025-01-12 03:59:34
0001 /** 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include <QtDebug> 0010 #include <QDebug> 0011 #include <QtTest/QtTest> 0012 #include <QStandardItem> 0013 #include <QStandardItemModel> 0014 0015 #include <KChartCartesianDiagramDataCompressor_p.h> 0016 0017 typedef KChart::CartesianDiagramDataCompressor::CachePosition CachePosition; 0018 0019 struct Match { 0020 Match( const CachePosition& pos, const QModelIndex& index ) 0021 : cachePosition( pos ), 0022 index( index ) 0023 { 0024 } 0025 CachePosition cachePosition; 0026 QModelIndex index; 0027 }; 0028 0029 class CartesianDiagramDataCompressorTests : public QObject 0030 { 0031 Q_OBJECT 0032 0033 private Q_SLOTS: 0034 0035 void initTestCase() 0036 { 0037 // make 10 data sets a n elements 0038 model.clear(); 0039 model.setColumnCount( ColumnCount ); 0040 model.setRowCount( RowCount ); 0041 for ( int row = 0; row < RowCount; ++row ) 0042 for ( int column = 0; column < ColumnCount; ++column ) { 0043 QStandardItem* item = new QStandardItem(); 0044 item->setData( 1, Qt::DisplayRole ); 0045 model.setItem( row, column, item ); 0046 } 0047 0048 width = 200; 0049 height = 100; 0050 // these settings result in 5 indexes per pixel 0051 } 0052 0053 void initializationTest() 0054 { 0055 QVERIFY2( compressor.modelDataColumns() == 0, "without a model, columns should be zero" ); 0056 QVERIFY2( compressor.modelDataRows() == 0, "without a model,rows should be zero" ); 0057 } 0058 0059 void setModelTest() 0060 { 0061 compressor.setModel( &model ); 0062 QVERIFY2( compressor.modelDataColumns() == model.columnCount(), 0063 "columns should be equal to model columns, independent of resolution" ); 0064 QVERIFY2( compressor.modelDataRows() == 0, "without a diagram resolution, columns should be zero" ); 0065 } 0066 0067 void setResolutionTest() 0068 { 0069 compressor.setResolution( width, height ); 0070 QVERIFY2( compressor.modelDataColumns() == model.columnCount(), 0071 "column count should be equal to dataset count when both model and resolution are set" ); 0072 QVERIFY2( compressor.modelDataRows() == width, 0073 "row count should be equal to width when both model and resolution are set, and " 0074 "model row count exceeds widget width"); 0075 } 0076 0077 void mapToCacheTest() 0078 { 0079 CachePosition NullPoint( -1, -1 ); 0080 Match matches[] = { 0081 Match( CachePosition( 0, 0 ), model.index( 0, 0 ) ), 0082 Match( CachePosition( 0, 0 ), model.index( 1, 0 ) ), 0083 Match( CachePosition( 0, 0 ), model.index( 2, 0 ) ), 0084 Match( CachePosition( 0, 0 ), model.index( 3, 0 ) ), 0085 Match( CachePosition( 0, 0 ), model.index( 4, 0 ) ), 0086 Match( CachePosition( 0, 1 ), model.index( 0, 1 ) ), 0087 Match( CachePosition( 0, 1 ), model.index( 1, 1 ) ), 0088 Match( CachePosition( 0, 1 ), model.index( 2, 1 ) ), 0089 Match( CachePosition( 0, 1 ), model.index( 3, 1 ) ), 0090 Match( CachePosition( 0, 1 ), model.index( 4, 1 ) ), 0091 Match( CachePosition( 2, 2 ), model.index( 10, 2 ) ), 0092 Match( CachePosition( 2, 2 ), model.index( 11, 2 ) ), 0093 Match( CachePosition( 2, 2 ), model.index( 12, 2 ) ), 0094 Match( CachePosition( 2, 2 ), model.index( 13, 2 ) ), 0095 Match( CachePosition( 2, 2 ), model.index( 14, 2 ) ), 0096 // the following are outside the model boundary: 0097 Match( NullPoint, model.index( 0, ColumnCount ) ), 0098 Match( NullPoint, model.index( 1, ColumnCount ) ), 0099 Match( NullPoint, model.index( 2, ColumnCount ) ), 0100 Match( NullPoint, model.index( 3, ColumnCount ) ), 0101 Match( NullPoint, model.index( 4, ColumnCount) ), 0102 Match( NullPoint, model.index( RowCount, 0 ) ), 0103 // sentinel 0104 Match( CachePosition( 0, 0 ), QModelIndex() ) 0105 }; 0106 0107 for ( int i = 0; matches[i].index.isValid(); ++i ) { 0108 QCOMPARE( matches[i].cachePosition, compressor.mapToCache( matches[i].index ) ); 0109 } 0110 0111 QCOMPARE( NullPoint, compressor.mapToCache( QModelIndex() ) ); 0112 } 0113 0114 void mapToModelTest() 0115 { 0116 // test 1: valid point: 0117 { 0118 QModelIndexList indexes; 0119 CachePosition point( 0, 0 ); 0120 indexes = compressor.mapToModel( point ); 0121 for ( const QModelIndex& index : qAsConst(indexes) ) { 0122 QVERIFY2( compressor.mapToCache( index ) == point, 0123 "index mapToModel does not map back to the original cache point" ); 0124 } 0125 } 0126 // test 2: invalid point: 0127 { 0128 QModelIndexList indexes; 0129 CachePosition point( 0, ColumnCount ); // just outside column count 0130 indexes = compressor.mapToModel( point ); 0131 QVERIFY2( indexes.isEmpty(), 0132 "index list for a point outside the data space should be empty" ); 0133 } 0134 { 0135 QModelIndexList indexes; 0136 CachePosition point( RowCount, 0 ); // just outside row count 0137 indexes = compressor.mapToModel( point ); 0138 QVERIFY2( indexes.isEmpty(), 0139 "index list for a point outside the data space should be empty" ); 0140 } 0141 } 0142 0143 0144 void invalidateTest() 0145 { 0146 CachePosition position( 0, 0 ); 0147 // KChart::CartesianDiagramDataCompressor::DataPoint point; 0148 QVERIFY( compressor.mapsToModelIndex( position ) ); 0149 compressor.retrieveModelData( position ); 0150 QVERIFY2( compressor.isCached( position ), 0151 "datapoint should be valid after retrieveModelData( position )" ); 0152 QModelIndex index( model.index( 0, 0 ) ); 0153 compressor.slotModelDataChanged( index, index ); 0154 QVERIFY2( ! compressor.isCached( position ), 0155 "datapoint should be not valid after call to dataChanged slot" ); 0156 CachePosition position2( 1, 0 ); 0157 CachePosition position3( 2, 1 ); 0158 compressor.retrieveModelData( position2 ); 0159 compressor.retrieveModelData( position3 ); 0160 QVERIFY2( ! compressor.isCached( position ), 0161 "datapoint should be not valid after call to dataChanged slot" ); 0162 compressor.retrieveModelData( position ); 0163 QVERIFY2( compressor.isCached( position ) && compressor.isCached( position2 ) && compressor.isCached( position3 ), 0164 "datapoints should all be valid after retrieveModelData" ); 0165 QModelIndex index2( model.index( 1 * compressor.indexesPerPixel(), 0 ) ); 0166 compressor.slotModelDataChanged( index, index2 ); 0167 QVERIFY2( ! compressor.isCached( position ) && ! compressor.isCached( position2 ) && compressor.isCached( position3 ), 0168 "dataChanged needs to invalidate an exact range" ); 0169 } 0170 0171 void datasetDimensionTest() 0172 { 0173 int oldDimension = compressor.m_datasetDimension; 0174 compressor.setDatasetDimension( 2 ); 0175 QVERIFY2( compressor.modelDataColumns() == ColumnCount / 2, 0176 "datasetDimension == 2 should cut the column count in half" ); 0177 compressor.setDatasetDimension( oldDimension ); 0178 QVERIFY2( compressor.modelDataColumns() == ColumnCount, 0179 "datasetDimension == 1 should restore the old column count" ); 0180 } 0181 0182 void cleanupTestCase() 0183 { 0184 } 0185 0186 private: 0187 KChart::CartesianDiagramDataCompressor compressor; 0188 QStandardItemModel model; 0189 static const int RowCount; 0190 static const int ColumnCount; 0191 int width; 0192 int height; 0193 }; 0194 0195 const int CartesianDiagramDataCompressorTests::ColumnCount = 10; 0196 const int CartesianDiagramDataCompressorTests::RowCount = 1000; 0197 0198 0199 QTEST_MAIN(CartesianDiagramDataCompressorTests) 0200 0201 #include "CartesianDiagramDataCompressorTests.moc"