225 lines
7.1 KiB
Odin
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")
|
|
}
|