backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)

This commit is contained in:
scawful
2025-12-22 00:20:49 +00:00
parent 2934c82b75
commit 5c4cd57ff8
1259 changed files with 239160 additions and 43801 deletions

View File

@@ -0,0 +1,284 @@
// sdl3_audio_backend_test.cc - Unit tests for SDL3 audio backend
// Tests the SDL3 audio backend implementation without requiring SDL3 runtime
#include <gtest/gtest.h>
#ifdef YAZE_USE_SDL3
#include <cmath>
#include <vector>
#include "app/emu/audio/sdl3_audio_backend.h"
namespace yaze {
namespace emu {
namespace audio {
namespace {
// Test fixture for SDL3 audio backend tests
class SDL3AudioBackendTest : public ::testing::Test {
protected:
void SetUp() override {
backend_ = std::make_unique<SDL3AudioBackend>();
}
void TearDown() override {
if (backend_ && backend_->IsInitialized()) {
backend_->Shutdown();
}
}
// Generate a simple sine wave for testing
std::vector<int16_t> GenerateSineWave(int sample_rate, float frequency,
float duration_seconds) {
int num_samples = static_cast<int>(sample_rate * duration_seconds);
std::vector<int16_t> samples(num_samples);
for (int i = 0; i < num_samples; ++i) {
float t = static_cast<float>(i) / sample_rate;
float value = std::sin(2.0f * M_PI * frequency * t);
samples[i] = static_cast<int16_t>(value * 32767.0f);
}
return samples;
}
std::unique_ptr<SDL3AudioBackend> backend_;
};
// Test basic initialization and shutdown
TEST_F(SDL3AudioBackendTest, InitializeAndShutdown) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
EXPECT_FALSE(backend_->IsInitialized());
// Note: This test will fail if SDL3 is not available at runtime
// We'll mark it as optional/skippable
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
EXPECT_TRUE(backend_->Initialize(config));
EXPECT_TRUE(backend_->IsInitialized());
EXPECT_EQ(backend_->GetBackendName(), "SDL3");
backend_->Shutdown();
EXPECT_FALSE(backend_->IsInitialized());
}
// Test configuration retrieval
TEST_F(SDL3AudioBackendTest, GetConfiguration) {
AudioConfig config;
config.sample_rate = 44100;
config.channels = 2;
config.buffer_frames = 512;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
AudioConfig retrieved = backend_->GetConfig();
// Note: Actual values might differ from requested
EXPECT_GT(retrieved.sample_rate, 0);
EXPECT_GT(retrieved.channels, 0);
EXPECT_GT(retrieved.buffer_frames, 0);
}
// Test volume control
TEST_F(SDL3AudioBackendTest, VolumeControl) {
EXPECT_EQ(backend_->GetVolume(), 1.0f);
backend_->SetVolume(0.5f);
EXPECT_EQ(backend_->GetVolume(), 0.5f);
backend_->SetVolume(-0.1f); // Should clamp to 0
EXPECT_EQ(backend_->GetVolume(), 0.0f);
backend_->SetVolume(1.5f); // Should clamp to 1
EXPECT_EQ(backend_->GetVolume(), 1.0f);
}
// Test audio queueing (INT16)
TEST_F(SDL3AudioBackendTest, QueueSamplesInt16) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
// Generate test audio
auto samples = GenerateSineWave(48000, 440.0f, 0.1f); // 440Hz for 0.1s
// Queue the samples
EXPECT_TRUE(backend_->QueueSamples(samples.data(), samples.size()));
// Check status
AudioStatus status = backend_->GetStatus();
EXPECT_GT(status.queued_bytes, 0);
}
// Test audio queueing (float)
TEST_F(SDL3AudioBackendTest, QueueSamplesFloat) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::FLOAT32;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
// Generate float samples
std::vector<float> samples(4800); // 0.1 second at 48kHz
for (size_t i = 0; i < samples.size(); ++i) {
float t = static_cast<float>(i) / 48000.0f;
samples[i] = std::sin(2.0f * M_PI * 440.0f * t); // 440Hz sine wave
}
// Queue the samples
EXPECT_TRUE(backend_->QueueSamples(samples.data(), samples.size()));
// Check status
AudioStatus status = backend_->GetStatus();
EXPECT_GT(status.queued_bytes, 0);
}
// Test playback control
TEST_F(SDL3AudioBackendTest, PlaybackControl) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
// Initially should be playing (auto-started)
AudioStatus status = backend_->GetStatus();
EXPECT_TRUE(status.is_playing);
// Test pause
backend_->Pause();
status = backend_->GetStatus();
EXPECT_FALSE(status.is_playing);
// Test resume
backend_->Play();
status = backend_->GetStatus();
EXPECT_TRUE(status.is_playing);
// Test stop (should clear and pause)
backend_->Stop();
status = backend_->GetStatus();
EXPECT_FALSE(status.is_playing);
EXPECT_EQ(status.queued_bytes, 0);
}
// Test clear functionality
TEST_F(SDL3AudioBackendTest, ClearQueue) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
// Queue some samples
auto samples = GenerateSineWave(48000, 440.0f, 0.1f);
ASSERT_TRUE(backend_->QueueSamples(samples.data(), samples.size()));
// Verify samples were queued
AudioStatus status = backend_->GetStatus();
EXPECT_GT(status.queued_bytes, 0);
// Clear the queue
backend_->Clear();
// Verify queue is empty
status = backend_->GetStatus();
EXPECT_EQ(status.queued_bytes, 0);
}
// Test resampling support
TEST_F(SDL3AudioBackendTest, ResamplingSupport) {
EXPECT_TRUE(backend_->SupportsAudioStream());
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
// Enable resampling for 32kHz native rate
backend_->SetAudioStreamResampling(true, 32000, 2);
// Generate samples at native rate
auto samples = GenerateSineWave(32000, 440.0f, 0.1f);
// Queue native rate samples
EXPECT_TRUE(backend_->QueueSamplesNative(samples.data(),
samples.size() / 2, 2, 32000));
}
// Test double initialization
TEST_F(SDL3AudioBackendTest, DoubleInitialization) {
AudioConfig config;
config.sample_rate = 48000;
config.channels = 2;
config.buffer_frames = 1024;
config.format = SampleFormat::INT16;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
GTEST_SKIP() << "SDL3 audio not available, skipping test";
}
ASSERT_TRUE(backend_->Initialize(config));
EXPECT_TRUE(backend_->IsInitialized());
// Second initialization should reinitialize
config.sample_rate = 44100; // Different rate
EXPECT_TRUE(backend_->Initialize(config));
EXPECT_TRUE(backend_->IsInitialized());
AudioConfig retrieved = backend_->GetConfig();
// Should have the new configuration (or device's actual rate)
EXPECT_GT(retrieved.sample_rate, 0);
}
} // namespace
} // namespace audio
} // namespace emu
} // namespace yaze
#endif // YAZE_USE_SDL3

View File

@@ -0,0 +1,60 @@
#ifdef __EMSCRIPTEN__
#include <gtest/gtest.h>
#include "app/platform/wasm/wasm_error_handler.h"
namespace yaze {
namespace platform {
namespace {
// Note: These tests are primarily compile-time checks and basic API validation
// since we can't actually test browser UI interactions in a unit test
TEST(WasmErrorHandlerTest, InitializeDoesNotCrash) {
// Should be safe to call multiple times
WasmErrorHandler::Initialize();
WasmErrorHandler::Initialize();
}
TEST(WasmErrorHandlerTest, ShowErrorAPIWorks) {
WasmErrorHandler::ShowError("Test Error", "This is a test error message");
}
TEST(WasmErrorHandlerTest, ShowWarningAPIWorks) {
WasmErrorHandler::ShowWarning("Test Warning", "This is a test warning");
}
TEST(WasmErrorHandlerTest, ShowInfoAPIWorks) {
WasmErrorHandler::ShowInfo("Test Info", "This is informational");
}
TEST(WasmErrorHandlerTest, ToastAPIWorks) {
WasmErrorHandler::Toast("Test toast", ToastType::kInfo, 1000);
WasmErrorHandler::Toast("Success!", ToastType::kSuccess);
WasmErrorHandler::Toast("Warning", ToastType::kWarning, 2000);
WasmErrorHandler::Toast("Error", ToastType::kError, 500);
}
TEST(WasmErrorHandlerTest, ProgressAPIWorks) {
WasmErrorHandler::ShowProgress("Loading ROM", 0.0f);
WasmErrorHandler::ShowProgress("Loading ROM", 0.5f);
WasmErrorHandler::ShowProgress("Loading ROM", 1.0f);
WasmErrorHandler::HideProgress();
}
TEST(WasmErrorHandlerTest, ConfirmAPIWorks) {
bool callback_called = false;
WasmErrorHandler::Confirm("Are you sure?", [&callback_called](bool result) {
callback_called = true;
// In a real browser environment, this would be called when the user clicks
});
// Note: callback won't actually be called in unit test environment
// This just tests that the API compiles and doesn't crash
}
} // namespace
} // namespace platform
} // namespace yaze
#endif // __EMSCRIPTEN__

View File

@@ -0,0 +1,37 @@
#include <gtest/gtest.h>
#include "app/platform/iwindow.h"
namespace yaze {
namespace platform {
namespace test {
TEST(WindowBackendFactoryTest, DefaultTypeRespectsBuildFlag) {
WindowBackendType default_type = WindowBackendFactory::GetDefaultType();
#ifdef YAZE_USE_SDL3
EXPECT_EQ(default_type, WindowBackendType::SDL3);
EXPECT_TRUE(WindowBackendFactory::IsAvailable(WindowBackendType::SDL3));
EXPECT_FALSE(WindowBackendFactory::IsAvailable(WindowBackendType::SDL2));
#else
EXPECT_EQ(default_type, WindowBackendType::SDL2);
EXPECT_TRUE(WindowBackendFactory::IsAvailable(WindowBackendType::SDL2));
EXPECT_FALSE(WindowBackendFactory::IsAvailable(WindowBackendType::SDL3));
#endif
}
TEST(WindowBackendFactoryTest, CreateAutoReturnsDefault) {
auto backend = WindowBackendFactory::Create(WindowBackendType::Auto);
ASSERT_NE(backend, nullptr);
#ifdef YAZE_USE_SDL3
EXPECT_EQ(backend->GetSDLVersion(), 3);
#else
// SDL2 version check might vary, but shouldn't be 3
// Typically SDL2 returns 2xxx
EXPECT_NE(backend->GetSDLVersion(), 3);
#endif
}
} // namespace test
} // namespace platform
} // namespace yaze