164 lines
5.6 KiB
Java
164 lines
5.6 KiB
Java
package dev.marcospaulo.canalhandia;
|
|
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.io.TempDir;
|
|
|
|
import java.io.File;
|
|
import java.nio.file.Path;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
class PlayerMemoryTest {
|
|
|
|
@TempDir
|
|
Path tempDir;
|
|
|
|
private File file;
|
|
private PlayerMemory memory;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
file = tempDir.resolve("ia-memoria.yml").toFile();
|
|
memory = new PlayerMemory(file);
|
|
}
|
|
|
|
@org.junit.jupiter.api.AfterEach
|
|
void tearDown() {
|
|
if (memory != null) {
|
|
memory.flush();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void startsEmpty() {
|
|
assertEquals(0, memory.size());
|
|
}
|
|
|
|
@Test
|
|
void setsAndPersistsPersona() {
|
|
UUID id = UUID.randomUUID();
|
|
assertEquals(Persona.ZOEIRO, memory.persona(id, Persona.ZOEIRO));
|
|
assertNull(memory.rawPersona(id));
|
|
|
|
memory.setPersona(id, "Marcos", Persona.JUDITE);
|
|
assertEquals(Persona.JUDITE, memory.persona(id, Persona.ZOEIRO));
|
|
assertEquals(Persona.JUDITE, memory.rawPersona(id));
|
|
|
|
// Reload from disk
|
|
memory.flush();
|
|
PlayerMemory reloaded = new PlayerMemory(file);
|
|
assertEquals(Persona.JUDITE, reloaded.persona(id, Persona.ZOEIRO));
|
|
assertEquals(Persona.JUDITE, reloaded.rawPersona(id));
|
|
|
|
// Reset
|
|
reloaded.resetPersona(id);
|
|
reloaded.flush();
|
|
assertNull(reloaded.rawPersona(id));
|
|
assertEquals(Persona.ZOEIRO, reloaded.persona(id, Persona.ZOEIRO));
|
|
}
|
|
|
|
@Test
|
|
void recordsTurnAndCompressesWhenLong() {
|
|
UUID id = UUID.randomUUID();
|
|
memory.recordTurn(id, "Marcos", "Onde tem diamante?", "Na camada -58.");
|
|
String s = memory.summary(id);
|
|
assertNotNull(s);
|
|
assertTrue(s.contains("diamante"));
|
|
assertTrue(s.contains("-58"));
|
|
|
|
// Push many turns to trigger compression
|
|
for (int i = 0; i < 20; i++) {
|
|
memory.recordTurn(id, "Marcos", "Pergunta " + i, "Resposta bem longa para a pergunta " + i);
|
|
}
|
|
String compressed = memory.summary(id);
|
|
assertNotNull(compressed);
|
|
assertTrue(compressed.length() <= PlayerMemory.MAX_SUMMARY_CHARS + 10);
|
|
}
|
|
|
|
@Test
|
|
void addsAndCapsFacts() {
|
|
UUID id = UUID.randomUUID();
|
|
for (int i = 1; i <= 10; i++) {
|
|
memory.addFact(id, "Marcos", "Fato número " + i);
|
|
}
|
|
List<String> facts = memory.facts(id);
|
|
assertEquals(PlayerMemory.MAX_FACTS, facts.size());
|
|
assertTrue(facts.contains("Fato número 10"));
|
|
assertFalse(facts.contains("Fato número 1")); // Oldest evicted
|
|
}
|
|
|
|
@Test
|
|
void formatContextProducesCleanPrompt() {
|
|
UUID id = UUID.randomUUID();
|
|
assertNull(memory.formatContext(id));
|
|
|
|
memory.recordTurn(id, "Marcos", "Como fazer poção?", "Use suporte de poções.");
|
|
memory.addFact(id, "Marcos", "Mora na vila do deserto");
|
|
|
|
String context = memory.formatContext(id);
|
|
assertNotNull(context);
|
|
assertTrue(context.contains("Resumo de tópicos recentes"));
|
|
assertTrue(context.contains("Fatos conhecidos"));
|
|
assertTrue(context.contains("Mora na vila do deserto"));
|
|
}
|
|
|
|
@Test
|
|
void clearHistoryKeepsPersona() {
|
|
UUID id = UUID.randomUUID();
|
|
memory.setPersona(id, "Marcos", Persona.SECO);
|
|
memory.recordTurn(id, "Marcos", "Oi", "Tchau");
|
|
memory.addFact(id, "Marcos", "Fato 1");
|
|
|
|
memory.clearHistory(id);
|
|
assertEquals(Persona.SECO, memory.rawPersona(id));
|
|
assertEquals("", memory.summary(id));
|
|
assertTrue(memory.facts(id).isEmpty());
|
|
}
|
|
|
|
@Test
|
|
void forgetRemovesProfileCompletely() {
|
|
UUID id = UUID.randomUUID();
|
|
memory.setPersona(id, "Marcos", Persona.NARRADOR);
|
|
memory.forget(id);
|
|
assertEquals(0, memory.size());
|
|
assertNull(memory.rawPersona(id));
|
|
}
|
|
|
|
@Test
|
|
void extractsHeuristicFactsAutomatically() {
|
|
UUID id = UUID.randomUUID();
|
|
memory.recordTurn(id, "Marcos", "Minha base fica nas montanhas nevadas!", "Que lugar bonito!");
|
|
List<String> facts = memory.facts(id);
|
|
assertFalse(facts.isEmpty());
|
|
assertTrue(facts.get(0).toLowerCase().contains("minha base"));
|
|
|
|
String fact = PlayerMemory.extractHeuristicFact("Eu estou construindo uma pirâmide gigante?");
|
|
assertNotNull(fact);
|
|
assertTrue(fact.contains("estou construindo uma pirâmide gigante"));
|
|
assertNull(PlayerMemory.extractHeuristicFact("quantos blocos tem o mundo?"));
|
|
|
|
// Leading / trailing whitespace index alignment
|
|
assertEquals("minha base fica no topo", PlayerMemory.extractHeuristicFact(" minha base fica no topo! "));
|
|
assertEquals("estou construindo uma ponte", PlayerMemory.extractHeuristicFact(" oi, estou construindo uma ponte..."));
|
|
}
|
|
|
|
@Test
|
|
void flushesToDiskCorrectly() {
|
|
UUID id = UUID.randomUUID();
|
|
memory.setPersona(id, "Marcos", Persona.JUDITE);
|
|
memory.recordTurn(id, "Marcos", "Preciso de ajuda", "Aguarde na linha");
|
|
memory.flush();
|
|
|
|
PlayerMemory disk = new PlayerMemory(file);
|
|
assertEquals(Persona.JUDITE, disk.persona(id, Persona.ZOEIRO));
|
|
assertTrue(disk.summary(id).contains("ajuda"));
|
|
}
|
|
}
|