Adding Tests to Characterize Existing Behavior

We need to change code in writeSamples. Let’s start with a couple tests!

wav/6/WavReaderTest.cpp
 
#include "CppUTest/TestHarness.h"
 
#include "WavReader.h"
 
#include <iostream>
 
#include <string>
 
#include <sstream>
 
 
using​ ​namespace​ std;
 
 
TEST_GROUP(WavReader_WriteSamples)
 
{
 
WavReader reader{​""​,​""​};
 
ostringstream out;
 
};
 
 
TEST(WavReader_WriteSamples, WritesSingleSample) {
 
char​ data[] { ​"abcd"​ };
 
uint32_t bytesPerSample { 1 };
 
uint32_t startingSample { 0 };
 
uint32_t samplesToWrite { 1 };
 
reader.writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample);
 
CHECK_EQUAL(​"a"​, out.str());
 
}
 
 
TEST(WavReader_WriteSamples, WritesMultibyteSampleFromMiddle) {
 
char​ data[] { ​"0123456789ABCDEFG"​ };
 
uint32_t bytesPerSample { 2 };
 
uint32_t startingSample { 4 };
 
uint32_t samplesToWrite { 3 };
 
 
reader.writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample);
 
CHECK_EQUAL(​"89ABCD"​, out.str());
 
}

The direct tests against writeSamples help us understand the looping behavior in isolation. They’re not great, though. The test WritesMultibyteSampleFromMiddle requires careful reading and a little bit of math. How would you make it more directly expressive?

Rather than slow down our tests by using actual files, we use fast, in-memory string objects of type std::ostringstream. Doing so requires changing the interface of writeSamples to take std::ostream objects, the common type from which both std::ofstream and std::ostringstream derive. More specifically, we alter the interface to take a pointer to an std::ostream. Production code can pass the address of a file stream; tests can pass the address of a string stream. We change the dereferencing of the writeSamples local variable out to use pointer semantics.

wav/6/WavReader.cpp
 
writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample);
wav/6/WavReader.cpp
*
void​ WavReader::writeSamples(ostream* out, ​char​* data,
 
uint32_t startingSample,
 
uint32_t samplesToWrite,
 
uint32_t bytesPerSample) {
 
rLog(channel, ​"writing %i samples"​, samplesToWrite);
 
 
for​ (​auto​ sample = startingSample;
 
sample < startingSample + samplesToWrite;
 
sample++) {
 
auto​ byteOffsetForSample = sample * bytesPerSample;
 
for​ (uint32_t byte{0}; byte < bytesPerSample; byte++)
*
out->put(data[byteOffsetForSample + byte]);
 
}
 
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.137.38