Add test fixture.

This commit is contained in:
James Grogan 2022-11-29 18:00:19 +00:00
parent af6fad72eb
commit d6d4319e21
37 changed files with 421 additions and 279 deletions

View file

@ -64,11 +64,9 @@ unsigned char Lz77Encoder::getSearchBufferItem(unsigned index) const
unsigned Lz77Encoder::lookAheadForMatchingChars(unsigned distance) unsigned Lz77Encoder::lookAheadForMatchingChars(unsigned distance)
{ {
unsigned length{0}; unsigned length{0};
std::cout << "In hit check at distance " << distance << " max buffer index is: " << mMaxLookAheadBufferIndex << std::endl;
for(unsigned idx=0; idx<mMaxLookAheadBufferIndex + 1; idx++) for(unsigned idx=0; idx<mMaxLookAheadBufferIndex + 1; idx++)
{ {
int search_offset = int(distance-1) - idx; int search_offset = int(distance-1) - idx;
std::cout << "Have search offet " << search_offset << std::endl;
unsigned char search_char{0}; unsigned char search_char{0};
if (search_offset < 0) if (search_offset < 0)
{ {
@ -78,10 +76,7 @@ unsigned Lz77Encoder::lookAheadForMatchingChars(unsigned distance)
{ {
search_char = getSearchBufferItem(static_cast<unsigned>(search_offset)); search_char = getSearchBufferItem(static_cast<unsigned>(search_offset));
} }
unsigned char lookahead_char = mLookaheadBuffer.getItem(idx); unsigned char lookahead_char = mLookaheadBuffer.getItem(idx);
std::cout << "Checking search char " << static_cast<int>(search_char) << " and lookup char " << static_cast<int>(lookahead_char) << std::endl;
if ((lookahead_char != search_char) || (idx == mMaxLookAheadBufferIndex)) if ((lookahead_char != search_char) || (idx == mMaxLookAheadBufferIndex))
{ {
if (idx + 1>= mMinLengthMatchSize) if (idx + 1>= mMinLengthMatchSize)
@ -100,9 +95,7 @@ void Lz77Encoder::lookForMatches(unsigned char searchChar, unsigned& hitLength,
{ {
if (mSearchBuffer.getItem(mSearchBuffer.getNumItems() - 1 - idx) == searchChar) if (mSearchBuffer.getItem(mSearchBuffer.getNumItems() - 1 - idx) == searchChar)
{ {
std::cout << "Looking for hits " << std::endl;
auto num_hits = lookAheadForMatchingChars(idx + 1); auto num_hits = lookAheadForMatchingChars(idx + 1);
if (num_hits > 0 && num_hits >= hitLength) if (num_hits > 0 && num_hits >= hitLength)
{ {
hitLength = num_hits; hitLength = num_hits;
@ -197,14 +190,10 @@ bool Lz77Encoder::encode()
} }
const auto working_byte = mLookaheadBuffer.getItem(0); const auto working_byte = mLookaheadBuffer.getItem(0);
std::cout << "Working byte is " << static_cast<int>(working_byte) << std::endl;
unsigned hit_length{0}; unsigned hit_length{0};
unsigned hit_distance{0}; unsigned hit_distance{0};
lookForMatches(working_byte, hit_length, hit_distance); lookForMatches(working_byte, hit_length, hit_distance);
std::cout << "Got hit length " << hit_length << " and distance " << hit_distance << std::endl;
const Hit hit{hit_length, hit_distance, working_byte}; const Hit hit{hit_length, hit_distance, working_byte};
mHitBuffer.push_back(hit); mHitBuffer.push_back(hit);

View file

@ -2,6 +2,8 @@
#include "RawTree.h" #include "RawTree.h"
#include "HuffmanFixedCodes.h"
#include <unordered_map> #include <unordered_map>
#include <queue> #include <queue>
#include <tuple> #include <tuple>
@ -40,34 +42,22 @@ void HuffmanEncoder::dumpTree(const RawTree<CountPair>& tree) const
dumpNode(tree.getRootNode(), 0); dumpNode(tree.getRootNode(), 0);
} }
void HuffmanEncoder::encode(const HuffmanEncoder::DataStream& stream) void HuffmanEncoder::encode(const std::vector<unsigned>& counts)
{ {
std::unordered_map<unsigned char, unsigned> counts;
for (auto c : stream)
{
counts[c]++;
}
encode(counts);
}
void HuffmanEncoder::encode(const std::unordered_map<unsigned char, unsigned>& counts)
{
std::cout << "Counts" << std::endl;
for (const auto& data: counts)
{
std::cout << data.first << " | " << data.second << std::endl;
}
std::cout << "*******" << std::endl;
auto cmp = [](RawNode<CountPair>* left, RawNode<CountPair>* right) auto cmp = [](RawNode<CountPair>* left, RawNode<CountPair>* right)
{ {
return left->getData().second > right->getData().second; return left->getData().second > right->getData().second;
}; };
std::priority_queue<RawNode<CountPair>*, std::vector<RawNode<CountPair>* >, decltype(cmp)> q(cmp); std::priority_queue<RawNode<CountPair>*, std::vector<RawNode<CountPair>* >, decltype(cmp)> q(cmp);
for (const auto& entry : counts) unsigned offset{0};
for (auto count : counts)
{ {
q.push(new RawNode<CountPair>(entry)); if (count > 0)
{
q.push(new RawNode<CountPair>({offset, count}));
}
offset++;
} }
while(q.size() > 1) while(q.size() > 1)
@ -99,6 +89,18 @@ void HuffmanEncoder::encode(const std::unordered_map<unsigned char, unsigned>& c
std::cout << "********" << std::endl; std::cout << "********" << std::endl;
} }
void HuffmanEncoder::encode(const std::unordered_map<unsigned char, unsigned>& counts)
{
std::vector<unsigned> just_counts;
for (const auto& data: counts)
{
mSymbolMapping.push_back(data.first);
just_counts.push_back(data.second);
}
encode(just_counts);
}
void HuffmanEncoder::setUseFixedCode(bool useFixed) void HuffmanEncoder::setUseFixedCode(bool useFixed)
{ {
mUseFixedCode = useFixed; mUseFixedCode = useFixed;
@ -129,16 +131,43 @@ std::optional<PrefixCode> HuffmanEncoder::getEndOfStreamValue() const
return mLiteralLengthTable.getCodeForSymbol(256); return mLiteralLengthTable.getCodeForSymbol(256);
} }
void HuffmanEncoder::initializeTrees() void HuffmanEncoder::initializeTrees(const std::vector<Hit>& hits)
{ {
initializeLiteralLengthTable(); initializeLiteralLengthTable(hits);
} }
void HuffmanEncoder::initializeLiteralLengthTable() void HuffmanEncoder::initializeLiteralLengthTable(const std::vector<Hit>& hits)
{ {
if(mUseFixedCode) if(mUseFixedCode)
{ {
mLiteralLengthTable.setInputLengthSequence(HuffmanFixedCodes::getDeflateFixedHuffmanCodes(), false); mLiteralLengthTable.setInputLengthSequence(HuffmanFixedCodes::getDeflateFixedHuffmanCodes(), false);
mLiteralLengthTable.buildPrefixCodes(); mLiteralLengthTable.buildPrefixCodes();
return;
}
std::vector<unsigned> counts(285, 0);
counts[256] = 1;
for (const auto& hit : hits)
{
const auto& [length, distance, next_char] = hit;
if (length > 0 )
{
const auto& [code, extra_bits, num_extra_bits] = HuffmanFixedCodes::getCodeForLength(length);
counts[code]++;
}
else
{
counts[next_char]++;
} }
} }
for(unsigned idx=0; idx<counts.size(); idx++)
{
if (counts[idx]>0)
{
std::cout << "Count for " << idx << " is " << counts[idx] << std::endl;
}
}
encode(counts);
}

View file

@ -6,6 +6,7 @@
#include "HuffmanFixedCodes.h" #include "HuffmanFixedCodes.h"
#include <vector> #include <vector>
#include <tuple>
#include <unordered_map> #include <unordered_map>
class PrefixCodeGenerator class PrefixCodeGenerator
@ -21,11 +22,11 @@ public:
class HuffmanEncoder : public PrefixCodeGenerator class HuffmanEncoder : public PrefixCodeGenerator
{ {
using DataStream = std::vector<unsigned char>; using CountPair = std::pair<unsigned, unsigned>;
using CountPair = std::pair<unsigned char, unsigned>; using Hit = std::tuple<unsigned, unsigned, unsigned char>;
public: public:
void encode(const DataStream& stream); void encode(const std::vector<unsigned>& counts);
void encode(const std::unordered_map<unsigned char, unsigned>& counts); void encode(const std::unordered_map<unsigned char, unsigned>& counts);
uint32_t getLengthValue(unsigned length); uint32_t getLengthValue(unsigned length);
@ -38,18 +39,19 @@ public:
std::optional<PrefixCode> getEndOfStreamValue() const override; std::optional<PrefixCode> getEndOfStreamValue() const override;
void initializeTrees(); void initializeTrees(const std::vector<Hit>& hits);
void setUseFixedCode(bool useFixed); void setUseFixedCode(bool useFixed);
private: private:
void initializeLiteralLengthTable(); void initializeLiteralLengthTable(const std::vector<Hit>& hits);
void dumpTree(const RawTree<CountPair>& tree) const; void dumpTree(const RawTree<CountPair>& tree) const;
void dumpNode(RawNode<CountPair>* node, unsigned depth) const; void dumpNode(RawNode<CountPair>* node, unsigned depth) const;
bool mUseFixedCode{false}; bool mUseFixedCode{false};
bool mTableIsInitialized{false}; bool mTableIsInitialized{false};
std::vector<unsigned char> mSymbolMapping;
HuffmanCodeLengthTable mLiteralLengthTable; HuffmanCodeLengthTable mLiteralLengthTable;
HuffmanCodeLengthTable mDistanceTable; HuffmanCodeLengthTable mDistanceTable;
}; };

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <tuple>
namespace HuffmanFixedCodes namespace HuffmanFixedCodes
{ {
@ -17,4 +18,128 @@ namespace HuffmanFixedCodes
} }
return sequence; return sequence;
} }
inline std::tuple<unsigned, unsigned char, unsigned char> getCodeForLength(unsigned length)
{
if (length <= 10)
{
return {length - 3, 0, 0};
}
unsigned base = 2;
unsigned last_offset = 10;
for (unsigned n = 1; n < 5; n++)
{
const auto diff = length - last_offset;
if (diff <= 4*base)
{
auto extra = diff/base + diff % base;
return {last_offset + diff/base, extra, n};
}
last_offset += 4*n;
base = base*2;
}
return {258, 0, 0};
}
/*
inline std::pair<unsigned, unsigned char> getCodeForLength(unsigned length)
{
if (length <= 10)
{
return {257 + length - 3, 0};
}
else if(length <= 18)
{
auto offset = length - 10;
auto extra = offset/2 + offset % 2;
return {265 + offset/2, extra};
}
else if(length <= 34)
{
auto offset = length - 19;
auto extra = offset/4 + offset % 4;
return {269 + offset/4, extra};
}
else if(length <= 66)
{
auto offset = length - 35;
auto extra = offset/8 + offset % 8;
return {273 + offset/8, extra};
}
else if(length <= 114)
{
auto offset = length - 67;
auto extra = offset/16 + offset % 16;
return {277 + offset/16, extra};
}
else if(length <= 257)
{
auto offset = length - 115;
auto extra = offset/32 + offset % 32;
return {281 + offset/32, extra};
}
else
{
return {258, 0};
}
}
inline unsigned getLengthForCode(unsigned symbol, unsigned extra)
{
if (symbol <= 264)
{
return 3 + symbol - 257;
}
else if (symbol <= 268)
{
return 11 + 2*(symbol - 265) + extra;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
else if (symbol <= 272)
{
unsigned char extra{0};
mInputStream->readNextNBits(2, extra);
auto length = 19 + 4*(symbol - 269) + extra;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
else if (symbol <= 276)
{
unsigned char extra{0};
mInputStream->readNextNBits(3, extra);
auto length = 35 + 8*(symbol - 273) + extra;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
else if (symbol <= 280)
{
unsigned char extra{0};
mInputStream->readNextNBits(4, extra);
auto length = 67 + 16*(symbol - 277) + extra;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
else if (symbol <= 284)
{
unsigned char extra{0};
mInputStream->readNextNBits(5, extra);
auto length = 131 + 32*(symbol - 281) + extra;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
else if (symbol == 285)
{
auto length = 258;
const auto valid_dist = readNextDistanceSymbol(distance);
copyFromBuffer(length, distance);
}
}
*/
} }

View file

@ -200,7 +200,6 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
{ {
auto huffman_encoder = std::make_unique<HuffmanEncoder>(); auto huffman_encoder = std::make_unique<HuffmanEncoder>();
huffman_encoder->setUseFixedCode(true); huffman_encoder->setUseFixedCode(true);
huffman_encoder->initializeTrees();
lz77_encoder.setPrefixCodeGenerator(std::move(huffman_encoder)); lz77_encoder.setPrefixCodeGenerator(std::move(huffman_encoder));
} }
lz77_encoder.encode(); lz77_encoder.encode();

View file

@ -10,16 +10,14 @@ target_include_directories(test_utils PUBLIC
list(APPEND TestFiles list(APPEND TestFiles
audio/TestAudioWriter.cpp audio/TestAudioWriter.cpp
audio/TestMidiReader.cpp audio/TestMidiReader.cpp
core/TestByteUtils.cpp
core/TestBinaryStream.cpp
core/TestBitStream.cpp
core/TestTomlReader.cpp
core/TestDataStructures.cpp
compiler/TestLexer.cpp
compiler/TestTemplatingEngine.cpp compiler/TestTemplatingEngine.cpp
compression/TestStreamCompressor.cpp compression/TestStreamCompressor.cpp
compression/TestHuffmanStream.cpp compression/TestHuffmanStream.cpp
compression/TestLz77Encoder.cpp compression/TestLz77Encoder.cpp
core/TestByteUtils.cpp
core/TestBitStream.cpp
core/TestTomlReader.cpp
core/TestDataStructures.cpp
database/TestDatabase.cpp database/TestDatabase.cpp
fonts/TestFontReader.cpp fonts/TestFontReader.cpp
graphics/TestRasterizer.cpp graphics/TestRasterizer.cpp
@ -29,7 +27,8 @@ list(APPEND TestFiles
network/TestNetworkManagerServer.cpp network/TestNetworkManagerServer.cpp
publishing/TestPdfWriter.cpp publishing/TestPdfWriter.cpp
web/TestMarkdownParser.cpp web/TestMarkdownParser.cpp
web/TestXmlParser.cpp) web/TestXmlParser.cpp
)
if (${HAS_FFMPEG}) if (${HAS_FFMPEG})
list(APPEND TestFiles list(APPEND TestFiles
@ -71,16 +70,6 @@ if(UNIX)
endif() endif()
endif() endif()
foreach(TestFile ${TestFiles}) add_executable(test_runner test_runner.cpp ${TestFiles})
cmake_path(GET TestFile FILENAME TestFileName)
cmake_path(GET TestFileName STEM TestName)
add_executable(${TestName} ${TestFile}) target_link_libraries(test_runner PUBLIC test_utils publishing core compiler fonts network database geometry audio graphics web client)
target_link_libraries(${TestName} PUBLIC core compiler compression fonts network image publishing video database geometry audio graphics web client test_utils ${DBUS_LIBRARIES})
set_property(TARGET ${TestName} PROPERTY FOLDER test)
endforeach()
add_executable(test_runner test_runner.cpp)
target_link_libraries(test_runner PUBLIC core fonts network database geometry audio graphics web client)

View file

@ -3,8 +3,7 @@
#include "AudioWriter.h" #include "AudioWriter.h"
#include "WasapiInterface.h" #include "WasapiInterface.h"
#include "TestCase.h" #include "TestFramework.h"
#include "TestCaseRunner.h"
#include <memory> #include <memory>
#include <string> #include <string>
@ -13,10 +12,7 @@
#endif #endif
#include <iostream> #include <iostream>
class TestWriteWav : public TestCase TEST_CASE(TestWriteWav, "audio")
{
public:
bool Run() override
{ {
AudioWriter writer; AudioWriter writer;
writer.SetPath("test.wav"); writer.SetPath("test.wav");
@ -25,38 +21,14 @@ public:
auto sample = synth.GetSineWave(240, 5); auto sample = synth.GetSineWave(240, 5);
writer.Write(sample); writer.Write(sample);
return true;
}
}; };
class TestAudioRender : public TestCase TEST_CASE(TestAudioRender, "audio")
{
public:
bool Run() override
{ {
#ifdef _WIN32 #ifdef _WIN32
WasapiInterface audio_interface; WasapiInterface audio_interface;
auto device = AudioDevice::Create(); auto device = AudioDevice::Create();
audio_interface.Play(device); audio_interface.Play(device);
#endif #endif
return true;
}
}; };
//int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
int main()
{
#ifdef _WIN32
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
#endif
std::cout << "into entry point" << std::endl;
TestCaseRunner runner;
runner.AddTestCase("TestWriteNav", std::make_unique<TestWriteWav>());
runner.AddTestCase("TestAudioRender", std::make_unique<TestAudioRender>());
const auto testsPassed = runner.Run();
return testsPassed ? 0 : -1;
#ifdef _WIN32
CoUninitialize();
#endif
}

View file

@ -1,31 +1,16 @@
#include "MidiReader.h" #include "MidiReader.h"
#include "TestCase.h" #include "TestFramework.h"
#include "TestCaseRunner.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <iostream> #include <iostream>
class TestReadMidi : public TestCase TEST_CASE(TestReadMidi, "audio")
{
public:
bool Run() override
{ {
MidiReader reader; MidiReader reader;
reader.Read("/home/jmsgrogan/Downloads/test.mid"); reader.Read("/home/jmsgrogan/Downloads/test.mid");
auto document = reader.GetDocument(); auto document = reader.GetDocument();
std::cout << document->Serialize() << std::endl; // std::cout << document->Serialize() << std::endl;
return true;
}
}; };
int main()
{
TestCaseRunner runner;
runner.AddTestCase("TestReadMidi", std::make_unique<TestReadMidi>());
const auto testsPassed = runner.Run();
return testsPassed ? 0 : -1;
}

View file

@ -1,5 +0,0 @@
int main(int argc, char** argv)
{
return 0;
}

View file

@ -1,11 +1,12 @@
#include "TemplatingEngine.h" #include "TemplatingEngine.h"
#include <File.h> #include <File.h>
#include "TestFramework.h"
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
int main() TEST_CASE(TestTemplatingEngine, "compiler")
{ {
const auto data_loc = std::filesystem::path(__FILE__) / "../../data"; const auto data_loc = std::filesystem::path(__FILE__) / "../../data";

View file

@ -1,9 +1,11 @@
#include <iostream> #include <iostream>
#include "TestFramework.h"
#include "HuffmanStream.h" #include "HuffmanStream.h"
#include "BufferBitStream.h" #include "BufferBitStream.h"
void testHuffmanCodeLengthTable() TEST_CASE(TestHuffmanCodeLengthTable, "compression")
{ {
HuffmanCodeLengthTable table; HuffmanCodeLengthTable table;
@ -17,23 +19,23 @@ void testHuffmanCodeLengthTable()
} }
} }
table.setInputLengthSequence(code_length_sequence, false); table.setInputLengthSequence(code_length_sequence, false);
table.buildCompressedLengthSequence(); table.buildCompressedLengthSequence();
auto compressed_sequence = table.getCompressedLengthSequence(); auto compressed_sequence = table.getCompressedLengthSequence();
for (auto entry : compressed_sequence) for (auto entry : compressed_sequence)
{ {
std::cout << "Count " << entry.first << " extra bits " << entry.second << std::endl; // std::cout << "Count " << entry.first << " extra bits " << entry.second << std::endl;
} }
auto compressed_lengths = table.getCompressedLengthCounts(); auto compressed_lengths = table.getCompressedLengthCounts();
for(unsigned idx = 0; idx<compressed_lengths.size(); idx++) for(unsigned idx = 0; idx<compressed_lengths.size(); idx++)
{ {
std::cout << "Slot " << idx << " length " << compressed_lengths[idx] << std::endl; //std::cout << "Slot " << idx << " length " << compressed_lengths[idx] << std::endl;
}
} }
};
void testLiteralsTable()
TEST_CASE(TestLiteralsTable, "compression")
{ {
std::vector<unsigned char> lengths = {7,4,4,7,5,5,7,7,6,6,7,6,6,6,8,6,6,8, std::vector<unsigned char> lengths = {7,4,4,7,5,5,7,7,6,6,7,6,6,6,8,6,6,8,
6,6,7,6,8,7,7,7,7,7,7,6,6,7,7,6,6,7,7,8,8,7,7,7,6,6,7,7,7,7,6,7,7,7, 6,6,7,6,8,7,7,7,7,7,7,6,6,7,7,6,6,7,7,8,8,7,7,7,6,6,7,7,7,7,6,7,7,7,
@ -53,13 +55,13 @@ void testLiteralsTable()
auto compressed_sequence = table.getCompressedLengthSequence(); auto compressed_sequence = table.getCompressedLengthSequence();
for (auto entry : compressed_sequence) for (auto entry : compressed_sequence)
{ {
std::cout << "Code " << entry.first << " extra bits " << entry.second << std::endl; // std::cout << "Code " << entry.first << " extra bits " << entry.second << std::endl;
} }
auto compressed_lengths = table.getCompressedLengthCounts(); auto compressed_lengths = table.getCompressedLengthCounts();
for(unsigned idx = 0; idx<compressed_lengths.size(); idx++) for(unsigned idx = 0; idx<compressed_lengths.size(); idx++)
{ {
std::cout << "Slot " << idx << " length " << compressed_lengths[idx] << std::endl; // std::cout << "Slot " << idx << " length " << compressed_lengths[idx] << std::endl;
} }
HuffmanCodeLengthTable codingTable; HuffmanCodeLengthTable codingTable;
@ -99,7 +101,6 @@ void testLiteralsTable()
{ {
out_stream.writeNBits(permuted[idx], 3); out_stream.writeNBits(permuted[idx], 3);
} }
*/
for(unsigned idx=0; idx<14;idx++) for(unsigned idx=0; idx<14;idx++)
{ {
@ -131,15 +132,15 @@ void testLiteralsTable()
std::cout << "Output is: " << std::endl; std::cout << "Output is: " << std::endl;
auto dump = out_stream.logNextNBytes(out_stream.getBuffer().size()); auto dump = out_stream.logNextNBytes(out_stream.getBuffer().size());
std::cout << dump << std::endl; std::cout << dump << std::endl;
*/
} };
int main() //int main()
{ //{
//testHuffmanCodeLengthTable(); //testHuffmanCodeLengthTable();
testLiteralsTable(); // testLiteralsTable();
//HuffmanStream stream(nullptr, nullptr); //HuffmanStream stream(nullptr, nullptr);
//stream.setCodeLengthAlphabetLengths({3, 3, 3, 3, 3, 2, 4, 4}); //stream.setCodeLengthAlphabetLengths({3, 3, 3, 3, 3, 2, 4, 4});
@ -148,7 +149,7 @@ int main()
//stream.buildCodeLengthMapping(); //stream.buildCodeLengthMapping();
std::cout << "*******" << std::endl; //std::cout << "*******" << std::endl;
//stream.setCodeLengthAlphabetLengths({4, 0, 6, 7, 3, 2, 4, 2, 7, 4, 6, 3, 0, 6}); //stream.setCodeLengthAlphabetLengths({4, 0, 6, 7, 3, 2, 4, 2, 7, 4, 6, 3, 0, 6});
//stream.buildCodeLengthMapping(); //stream.buildCodeLengthMapping();
@ -157,6 +158,8 @@ int main()
//stream.generateFixedCodeMapping(); //stream.generateFixedCodeMapping();
// testCodeConversions();
return 0;
} // return 0;
//}

View file

@ -1,9 +1,12 @@
#include <iostream> #include <iostream>
#include "Lz77Encoder.h" #include "Lz77Encoder.h"
#include "HuffmanEncoder.h"
#include "BufferBitStream.h" #include "BufferBitStream.h"
int main() #include "TestFramework.h"
TEST_CASE(TestLz77Encoder, "compression")
{ {
std::vector<unsigned> values {0, 10, 11, 12, 10, 11, 12, 0, 13, 14, 15, 10, 11, 12}; std::vector<unsigned> values {0, 10, 11, 12, 10, 11, 12, 0, 13, 14, 15, 10, 11, 12};
@ -28,5 +31,6 @@ int main()
std::cout << "Got hit " << length << " | " << distance << " | " << static_cast<int>(next_char) << std::endl; std::cout << "Got hit " << length << " | " << distance << " | " << static_cast<int>(next_char) << std::endl;
} }
return 0; HuffmanEncoder huffman_encoder;
huffman_encoder.initializeTrees(hit_buffer);
} }

View file

@ -5,21 +5,25 @@
#include "RunLengthEncoder.h" #include "RunLengthEncoder.h"
#include "Lz77Encoder.h" #include "Lz77Encoder.h"
void test_run_length_encoder() #include "StringUtils.h"
#include "TestFramework.h"
TEST_CASE(TestRunLengthEncoder, "compression")
{ {
std::string test_data = "BCAAAADDDCCACACAC"; std::string test_data = "BCAAAADDDCCACACAC";
RunLengthEncoder encoder; RunLengthEncoder encoder;
auto encoded = encoder.encode(test_data); auto encoded = encoder.encode(StringUtils::toBytes(test_data));
std::cout << "Encoded: " << encoded << std::endl; //std::cout << "Encoded: " << encoded << std::endl;
auto decoded = encoder.decode(encoded); auto decoded = encoder.decode(encoded);
std::cout << "Decoded: " << decoded << std::endl; //std::cout << "Decoded: " << decoded << std::endl;
} }
void test_huffman_encoder() TEST_CASE(TestHuffmanEncoder, "compression")
{ {
//std::string testData = "BCAADDDCCACACAC"; //std::string testData = "BCAADDDCCACACAC";
//std::vector<unsigned char> stream(testData.begin(), testData.end()); //std::vector<unsigned char> stream(testData.begin(), testData.end());
@ -38,7 +42,7 @@ void test_huffman_encoder()
encoder.encode(counts); encoder.encode(counts);
} }
void test_lz77_encoder() TEST_CASE(TestLz77Encoder, "compression")
{ {
std::string test_data = "sir sid eastman easily teases sea sick seals"; std::string test_data = "sir sid eastman easily teases sea sick seals";
//std::string test_data = "sir sid eastman"; //std::string test_data = "sir sid eastman";
@ -56,14 +60,3 @@ void test_lz77_encoder()
//std::cout << "Decoded: " << decoded << std::endl; //std::cout << "Decoded: " << decoded << std::endl;
} }
int main()
{
//test_huffman_encoder();
//test_run_length_encoder();
test_lz77_encoder();
return 0;
}

View file

@ -1,4 +0,0 @@
int main()
{
return 0;
}

View file

@ -1,9 +1,11 @@
#include "ByteUtils.h" #include "ByteUtils.h"
#include "BufferBitStream.h" #include "BufferBitStream.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
void testReading() TEST_CASE(TestReadBitStream, "core")
{ {
std::vector<std::string> bytes{ std::vector<std::string> bytes{
"11101101", "11101101",
@ -37,7 +39,7 @@ void testReading()
std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl; std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl;
} }
void testWriting() TEST_CASE(TestWritingBitStream, "core")
{ {
BufferBitStream stream; BufferBitStream stream;
@ -72,13 +74,3 @@ void testWriting()
std::cout << "Got bytes 3 " << byte3 << std::endl; std::cout << "Got bytes 3 " << byte3 << std::endl;
std::cout << "Got bytes 4 " << byte4 << std::endl; std::cout << "Got bytes 4 " << byte4 << std::endl;
} }
int main()
{
//testReading()
testWriting();
return 0;
}

View file

@ -1,8 +1,10 @@
#include "ByteUtils.h" #include "ByteUtils.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
int main() TEST_CASE(TestReadByteUtils, "core")
{ {
auto byte = ByteUtils::getFromString("00110101"); auto byte = ByteUtils::getFromString("00110101");
std::cout << "Value is " << static_cast<unsigned>(byte) << std::endl; std::cout << "Value is " << static_cast<unsigned>(byte) << std::endl;
@ -32,6 +34,4 @@ int main()
unsigned hold = byte; unsigned hold = byte;
hold = (hold << 5) + 3; hold = (hold << 5) + 3;
std::cout << "Big val is " << ByteUtils::toString(hold, 16) << std::endl; std::cout << "Big val is " << ByteUtils::toString(hold, 16) << std::endl;
return 0;
} }

View file

@ -1,8 +1,10 @@
#include "CircleBuffer.h" #include "CircleBuffer.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
int main() TEST_CASE(TestCircleBuffer, "core")
{ {
CircleBuffer<unsigned> buffer(3); CircleBuffer<unsigned> buffer(3);
@ -29,6 +31,4 @@ int main()
auto item = buffer.getItem(idx); auto item = buffer.getItem(idx);
std::cout << "Got item: " << idx << " " << item << std::endl; std::cout << "Got item: " << idx << " " << item << std::endl;
} }
return 0;
} }

View file

@ -1,9 +1,11 @@
#include "TomlReader.h" #include "TomlReader.h"
#include "TestFramework.h"
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
int main() TEST_CASE(TestTomlReader, "core")
{ {
const auto data_loc = std::filesystem::path(__FILE__) / "../../data"; const auto data_loc = std::filesystem::path(__FILE__) / "../../data";
const auto sample_toml_file = data_loc / "sample_toml.toml"; const auto sample_toml_file = data_loc / "sample_toml.toml";
@ -16,6 +18,4 @@ int main()
{ {
std::cout << "Got entry with key: " << items.first << " and val " << items.second << std::endl; std::cout << "Got entry with key: " << items.first << " and val " << items.second << std::endl;
} }
return 0;
} }

View file

@ -1,12 +1,12 @@
#include "DatabaseManager.h" #include "DatabaseManager.h"
int main() #include "TestFramework.h"
TEST_CASE(TestDatabaseManager, "database")
{ {
DatabaseManager db_manager; DatabaseManager db_manager;
db_manager.CreateDatabase("test.db"); db_manager.CreateDatabase("test.db");
std::string statement = "CREATE TABLE corporation;"; std::string statement = "CREATE TABLE corporation;";
db_manager.Run(statement); db_manager.Run(statement);
return 0;
} }

View file

@ -3,7 +3,9 @@
#include <iostream> #include <iostream>
int main() #include "TestFramework.h"
TEST_CASE(TestFontReader, "fonts")
{ {
const auto font_path = "/usr/share/fonts/truetype/tlwg/TlwgTypo-Bold.ttf"; const auto font_path = "/usr/share/fonts/truetype/tlwg/TlwgTypo-Bold.ttf";
@ -12,6 +14,4 @@ int main()
auto font = reader.read(); auto font = reader.read();
font->dumpInfo(); font->dumpInfo();
return 0;
} }

View file

@ -3,9 +3,11 @@
#include "FontGlyph.h" #include "FontGlyph.h"
#include "Image.h" #include "Image.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
int main() TEST_CASE(TestFreeTypeFontEngine, "fonts")
{ {
FreeTypeFontEngine engine; FreeTypeFontEngine engine;
engine.initialize(); engine.initialize();
@ -14,6 +16,4 @@ int main()
engine.loadGlyph('A'); engine.loadGlyph('A');
engine.loadGlyph(66); engine.loadGlyph(66);
engine.loadGlyph(67); engine.loadGlyph(67);
return 0;
} }

View file

@ -3,30 +3,17 @@
#include "GuiApplication.h" #include "GuiApplication.h"
#include "TestFramework.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <iostream> #include <iostream>
class TestOpenGlRendering : public TestCase TEST_CASE(TestOpenGlRendering, "graphics")
{
public:
bool Run() override
{ {
auto app = std::make_unique<GuiApplication>(); auto app = std::make_unique<GuiApplication>();
app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11); app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11);
//app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER); //app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER);
app->run(); app->run();
return true;
}
}; };
int main()
{
TestCaseRunner runner;
runner.AddTestCase("TestOpenGlRendering", std::make_unique<TestOpenGlRendering>());
const auto testsPassed = runner.Run();
return testsPassed ? 0 : -1;
}

View file

@ -9,7 +9,9 @@
#include "Point.h" #include "Point.h"
#include "TriMesh.h" #include "TriMesh.h"
int main() #include "TestFramework.h"
TEST_CASE(TestRasterizer, "graphics")
{ {
/* /*
DrawingManager manager; DrawingManager manager;
@ -18,6 +20,4 @@ int main()
auto line = LineSegment::Create(Point(10.0, 10.0), Point(190.0, 190.0)); auto line = LineSegment::Create(Point(10.0, 10.0), Point(190.0, 190.0));
*/ */
return 0;
} }

View file

@ -5,7 +5,9 @@
#include "Image.h" #include "Image.h"
#include <iostream> #include <iostream>
void testThirdParty() #include "TestFramework.h"
TEST_CASE(TestThirdPartyPng, "image")
{ {
const auto path = "/home/jmsgrogan/Downloads/test.png"; const auto path = "/home/jmsgrogan/Downloads/test.png";
@ -26,7 +28,7 @@ void testThirdParty()
//} //}
} }
void testFixedCode() TEST_CASE(TestFxedCodePng, "image")
{ {
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test_fixed.png"; const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test_fixed.png";
@ -37,11 +39,3 @@ void testFixedCode()
reader.setPath(path); reader.setPath(path);
auto image = reader.read(); auto image = reader.read();
} }
int main()
{
testThirdParty();
//testFixedCode();
return 0;
}

View file

@ -6,9 +6,11 @@
#include "ByteUtils.h" #include "ByteUtils.h"
#include "ImagePrimitives.h" #include "ImagePrimitives.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
void testCompressedPng() TEST_CASE(TestCompressedPng, "image")
{ {
unsigned width = 20; unsigned width = 20;
unsigned height = 20; unsigned height = 20;
@ -43,7 +45,7 @@ void testCompressedPng()
test_file.Close(); test_file.Close();
} }
void testFixedPng() TEST_CASE(TestFixedPng, "image")
{ {
unsigned width = 10; unsigned width = 10;
unsigned height = 10; unsigned height = 10;
@ -73,7 +75,7 @@ void testFixedPng()
} }
void testDynamicCompressedPng() TEST_CASE(TestDynamicCompressedPng, "image")
{ {
unsigned width = 10; unsigned width = 10;
unsigned height = 10; unsigned height = 10;
@ -99,14 +101,4 @@ void testDynamicCompressedPng()
//return; //return;
File test_file("test_dynamic.png"); File test_file("test_dynamic.png");
std::cout << test_file.dumpBinary(); std::cout << test_file.dumpBinary();
}
int main()
{
//testCompressedPng();
//testFixedPng();
testDynamicCompressedPng();
return 0;
} }

View file

@ -1,12 +1,13 @@
#include "NetworkManager.h" #include "NetworkManager.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
int main() TEST_CASE(TestNetworkManagerClient, "network")
{ {
std::cout << "into main" << std::endl; std::cout << "into main" << std::endl;
auto network_manager = NetworkManager::Create(); auto network_manager = NetworkManager::Create();
network_manager->RunHttpClient(); network_manager->RunHttpClient();
return 0;
} }

View file

@ -1,12 +1,13 @@
#include "NetworkManager.h" #include "NetworkManager.h"
#include "TestFramework.h"
#include <iostream> #include <iostream>
int main() TEST_CASE(TestNetworkManagerServer, "network")
{ {
std::cout << "into main" << std::endl; std::cout << "into main" << std::endl;
auto network_manager = NetworkManager::Create(); auto network_manager = NetworkManager::Create();
network_manager->RunHttpServer(); network_manager->RunHttpServer();
return 0;
} }

View file

@ -3,7 +3,9 @@
#include "PdfObject.h" #include "PdfObject.h"
#include "File.h" #include "File.h"
int main() #include "TestFramework.h"
TEST_CASE(TestPdfWriter, "publishing")
{ {
auto document = std::make_unique<PdfDocument>(); auto document = std::make_unique<PdfDocument>();
@ -14,5 +16,4 @@ int main()
pdf_file.SetAccessMode(File::AccessMode::Write); pdf_file.SetAccessMode(File::AccessMode::Write);
pdf_file.Open(); pdf_file.Open();
pdf_file.WriteText(output); pdf_file.WriteText(output);
return 0;
} }

View file

@ -1,4 +1,21 @@
#include "TestFramework.h"
#ifdef _WIN32
#include <windows.h>
#endif
//int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
int main() int main()
{ {
#ifdef _WIN32
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
#endif
auto test_runner = TestCaseRunner::getInstance();
test_runner.run();
#ifdef _WIN32
CoUninitialize();
#endif
return 0; return 0;
} }

View file

@ -1,13 +1,45 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <string>
#include <functional>
class TestCase class TestCase
{ {
public: public:
TestCase(){}; using TestCaseFunction = std::function<void()>;
TestCase(const std::string& name, const std::string& tags, TestCaseFunction func)
: mName(name),
mTags(tags),
mTestFunction(func)
{
};
virtual ~TestCase() = default; virtual ~TestCase() = default;
TestCase(const TestCase&) = delete;
virtual bool Run() {return false;}; const std::string& getName() const
{
return mName;
}
const std::string& getTags() const
{
return mTags;
}
virtual void run()
{
mTestFunction();
};
public:
TestCaseFunction mTestFunction{nullptr};
private:
std::string mName;
std::string mTags;
}; };
using TestCasePtr = std::unique_ptr<TestCase>; using TestCasePtr = std::unique_ptr<TestCase>;

View file

@ -3,24 +3,42 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
void TestCaseRunner::AddTestCase(const std::string& label, TestCasePtr testCase) TestCaseRunner::~TestCaseRunner()
{ {
mCases.push_back({label, std::move(testCase)}); for (auto testCase : mCases)
{
//delete testCase;
}
} }
bool TestCaseRunner::Run() void TestCaseRunner::addTestCase(const std::string& label, const std::string& tag, TestCase::TestCaseFunction func)
{ {
auto test_case = new TestCase(label, tag, func);
mCases.push_back(test_case);
}
bool TestCaseRunner::run()
{
for (auto test_case : mCases)
{
std::cout << "TestFramework: Running Test - " << test_case->getName() << std::endl;
test_case->run();
}
bool testsPassed = true; bool testsPassed = true;
/*
for(const auto& test : mCases) for(const auto& test : mCases)
{ {
std::cout << "Running " << test.first << std::endl; std::cout << "Running " << test->getName() << std::endl;
const auto result = test.second->Run(); const auto result = test->Run();
if (!result) if (!result)
{ {
std::cout << test.first << " Failed" << std::endl; std::cout << test->getName() << " Failed" << std::endl;
testsPassed = false; testsPassed = false;
break; break;
} }
} }
return testsPassed; return testsPassed;
*/
return true;
} }

View file

@ -8,12 +8,20 @@
class TestCaseRunner class TestCaseRunner
{ {
public: public:
TestCaseRunner() = default;
void AddTestCase(const std::string& label, TestCasePtr testCase); static TestCaseRunner& getInstance()
{
static TestCaseRunner instance;
return instance;
}
bool Run(); ~TestCaseRunner();
void addTestCase(const std::string& label, const std::string& tag, TestCase::TestCaseFunction func);
bool run();
private: private:
using TestInstance = std::pair<std::string, TestCasePtr>; std::vector<TestCase*> mCases;
std::vector<TestInstance> mCases;
}; };

View file

@ -0,0 +1,18 @@
#pragma once
#include "TestCaseRunner.h"
struct Holder
{
Holder(const std::string& name, const std::string& tags, std::function<void()> func)
{
TestCaseRunner::getInstance().addTestCase(name, tags, func);
}
};
#define TEST_CASE(NAME, TAGS) \
static void Test##NAME(); \
namespace{Holder holder##NAME( #NAME, #TAGS, &Test##NAME );} \
static void Test##NAME() \

View file

@ -2,10 +2,11 @@
#include "Image.h" #include "Image.h"
#include "FfmpegInterface.h" #include "FfmpegInterface.h"
#include "PngWriter.h" #include "PngWriter.h"
#include "PngWriterImpl.h"
#include <iostream> #include <iostream>
int main() #include "TestFramework.h"
TEST_CASE(TestVideoDecoder, "video")
{ {
auto video = Video::Create(); auto video = Video::Create();
video->SetPath("/home/jmsgrogan/test.mp4"); video->SetPath("/home/jmsgrogan/test.mp4");
@ -21,6 +22,4 @@ int main()
writer.SetPath(filename); writer.SetPath(filename);
writer.Write(images[idx]); writer.Write(images[idx]);
} }
return 0;
} }

View file

@ -2,7 +2,9 @@
#include "File.h" #include "File.h"
#include "HtmlWriter.h" #include "HtmlWriter.h"
int main() #include "TestFramework.h"
TEST_CASE(TestMarkdownParser, "web")
{ {
File md_file("/home/jmsgrogan/code/MediaTool/test/data/sample_markdown.md"); File md_file("/home/jmsgrogan/code/MediaTool/test/data/sample_markdown.md");
md_file.Open(); md_file.Open();
@ -20,6 +22,4 @@ int main()
html_file.SetAccessMode(File::AccessMode::Write); html_file.SetAccessMode(File::AccessMode::Write);
html_file.Open(); html_file.Open();
html_file.WriteText(html_string); html_file.WriteText(html_string);
return 0;
} }

View file

@ -5,7 +5,9 @@
#include "XmlWriter.h" #include "XmlWriter.h"
#include "File.h" #include "File.h"
int main(int argc, char *argv[]) #include "TestFramework.h"
TEST_CASE(TestXmlParser, "web")
{ {
XmlParser parser; XmlParser parser;
@ -26,6 +28,4 @@ int main(int argc, char *argv[])
XmlWriter writer; XmlWriter writer;
auto content = writer.ToString(parser.GetDocument().get()); auto content = writer.ToString(parser.GetDocument().get());
outFile->WriteText(content); outFile->WriteText(content);
return 0;
} }

View file

@ -5,7 +5,9 @@
#include "GuiApplication.h" #include "GuiApplication.h"
int main() #include "TestFramework.h"
TEST_CASE(TestWaylandWindow, "web")
{ {
FileLogger::GetInstance().Open(); FileLogger::GetInstance().Open();
@ -15,6 +17,4 @@ int main()
app->setUiInterfaceBackend(UiInterfaceFactory::Backend::WAYLAND_RASTER); app->setUiInterfaceBackend(UiInterfaceFactory::Backend::WAYLAND_RASTER);
app->run(); app->run();
return 0;
} }