dev@1430: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ dev@1430: dev@1430: /* dev@1430: Sonic Visualiser dev@1430: An audio file viewer and annotation editor. dev@1430: Centre for Digital Music, Queen Mary, University of London. dev@1438: This file copyright 2017 Queen Mary, University of London. dev@1430: dev@1430: This program is free software; you can redistribute it and/or dev@1430: modify it under the terms of the GNU General Public License as dev@1430: published by the Free Software Foundation; either version 2 of the dev@1430: License, or (at your option) any later version. See the file dev@1430: COPYING included with this distribution for more information. dev@1430: */ dev@1430: dev@1430: #ifndef TEST_CSV_STREAM_H dev@1430: #define TEST_CSV_STREAM_H dev@1430: dev@1434: #include dev@1430: #include dev@1434: #include dev@1434: #include dev@1434: dev@1434: #include "base/ProgressReporter.h" dev@1434: #include "base/DataExportOptions.h" dev@1430: #include "../CSVStreamWriter.h" dev@1434: #include "../../model/test/MockWaveModel.h" dev@1434: dev@1434: namespace dev@1434: { dev@1434: class StubReporter : public ProgressReporter dev@1434: { dev@1434: public: dev@1434: StubReporter( std::function isCancelled ) dev@1434: : m_isCancelled(isCancelled) {} dev@1434: bool isDefinite() const override { return true; } dev@1434: void setDefinite(bool) override {} dev@1434: bool wasCancelled() const override { return m_isCancelled(); } dev@1434: void setMessage(QString) override {} dev@1440: void setProgress(int p) override dev@1440: { dev@1440: ++m_calls; dev@1440: m_percentageLog.push_back(p); dev@1440: } dev@1440: dev@1434: size_t getCallCount() const { return m_calls; } dev@1440: std::vector getPercentageLog() const { return m_percentageLog; } dev@1434: void reset() { m_calls = 0; } dev@1434: private: dev@1434: size_t m_calls = 0; dev@1434: std::function m_isCancelled; dev@1440: std::vector m_percentageLog; dev@1434: }; dev@1434: } // namespace dev@1430: dev@1430: class CSVStreamWriterTest : public QObject dev@1430: { dev@1430: Q_OBJECT dev@1430: public: dev@1434: std::string getExpectedString() dev@1434: { dev@1434: return dev@1434: { dev@1434: "0,0,0\n" dev@1434: "1,0,0\n" dev@1434: "2,0,0\n" dev@1434: "3,0,0\n" dev@1434: "4,1,1\n" dev@1434: "5,1,1\n" dev@1434: "6,1,1\n" dev@1434: "7,1,1\n" dev@1434: "8,1,1\n" dev@1434: "9,1,1\n" dev@1434: "10,1,1\n" dev@1434: "11,1,1\n" dev@1434: "12,1,1\n" dev@1434: "13,1,1\n" dev@1434: "14,1,1\n" dev@1434: "15,1,1\n" dev@1434: "16,1,1\n" dev@1434: "17,1,1\n" dev@1434: "18,1,1\n" dev@1434: "19,1,1\n" dev@1434: "20,0,0\n" dev@1434: "21,0,0\n" dev@1434: "22,0,0\n" dev@1434: "23,0,0" dev@1434: }; dev@1434: } dev@1430: dev@1430: private slots: dev@1434: void simpleValidOutput() dev@1430: { dev@1434: MockWaveModel mwm({ DC, DC }, 16, 4); dev@1430: dev@1434: std::ostringstream oss; dev@1438: const auto result = CSVStreamWriter::writeInChunks(oss, mwm); dev@1434: QVERIFY( oss.str() == getExpectedString() ); dev@1434: QVERIFY( result ); dev@1434: } dev@1434: dev@1434: void callsReporterCorrectTimes() dev@1434: { dev@1434: MockWaveModel mwm({ DC, DC }, 16, 4); dev@1434: StubReporter reporter { []() -> bool { return false; } }; dev@1434: const auto expected = getExpectedString(); dev@1434: dev@1434: std::ostringstream oss; dev@1434: const auto writeStreamWithBlockSize = [&](int blockSize) { dev@1438: return CSVStreamWriter::writeInChunks( dev@1434: oss, dev@1434: mwm, dev@1434: &reporter, dev@1434: ",", dev@1434: DataExportDefaults, dev@1434: blockSize dev@1434: ); dev@1434: }; dev@1434: dev@1434: const auto reset = [&]() { dev@1434: oss.str({}); dev@1434: reporter.reset(); dev@1434: }; dev@1434: dev@1434: const auto nonIntegerMultipleResult = writeStreamWithBlockSize(5); dev@1434: QVERIFY( nonIntegerMultipleResult ); dev@1434: QVERIFY( reporter.getCallCount() == 5 /* 4.8 rounded up */ ); dev@1434: QVERIFY( oss.str() == expected ); dev@1434: reset(); dev@1434: dev@1434: const auto integerMultiple = writeStreamWithBlockSize(2); dev@1434: QVERIFY( integerMultiple ); dev@1434: QVERIFY( reporter.getCallCount() == 12 ); dev@1434: QVERIFY( oss.str() == expected ); dev@1434: reset(); dev@1434: dev@1434: const auto largerThanNumberOfSamples = writeStreamWithBlockSize(100); dev@1434: QVERIFY( largerThanNumberOfSamples ); dev@1434: QVERIFY( reporter.getCallCount() == 1 ); dev@1434: QVERIFY( oss.str() == expected ); dev@1434: reset(); dev@1434: dev@1434: const auto zero = writeStreamWithBlockSize(0); dev@1434: QVERIFY( zero == false ); dev@1434: QVERIFY( reporter.getCallCount() == 0 ); dev@1434: } dev@1434: dev@1434: void isCancellable() dev@1434: { dev@1434: MockWaveModel mwm({ DC, DC }, 16, 4); dev@1434: StubReporter reporter { []() -> bool { return true; } }; dev@1434: dev@1434: std::ostringstream oss; dev@1438: const auto cancelImmediately = CSVStreamWriter::writeInChunks( dev@1434: oss, dev@1434: mwm, dev@1434: &reporter, dev@1434: ",", dev@1434: DataExportDefaults, dev@1434: 4 dev@1434: ); dev@1434: QVERIFY( cancelImmediately == false ); dev@1434: QVERIFY( reporter.getCallCount() == 0 ); dev@1434: dev@1434: StubReporter cancelMidway { dev@1434: [&]() { return cancelMidway.getCallCount() == 3; } dev@1434: }; dev@1438: const auto cancelledMidway = CSVStreamWriter::writeInChunks( dev@1434: oss, dev@1434: mwm, dev@1434: &cancelMidway, dev@1434: ",", dev@1434: DataExportDefaults, dev@1434: 4 dev@1434: ); dev@1434: QVERIFY( cancelMidway.getCallCount() == 3 ); dev@1434: QVERIFY( cancelledMidway == false ); dev@1430: } dev@1440: dev@1440: void zeroStartTimeReportsPercentageCorrectly() dev@1440: { dev@1440: MockWaveModel mwm({ DC, DC }, 16, 4); dev@1440: StubReporter reporter { []() -> bool { return false; } }; dev@1440: std::ostringstream oss; dev@1440: const auto succeeded = CSVStreamWriter::writeInChunks( dev@1440: oss, dev@1440: mwm, dev@1440: &reporter, dev@1440: ",", dev@1440: DataExportDefaults, dev@1440: 4 dev@1440: ); dev@1440: QVERIFY( succeeded == true ); dev@1440: QVERIFY( reporter.getCallCount() == 6 ); dev@1440: const std::vector expectedCallLog { dev@1440: 16, dev@1440: 33, dev@1440: 50, dev@1440: 66, dev@1440: 83, dev@1440: 100 dev@1440: }; dev@1440: QVERIFY( reporter.getPercentageLog() == expectedCallLog ); dev@1440: QVERIFY( oss.str() == getExpectedString() ); dev@1440: } dev@1440: dev@1440: void nonZeroStartTimeReportsPercentageCorrectly() dev@1440: { dev@1440: MockWaveModel mwm({ DC, DC }, 16, 4); dev@1440: StubReporter reporter { []() -> bool { return false; } }; dev@1440: std::ostringstream oss; dev@1440: const auto writeSubSection = CSVStreamWriter::writeInChunks( dev@1440: oss, dev@1440: mwm, dev@1440: {4, 20}, dev@1440: &reporter, dev@1440: ",", dev@1440: DataExportDefaults, dev@1440: 4 dev@1440: ); dev@1440: QVERIFY( reporter.getCallCount() == 4 ); dev@1440: const std::vector expectedCallLog { dev@1440: 25, dev@1440: 50, dev@1440: 75, dev@1440: 100 dev@1440: }; dev@1440: QVERIFY( reporter.getPercentageLog() == expectedCallLog ); dev@1440: QVERIFY( writeSubSection == true ); dev@1440: const std::string expectedOutput { dev@1440: "4,1,1\n" dev@1440: "5,1,1\n" dev@1440: "6,1,1\n" dev@1440: "7,1,1\n" dev@1440: "8,1,1\n" dev@1440: "9,1,1\n" dev@1440: "10,1,1\n" dev@1440: "11,1,1\n" dev@1440: "12,1,1\n" dev@1440: "13,1,1\n" dev@1440: "14,1,1\n" dev@1440: "15,1,1\n" dev@1440: "16,1,1\n" dev@1440: "17,1,1\n" dev@1440: "18,1,1\n" dev@1440: "19,1,1" dev@1440: }; dev@1440: QVERIFY( oss.str() == expectedOutput ); dev@1440: } dev@1430: }; dev@1430: dev@1430: #endif