Mercurial > hg > svcore
comparison data/fileio/test/CSVStreamWriterTest.h @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | 0d4f1fcad97a |
children | 560453546749 |
comparison
equal
deleted
inserted
replaced
1324:d4a28d1479a8 | 1527:710e6250a401 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2017 Queen Mary, University of London. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #ifndef TEST_CSV_STREAM_H | |
17 #define TEST_CSV_STREAM_H | |
18 | |
19 #include <QtTest> | |
20 #include <QObject> | |
21 #include <sstream> | |
22 #include <functional> | |
23 | |
24 #include "base/ProgressReporter.h" | |
25 #include "base/DataExportOptions.h" | |
26 #include "base/Selection.h" | |
27 #include "data/model/NoteModel.h" | |
28 #include "../CSVStreamWriter.h" | |
29 #include "../../model/test/MockWaveModel.h" | |
30 | |
31 class StubReporter : public ProgressReporter | |
32 { | |
33 public: | |
34 StubReporter( std::function<bool()> isCancelled ) | |
35 : m_isCancelled(isCancelled) {} | |
36 bool isDefinite() const override { return true; } | |
37 void setDefinite(bool) override {} | |
38 bool wasCancelled() const override { return m_isCancelled(); } | |
39 void setMessage(QString) override {} | |
40 void setProgress(int p) override | |
41 { | |
42 ++m_calls; | |
43 m_percentageLog.push_back(p); | |
44 } | |
45 | |
46 size_t getCallCount() const { return m_calls; } | |
47 std::vector<int> getPercentageLog() const { return m_percentageLog; } | |
48 void reset() { m_calls = 0; } | |
49 private: | |
50 size_t m_calls = 0; | |
51 std::function<bool()> m_isCancelled; | |
52 std::vector<int> m_percentageLog; | |
53 }; | |
54 | |
55 class CSVStreamWriterTest : public QObject | |
56 { | |
57 Q_OBJECT | |
58 public: | |
59 std::string getExpectedString() | |
60 { | |
61 return | |
62 { | |
63 "0,0,0\n" | |
64 "1,0,0\n" | |
65 "2,0,0\n" | |
66 "3,0,0\n" | |
67 "4,1,1\n" | |
68 "5,1,1\n" | |
69 "6,1,1\n" | |
70 "7,1,1\n" | |
71 "8,1,1\n" | |
72 "9,1,1\n" | |
73 "10,1,1\n" | |
74 "11,1,1\n" | |
75 "12,1,1\n" | |
76 "13,1,1\n" | |
77 "14,1,1\n" | |
78 "15,1,1\n" | |
79 "16,1,1\n" | |
80 "17,1,1\n" | |
81 "18,1,1\n" | |
82 "19,1,1\n" | |
83 "20,0,0\n" | |
84 "21,0,0\n" | |
85 "22,0,0\n" | |
86 "23,0,0" | |
87 }; | |
88 } | |
89 | |
90 private slots: | |
91 void simpleValidOutput() | |
92 { | |
93 MockWaveModel mwm({ DC, DC }, 16, 4); | |
94 | |
95 std::ostringstream oss; | |
96 const auto result = CSVStreamWriter::writeInChunks(oss, mwm); | |
97 QVERIFY( oss.str() == getExpectedString() ); | |
98 QVERIFY( result ); | |
99 } | |
100 | |
101 void callsReporterCorrectTimes() | |
102 { | |
103 MockWaveModel mwm({ DC, DC }, 16, 4); | |
104 StubReporter reporter { []() -> bool { return false; } }; | |
105 const auto expected = getExpectedString(); | |
106 | |
107 std::ostringstream oss; | |
108 const auto writeStreamWithBlockSize = [&](int blockSize) { | |
109 return CSVStreamWriter::writeInChunks( | |
110 oss, | |
111 mwm, | |
112 &reporter, | |
113 ",", | |
114 DataExportDefaults, | |
115 blockSize | |
116 ); | |
117 }; | |
118 | |
119 const auto reset = [&]() { | |
120 oss.str({}); | |
121 reporter.reset(); | |
122 }; | |
123 | |
124 const auto nonIntegerMultipleResult = writeStreamWithBlockSize(5); | |
125 QVERIFY( nonIntegerMultipleResult ); | |
126 QVERIFY( reporter.getCallCount() == 5 /* 4.8 rounded up */ ); | |
127 QVERIFY( oss.str() == expected ); | |
128 reset(); | |
129 | |
130 const auto integerMultiple = writeStreamWithBlockSize(2); | |
131 QVERIFY( integerMultiple ); | |
132 QVERIFY( reporter.getCallCount() == 12 ); | |
133 QVERIFY( oss.str() == expected ); | |
134 reset(); | |
135 | |
136 const auto largerThanNumberOfSamples = writeStreamWithBlockSize(100); | |
137 QVERIFY( largerThanNumberOfSamples ); | |
138 QVERIFY( reporter.getCallCount() == 1 ); | |
139 QVERIFY( oss.str() == expected ); | |
140 reset(); | |
141 | |
142 const auto zero = writeStreamWithBlockSize(0); | |
143 QVERIFY( zero == false ); | |
144 QVERIFY( reporter.getCallCount() == 0 ); | |
145 } | |
146 | |
147 void isCancellable() | |
148 { | |
149 MockWaveModel mwm({ DC, DC }, 16, 4); | |
150 StubReporter reporter { []() -> bool { return true; } }; | |
151 | |
152 std::ostringstream oss; | |
153 const auto cancelImmediately = CSVStreamWriter::writeInChunks( | |
154 oss, | |
155 mwm, | |
156 &reporter, | |
157 ",", | |
158 DataExportDefaults, | |
159 4 | |
160 ); | |
161 QVERIFY( cancelImmediately == false ); | |
162 QVERIFY( reporter.getCallCount() == 0 ); | |
163 | |
164 StubReporter cancelMidway { | |
165 [&]() { return cancelMidway.getCallCount() == 3; } | |
166 }; | |
167 const auto cancelledMidway = CSVStreamWriter::writeInChunks( | |
168 oss, | |
169 mwm, | |
170 &cancelMidway, | |
171 ",", | |
172 DataExportDefaults, | |
173 4 | |
174 ); | |
175 QVERIFY( cancelMidway.getCallCount() == 3 ); | |
176 QVERIFY( cancelledMidway == false ); | |
177 } | |
178 | |
179 void zeroStartTimeReportsPercentageCorrectly() | |
180 { | |
181 MockWaveModel mwm({ DC, DC }, 16, 4); | |
182 StubReporter reporter { []() -> bool { return false; } }; | |
183 std::ostringstream oss; | |
184 const auto succeeded = CSVStreamWriter::writeInChunks( | |
185 oss, | |
186 mwm, | |
187 &reporter, | |
188 ",", | |
189 DataExportDefaults, | |
190 4 | |
191 ); | |
192 QVERIFY( succeeded == true ); | |
193 QVERIFY( reporter.getCallCount() == 6 ); | |
194 const std::vector<int> expectedCallLog { | |
195 16, | |
196 33, | |
197 50, | |
198 66, | |
199 83, | |
200 100 | |
201 }; | |
202 QVERIFY( reporter.getPercentageLog() == expectedCallLog ); | |
203 QVERIFY( oss.str() == getExpectedString() ); | |
204 } | |
205 | |
206 void nonZeroStartTimeReportsPercentageCorrectly() | |
207 { | |
208 MockWaveModel mwm({ DC, DC }, 16, 4); | |
209 StubReporter reporter { []() -> bool { return false; } }; | |
210 std::ostringstream oss; | |
211 const auto writeSubSection = CSVStreamWriter::writeInChunks( | |
212 oss, | |
213 mwm, | |
214 {4, 20}, | |
215 &reporter, | |
216 ",", | |
217 DataExportDefaults, | |
218 4 | |
219 ); | |
220 QVERIFY( reporter.getCallCount() == 4 ); | |
221 const std::vector<int> expectedCallLog { | |
222 25, | |
223 50, | |
224 75, | |
225 100 | |
226 }; | |
227 QVERIFY( reporter.getPercentageLog() == expectedCallLog ); | |
228 QVERIFY( writeSubSection == true ); | |
229 const std::string expectedOutput { | |
230 "4,1,1\n" | |
231 "5,1,1\n" | |
232 "6,1,1\n" | |
233 "7,1,1\n" | |
234 "8,1,1\n" | |
235 "9,1,1\n" | |
236 "10,1,1\n" | |
237 "11,1,1\n" | |
238 "12,1,1\n" | |
239 "13,1,1\n" | |
240 "14,1,1\n" | |
241 "15,1,1\n" | |
242 "16,1,1\n" | |
243 "17,1,1\n" | |
244 "18,1,1\n" | |
245 "19,1,1" | |
246 }; | |
247 QVERIFY( oss.str() == expectedOutput ); | |
248 } | |
249 | |
250 void multipleSelectionOutput() | |
251 { | |
252 MockWaveModel mwm({ DC, DC }, 16, 4); | |
253 StubReporter reporter { []() -> bool { return false; } }; | |
254 std::ostringstream oss; | |
255 MultiSelection regions; | |
256 regions.addSelection({0, 2}); | |
257 regions.addSelection({4, 6}); | |
258 regions.addSelection({16, 18}); | |
259 // qDebug("End frame: %lld", (long long int)mwm.getEndFrame()); | |
260 const std::string expectedOutput { | |
261 "0,0,0\n" | |
262 "1,0,0\n" | |
263 "4,1,1\n" | |
264 "5,1,1\n" | |
265 "16,1,1\n" | |
266 "17,1,1" | |
267 }; | |
268 const auto wroteMultiSection = CSVStreamWriter::writeInChunks( | |
269 oss, | |
270 mwm, | |
271 regions, | |
272 &reporter, | |
273 ",", | |
274 DataExportDefaults, | |
275 2 | |
276 ); | |
277 QVERIFY( wroteMultiSection == true ); | |
278 QVERIFY( reporter.getCallCount() == 3 ); | |
279 const std::vector<int> expectedCallLog { 33, 66, 100 }; | |
280 QVERIFY( reporter.getPercentageLog() == expectedCallLog ); | |
281 // qDebug("%s", oss.str().c_str()); | |
282 QVERIFY( oss.str() == expectedOutput ); | |
283 } | |
284 | |
285 void writeSparseModel() | |
286 { | |
287 const auto pentatonicFromRoot = [](float midiPitch) { | |
288 return std::vector<float> { | |
289 0 + midiPitch, | |
290 2 + midiPitch, | |
291 4 + midiPitch, | |
292 7 + midiPitch, | |
293 9 + midiPitch | |
294 }; | |
295 }; | |
296 const auto cMajorPentatonic = pentatonicFromRoot(60.0); | |
297 NoteModel notes(8 /* sampleRate */, 4 /* resolution */); | |
298 sv_frame_t startFrame = 0; | |
299 for (const auto& note : cMajorPentatonic) { | |
300 notes.addPoint({startFrame, note, 4, 1.f, ""}); | |
301 startFrame += 8; | |
302 } | |
303 // qDebug("Create Expected Output\n"); | |
304 | |
305 // NB. removed end line break | |
306 const auto expectedOutput = notes.toDelimitedDataString(",").trimmed(); | |
307 | |
308 StubReporter reporter { []() -> bool { return false; } }; | |
309 std::ostringstream oss; | |
310 // qDebug("End frame: %lld", (long long int)notes.getEndFrame()); | |
311 // qDebug("Write streaming\n"); | |
312 const auto wroteSparseModel = CSVStreamWriter::writeInChunks( | |
313 oss, | |
314 notes, | |
315 &reporter, | |
316 ",", | |
317 DataExportDefaults, | |
318 2 | |
319 ); | |
320 | |
321 // qDebug("\n%s\n", expectedOutput.toLocal8Bit().data()); | |
322 // qDebug("\n%s\n", oss.str().c_str()); | |
323 QVERIFY( wroteSparseModel == true ); | |
324 QVERIFY( oss.str() == expectedOutput.toStdString() ); | |
325 } | |
326 }; | |
327 | |
328 #endif |