comic/odin/tests/phase6_appearance_bubbles.odin
2026-05-22 03:51:50 +02:00

225 lines
7.1 KiB
Odin

package tests
import "core:fmt"
import "core:strings"
import "core:testing"
import "../src/core"
import "../src/adapters"
import "../src/gui"
import "../src/ui"
// ─────────────────────────────────────────────────────────────
// Phase 6: Appearance Count + Streaming + Bubble Editing
// ─────────────────────────────────────────────────────────────
// ── Appearance Count Tests ──
@test
core_count_appearances_basic :: proc(t: ^testing.T) {
script := core.Comic_Script{
title = "Test Comic",
synopsis = "A test comic",
characters = []core.Character{
{id = "hero", name = "Hero", role = .Protagonist},
{id = "villain", name = "Villain", role = .Antagonist},
{id = "sidekick", name = "Sidekick", role = .Supporting},
},
pages = []core.Page{
{
page_number = 1,
panels = []core.Panel{
{panel_id = "p1", characters_present = []string{"hero"}},
{panel_id = "p2", characters_present = []string{"hero", "villain"}},
},
},
{
page_number = 2,
panels = []core.Panel{
{panel_id = "p3", characters_present = []string{"hero", "sidekick"}},
{panel_id = "p4", characters_present = []string{"villain"}},
{panel_id = "p5", characters_present = []string{"hero", "villain", "sidekick"}},
},
},
},
}
core.count_character_appearances(&script)
testing.expect(t, script.characters[0].appearance_count == 4, fmt.tprintf("hero should appear 4 times, got %d", script.characters[0].appearance_count))
testing.expect(t, script.characters[1].appearance_count == 3, fmt.tprintf("villain should appear 3 times, got %d", script.characters[1].appearance_count))
testing.expect(t, script.characters[2].appearance_count == 2, fmt.tprintf("sidekick should appear 2 times, got %d", script.characters[2].appearance_count))
}
@test
core_count_appearances_first_panel :: proc(t: ^testing.T) {
script := core.Comic_Script{
title = "Test",
synopsis = "Test",
characters = []core.Character{
{id = "a", name = "A", role = .Protagonist},
{id = "b", name = "B", role = .Supporting},
},
pages = []core.Page{
{
page_number = 1,
panels = []core.Panel{
{panel_id = "panel_001", characters_present = []string{"a"}},
{panel_id = "panel_002", characters_present = []string{"a", "b"}},
},
},
},
}
core.count_character_appearances(&script)
testing.expect(t, script.characters[0].first_appearance_panel == "panel_001", fmt.tprintf("A first panel should be panel_001, got %q", script.characters[0].first_appearance_panel))
testing.expect(t, script.characters[1].first_appearance_panel == "panel_002", fmt.tprintf("B first panel should be panel_002, got %q", script.characters[1].first_appearance_panel))
}
@test
core_count_appearances_zero :: proc(t: ^testing.T) {
script := core.Comic_Script{
title = "Test",
synopsis = "Test",
characters = []core.Character{
{id = "unused", name = "Unused", role = .Extra},
},
pages = []core.Page{
{
page_number = 1,
panels = []core.Panel{
{panel_id = "p1", characters_present = []string{"other"}},
},
},
},
}
core.count_character_appearances(&script)
testing.expect(t, script.characters[0].appearance_count == 0, "unused character should have 0 appearances")
testing.expect(t, len(script.characters[0].first_appearance_panel) == 0, "unused character should have no first panel")
}
@test
core_count_appearances_empty_script :: proc(t: ^testing.T) {
script := core.Comic_Script{
title = "Empty",
synopsis = "Empty",
characters = []core.Character{},
pages = []core.Page{},
}
core.count_character_appearances(&script)
testing.expect(t, len(script.characters) == 0, "should have no characters")
}
// ── Bubble Text Editing Tests ──
@test
core_update_bubble_text :: proc(t: ^testing.T) {
bubble := core.Speech_Bubble{
id = "bubble_1",
panel_id = "panel_1",
text = "Hello world",
speaker_id = "char_1",
}
updated := core.update_bubble_text(bubble, "New text")
testing.expect(t, updated.text == "New text", fmt.tprintf("text should be updated, got %q", updated.text))
testing.expect(t, updated.id == "bubble_1", "id should be preserved")
testing.expect(t, updated.panel_id == "panel_1", "panel_id should be preserved")
}
@test
gui_action_update_bubble_text :: proc(t: ^testing.T) {
state := core.new_initial_state()
defer core.dispose_state(&state)
controller := ui.new_controller(state)
defer ui.dispose_job_manager(&controller.jobs)
// Add a character and panel with dialogue
char := core.Character{id = "char_1", name = "Hero", role = .Protagonist}
chars: [dynamic]core.Character
append(&chars, char)
controller.state.characters = chars[:]
defer delete(chars)
panel := core.Panel{
panel_id = "panel_1",
panel_number = 1,
dialogue = []core.Dialogue{
{speaker_id = "char_1", text = "Original text", emotion = .Neutral},
},
}
// Generate bubbles for the panel
bubbles := core.auto_place_panel_bubbles(panel, 800, 600)
defer delete(bubbles)
controller.state.speech_bubbles = make(map[string][]core.Speech_Bubble)
controller.state.speech_bubbles["panel_1"] = bubbles
// Update bubble text
if len(bubbles) > 0 {
bubble_id := bubbles[0].id
msg := gui.action_update_bubble_text(&controller, bubble_id, "Updated dialogue")
testing.expect(t, strings.contains(msg, "updated"), fmt.tprintf("should update bubble text, got %q", msg))
}
}
// ── Bubble Position Tests ──
@test
core_bubble_position_update :: proc(t: ^testing.T) {
bubble := core.Speech_Bubble{
id = "b1",
panel_id = "p1",
text = "Test",
position = core.Position{x = 0.1, y = 0.1},
}
updated := core.update_bubble_position(bubble, 0.5, 0.5)
testing.expect(t, updated.position.x == 0.5, "x should be 0.5")
testing.expect(t, updated.position.y == 0.5, "y should be 0.5")
}
@test
core_bubble_reset_position :: proc(t: ^testing.T) {
bubble := core.Speech_Bubble{
id = "b1",
panel_id = "p1",
text = "Test",
position = core.Position{x = 0.9, y = 0.9},
}
reset := core.reset_bubble_position(bubble)
testing.expect(t, reset.position.x == 0.0, "reset x should be 0")
testing.expect(t, reset.position.y == 0.0, "reset y should be 0")
}
// ── Integration: Full Pipeline with Appearance Count ──
@test
core_normalize_and_count_appearances :: proc(t: ^testing.T) {
script := core.Comic_Script{
title = "Test",
synopsis = "Test",
characters = []core.Character{
{id = "hero", name = "Hero", role = .Protagonist},
{id = "villain", name = "Villain", role = .Antagonist},
},
pages = []core.Page{
{
panels = []core.Panel{
{characters_present = []string{"hero"}},
{characters_present = []string{"hero", "villain"}},
{characters_present = []string{"villain"}},
},
},
},
}
normalized := core.normalize_script(script)
core.count_character_appearances(&normalized)
testing.expect(t, normalized.characters[0].appearance_count == 2, "hero should appear twice")
testing.expect(t, normalized.characters[1].appearance_count == 2, "villain should appear twice")
}