Files
radiantwave/tests/test_scroller_streams.cpp
T
2026-08-07 14:51:41 -05:00

166 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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");
}