mirror of
https://github.com/Earth-Genesis-Games/Ajedrez_Purgatorio.git
synced 2026-09-11 09:47:35 +00:00
194 lines
6.5 KiB
C#
194 lines
6.5 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using NUnit.Framework;
|
|
using UnityEngine;
|
|
using UnityEngine.TestTools;
|
|
using UnityEditor;
|
|
|
|
/// <summary>
|
|
/// Cobertura de ramas restantes de CampaignManager: registro de campañas
|
|
/// (config del Inspector, JSON inválido y duplicado en Resources), guards de
|
|
/// LoadChapter, EnsureChildSystem y cierre forzado del diálogo mid-turn.
|
|
/// </summary>
|
|
[TestFixture]
|
|
[Category("Unit")]
|
|
[Category("Campaign")]
|
|
[Category("FastTests")]
|
|
public class CampaignManagerCoverageTests
|
|
{
|
|
private static readonly BindingFlags Flags =
|
|
BindingFlags.NonPublic | BindingFlags.Instance;
|
|
|
|
private const string ResourcesFolder = "Assets/Game/Data/Resources/Campaigns";
|
|
|
|
private GameObject _root;
|
|
private CampaignManager _manager;
|
|
private readonly List<string> _tempFiles = new List<string>();
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
_root = new GameObject("CampaignManagerCoverageRoot");
|
|
_manager = _root.AddComponent<CampaignManager>();
|
|
}
|
|
|
|
[TearDown]
|
|
public void Teardown()
|
|
{
|
|
bool removedAny = false;
|
|
foreach (string file in _tempFiles)
|
|
{
|
|
if (File.Exists(file))
|
|
{
|
|
File.Delete(file);
|
|
removedAny = true;
|
|
}
|
|
}
|
|
_tempFiles.Clear();
|
|
|
|
if (removedAny)
|
|
{
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
Object.DestroyImmediate(_root);
|
|
LogAssert.ignoreFailingMessages = false;
|
|
}
|
|
|
|
private object GetPrivate(string name)
|
|
{
|
|
return typeof(CampaignManager).GetField(name, Flags).GetValue(_manager);
|
|
}
|
|
|
|
private void InvokePrivate(string name, params object[] args)
|
|
{
|
|
var method = typeof(CampaignManager).GetMethod(name, Flags);
|
|
Assert.IsNotNull(method, $"{name} no encontrado.");
|
|
method.Invoke(_manager, args);
|
|
}
|
|
|
|
private CampaignConfig MakeConfigFromJson(string json)
|
|
{
|
|
// CreateInstance dispara OnEnable → LoadFromJson sin fuente.
|
|
// OnEnable es silencioso cuando no hay fuente JSON asignada.
|
|
var config = ScriptableObject.CreateInstance<CampaignConfig>();
|
|
config.SetJsonSource(new TextAsset(json));
|
|
config.LoadFromJson();
|
|
return config;
|
|
}
|
|
|
|
private string WriteTempResource(string fileName, string contents)
|
|
{
|
|
string path = Path.Combine(ResourcesFolder, fileName);
|
|
File.WriteAllText(path, contents);
|
|
_tempFiles.Add(path);
|
|
AssetDatabase.Refresh();
|
|
return path;
|
|
}
|
|
|
|
[Test]
|
|
public void BuildCampaignRegistry_InspectorConfig_IsFirstAndActive()
|
|
{
|
|
var inspectorConfig = MakeConfigFromJson(
|
|
"{\"campaignId\":\"_inspector\",\"chapters\":[{\"id\":\"c1\"}]}");
|
|
|
|
typeof(CampaignManager).GetField("_campaignConfig", Flags)
|
|
.SetValue(_manager, inspectorConfig);
|
|
|
|
// La config del Inspector se añade SIN log; los recursos de
|
|
// Resources se registran al BuildCampaignRegistry (OnEnable silencioso).
|
|
LogAssert.ignoreFailingMessages = true;
|
|
InvokePrivate("BuildCampaignRegistry");
|
|
LogAssert.ignoreFailingMessages = false;
|
|
|
|
var registry = GetPrivate("_campaigns") as List<CampaignConfig>;
|
|
Assert.IsNotNull(registry);
|
|
Assert.IsTrue(RegistryHasId(registry, "_inspector"),
|
|
"La config del Inspector debe estar registrada.");
|
|
Assert.AreSame(inspectorConfig, GetPrivate("_activeConfig"),
|
|
"La config del Inspector debe ser la activa por defecto.");
|
|
|
|
Object.DestroyImmediate(inspectorConfig);
|
|
}
|
|
|
|
[Test]
|
|
public void BuildCampaignRegistry_InvalidResourceJson_IsSkipped()
|
|
{
|
|
WriteTempResource("_zz_invalid_test.json", "{esto no es json válido::");
|
|
|
|
LogAssert.ignoreFailingMessages = true;
|
|
InvokePrivate("BuildCampaignRegistry");
|
|
LogAssert.ignoreFailingMessages = false;
|
|
|
|
var registry = GetPrivate("_campaigns") as List<CampaignConfig>;
|
|
Assert.IsNotNull(registry);
|
|
Assert.IsFalse(RegistryHasId(registry, "_zz_invalid_test"),
|
|
"El JSON inválido no debe registrarse.");
|
|
}
|
|
|
|
[Test]
|
|
public void BuildCampaignRegistry_DuplicateCampaignId_SecondIsIgnored()
|
|
{
|
|
WriteTempResource("_zz_dup_a.json", "{\"campaignId\":\"_zzdup\",\"chapters\":[{\"id\":\"z1\"}]}");
|
|
WriteTempResource("_zz_dup_b.json", "{\"campaignId\":\"_zzdup\",\"chapters\":[{\"id\":\"z2\"}]}");
|
|
|
|
LogAssert.ignoreFailingMessages = true;
|
|
InvokePrivate("BuildCampaignRegistry");
|
|
LogAssert.ignoreFailingMessages = false;
|
|
|
|
var registry = GetPrivate("_campaigns") as List<CampaignConfig>;
|
|
Assert.IsNotNull(registry);
|
|
int dupCount = 0;
|
|
foreach (var campaign in registry)
|
|
{
|
|
if (campaign.CampaignId == "_zzdup") dupCount++;
|
|
}
|
|
Assert.AreEqual(1, dupCount, "Solo la primera campaña con el id debe registrarse.");
|
|
}
|
|
|
|
private static bool RegistryHasId(List<CampaignConfig> registry, string id)
|
|
{
|
|
foreach (var campaign in registry)
|
|
{
|
|
if (campaign.CampaignId == id) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
[Test]
|
|
public void LoadChapter_WithoutActiveConfig_LogsError()
|
|
{
|
|
LogAssert.Expect(LogType.Error, "[CampaignManager] CampaignConfig no asignado.");
|
|
_manager.LoadChapter(0);
|
|
}
|
|
|
|
[Test]
|
|
public void LoadChapter_IndexOutOfRange_LogsError()
|
|
{
|
|
var config = MakeConfigFromJson("{\"campaignId\":\"_one\",\"chapters\":[{\"id\":\"c1\"}]}");
|
|
typeof(CampaignManager).GetField("_activeConfig", Flags).SetValue(_manager, config);
|
|
LogAssert.ignoreFailingMessages = false;
|
|
|
|
LogAssert.Expect(LogType.Error, "[CampaignManager] Índice fuera de rango: 7");
|
|
_manager.LoadChapter(7);
|
|
|
|
Object.DestroyImmediate(config);
|
|
}
|
|
|
|
[Test]
|
|
public void EnsureChildSystem_CreatesOnceAndReusesAfterwards()
|
|
{
|
|
var ensureMethod = typeof(CampaignManager).GetMethod("EnsureChildSystem", Flags);
|
|
Assert.IsNotNull(ensureMethod, "EnsureChildSystem no encontrado.");
|
|
|
|
var generic = ensureMethod.MakeGenericMethod(typeof(DialogueTriggerSystem));
|
|
DialogueTriggerSystem first = (DialogueTriggerSystem)generic.Invoke(_manager, null);
|
|
DialogueTriggerSystem second = (DialogueTriggerSystem)generic.Invoke(_manager, null);
|
|
|
|
Assert.IsNotNull(first);
|
|
Assert.AreSame(first, second, "La segunda llamada debe reutilizar el sistema existente.");
|
|
Assert.IsTrue(first.transform.IsChildOf(_root.transform));
|
|
}
|
|
}
|