feat(palette): implement centralized PaletteManager for improved color management
- Introduced PaletteManager to handle all palette-related operations, including color modifications, undo/redo functionality, and batch processing. - Updated PaletteEditor and PaletteGroupCard to utilize PaletteManager for managing palette states and modifications, streamlining the editing process. - Enhanced user interface with confirmation popups for discard actions and error notifications for save failures. Benefits: - Centralizes palette management, improving consistency and reducing code duplication across editors. - Enhances user experience by providing clear feedback on unsaved changes and simplifying color operations.
This commit is contained in:
@@ -74,6 +74,7 @@ if(YAZE_BUILD_TESTS)
|
||||
unit/gfx/snes_tile_test.cc
|
||||
unit/gfx/compression_test.cc
|
||||
unit/gfx/snes_palette_test.cc
|
||||
unit/snes_color_test.cc
|
||||
unit/gui/tile_selector_widget_test.cc
|
||||
unit/gui/canvas_automation_api_test.cc
|
||||
unit/zelda3/overworld_test.cc
|
||||
@@ -98,6 +99,7 @@ if(YAZE_BUILD_TESTS)
|
||||
integration/zelda3/dungeon_room_test.cc
|
||||
integration/zelda3/sprite_position_test.cc
|
||||
integration/zelda3/message_test.cc
|
||||
integration/palette_manager_test.cc
|
||||
)
|
||||
yaze_add_test_suite(yaze_test_stable "stable" OFF ${STABLE_TEST_SOURCES})
|
||||
|
||||
|
||||
360
test/integration/palette_manager_test.cc
Normal file
360
test/integration/palette_manager_test.cc
Normal file
@@ -0,0 +1,360 @@
|
||||
#include "app/gfx/palette_manager.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "app/gfx/snes_color.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/rom.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
namespace {
|
||||
|
||||
// Test fixture for PaletteManager integration tests
|
||||
class PaletteManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// PaletteManager is a singleton, so we need to reset it between tests
|
||||
// Note: In a real scenario, we'd need a way to reset the singleton
|
||||
// For now, we'll work with the existing instance
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Clean up any test state
|
||||
PaletteManager::Get().ClearHistory();
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Initialization Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, InitializationState) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Before initialization, should not be initialized
|
||||
// Note: This might fail if other tests have already initialized it
|
||||
// In production, we'd need a Reset() method for testing
|
||||
|
||||
// After initialization with null ROM, should handle gracefully
|
||||
manager.Initialize(nullptr);
|
||||
EXPECT_FALSE(manager.IsInitialized());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, HasNoUnsavedChangesInitially) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Should have no unsaved changes initially
|
||||
EXPECT_FALSE(manager.HasUnsavedChanges());
|
||||
EXPECT_EQ(manager.GetModifiedColorCount(), 0);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Dirty Tracking Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, TracksModifiedGroups) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Initially, no groups should be modified
|
||||
auto modified_groups = manager.GetModifiedGroups();
|
||||
EXPECT_TRUE(modified_groups.empty());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, GetModifiedColorCount) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Initially, no colors modified
|
||||
EXPECT_EQ(manager.GetModifiedColorCount(), 0);
|
||||
|
||||
// After initialization and making changes, count should increase
|
||||
// (This would require a valid ROM to test properly)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Undo/Redo Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, UndoRedoInitialState) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Initially, should not be able to undo or redo
|
||||
EXPECT_FALSE(manager.CanUndo());
|
||||
EXPECT_FALSE(manager.CanRedo());
|
||||
EXPECT_EQ(manager.GetUndoStackSize(), 0);
|
||||
EXPECT_EQ(manager.GetRedoStackSize(), 0);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, ClearHistoryResetsStacks) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Clear history should reset both stacks
|
||||
manager.ClearHistory();
|
||||
|
||||
EXPECT_FALSE(manager.CanUndo());
|
||||
EXPECT_FALSE(manager.CanRedo());
|
||||
EXPECT_EQ(manager.GetUndoStackSize(), 0);
|
||||
EXPECT_EQ(manager.GetRedoStackSize(), 0);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, UndoWithoutChangesIsNoOp) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.CanUndo());
|
||||
|
||||
// Should not crash
|
||||
manager.Undo();
|
||||
|
||||
EXPECT_FALSE(manager.CanUndo());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, RedoWithoutUndoIsNoOp) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.CanRedo());
|
||||
|
||||
// Should not crash
|
||||
manager.Redo();
|
||||
|
||||
EXPECT_FALSE(manager.CanRedo());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Batch Operations Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, BatchModeTracking) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.InBatch());
|
||||
|
||||
manager.BeginBatch();
|
||||
EXPECT_TRUE(manager.InBatch());
|
||||
|
||||
manager.EndBatch();
|
||||
EXPECT_FALSE(manager.InBatch());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, NestedBatchOperations) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.InBatch());
|
||||
|
||||
manager.BeginBatch();
|
||||
EXPECT_TRUE(manager.InBatch());
|
||||
|
||||
manager.BeginBatch(); // Nested
|
||||
EXPECT_TRUE(manager.InBatch());
|
||||
|
||||
manager.EndBatch();
|
||||
EXPECT_TRUE(manager.InBatch()); // Still in batch (outer)
|
||||
|
||||
manager.EndBatch();
|
||||
EXPECT_FALSE(manager.InBatch()); // Now out of batch
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, EndBatchWithoutBeginIsNoOp) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.InBatch());
|
||||
|
||||
// Should not crash
|
||||
manager.EndBatch();
|
||||
|
||||
EXPECT_FALSE(manager.InBatch());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Change Notification Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, RegisterAndUnregisterListener) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
int callback_count = 0;
|
||||
auto callback = [&callback_count](const PaletteChangeEvent& event) {
|
||||
callback_count++;
|
||||
};
|
||||
|
||||
// Register listener
|
||||
int id = manager.RegisterChangeListener(callback);
|
||||
EXPECT_GT(id, 0);
|
||||
|
||||
// Unregister listener
|
||||
manager.UnregisterChangeListener(id);
|
||||
|
||||
// After unregistering, callback should not be called
|
||||
// (Would need to trigger an event to test this properly)
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, MultipleListeners) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
int callback1_count = 0;
|
||||
int callback2_count = 0;
|
||||
|
||||
auto callback1 = [&callback1_count](const PaletteChangeEvent& event) {
|
||||
callback1_count++;
|
||||
};
|
||||
|
||||
auto callback2 = [&callback2_count](const PaletteChangeEvent& event) {
|
||||
callback2_count++;
|
||||
};
|
||||
|
||||
int id1 = manager.RegisterChangeListener(callback1);
|
||||
int id2 = manager.RegisterChangeListener(callback2);
|
||||
|
||||
EXPECT_NE(id1, id2);
|
||||
|
||||
// Clean up
|
||||
manager.UnregisterChangeListener(id1);
|
||||
manager.UnregisterChangeListener(id2);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Color Query Tests (without ROM)
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, GetColorWithoutInitialization) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Getting color without initialization should return default color
|
||||
SnesColor color = manager.GetColor("ow_main", 0, 0);
|
||||
|
||||
// Default SnesColor should have zero values
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, SetColorWithoutInitializationFails) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
SnesColor new_color(0x7FFF);
|
||||
auto status = manager.SetColor("ow_main", 0, 0, new_color);
|
||||
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(status.code(), absl::StatusCode::kFailedPrecondition);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, ResetColorWithoutInitializationReturnsError) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
auto status = manager.ResetColor("ow_main", 0, 0);
|
||||
|
||||
// Should return an error or default color
|
||||
// Exact behavior depends on implementation
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, ResetPaletteWithoutInitializationFails) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
auto status = manager.ResetPalette("ow_main", 0);
|
||||
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(status.code(), absl::StatusCode::kFailedPrecondition);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Save/Discard Tests (without ROM)
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, SaveGroupWithoutInitializationFails) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
auto status = manager.SaveGroup("ow_main");
|
||||
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(status.code(), absl::StatusCode::kFailedPrecondition);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, SaveAllWithoutInitializationFails) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
auto status = manager.SaveAllToRom();
|
||||
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(status.code(), absl::StatusCode::kFailedPrecondition);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, DiscardGroupWithoutInitializationIsNoOp) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Should not crash
|
||||
manager.DiscardGroup("ow_main");
|
||||
|
||||
// No unsaved changes
|
||||
EXPECT_FALSE(manager.HasUnsavedChanges());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, DiscardAllWithoutInitializationIsNoOp) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
// Should not crash
|
||||
manager.DiscardAllChanges();
|
||||
|
||||
// No unsaved changes
|
||||
EXPECT_FALSE(manager.HasUnsavedChanges());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Group Modification Query Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, IsGroupModifiedInitiallyFalse) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.IsGroupModified("ow_main"));
|
||||
EXPECT_FALSE(manager.IsGroupModified("dungeon_main"));
|
||||
EXPECT_FALSE(manager.IsGroupModified("global_sprites"));
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, IsPaletteModifiedInitiallyFalse) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.IsPaletteModified("ow_main", 0));
|
||||
EXPECT_FALSE(manager.IsPaletteModified("ow_main", 5));
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, IsColorModifiedInitiallyFalse) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.IsColorModified("ow_main", 0, 0));
|
||||
EXPECT_FALSE(manager.IsColorModified("ow_main", 0, 7));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Invalid Input Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(PaletteManagerTest, SetColorInvalidGroupName) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
SnesColor color(0x7FFF);
|
||||
auto status = manager.SetColor("invalid_group", 0, 0, color);
|
||||
|
||||
EXPECT_FALSE(status.ok());
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, GetColorInvalidGroupName) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
SnesColor color = manager.GetColor("invalid_group", 0, 0);
|
||||
|
||||
// Should return default color
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(PaletteManagerTest, IsGroupModifiedInvalidGroupName) {
|
||||
auto& manager = PaletteManager::Get();
|
||||
|
||||
EXPECT_FALSE(manager.IsGroupModified("invalid_group"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace gfx
|
||||
} // namespace yaze
|
||||
258
test/unit/snes_color_test.cc
Normal file
258
test/unit/snes_color_test.cc
Normal file
@@ -0,0 +1,258 @@
|
||||
#include "app/gfx/snes_color.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
namespace {
|
||||
|
||||
// Test fixture for SnesColor tests
|
||||
class SnesColorTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Common setup if needed
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// RGB Format Conversion Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, SetRgbFromImGuiNormalizedValues) {
|
||||
SnesColor color;
|
||||
|
||||
// ImGui ColorPicker returns values in 0-1 range
|
||||
ImVec4 imgui_color(0.5f, 0.75f, 1.0f, 1.0f);
|
||||
color.set_rgb(imgui_color);
|
||||
|
||||
// Internal storage should be in 0-255 range
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 127.5f); // 0.5 * 255
|
||||
EXPECT_FLOAT_EQ(rgb.y, 191.25f); // 0.75 * 255
|
||||
EXPECT_FLOAT_EQ(rgb.z, 255.0f); // 1.0 * 255
|
||||
EXPECT_FLOAT_EQ(rgb.w, 255.0f); // Alpha always 255
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, SetRgbBlackColor) {
|
||||
SnesColor color;
|
||||
|
||||
ImVec4 black(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
color.set_rgb(black);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.w, 255.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, SetRgbWhiteColor) {
|
||||
SnesColor color;
|
||||
|
||||
ImVec4 white(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
color.set_rgb(white);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 255.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 255.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 255.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.w, 255.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, SetRgbMidRangeColor) {
|
||||
SnesColor color;
|
||||
|
||||
// Test a mid-range color (medium gray)
|
||||
ImVec4 gray(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
color.set_rgb(gray);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_NEAR(rgb.x, 127.5f, 0.01f);
|
||||
EXPECT_NEAR(rgb.y, 127.5f, 0.01f);
|
||||
EXPECT_NEAR(rgb.z, 127.5f, 0.01f);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Constructor Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, ConstructFromImVec4) {
|
||||
// ImGui color in 0-1 range
|
||||
ImVec4 imgui_color(0.25f, 0.5f, 0.75f, 1.0f);
|
||||
|
||||
SnesColor color(imgui_color);
|
||||
|
||||
// Should be converted to 0-255 range
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_NEAR(rgb.x, 63.75f, 0.01f); // 0.25 * 255
|
||||
EXPECT_NEAR(rgb.y, 127.5f, 0.01f); // 0.5 * 255
|
||||
EXPECT_NEAR(rgb.z, 191.25f, 0.01f); // 0.75 * 255
|
||||
EXPECT_FLOAT_EQ(rgb.w, 255.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, ConstructFromSnesValue) {
|
||||
// SNES BGR555 format: 0x7FFF = white (all bits set in 15-bit color)
|
||||
SnesColor white(0x7FFF);
|
||||
|
||||
auto rgb = white.rgb();
|
||||
// All channels should be max (after BGR555 conversion)
|
||||
EXPECT_GT(rgb.x, 240.0f); // Close to 255
|
||||
EXPECT_GT(rgb.y, 240.0f);
|
||||
EXPECT_GT(rgb.z, 240.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, ConstructFromSnesBlack) {
|
||||
// SNES BGR555 format: 0x0000 = black
|
||||
SnesColor black(0x0000);
|
||||
|
||||
auto rgb = black.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 0.0f);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SNES Format Conversion Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, SetSnesUpdatesRgb) {
|
||||
SnesColor color;
|
||||
|
||||
// Set a SNES color value
|
||||
color.set_snes(0x7FFF); // White in BGR555
|
||||
|
||||
// RGB should be updated
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_GT(rgb.x, 240.0f);
|
||||
EXPECT_GT(rgb.y, 240.0f);
|
||||
EXPECT_GT(rgb.z, 240.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, RgbToSnesConversion) {
|
||||
SnesColor color;
|
||||
|
||||
// Set pure red in RGB (0-1 range for ImGui)
|
||||
ImVec4 red(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
color.set_rgb(red);
|
||||
|
||||
// SNES value should be set (BGR555 format)
|
||||
uint16_t snes = color.snes();
|
||||
EXPECT_NE(snes, 0x0000); // Should not be black
|
||||
|
||||
// Extract red component from BGR555 (bits 0-4)
|
||||
uint16_t snes_red = snes & 0x1F;
|
||||
EXPECT_EQ(snes_red, 0x1F); // Max red in 5-bit
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Round-Trip Conversion Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, RoundTripImGuiToSnesColor) {
|
||||
// Start with ImGui color
|
||||
ImVec4 original(0.6f, 0.4f, 0.8f, 1.0f);
|
||||
|
||||
// Convert to SnesColor
|
||||
SnesColor color(original);
|
||||
|
||||
// Convert back to ImVec4 (normalized)
|
||||
auto rgb = color.rgb();
|
||||
ImVec4 converted(rgb.x / 255.0f, rgb.y / 255.0f, rgb.z / 255.0f, 1.0f);
|
||||
|
||||
// Should be approximately equal (within floating point precision)
|
||||
EXPECT_NEAR(converted.x, original.x, 0.01f);
|
||||
EXPECT_NEAR(converted.y, original.y, 0.01f);
|
||||
EXPECT_NEAR(converted.z, original.z, 0.01f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, MultipleSetRgbCalls) {
|
||||
SnesColor color;
|
||||
|
||||
// First color
|
||||
ImVec4 color1(0.2f, 0.4f, 0.6f, 1.0f);
|
||||
color.set_rgb(color1);
|
||||
|
||||
auto rgb1 = color.rgb();
|
||||
EXPECT_NEAR(rgb1.x, 51.0f, 1.0f);
|
||||
EXPECT_NEAR(rgb1.y, 102.0f, 1.0f);
|
||||
EXPECT_NEAR(rgb1.z, 153.0f, 1.0f);
|
||||
|
||||
// Second color (should completely replace)
|
||||
ImVec4 color2(0.8f, 0.6f, 0.4f, 1.0f);
|
||||
color.set_rgb(color2);
|
||||
|
||||
auto rgb2 = color.rgb();
|
||||
EXPECT_NEAR(rgb2.x, 204.0f, 1.0f);
|
||||
EXPECT_NEAR(rgb2.y, 153.0f, 1.0f);
|
||||
EXPECT_NEAR(rgb2.z, 102.0f, 1.0f);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Edge Case Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, HandlesMaxValues) {
|
||||
SnesColor color;
|
||||
|
||||
ImVec4 max(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
color.set_rgb(max);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 255.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 255.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 255.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, HandlesMinValues) {
|
||||
SnesColor color;
|
||||
|
||||
ImVec4 min(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
color.set_rgb(min);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(rgb.z, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, AlphaAlwaysMaximum) {
|
||||
SnesColor color;
|
||||
|
||||
// Try setting alpha to different values (should always be ignored)
|
||||
ImVec4 color_with_alpha(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
color.set_rgb(color_with_alpha);
|
||||
|
||||
auto rgb = color.rgb();
|
||||
EXPECT_FLOAT_EQ(rgb.w, 255.0f); // Alpha should always be 255
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Modified Flag Tests
|
||||
// ============================================================================
|
||||
|
||||
TEST_F(SnesColorTest, ModifiedFlagSetOnRgbChange) {
|
||||
SnesColor color;
|
||||
|
||||
EXPECT_FALSE(color.is_modified());
|
||||
|
||||
ImVec4 new_color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
color.set_rgb(new_color);
|
||||
|
||||
EXPECT_TRUE(color.is_modified());
|
||||
}
|
||||
|
||||
TEST_F(SnesColorTest, ModifiedFlagSetOnSnesChange) {
|
||||
SnesColor color;
|
||||
|
||||
EXPECT_FALSE(color.is_modified());
|
||||
|
||||
color.set_snes(0x7FFF);
|
||||
|
||||
EXPECT_TRUE(color.is_modified());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace gfx
|
||||
} // namespace yaze
|
||||
Reference in New Issue
Block a user