Improve code coverage of tests

This commit is contained in:
Thomas Goyne 2015-07-28 12:02:41 -07:00
parent 4a3b411092
commit fefa31eb47
12 changed files with 96 additions and 23 deletions

View File

@ -36,8 +36,8 @@ void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count,
void AudioProvider::ZeroFill(void *buf, int64_t count) const {
if (bytes_per_sample == 1)
// 8 bit formats are usually unsigned with bias 127
memset(buf, 127, count * channels);
// 8 bit formats are usually unsigned with bias 128
memset(buf, 128, count * channels);
else // While everything else is signed
memset(buf, 0, count * bytes_per_sample * channels);
}
@ -100,13 +100,13 @@ public:
};
}
void SaveAudioClip(AudioProvider *provider, fs::path const& path, int start_time, int end_time) {
auto start_sample = ((int64_t)start_time * provider->GetSampleRate() + 999) / 1000;
auto end_sample = ((int64_t)end_time * provider->GetSampleRate() + 999) / 1000;
if (start_sample >= provider->GetNumSamples() || start_sample >= end_sample) return;
void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int start_time, int end_time) {
const auto max_samples = provider.GetNumSamples();
const auto start_sample = std::min(max_samples, ((int64_t)start_time * provider.GetSampleRate() + 999) / 1000);
const auto end_sample = util::mid(start_sample, ((int64_t)end_time * provider.GetSampleRate() + 999) / 1000, max_samples);
size_t bytes_per_sample = provider->GetBytesPerSample() * provider->GetChannels();
size_t bufsize = (end_sample - start_sample) * bytes_per_sample;
const size_t bytes_per_sample = provider.GetBytesPerSample() * provider.GetChannels();
const size_t bufsize = (end_sample - start_sample) * bytes_per_sample;
writer out{path};
out.write("RIFF");
@ -115,11 +115,11 @@ void SaveAudioClip(AudioProvider *provider, fs::path const& path, int start_time
out.write("WAVEfmt ");
out.write<int32_t>(16); // Size of chunk
out.write<int16_t>(1); // compression format (PCM)
out.write<int16_t>(provider->GetChannels());
out.write<int32_t>(provider->GetSampleRate());
out.write<int32_t>(provider->GetSampleRate() * provider->GetChannels() * provider->GetBytesPerSample());
out.write<int16_t>(provider->GetChannels() * provider->GetBytesPerSample());
out.write<int16_t>(provider->GetBytesPerSample() * 8);
out.write<int16_t>(provider.GetChannels());
out.write<int32_t>(provider.GetSampleRate());
out.write<int32_t>(provider.GetSampleRate() * provider.GetChannels() * provider.GetBytesPerSample());
out.write<int16_t>(provider.GetChannels() * provider.GetBytesPerSample());
out.write<int16_t>(provider.GetBytesPerSample() * 8);
out.write("data");
out.write<int32_t>(bufsize);
@ -130,7 +130,7 @@ void SaveAudioClip(AudioProvider *provider, fs::path const& path, int start_time
for (int64_t i = start_sample; i < end_sample; i += spr) {
spr = std::min<size_t>(spr, end_sample - i);
buf.resize(spr * bytes_per_sample);
provider->GetAudio(&buf[0], i, spr);
provider.GetAudio(&buf[0], i, spr);
out.write(buf);
}
}

View File

@ -193,7 +193,7 @@ Calltip GetCalltip(std::vector<ass::DialogueToken> const& tokens, std::string co
auto start = proto->args + tag_name_length + 2; // One for slash, one for open paren
for (; commas > 0; --commas) {
start = strchr(start, ',');
if (!start) return ret; // No calltip if there's too many args
if (!start) return ret; // No calltip if we're after the last arg
++start;
}

View File

@ -91,5 +91,5 @@ std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProv
std::unique_ptr<AudioProvider> CreateHDAudioProvider(std::unique_ptr<AudioProvider> source_provider, fs::path const& dir);
std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvider> source_provider);
void SaveAudioClip(AudioProvider *provider, fs::path const& path, int start_time, int end_time);
void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int start_time, int end_time);
}

View File

@ -184,7 +184,7 @@ struct audio_save_clip final : public Command {
end = std::max(end, line->End);
}
agi::SaveAudioClip(c->project->AudioProvider(), filename, start, end);
agi::SaveAudioClip(*c->project->AudioProvider(), filename, start, end);
}
};

View File

@ -87,6 +87,20 @@ TEST(lagi_audio, before_sample_zero) {
ASSERT_EQ(i - 8, buff[i]);
}
TEST(lagi_audio, before_sample_zero_8bit) {
TestAudioProvider<uint8_t> provider;
provider.bias = 128;
uint8_t buff[16];
memset(buff, sizeof(buff), 1);
provider.GetAudio(buff, -8, 16);
for (int i = 0; i < 8; ++i)
ASSERT_EQ(128, buff[i]);
for (int i = 8; i < 16; ++i)
ASSERT_EQ(128 + i - 8, buff[i]);
}
TEST(lagi_audio, after_end) {
TestAudioProvider<> provider(1);
@ -105,7 +119,7 @@ TEST(lagi_audio, save_audio_clip) {
agi::fs::Remove(path);
auto provider = agi::CreateDummyAudioProvider("dummy-audio:noise?", nullptr);
agi::SaveAudioClip(provider.get(), path, 60 * 60 * 1000, (60 * 60 + 10) * 1000);
agi::SaveAudioClip(*provider, path, 60 * 60 * 1000, (60 * 60 + 10) * 1000);
{
bfs::ifstream s(path);
@ -117,6 +131,45 @@ TEST(lagi_audio, save_audio_clip) {
agi::fs::Remove(path);
}
TEST(lagi_audio, save_audio_clip_out_of_audio_range) {
const auto path = agi::Path().Decode("?temp/save_clip");
agi::fs::Remove(path);
const auto provider = agi::CreateDummyAudioProvider("dummy-audio:noise?", nullptr);
const auto end_time = 150 * 60 * 1000;
// Start time after end of clip: empty file
agi::SaveAudioClip(*provider, path, end_time, end_time + 1);
{
bfs::ifstream s(path);
ASSERT_TRUE(s.good());
s.seekg(0, std::ios::end);
EXPECT_EQ(44, s.tellg());
}
agi::fs::Remove(path);
// Start time >= end time: empty file
agi::SaveAudioClip(*provider, path, end_time - 1, end_time - 1);
{
bfs::ifstream s(path);
ASSERT_TRUE(s.good());
s.seekg(0, std::ios::end);
EXPECT_EQ(44, s.tellg());
}
agi::fs::Remove(path);
// Start time during clip, end time after end of clip: save only the part that exists
agi::SaveAudioClip(*provider, path, end_time - 1000, end_time + 1000);
{
bfs::ifstream s(path);
ASSERT_TRUE(s.good());
s.seekg(0, std::ios::end);
// 1 second of 44.1 kHz samples per second of 16-bit mono, plus 44 bytes of header
EXPECT_EQ(44100 * 2 + 44, s.tellg());
}
agi::fs::Remove(path);
}
TEST(lagi_audio, get_with_volume) {
TestAudioProvider<> provider;
uint16_t buff[4];
@ -309,7 +362,7 @@ TEST(lagi_audio, pcm_simple) {
auto path = agi::Path().Decode("?temp/pcm_simple");
{
TestAudioProvider<> provider;
agi::SaveAudioClip(&provider, path, 0, 1000);
agi::SaveAudioClip(provider, path, 0, 1000);
}
auto provider = agi::CreatePCMAudioProvider(path, nullptr);
@ -333,7 +386,7 @@ TEST(lagi_audio, pcm_truncated) {
auto path = agi::Path().Decode("?temp/pcm_truncated");
{
TestAudioProvider<> provider;
agi::SaveAudioClip(&provider, path, 0, 1000);
agi::SaveAudioClip(provider, path, 0, 1000);
}
char file[1000];

View File

@ -68,10 +68,11 @@ TEST(lagi_calltip, overloads) {
}
TEST(lagi_calltip, too_many_args) {
expect_tip("{\\pos(100,100,100)}hello", 2, bad_tip);
expect_tip("{\\pos(100,100,100)}hello", 15, bad_tip);
expect_tip("{\\pos(100,100,100)}hello", 3, Calltip{"\\pos(X,Y)", 5, 6, 2});
}
TEST(lagi_calltip, unknown_tag) {
expect_tip("{\\foo(100,100,100)}hello", 2, bad_tip);
expect_tip("{\\toolong(100,100,100)}hello", 2, bad_tip);
expect_tip("{\\foo(100,100,100)}hello", 3, bad_tip);
expect_tip("{\\toolong(100,100,100)}hello", 3, bad_tip);
}

View File

@ -51,6 +51,10 @@ TEST(lagi_character_count, ignore_blocks_and_punctuation) {
EXPECT_EQ(5, agi::CharacterCount("{asdf}hello.", agi::IGNORE_PUNCTUATION | agi::IGNORE_BLOCKS));
}
TEST(lagi_character_count, ignore_blocks_unclosed) {
EXPECT_EQ(6, agi::CharacterCount("{hello", agi::IGNORE_BLOCKS));
}
TEST(lagi_character_count, line_length) {
EXPECT_EQ(5, agi::MaxLineLength("hello", agi::IGNORE_NONE));
EXPECT_EQ(5, agi::MaxLineLength("hello\\Nasdf", agi::IGNORE_NONE));

View File

@ -43,6 +43,13 @@ TEST(lagi_color, hex) {
EXPECT_EQ("#102030", agi::Color(16, 32, 48).GetHexFormatted());
}
TEST(lagi_color, hex_rgba) {
EXPECT_EQ("#00000000", agi::Color(0, 0, 0, 0).GetHexFormatted(true));
EXPECT_EQ("#FFFFFFFF", agi::Color(255, 255, 255, 255).GetHexFormatted(true));
EXPECT_EQ("#FF007F20", agi::Color(255, 0, 127, 32).GetHexFormatted(true));
EXPECT_EQ("#10203040", agi::Color(16, 32, 48, 64).GetHexFormatted(true));
}
TEST(lagi_color, rgb) {
EXPECT_EQ(agi::Color(0, 0, 0), agi::Color("rgb(0, 0, 0)"));
EXPECT_EQ(agi::Color(255, 255, 255), agi::Color("rgb(255, 255, 255)"));

View File

@ -94,6 +94,7 @@ TEST(lagi_format, length_modifiers) {
TEST(lagi_format, precision_width) {
EXPECT_EQ("05", agi::format("%02X", 5));
EXPECT_EQ(" -10", agi::format("%10d", -10));
EXPECT_EQ("-10 ", agi::format("%-10d", -10));
EXPECT_EQ("0010", agi::format("%04d", 10));
EXPECT_EQ(" 1234.1235", agi::format("%10.4f", 1234.1234567890));
EXPECT_EQ("10", agi::format("%.f", 10.1));

View File

@ -216,4 +216,6 @@ TEST(lagi_hotkey, old_format_is_backed_up_before_migrating) {
tmp.read(buff, sizeof(buff));
ASSERT_TRUE(memcmp(buff, simple_valid, sizeof(buff)) == 0);
}
agi::fs::Remove("data/hotkey_tmp.3_1");
}

View File

@ -39,6 +39,7 @@
TEST(lagi_ifind, basic_match) {
EXPECT_IFIND(" a ", "a", 1, 2);
EXPECT_IFIND(" a ", "A", 1, 2);
EXPECT_IFIND(" A ", "a", 1, 2);
EXPECT_NO_MATCH(" a ", "b");
}

View File

@ -58,6 +58,10 @@ TEST(lagi_time, comma_decimal) {
EXPECT_STREQ("1:23:45.67", Time("1:23:45,67").GetAssFormatted().c_str());
}
TEST(lagi_time, extra_garbage_is_ignored) {
EXPECT_STREQ("1:23:45.67", Time("1a:b2c3d:e4f5g.!6&7").GetAssFormatted().c_str());
}
TEST(lagi_time, component_getters) {
Time t("1:23:45.67");
EXPECT_EQ(1, t.GetTimeHours());