Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++
++ #include <QtTest/QtTest>
++ #include <QtCharts/qabstractaxis.h>
++ #include <QtCharts/qvalueaxis.h>
++ #include <QtCharts/qlogvalueaxis.h>
++ #include <QtCharts/qbarcategoryaxis.h>
++ #include <QtCharts/qcategoryaxis.h>
++ #if QT_CONFIG(charts_datetime_axis)
++ #include <QtCharts/qdatetimeaxis.h>
++ #endif
++ #include <QtCharts/qlineseries.h>
++ #include <QtCharts/qareaseries.h>
++ #include <QtCharts/qscatterseries.h>
++ #include <QtCharts/qsplineseries.h>
++ #include <QtCharts/qpieseries.h>
++ #include <QtCharts/qbarseries.h>
++ #include <QtCharts/qpercentbarseries.h>
++ #include <QtCharts/qstackedbarseries.h>
++ #include <private/chartdataset_p.h>
++ #include <private/abstractdomain_p.h>
++ #include <tst_definitions.h>
++
++ QT_USE_NAMESPACE
++
++ Q_DECLARE_METATYPE(AbstractDomain *)
++ Q_DECLARE_METATYPE(QAbstractAxis *)
++ Q_DECLARE_METATYPE(QAbstractSeries *)
++ Q_DECLARE_METATYPE(QList<QAbstractSeries *>)
++ Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
++ Q_DECLARE_METATYPE(Qt::Alignment)
++ Q_DECLARE_METATYPE(QList<Qt::Alignment>)
++ Q_DECLARE_METATYPE(QLineSeries *)
++
++ class tst_ChartDataSet: public QObject {
++
++ Q_OBJECT
++ public:
++ tst_ChartDataSet():m_dataset(0){};
++
++ public Q_SLOTS:
++ void initTestCase();
++ void cleanupTestCase();
++ void init();
++ void cleanup();
++
++ private Q_SLOTS:
++ void chartdataset_data();
++ void chartdataset();
++ void addSeries_data();
++ void addSeries();
++ void removeSeries_data();
++ void removeSeries();
++ void addAxis_data();
++ void addAxis();
++ void removeAxis_data();
++ void removeAxis();
++ void attachAxis_data();
++ void attachAxis();
++ void detachAxis_data();
++ void detachAxis();
++ void domainChangePreservesRanges();
++
++ private:
++ void compareDomain(QAbstractSeries *series, qreal minX, qreal maxX,
++ qreal minY, qreal maxY) const;
++ ChartDataSet* m_dataset;
++ };
++
++ void tst_ChartDataSet::initTestCase()
++ {
++ qRegisterMetaType<AbstractDomain*>();
++ qRegisterMetaType<QAbstractAxis*>();
++ qRegisterMetaType<QAbstractSeries*>();
++ }
++
++ void tst_ChartDataSet::cleanupTestCase()
++ {
++ QTest::qWait(1); // Allow final deleteLaters to run
++ }
++
++ void tst_ChartDataSet::init()
++ {
++ Q_ASSERT(!m_dataset);
++ m_dataset = new ChartDataSet(0);
++ }
++
++
++ void tst_ChartDataSet::cleanup()
++ {
++ delete m_dataset;
++ m_dataset = 0;
++ }
++
++ void tst_ChartDataSet::chartdataset_data()
++ {
++ }
++
++ void tst_ChartDataSet::chartdataset()
++ {
++ QVERIFY(m_dataset->axes().isEmpty());
++ QVERIFY(m_dataset->series().isEmpty());
++ m_dataset->createDefaultAxes();
++ }
++
++
++ void tst_ChartDataSet::addSeries_data()
++ {
++ QTest::addColumn<QAbstractSeries*>("series");
++
++ QAbstractSeries* line = new QLineSeries(this);
++ QTest::newRow("line") << line;
++
++ QAbstractSeries* area = new QAreaSeries(static_cast<QLineSeries*>(new QLineSeries(this)));
++ QTest::newRow("area") << area;
++
++ QAbstractSeries* scatter = new QScatterSeries(this);
++ QTest::newRow("scatter") << scatter;
++
++ QAbstractSeries* spline = new QSplineSeries(this);
++ QTest::newRow("spline") << spline;
++
++ QAbstractSeries* pie = new QPieSeries(this);
++ QTest::newRow("pie") << pie;
++
++ QAbstractSeries* bar = new QBarSeries(this);
++ QTest::newRow("bar") << bar;
++
++ QAbstractSeries* percent = new QPercentBarSeries(this);
++ QTest::newRow("percent") << percent;
++
++ QAbstractSeries* stacked = new QStackedBarSeries(this);
++ QTest::newRow("stacked") << stacked;
++ }
++
++ void tst_ChartDataSet::addSeries()
++ {
++ QFETCH(QAbstractSeries*, series);
++ QVERIFY(m_dataset->series().isEmpty());
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ m_dataset->addSeries(series);
++
++ QCOMPARE(m_dataset->series().size(),1);
++ TRY_COMPARE(spy0.size(), 0);
++ TRY_COMPARE(spy1.size(), 0);
++ TRY_COMPARE(spy2.size(), 1);
++ TRY_COMPARE(spy3.size(), 0);
++ }
++
++ void tst_ChartDataSet::removeSeries_data()
++ {
++ addSeries_data();
++ }
++
++ void tst_ChartDataSet::removeSeries()
++ {
++ QFETCH(QAbstractSeries*, series);
++ QVERIFY(m_dataset->series().isEmpty());
++ m_dataset->addSeries(series);
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ m_dataset->removeSeries(series);
++
++ QCOMPARE(m_dataset->series().size(),0);
++ TRY_COMPARE(spy0.size(), 0);
++ TRY_COMPARE(spy1.size(), 0);
++ TRY_COMPARE(spy2.size(), 0);
++ TRY_COMPARE(spy3.size(), 1);
++
++ delete series;
++ }
++
++ void tst_ChartDataSet::addAxis_data()
++ {
++ QTest::addColumn<QAbstractAxis*>("axis");
++ QAbstractAxis* value = new QValueAxis(this);
++ QAbstractAxis* logvalue = new QLogValueAxis(this);
++ QAbstractAxis* category = new QCategoryAxis(this);
++ QAbstractAxis* barcategory = new QBarCategoryAxis(this);
++ #if QT_CONFIG(charts_datetime_axis)
++ QAbstractAxis* datetime = new QDateTimeAxis(this);
++ #endif
++
++ QTest::newRow("value") << value;
++ QTest::newRow("logvalue") << logvalue;
++ QTest::newRow("category") << category;
++ QTest::newRow("barcategory") << barcategory;
++ #if QT_CONFIG(charts_datetime_axis)
++ QTest::newRow("datetime") << datetime;
++ #endif
++ }
++
++ void tst_ChartDataSet::addAxis()
++ {
++ QFETCH(QAbstractAxis*, axis);
++ QVERIFY(m_dataset->axes().isEmpty());
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ m_dataset->addAxis(axis,Qt::AlignBottom);
++
++ QCOMPARE(m_dataset->axes().size(),1);
++ TRY_COMPARE(spy0.size(), 1);
++ TRY_COMPARE(spy1.size(), 0);
++ TRY_COMPARE(spy2.size(), 0);
++ TRY_COMPARE(spy3.size(), 0);
++ }
++
++ void tst_ChartDataSet::removeAxis_data()
++ {
++ addAxis_data();
++ }
++
++ void tst_ChartDataSet::removeAxis()
++ {
++ QFETCH(QAbstractAxis*, axis);
++ QVERIFY(m_dataset->series().isEmpty());
++ m_dataset->addAxis(axis,Qt::AlignBottom);
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ m_dataset->removeAxis(axis);
++
++ QCOMPARE(m_dataset->axes().size(),0);
++ QCOMPARE(m_dataset->series().size(),0);
++ TRY_COMPARE(spy0.size(), 0);
++ TRY_COMPARE(spy1.size(), 1);
++ TRY_COMPARE(spy2.size(), 0);
++ TRY_COMPARE(spy3.size(), 0);
++
++ delete axis;
++ }
++
++ void tst_ChartDataSet::attachAxis_data()
++ {
++
++ QTest::addColumn<QList<QAbstractSeries*> >("series");
++ QTest::addColumn<QList<QAbstractAxis*> >("axis");
++ QTest::addColumn<QList<Qt::Alignment> >("alignment");
++ QTest::addColumn<QAbstractSeries*>("attachSeries");
++ QTest::addColumn<QAbstractAxis*>("attachAxis");
++ QTest::addColumn<bool>("success");
++
++ {
++ QList<QAbstractSeries*> series;
++ QList<QAbstractAxis*> axes;
++ QList<Qt::Alignment> alignment;
++ QAbstractSeries* line = new QLineSeries(this);
++ QAbstractAxis* value1 = new QValueAxis(this);
++ QAbstractAxis* value2 = new QValueAxis(this);
++ series << line << 0;
++ axes << value1 << value2;
++ alignment << Qt::AlignBottom << Qt::AlignLeft;
++ QTest::newRow("first") << series << axes << alignment << line << value2 << true ;
++ }
++
++ {
++ QList<QAbstractSeries*> series;
++ QList<QAbstractAxis*> axes;
++ QList<Qt::Alignment> alignment;
++ QAbstractSeries* line = new QLineSeries(this);
++ QAbstractAxis* value1 = new QValueAxis(this);
++ QAbstractAxis* value2 = new QValueAxis(this);
++ series << 0 << line;
++ axes << value1 << value2;
++ alignment << Qt::AlignBottom << Qt::AlignLeft;
++ QTest::newRow("second") << series << axes << alignment << line << value1 << true;
++ }
++
++ }
++
++ void tst_ChartDataSet::attachAxis()
++ {
++ QFETCH(QList<QAbstractSeries*>, series);
++ QFETCH(QList<QAbstractAxis*>, axis);
++ QFETCH(QList<Qt::Alignment>, alignment);
++ QFETCH(QAbstractSeries*, attachSeries);
++ QFETCH(QAbstractAxis*, attachAxis);
++ QFETCH(bool, success);
++
++ Q_ASSERT(series.size() == axis.size());
++ Q_ASSERT(series.size() == alignment.size());
++
++ QVERIFY(m_dataset->series().isEmpty());
++ QVERIFY(m_dataset->axes().isEmpty());
++
++ for(int i = 0 ; i < series.size() ; i++){
++ if(series[i]) m_dataset->addSeries(series[i]);
++ if(axis[i]) m_dataset->addAxis(axis[i],alignment[i]);
++ if(series[i] && axis[i]) m_dataset->attachAxis(series[i],axis[i]);
++ }
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ QCOMPARE(m_dataset->attachAxis(attachSeries,attachAxis),success);
++
++ }
++
++ void tst_ChartDataSet::detachAxis_data()
++ {
++ QTest::addColumn<QList<QAbstractSeries*> >("series");
++ QTest::addColumn<QList<QAbstractAxis*> >("axis");
++ QTest::addColumn<QAbstractSeries*>("detachSeries");
++ QTest::addColumn<QAbstractAxis*>("detachAxis");
++ QTest::addColumn<bool>("success");
++
++ {
++ QList<QAbstractSeries*> series;
++ QList<QAbstractAxis*> axes;
++ QAbstractSeries* line = new QLineSeries(this);
++ QAbstractAxis* value = new QValueAxis(this);
++ series << line;
++ axes << value;
++ QTest::newRow("first") << series << axes << line << value << true;
++ }
++ }
++
++ void tst_ChartDataSet::detachAxis()
++ {
++ QFETCH(QList<QAbstractSeries*>, series);
++ QFETCH(QList<QAbstractAxis*>, axis);
++ QFETCH(QAbstractSeries*, detachSeries);
++ QFETCH(QAbstractAxis*, detachAxis);
++ QFETCH(bool, success);
++
++ Q_ASSERT(series.size() == axis.size());
++
++ QVERIFY(m_dataset->series().isEmpty());
++ QVERIFY(m_dataset->axes().isEmpty());
++
++ for(int i = 0; i < series.size(); i++) {
++ if(series[i]) m_dataset->addSeries(series[i]);
++ if(axis[i]) m_dataset->addAxis(axis[i],Qt::AlignBottom);
++ if(series[i] && axis[i]) m_dataset->attachAxis(series[i],axis[i]);
++ }
++
++ QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
++ QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
++ QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
++ QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
++
++ QCOMPARE(m_dataset->detachAxis(detachSeries,detachAxis),success);
++ }
++
++ void tst_ChartDataSet::domainChangePreservesRanges()
++ {
++ // This test checks that domain ranges stay correct after an axis attachment causes domain
++ // to be recreated.
++ QVERIFY(m_dataset->series().isEmpty());
++ QVERIFY(m_dataset->axes().isEmpty());
++
++ QLineSeries* line = new QLineSeries(this);
++ QValueAxis* value1 = new QValueAxis(this);
++ QValueAxis* value2 = new QValueAxis(this);
++ QLogValueAxis* logValue1 = new QLogValueAxis(this);
++ QLogValueAxis* logValue2 = new QLogValueAxis(this);
++ (*line) << QPointF(1.0, 2.0) << QPointF(10.0, 20.0);
++
++ value1->setRange(2.0, 6.0);
++ value2->setRange(3.0, 7.0);
++ logValue1->setRange(4.0, 8.0);
++ logValue2->setRange(5.0, 9.0);
++
++ m_dataset->addSeries(line);
++ compareDomain(line, 1.0, 10.0, 2.0, 20.0);
++ m_dataset->addAxis(value1, Qt::AlignBottom);
++ m_dataset->addAxis(value2, Qt::AlignLeft);
++ m_dataset->addAxis(logValue1, Qt::AlignBottom);
++ m_dataset->addAxis(logValue2, Qt::AlignLeft);
++ compareDomain(line, 1.0, 10.0, 2.0, 20.0);
++
++ // Start with two value axes
++ m_dataset->attachAxis(line, value1);
++ compareDomain(line, 2.0, 6.0, 2.0, 20.0);
++ m_dataset->attachAxis(line, value2);
++ compareDomain(line, 2.0, 6.0, 3.0, 7.0);
++
++ // Detach y value and attach y logvalue
++ m_dataset->detachAxis(line, value2);
++ compareDomain(line, 2.0, 6.0, 3.0, 7.0); // Detach doesn't change domain ranges
++ m_dataset->attachAxis(line, logValue2);
++ compareDomain(line, 2.0, 6.0, 5.0, 9.0);
++
++ // Detach x value and attach x logvalue
++ m_dataset->detachAxis(line, value1);
++ compareDomain(line, 2.0, 6.0, 5.0, 9.0); // Detach doesn't change domain ranges
++ m_dataset->attachAxis(line, logValue1);
++ compareDomain(line, 4.0, 8.0, 5.0, 9.0);
++
++ // Detach y logvalue and attach y value
++ m_dataset->detachAxis(line, logValue2);
++ compareDomain(line, 4.0, 8.0, 5.0, 9.0); // Detach doesn't change domain ranges
++ m_dataset->attachAxis(line, value2);
++ compareDomain(line, 4.0, 8.0, 3.0, 7.0);
++ }
++
++ void tst_ChartDataSet::compareDomain(QAbstractSeries *series, qreal minX, qreal maxX,
++ qreal minY, qreal maxY) const
++ {
++ AbstractDomain *domain = m_dataset->domainForSeries(series);
++ QCOMPARE(domain->minX(), minX);
++ QCOMPARE(domain->maxX(), maxX);
++ QCOMPARE(domain->minY(), minY);
++ QCOMPARE(domain->maxY(), maxY);
++ }
++
++ QTEST_MAIN(tst_ChartDataSet)
++ #include "tst_chartdataset.moc"