166 lines
4.7 KiB
C++
166 lines
4.7 KiB
C++
#include "scroller_streams.h"
|
||
|
||
#include "db/database_manager.h"
|
||
|
||
#include <gtest/gtest.h>
|
||
|
||
#include <string>
|
||
#include <unordered_map>
|
||
#include <vector>
|
||
|
||
namespace {
|
||
|
||
using radiantwave::db::AudioFileRecord;
|
||
using radiantwave::db::ProclamationRecord;
|
||
using radiantwave::scroller::ProclamationStream;
|
||
using radiantwave::scroller::StreamColor;
|
||
using radiantwave::scroller::buildStreams;
|
||
using radiantwave::scroller::kDefaultRepeatCount;
|
||
using radiantwave::scroller::kSelectedRepeatCount;
|
||
|
||
const std::string kDefaultId = "default";
|
||
|
||
std::vector<StreamColor> palette()
|
||
{
|
||
StreamColor c;
|
||
c.r = 10;
|
||
c.g = 20;
|
||
c.b = 30;
|
||
return {c};
|
||
}
|
||
|
||
} // namespace
|
||
|
||
TEST(ScrollerStreamsTest, InterleavesSelectedWithDefault)
|
||
{
|
||
ProclamationRecord p1;
|
||
p1.id = "one";
|
||
p1.title = "One";
|
||
p1.content = "hello world";
|
||
p1.selected = true;
|
||
p1.solfeggio_frequency_id = 2;
|
||
|
||
ProclamationRecord p2;
|
||
p2.id = "two";
|
||
p2.title = "Two";
|
||
p2.content = "foo bar baz";
|
||
p2.selected = true;
|
||
p2.solfeggio_frequency_id = 5;
|
||
|
||
ProclamationRecord def;
|
||
def.id = kDefaultId;
|
||
def.title = "Default";
|
||
def.content = "default text";
|
||
def.selected = true;
|
||
def.solfeggio_frequency_id = 5;
|
||
|
||
std::unordered_map<int, std::vector<StreamColor>> palettes;
|
||
palettes[2] = palette();
|
||
|
||
std::unordered_map<int, AudioFileRecord> audio;
|
||
AudioFileRecord af;
|
||
af.id = 1;
|
||
af.filename = "396Hz.wav";
|
||
af.solfeggio_frequency_id = 2;
|
||
audio[2] = af;
|
||
|
||
auto streams = buildStreams({p1, p2, def}, palettes, palette(), audio, kDefaultId);
|
||
|
||
// The first user-selected proclamation plays first, followed by the
|
||
// default, then the next selected, then the default again.
|
||
ASSERT_EQ(streams.size(), 4u);
|
||
|
||
EXPECT_EQ(streams[0].name, "One");
|
||
ASSERT_EQ(streams[0].words.size(), 2u);
|
||
EXPECT_EQ(streams[0].words[0], "hello");
|
||
EXPECT_EQ(streams[0].words[1], "world");
|
||
EXPECT_EQ(streams[0].repeat, kSelectedRepeatCount);
|
||
EXPECT_EQ(streams[0].solfeggio_frequency_id, 2);
|
||
EXPECT_EQ(streams[0].audioFilename, "396Hz.wav");
|
||
EXPECT_EQ(streams[0].palette.size(), 1u);
|
||
|
||
EXPECT_EQ(streams[1].name, "Default");
|
||
EXPECT_EQ(streams[1].repeat, kDefaultRepeatCount);
|
||
EXPECT_EQ(streams[1].solfeggio_frequency_id, 5);
|
||
EXPECT_EQ(streams[1].audioFilename, "OriginalAudio.wav"); // no audio for freq 5
|
||
EXPECT_EQ(streams[1].palette.size(), 1u); // falls back to 528 palette
|
||
|
||
EXPECT_EQ(streams[2].name, "Two");
|
||
EXPECT_EQ(streams[2].repeat, kSelectedRepeatCount);
|
||
EXPECT_EQ(streams[2].palette.size(), 1u); // falls back to 528 palette
|
||
|
||
EXPECT_EQ(streams[3].name, "Default");
|
||
EXPECT_EQ(streams[3].repeat, kDefaultRepeatCount);
|
||
EXPECT_EQ(streams[3].audioFilename, "OriginalAudio.wav");
|
||
}
|
||
|
||
TEST(ScrollerStreamsTest, DefaultOnlyWhenNothingSelected)
|
||
{
|
||
ProclamationRecord p1;
|
||
p1.id = "one";
|
||
p1.title = "One";
|
||
p1.content = "x";
|
||
p1.selected = false;
|
||
|
||
ProclamationRecord def;
|
||
def.id = kDefaultId;
|
||
def.title = "Default";
|
||
def.content = "y";
|
||
def.selected = true;
|
||
|
||
auto streams = buildStreams({p1, def}, {}, palette(), {}, kDefaultId);
|
||
|
||
ASSERT_EQ(streams.size(), 1u);
|
||
EXPECT_EQ(streams[0].name, "Default");
|
||
EXPECT_EQ(streams[0].repeat, kDefaultRepeatCount);
|
||
}
|
||
|
||
TEST(ScrollerStreamsTest, MissingDefaultStillStreamsSelected)
|
||
{
|
||
ProclamationRecord p1;
|
||
p1.id = "one";
|
||
p1.title = "One";
|
||
p1.content = "x";
|
||
p1.selected = true;
|
||
|
||
auto streams = buildStreams({p1}, {}, palette(), {}, kDefaultId);
|
||
ASSERT_EQ(streams.size(), 1u);
|
||
EXPECT_EQ(streams[0].name, "One");
|
||
EXPECT_EQ(streams[0].repeat, kSelectedRepeatCount);
|
||
}
|
||
|
||
TEST(ScrollerStreamsTest, SplitsGluedSentencePunctuation)
|
||
{
|
||
ProclamationRecord p1;
|
||
p1.id = "one";
|
||
p1.title = "One";
|
||
p1.content = "state?Create NOW?KING field’s fine (Acts 17:27)I example.com";
|
||
p1.selected = true;
|
||
|
||
auto streams = buildStreams({p1}, {}, palette(), {}, kDefaultId);
|
||
|
||
ASSERT_EQ(streams.size(), 1u);
|
||
const auto& words = streams[0].words;
|
||
|
||
// "?" glued to an uppercase word splits after the punctuation, keeping the
|
||
// sentence separator attached to the preceding word.
|
||
EXPECT_EQ(words[0], "state?");
|
||
EXPECT_EQ(words[1], "Create");
|
||
EXPECT_EQ(words[2], "NOW?");
|
||
EXPECT_EQ(words[3], "KING");
|
||
|
||
// Curly apostrophes are not sentence punctuation and stay inside the word.
|
||
EXPECT_EQ(words[4], "field’s");
|
||
EXPECT_EQ(words[5], "fine");
|
||
|
||
// Closing paren followed by an uppercase letter splits so the verse
|
||
// reference and the next word are separate tokens.
|
||
EXPECT_EQ(words[6], "(Acts");
|
||
EXPECT_EQ(words[7], "17:27)");
|
||
EXPECT_EQ(words[8], "I");
|
||
|
||
// A lowercase continuation after a dot is not a new sentence, so this
|
||
// stays intact.
|
||
EXPECT_EQ(words[9], "example.com");
|
||
}
|