yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_object_rendering_e2e_tests.cc
Go to the documentation of this file.
1
50#define IMGUI_DEFINE_MATH_OPERATORS
51
52#include <gtest/gtest.h>
53
54#include "imgui.h"
55#include "imgui_test_engine/imgui_te_context.h"
56#include "imgui_test_engine/imgui_te_engine.h"
57#include "imgui_test_engine/imgui_te_ui.h"
58
59#include "app/core/controller.h"
60#include "app/core/window.h"
62#include "app/rom.h"
65#include "test_utils.h"
66
67namespace yaze {
68namespace test {
69
75 protected:
76 void SetUp() override {
77 BoundRomTest::SetUp();
78
79 // Initialize test environment
80 rom_ = std::shared_ptr<Rom>(rom(), [](Rom*) {});
81
82 dungeon_editor_ = std::make_unique<editor::DungeonEditorV2>();
83 dungeon_editor_->set_rom(rom_.get());
84 ASSERT_TRUE(dungeon_editor_->Load().ok());
85
86 // Initialize imgui test engine
87 engine_ = ImGuiTestEngine_CreateContext();
88 ImGuiTestEngineIO& test_io = ImGuiTestEngine_GetIO(engine_);
89 test_io.ConfigVerboseLevel = ImGuiTestVerboseLevel_Info;
90 test_io.ConfigVerboseLevelOnError = ImGuiTestVerboseLevel_Debug;
91 test_io.ConfigRunSpeed = ImGuiTestRunSpeed_Fast;
92
93 ImGuiTestEngine_Start(engine_, ImGui::GetCurrentContext());
94
95 // Register all test cases
97 }
98
99 void TearDown() override {
100 if (engine_) {
101 ImGuiTestEngine_Stop(engine_);
102 ImGuiTestEngine_DestroyContext(engine_);
103 engine_ = nullptr;
104 }
105 dungeon_editor_.reset();
106 rom_.reset();
107 BoundRomTest::TearDown();
108 }
109
110 void RegisterAllTests();
111
112 // Test registration helpers
120
121 ImGuiTestEngine* engine_ = nullptr;
122 std::shared_ptr<Rom> rom_;
123 std::unique_ptr<editor::DungeonEditorV2> dungeon_editor_;
124};
125
126// =============================================================================
127// OBJECT BROWSER TESTS
128// =============================================================================
129
139 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "ObjectBrowser_NavigateCategories");
140 test->GuiFunc = [](ImGuiTestContext* ctx) {
141 // Render dungeon editor UI
142 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
143 self->dungeon_editor_->Update();
144 };
145 test->TestFunc = [](ImGuiTestContext* ctx) {
146 // Open dungeon editor window
147 ctx->SetRef("Dungeon Editor");
148
149 // Navigate to object selector
150 ctx->ItemClick("Object Selector##tab");
151 ctx->Yield();
152
153 // Test category tabs
154 const char* categories[] = {
155 "Type1##tab",
156 "Type2##tab",
157 "Type3##tab",
158 "All##tab"
159 };
160
161 for (const char* category : categories) {
162 ctx->ItemClick(category);
163 ctx->Yield();
164
165 // Verify object list is visible and has content
166 ctx->ItemExists("AssetBrowser##child");
167
168 // Try scrolling the list
169 ctx->ItemClick("AssetBrowser##child");
170 ctx->KeyPress(ImGuiKey_DownArrow, 5);
171 ctx->Yield();
172 }
173 };
174 test->UserData = this;
175}
176
186 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectBrowser_SelectObject");
187 test->GuiFunc = [](ImGuiTestContext* ctx) {
188 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
189 self->dungeon_editor_->Update();
190 };
191 test->TestFunc = [](ImGuiTestContext* ctx) {
192 ctx->SetRef("Dungeon Editor");
193
194 // Navigate to object selector
195 ctx->ItemClick("Object Selector##tab");
196 ctx->Yield();
197
198 // Select Type1 category
199 ctx->ItemClick("Type1##tab");
200 ctx->Yield();
201
202 // Click on first object in list (wall object 0x10)
203 ctx->SetRef("AssetBrowser");
204 ctx->ItemClick("Object_0x10");
205 ctx->Yield();
206
207 // Verify object details window appears
208 ctx->SetRef("Object Details");
209 ctx->ItemExists("Object ID: 0x10");
210
211 // Verify preview canvas shows object
212 ctx->SetRef("Dungeon Editor/PreviewCanvas");
213 ctx->ItemExists("**/canvas##child");
214 };
215 test->UserData = self;
216}
217
227 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectBrowser_SearchFilter");
228 test->GuiFunc = [](ImGuiTestContext* ctx) {
229 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
230 self->dungeon_editor_->Update();
231 };
232 test->TestFunc = [](ImGuiTestContext* ctx) {
233 ctx->SetRef("Dungeon Editor/Object Selector");
234
235 // Type in search box
236 ctx->ItemClick("Search##input");
237 ctx->KeyCharsAppend("0x10");
238 ctx->Yield();
239
240 // Verify filtered results
241 ctx->ItemExists("Object_0x10");
242 ctx->ItemVerifyNotExists("Object_0x20");
243
244 // Clear search
245 ctx->ItemClick("Clear##button");
246 ctx->Yield();
247
248 // Verify full list restored
249 ctx->ItemExists("Object_0x10");
250 ctx->ItemExists("Object_0x20");
251 };
252 test->UserData = self;
253}
254
255// =============================================================================
256// OBJECT PLACEMENT TESTS
257// =============================================================================
258
269 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "ObjectPlacement_MouseClick");
270 test->GuiFunc = [](ImGuiTestContext* ctx) {
271 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
272 self->dungeon_editor_->Update();
273 };
274 test->TestFunc = [](ImGuiTestContext* ctx) {
275 ctx->SetRef("Dungeon Editor");
276
277 // Select an object (wall 0x10)
278 ctx->ItemClick("Object Selector##tab");
279 ctx->Yield();
280 ctx->SetRef("AssetBrowser");
281 ctx->ItemClick("Object_0x10");
282 ctx->Yield();
283
284 // Switch to main canvas
285 ctx->SetRef("Dungeon Editor");
286 ctx->ItemClick("Canvas##tab");
287 ctx->Yield();
288
289 // Click on canvas to place object
290 ctx->SetRef("Dungeon Editor/Canvas");
291 // TODO: fix this
292 // ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
293 // ctx->MouseMove(canvas_center);
294 // ctx->Yield();
295
296 // Verify preview is visible
297 // (Actual verification would check rendering)
298
299 ctx->MouseClick();
300 ctx->Yield();
301
302 // Verify object was placed
303 ctx->SetRef("Dungeon Editor");
304 ctx->ItemClick("Room Objects##tab");
305 ctx->Yield();
306
307 // Check object appears in list
308 ctx->ItemExists("Object ID: 0x10");
309 };
310 test->UserData = this;
311}
312
322 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectPlacement_SnapToGrid");
323 test->GuiFunc = [](ImGuiTestContext* ctx) {
324 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
325 self->dungeon_editor_->Update();
326 };
327 test->TestFunc = [](ImGuiTestContext* ctx) {
328 ctx->SetRef("Dungeon Editor");
329
330 // Enable snap to grid
331 ctx->ItemClick("Options##menu");
332 ctx->ItemClick("Snap to Grid##checkbox");
333 ctx->Yield();
334
335 // Select object
336 ctx->ItemClick("Object Selector##tab");
337 ctx->SetRef("AssetBrowser");
338 ctx->ItemClick("Object_0x10");
339 ctx->Yield();
340
341 // Place object at arbitrary position
342 ctx->SetRef("Dungeon Editor/Canvas");
343 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
344 ctx->MouseMove(ImVec2(canvas_pos.x + 37, canvas_pos.y + 49));
345 ctx->MouseClick();
346 ctx->Yield();
347
348 // Verify object was placed at snapped position (32, 48)
349 ctx->SetRef("Dungeon Editor/Object Details");
350 ctx->ItemVerifyValue("X Position", 32);
351 ctx->ItemVerifyValue("Y Position", 48);
352 };
353 test->UserData = self;
354}
355
365 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectPlacement_MultipleObjects");
366 test->GuiFunc = [](ImGuiTestContext* ctx) {
367 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
368 self->dungeon_editor_->Update();
369 };
370 test->TestFunc = [](ImGuiTestContext* ctx) {
371 ctx->SetRef("Dungeon Editor");
372
373 // Place 5 different objects
374 const uint16_t object_ids[] = {0x10, 0x11, 0x20, 0x100, 0xF99};
375
376 for (int i = 0; i < 5; i++) {
377 // Select object
378 ctx->ItemClick("Object Selector##tab");
379 ctx->SetRef("AssetBrowser");
380 ctx->ItemClick(ImGuiTestRef_Str("Object_0x%02X", object_ids[i]));
381 ctx->Yield();
382
383 // Place at different position
384 ctx->SetRef("Dungeon Editor/Canvas");
385 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
386 ctx->MouseMove(ImVec2(canvas_pos.x + (i * 32), canvas_pos.y + (i * 32)));
387 ctx->MouseClick();
388 ctx->Yield();
389 }
390
391 // Verify all 5 objects in room
392 ctx->SetRef("Dungeon Editor/Room Objects");
393 ctx->ItemExists("Object Count: 5");
394 };
395 test->UserData = self;
396}
397
398// =============================================================================
399// OBJECT SELECTION AND MANIPULATION TESTS
400// =============================================================================
401
411 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "ObjectSelection_Click");
412 test->GuiFunc = [](ImGuiTestContext* ctx) {
413 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
414 self->dungeon_editor_->Update();
415 };
416 test->TestFunc = [](ImGuiTestContext* ctx) {
417 // First place an object
418 ctx->SetRef("Dungeon Editor");
419 ctx->ItemClick("Object Selector##tab");
420 ctx->SetRef("AssetBrowser");
421 ctx->ItemClick("Object_0x10");
422 ctx->Yield();
423
424 ctx->SetRef("Dungeon Editor/Canvas");
425 ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
426 ctx->MouseMove(canvas_center);
427 ctx->MouseClick();
428 ctx->Yield();
429
430 // Now try to select it
431 ctx->MouseMove(canvas_center);
432 ctx->MouseClick();
433 ctx->Yield();
434
435 // Verify object is selected
436 ctx->SetRef("Dungeon Editor/Object Details");
437 ctx->ItemExists("Selected Object");
438 ctx->ItemVerifyValue("Object ID", 0x10);
439 };
440 test->UserData = this;
441}
442
452 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectSelection_MultiSelect");
453 test->GuiFunc = [](ImGuiTestContext* ctx) {
454 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
455 self->dungeon_editor_->Update();
456 };
457 test->TestFunc = [](ImGuiTestContext* ctx) {
458 // Place 3 objects in a line
459 ctx->SetRef("Dungeon Editor");
460 for (int i = 0; i < 3; i++) {
461 ctx->ItemClick("Object Selector##tab");
462 ctx->SetRef("AssetBrowser");
463 ctx->ItemClick("Object_0x10");
464 ctx->Yield();
465
466 ctx->SetRef("Dungeon Editor/Canvas");
467 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
468 ctx->MouseMove(ImVec2(canvas_pos.x + (i * 32) + 16, canvas_pos.y + 16));
469 ctx->MouseClick();
470 ctx->Yield();
471 }
472
473 // Ctrl+drag to select all
474 ctx->KeyDown(ImGuiKey_LeftCtrl);
475 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
476 ctx->MouseMove(ImVec2(canvas_pos.x, canvas_pos.y));
477 ctx->MouseDown();
478 ctx->MouseMove(ImVec2(canvas_pos.x + 100, canvas_pos.y + 50));
479 ctx->MouseUp();
480 ctx->KeyUp(ImGuiKey_LeftCtrl);
481 ctx->Yield();
482
483 // Verify 3 objects selected
484 ctx->SetRef("Dungeon Editor");
485 ctx->ItemVerifyValue("Selected Objects", 3);
486 };
487 test->UserData = self;
488}
489
499 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectSelection_MoveObject");
500 test->GuiFunc = [](ImGuiTestContext* ctx) {
501 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
502 self->dungeon_editor_->Update();
503 };
504 test->TestFunc = [](ImGuiTestContext* ctx) {
505 // Place object at (16, 16)
506 ctx->SetRef("Dungeon Editor");
507 ctx->ItemClick("Object Selector##tab");
508 ctx->SetRef("AssetBrowser");
509 ctx->ItemClick("Object_0x10");
510 ctx->Yield();
511
512 ctx->SetRef("Dungeon Editor/Canvas");
513 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
514 ImVec2 initial_pos = ImVec2(canvas_pos.x + 16, canvas_pos.y + 16);
515 ctx->MouseMove(initial_pos);
516 ctx->MouseClick();
517 ctx->Yield();
518
519 // Select and drag to (48, 48)
520 ctx->MouseMove(initial_pos);
521 ctx->MouseClick();
522 ctx->MouseDown();
523 ctx->MouseMove(ImVec2(canvas_pos.x + 48, canvas_pos.y + 48));
524 ctx->MouseUp();
525 ctx->Yield();
526
527 // Verify new position
528 ctx->SetRef("Dungeon Editor/Object Details");
529 ctx->ItemVerifyValue("X Position", 48);
530 ctx->ItemVerifyValue("Y Position", 48);
531 };
532 test->UserData = self;
533}
534
544 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "ObjectSelection_DeleteObject");
545 test->GuiFunc = [](ImGuiTestContext* ctx) {
546 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
547 self->dungeon_editor_->Update();
548 };
549 test->TestFunc = [](ImGuiTestContext* ctx) {
550 // Place object
551 ctx->SetRef("Dungeon Editor");
552 ctx->ItemClick("Object Selector##tab");
553 ctx->SetRef("AssetBrowser");
554 ctx->ItemClick("Object_0x10");
555 ctx->Yield();
556
557 ctx->SetRef("Dungeon Editor/Canvas");
558 ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
559 ctx->MouseMove(canvas_center);
560 ctx->MouseClick();
561 ctx->Yield();
562
563 // Select object
564 ctx->MouseClick();
565 ctx->Yield();
566
567 // Delete with Delete key
568 ctx->KeyPress(ImGuiKey_Delete);
569 ctx->Yield();
570
571 // Verify object removed
572 ctx->SetRef("Dungeon Editor/Room Objects");
573 ctx->ItemVerifyValue("Object Count", 0);
574 };
575 test->UserData = self;
576}
577
578// =============================================================================
579// LAYER MANAGEMENT TESTS
580// =============================================================================
581
591 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "LayerManagement_ToggleVisibility");
592 test->GuiFunc = [](ImGuiTestContext* ctx) {
593 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
594 self->dungeon_editor_->Update();
595 };
596 test->TestFunc = [](ImGuiTestContext* ctx) {
597 ctx->SetRef("Dungeon Editor");
598
599 // Open layer management panel
600 ctx->ItemClick("Layers##tab");
601 ctx->Yield();
602
603 // Toggle Layer 1 visibility
604 ctx->ItemClick("Layer 1 Visible##checkbox");
605 ctx->Yield();
606
607 // Verify checkbox state
608 ctx->ItemVerifyValue("Layer 1 Visible##checkbox", false);
609
610 // Toggle back on
611 ctx->ItemClick("Layer 1 Visible##checkbox");
612 ctx->Yield();
613
614 ctx->ItemVerifyValue("Layer 1 Visible##checkbox", true);
615 };
616 test->UserData = this;
617}
618
628 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "LayerManagement_PlaceOnLayers");
629 test->GuiFunc = [](ImGuiTestContext* ctx) {
630 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
631 self->dungeon_editor_->Update();
632 };
633 test->TestFunc = [](ImGuiTestContext* ctx) {
634 ctx->SetRef("Dungeon Editor");
635
636 // Place object on Layer 0
637 ctx->ItemClick("Layers##tab");
638 ctx->ItemClick("Layer 0##radio");
639 ctx->Yield();
640
641 ctx->ItemClick("Object Selector##tab");
642 ctx->SetRef("AssetBrowser");
643 ctx->ItemClick("Object_0x10");
644 ctx->Yield();
645
646 ctx->SetRef("Dungeon Editor/Canvas");
647 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
648 ctx->MouseMove(ImVec2(canvas_pos.x + 16, canvas_pos.y + 16));
649 ctx->MouseClick();
650 ctx->Yield();
651
652 // Verify object on Layer 0
653 ctx->SetRef("Dungeon Editor/Object Details");
654 ctx->ItemVerifyValue("Layer", 0);
655
656 // Switch to Layer 1 and place another object
657 ctx->SetRef("Dungeon Editor");
658 ctx->ItemClick("Layers##tab");
659 ctx->ItemClick("Layer 1##radio");
660 ctx->Yield();
661
662 ctx->ItemClick("Object Selector##tab");
663 ctx->SetRef("AssetBrowser");
664 ctx->ItemClick("Object_0x20");
665 ctx->Yield();
666
667 ctx->SetRef("Dungeon Editor/Canvas");
668 ctx->MouseMove(ImVec2(canvas_pos.x + 48, canvas_pos.y + 48));
669 ctx->MouseClick();
670 ctx->Yield();
671
672 // Verify object on Layer 1
673 ctx->SetRef("Dungeon Editor/Object Details");
674 ctx->ItemVerifyValue("Layer", 1);
675 };
676 test->UserData = self;
677}
678
688 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "LayerManagement_RenderingOrder");
689 test->GuiFunc = [](ImGuiTestContext* ctx) {
690 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
691 self->dungeon_editor_->Update();
692 };
693 test->TestFunc = [](ImGuiTestContext* ctx) {
694 // Place 3 objects at same position on different layers
695 ctx->SetRef("Dungeon Editor");
696
697 for (int layer = 0; layer < 3; layer++) {
698 ctx->ItemClick("Layers##tab");
699 ctx->ItemClick(ImGuiTestRef_Str("Layer %d##radio", layer));
700 ctx->Yield();
701
702 ctx->ItemClick("Object Selector##tab");
703 ctx->SetRef("AssetBrowser");
704 ctx->ItemClick(ImGuiTestRef_Str("Object_0x%02X", 0x10 + layer));
705 ctx->Yield();
706
707 ctx->SetRef("Dungeon Editor/Canvas");
708 ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
709 ctx->MouseMove(canvas_center);
710 ctx->MouseClick();
711 ctx->Yield();
712 }
713
714 // Verify all 3 objects exist
715 ctx->SetRef("Dungeon Editor/Room Objects");
716 ctx->ItemVerifyValue("Object Count", 3);
717
718 // Visual verification would be done with snapshot comparison
719 // Here we just verify the objects are in the right layers
720 ctx->ItemExists("Layer 0: 1 object");
721 ctx->ItemExists("Layer 1: 1 object");
722 ctx->ItemExists("Layer 2: 1 object");
723 };
724 test->UserData = self;
725}
726
727// =============================================================================
728// SAVE/LOAD WORKFLOW TESTS
729// =============================================================================
730
740 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "SaveWorkflow_SaveRoom");
741 test->GuiFunc = [](ImGuiTestContext* ctx) {
742 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
743 self->dungeon_editor_->Update();
744 };
745 test->TestFunc = [](ImGuiTestContext* ctx) {
746 // Place an object
747 ctx->SetRef("Dungeon Editor");
748 ctx->ItemClick("Object Selector##tab");
749 ctx->SetRef("AssetBrowser");
750 ctx->ItemClick("Object_0x10");
751 ctx->Yield();
752
753 ctx->SetRef("Dungeon Editor/Canvas");
754 ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
755 ctx->MouseMove(canvas_center);
756 ctx->MouseClick();
757 ctx->Yield();
758
759 // Save room
760 ctx->SetRef("Dungeon Editor");
761 ctx->ItemClick("File##menu");
762 ctx->ItemClick("Save Room##menuitem");
763 ctx->Yield();
764
765 // Verify save success message
766 ctx->ItemExists("Save successful");
767 };
768 test->UserData = this;
769}
770
780 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "SaveWorkflow_RoundTrip");
781 test->GuiFunc = [](ImGuiTestContext* ctx) {
782 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
783 self->dungeon_editor_->Update();
784 };
785 test->TestFunc = [](ImGuiTestContext* ctx) {
786 // Place object with specific properties
787 ctx->SetRef("Dungeon Editor");
788 ctx->ItemClick("Object Selector##tab");
789 ctx->SetRef("AssetBrowser");
790 ctx->ItemClick("Object_0x10");
791 ctx->Yield();
792
793 ctx->SetRef("Dungeon Editor/Canvas");
794 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
795 ctx->MouseMove(ImVec2(canvas_pos.x + 64, canvas_pos.y + 96));
796 ctx->MouseClick();
797 ctx->Yield();
798
799 // Verify initial state
800 ctx->SetRef("Dungeon Editor/Object Details");
801 int initial_x = ctx->ItemGetValue<int>("X Position");
802 int initial_y = ctx->ItemGetValue<int>("Y Position");
803 int initial_id = ctx->ItemGetValue<int>("Object ID");
804
805 // Save room
806 ctx->SetRef("Dungeon Editor");
807 ctx->ItemClick("File##menu");
808 ctx->ItemClick("Save Room##menuitem");
809 ctx->Yield();
810
811 // Reload room
812 ctx->ItemClick("File##menu");
813 ctx->ItemClick("Reload Room##menuitem");
814 ctx->Yield();
815
816 // Verify object persisted with same properties
817 ctx->SetRef("Dungeon Editor/Object Details");
818 ctx->ItemVerifyValue("X Position", initial_x);
819 ctx->ItemVerifyValue("Y Position", initial_y);
820 ctx->ItemVerifyValue("Object ID", initial_id);
821 };
822 test->UserData = self;
823}
824
834 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "SaveWorkflow_MultipleTypes");
835 test->GuiFunc = [](ImGuiTestContext* ctx) {
836 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
837 self->dungeon_editor_->Update();
838 };
839 test->TestFunc = [](ImGuiTestContext* ctx) {
840 // Place one of each object type
841 const uint16_t object_ids[] = {
842 0x10, // Type1
843 0x125, // Type2
844 0xF99 // Type3 (chest)
845 };
846
847 ctx->SetRef("Dungeon Editor");
848
849 for (int i = 0; i < 3; i++) {
850 ctx->ItemClick("Object Selector##tab");
851 ctx->SetRef("AssetBrowser");
852 ctx->ItemClick(ImGuiTestRef_Str("Object_0x%02X", object_ids[i]));
853 ctx->Yield();
854
855 ctx->SetRef("Dungeon Editor/Canvas");
856 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
857 ctx->MouseMove(ImVec2(canvas_pos.x + (i * 32), canvas_pos.y + (i * 32)));
858 ctx->MouseClick();
859 ctx->Yield();
860 }
861
862 // Save and reload
863 ctx->SetRef("Dungeon Editor");
864 ctx->ItemClick("File##menu");
865 ctx->ItemClick("Save Room##menuitem");
866 ctx->Yield();
867
868 ctx->ItemClick("File##menu");
869 ctx->ItemClick("Reload Room##menuitem");
870 ctx->Yield();
871
872 // Verify all 3 objects reloaded
873 ctx->SetRef("Dungeon Editor/Room Objects");
874 ctx->ItemVerifyValue("Object Count", 3);
875
876 // Verify each object type
877 for (int i = 0; i < 3; i++) {
878 ctx->ItemExists(ImGuiTestRef_Str("Object ID: 0x%02X", object_ids[i]));
879 }
880 };
881 test->UserData = self;
882}
883
884// =============================================================================
885// RENDERING QUALITY TESTS
886// =============================================================================
887
898 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "RenderingQuality_AllTypes");
899 test->GuiFunc = [](ImGuiTestContext* ctx) {
900 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
901 self->dungeon_editor_->Update();
902 };
903 test->TestFunc = [](ImGuiTestContext* ctx) {
904 // This would typically involve visual snapshot comparison
905 // For now, we verify objects are placed and rendered without errors
906
907 const uint16_t object_ids[] = {
908 0x10, 0x11, 0x20, // Type1 objects
909 0x100, 0x125, // Type2 objects
910 0xF99, 0xFB1 // Type3 objects
911 };
912
913 ctx->SetRef("Dungeon Editor");
914
915 for (int i = 0; i < 7; i++) {
916 ctx->ItemClick("Object Selector##tab");
917 ctx->SetRef("AssetBrowser");
918 ctx->ItemClick(ImGuiTestRef_Str("Object_0x%02X", object_ids[i]));
919 ctx->Yield();
920
921 ctx->SetRef("Dungeon Editor/Canvas");
922 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
923 ctx->MouseMove(ImVec2(canvas_pos.x + ((i % 4) * 48), canvas_pos.y + ((i / 4) * 48)));
924 ctx->MouseClick();
925 ctx->Yield();
926 }
927
928 // Verify all objects rendered without errors
929 ctx->SetRef("Dungeon Editor/Room Objects");
930 ctx->ItemVerifyValue("Object Count", 7);
931 ctx->ItemVerifyNotExists("Rendering Error");
932 };
933 test->UserData = this;
934}
935
945 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "RenderingQuality_Palettes");
946 test->GuiFunc = [](ImGuiTestContext* ctx) {
947 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
948 self->dungeon_editor_->Update();
949 };
950 test->TestFunc = [](ImGuiTestContext* ctx) {
951 // Place an object
952 ctx->SetRef("Dungeon Editor");
953 ctx->ItemClick("Object Selector##tab");
954 ctx->SetRef("AssetBrowser");
955 ctx->ItemClick("Object_0x10");
956 ctx->Yield();
957
958 ctx->SetRef("Dungeon Editor/Canvas");
959 ImVec2 canvas_center = ctx->ItemRectCenter("canvas##child");
960 ctx->MouseMove(canvas_center);
961 ctx->MouseClick();
962 ctx->Yield();
963
964 // Switch palettes and verify rendering
965 const int palette_ids[] = {0, 1, 2, 3, 4, 5};
966
967 for (int palette : palette_ids) {
968 ctx->SetRef("Dungeon Editor");
969 ctx->ItemClick("Options##menu");
970 ctx->ItemInput("Palette##input", palette);
971 ctx->Yield();
972
973 // Verify no rendering errors
974 ctx->ItemVerifyNotExists("Rendering Error");
975 }
976 };
977 test->UserData = self;
978}
979
989 ImGuiTest* test = IM_REGISTER_TEST(self->engine_, "DungeonObjectRendering", "RenderingQuality_ComplexRoom");
990 test->GuiFunc = [](ImGuiTestContext* ctx) {
991 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
992 self->dungeon_editor_->Update();
993 };
994 test->TestFunc = [](ImGuiTestContext* ctx) {
995 // Place many objects to create complex room
996 ctx->SetRef("Dungeon Editor");
997
998 // Place wall perimeter (Type1 objects)
999 for (int x = 0; x < 16; x++) {
1000 for (int side = 0; side < 2; side++) {
1001 ctx->ItemClick("Object Selector##tab");
1002 ctx->SetRef("AssetBrowser");
1003 ctx->ItemClick("Object_0x10");
1004 ctx->Yield();
1005
1006 ctx->SetRef("Dungeon Editor/Canvas");
1007 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
1008 int y = side == 0 ? 0 : 10;
1009 ctx->MouseMove(ImVec2(canvas_pos.x + (x * 16), canvas_pos.y + (y * 16)));
1010 ctx->MouseClick();
1011 ctx->Yield();
1012 }
1013 }
1014
1015 // Add some decorative objects
1016 const uint16_t decorative_objects[] = {0x20, 0x21, 0xF99};
1017 for (int i = 0; i < 3; i++) {
1018 ctx->ItemClick("Object Selector##tab");
1019 ctx->SetRef("AssetBrowser");
1020 ctx->ItemClick(ImGuiTestRef_Str("Object_0x%02X", decorative_objects[i]));
1021 ctx->Yield();
1022
1023 ctx->SetRef("Dungeon Editor/Canvas");
1024 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
1025 ctx->MouseMove(ImVec2(canvas_pos.x + (i * 64) + 32, canvas_pos.y + 80));
1026 ctx->MouseClick();
1027 ctx->Yield();
1028 }
1029
1030 // Verify all objects rendered
1031 ctx->SetRef("Dungeon Editor/Room Objects");
1032 ctx->ItemVerifyValue("Object Count", 35); // 32 walls + 3 decorative
1033
1034 // Verify no performance issues (frame time < 16ms for 60fps)
1035 ctx->SetRef("Dungeon Editor");
1036 ctx->ItemVerifyLessThan("Frame Time (ms)", 16.0f);
1037 };
1038 test->UserData = self;
1039}
1040
1041// =============================================================================
1042// PERFORMANCE TESTS
1043// =============================================================================
1044
1054 ImGuiTest* test = IM_REGISTER_TEST(engine_, "DungeonObjectRendering", "Performance_LargeRoom");
1055 test->GuiFunc = [](ImGuiTestContext* ctx) {
1056 auto* self = (DungeonObjectRenderingE2ETests*)ctx->UserData;
1057 self->dungeon_editor_->Update();
1058 };
1059 test->TestFunc = [](ImGuiTestContext* ctx) {
1060 ctx->SetRef("Dungeon Editor");
1061
1062 // Place 100 objects
1063 for (int i = 0; i < 100; i++) {
1064 ctx->ItemClick("Object Selector##tab");
1065 ctx->SetRef("AssetBrowser");
1066 ctx->ItemClick("Object_0x10");
1067 ctx->Yield();
1068
1069 ctx->SetRef("Dungeon Editor/Canvas");
1070 ImVec2 canvas_pos = ctx->ItemRectMin("canvas##child");
1071 ctx->MouseMove(ImVec2(
1072 canvas_pos.x + ((i % 16) * 16),
1073 canvas_pos.y + ((i / 16) * 16)
1074 ));
1075 ctx->MouseClick();
1076 ctx->Yield();
1077 }
1078
1079 // Measure rendering performance
1080 ctx->SetRef("Dungeon Editor");
1081 float frame_time = ctx->ItemGetValue<float>("Frame Time (ms)");
1082
1083 // Verify acceptable performance (< 16ms for 60fps)
1084 IM_CHECK_LT(frame_time, 16.0f);
1085
1086 // Verify object count
1087 ctx->SetRef("Dungeon Editor/Room Objects");
1088 ctx->ItemVerifyValue("Object Count", 100);
1089 };
1090 test->UserData = this;
1091}
1092
1093// =============================================================================
1094// TEST REGISTRATION
1095// =============================================================================
1096
1121
1122// =============================================================================
1123// TEST FIXTURE INTEGRATION
1124// =============================================================================
1125
1127 // Run all registered tests
1128 ImGuiTestEngine_QueueTests(engine_, ImGuiTestGroup_Tests, nullptr, nullptr);
1129 ImGuiTestEngine_Run(engine_);
1130
1131 // Verify all tests passed
1132 ImGuiTestEngineIO& test_io = ImGuiTestEngine_GetIO(engine_);
1133 EXPECT_EQ(test_io.TestsFailedCount, 0)
1134 << "Some E2E tests failed. Check test engine output for details.";
1135}
1136
1137} // namespace test
1138} // namespace yaze
1139
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
Comprehensive E2E test fixture for dungeon object rendering system.
void RegisterRenderingQualityTests()
Test: Render all object types correctly.
void RegisterObjectSelectionTests()
Test: Select object by clicking on canvas.
void RegisterLayerManagementTests()
Test: Toggle layer visibility.
std::unique_ptr< editor::DungeonEditorV2 > dungeon_editor_
void RegisterObjectBrowserTests()
Test: Navigate object browser categories.
void RegisterObjectPlacementTests()
Test: Place object on canvas with mouse click.
void RegisterPerformanceTests()
Test: Large room with many objects performance.
void RegisterRenderingQualityTests_ComplexRoom(DungeonObjectRenderingE2ETests *self)
Test: Complex room scenario rendering.
void RegisterObjectSelectionTests_MultiSelect(DungeonObjectRenderingE2ETests *self)
Test: Multi-select objects with Ctrl+drag.
void RegisterLayerManagementTests_RenderingOrder(DungeonObjectRenderingE2ETests *self)
Test: Layer rendering order.
void RegisterObjectPlacementTests_SnapToGrid(DungeonObjectRenderingE2ETests *self)
Test: Place object with snap to grid.
void RegisterObjectBrowserTests_SelectObject(DungeonObjectRenderingE2ETests *self)
Test: Select object from browser.
void RegisterObjectSelectionTests_MoveObject(DungeonObjectRenderingE2ETests *self)
Test: Move selected object with drag.
void RegisterSaveWorkflowTests_RoundTrip(DungeonObjectRenderingE2ETests *self)
Test: Save and reload room (round-trip)
void RegisterRenderingQualityTests_Palettes(DungeonObjectRenderingE2ETests *self)
Test: Render with different palettes.
void RegisterLayerManagementTests_PlaceOnLayers(DungeonObjectRenderingE2ETests *self)
Test: Place objects on different layers.
void RegisterObjectPlacementTests_MultipleObjects(DungeonObjectRenderingE2ETests *self)
Test: Place multiple objects sequentially.
void RegisterObjectBrowserTests_SearchFilter(DungeonObjectRenderingE2ETests *self)
Test: Search and filter objects.
void RegisterSaveWorkflowTests_MultipleTypes(DungeonObjectRenderingE2ETests *self)
Test: Save with multiple object types.
void RegisterObjectSelectionTests_DeleteObject(DungeonObjectRenderingE2ETests *self)
Test: Delete selected object.
TEST_F(DungeonObjectRenderingE2ETests, RunAllTests)
Main namespace for the application.