v-20260916a

- restaurar derivaciones
- añadido la pedida de anchura de calles y cariiles
- correcion paradas bus
- desglose del score
- historial no cambia la hora
- resuarar no cambia modo de historial
This commit is contained in:
2026-09-16 13:26:13 +02:00
parent 9f312d2ca9
commit 7090dfa9be
15 changed files with 867 additions and 83 deletions

View File

@@ -1,6 +1,7 @@
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging.Abstractions;
using RutasDBUS.Components.Pages;
using RutasDBUS.Modelos.Historial;
@@ -180,6 +181,55 @@ Check((bool)puntoDentro.Invoke(null, new object?[] { 43.3155, -1.9845, parametro
"Las paradas interiores a una zona se detectan antes de calcular");
var page = new PlanificadorRutas();
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var fabricaHistorial = (ConfiguracionHistorialRuta)baseMethod.Invoke(null, null)!;
fabricaHistorial.FactorEquilibradoAndarBus = 6;
typeof(PlanificadorRutas).GetField("_configuracionFabrica", flags)!.SetValue(page, fabricaHistorial);
var crearPredeterminadaHistorial = typeof(PlanificadorRutas).GetMethod(
"CrearConfiguracionPredeterminadaParaHistorial", flags)!;
var configuracionGuardada = fabricaHistorial.Clonar();
configuracionGuardada.UsarHoraSimulada = true;
configuracionGuardada.FechaSimulada = "2026-04-08";
configuracionGuardada.HoraSimulada = "08:46:17";
configuracionGuardada.FactorEquilibradoAndarBus = 99;
var registroConHora = new RegistroHistorialRuta { Configuracion = configuracionGuardada };
var predeterminadaConHora = (ConfiguracionHistorialRuta)crearPredeterminadaHistorial.Invoke(
page, new object[] { registroConHora })!;
Check(predeterminadaConHora.UsarHoraSimulada &&
predeterminadaConHora.FechaSimulada == "2026-04-08" &&
predeterminadaConHora.HoraSimulada == "08:46:17" &&
predeterminadaConHora.FactorEquilibradoAndarBus == 6,
"Predeterminada conserva solo la fecha y hora simuladas del historial");
configuracionGuardada.UsarHoraSimulada = false;
configuracionGuardada.FechaSimulada = "2020-01-01";
configuracionGuardada.HoraSimulada = "01:02:03";
var predeterminadaSinHora = (ConfiguracionHistorialRuta)crearPredeterminadaHistorial.Invoke(
page, new object[] { registroConHora })!;
Check(!predeterminadaSinHora.UsarHoraSimulada &&
predeterminadaSinHora.FechaSimulada == DateOnly.FromDateTime(DateTime.Now)
.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) &&
predeterminadaSinHora.HoraSimulada != "01:02:03",
"Predeterminada usa la hora actual cuando el historial no tenia simulacion");
typeof(PlanificadorRutas).GetField("_factorEquilibradoAndarBus", flags)!.SetValue(page, 6.0);
typeof(PlanificadorRutas).GetField("_factorPenalizacionDistanciaPie", flags)!.SetValue(page, 1.8);
typeof(PlanificadorRutas).GetField("_parametroPenalizacionDistanciaPieMetros", flags)!.SetValue(page, 200.0);
typeof(PlanificadorRutas).GetField("_pesoTransbordoRankingMinutos", flags)!.SetValue(page, 6.0);
typeof(PlanificadorRutas).GetField("_velocidadBusKmH", flags)!.SetValue(page, 16.0);
typeof(PlanificadorRutas).GetField("_mostrarElevacionesRuta", flags)!.SetValue(page, true);
var alternativaDesglose = new AlternativaRuta
{
AlternativaBus = new RutaBusAlternativa { DistanciaTotalBus = 6000 },
DistanciasPiePorTramoAprox = new List<double> { 100, 300 },
EsfuerzoExtraPendienteMetros = 25,
NumeroTransbordosReales = 1
};
var calcularScore = typeof(PlanificadorRutas).GetMethod("CalcularScoreEquilibradoFactor", flags)!;
var crearDesglose = typeof(PlanificadorRutas).GetMethod("CrearDesgloseScoreEquilibrado", flags)!;
var scoreCalculado = (double)calcularScore.Invoke(page, new object?[] { alternativaDesglose })!;
var desgloseCalculado = crearDesglose.Invoke(page, new object?[] { alternativaDesglose })!;
var scoreDesglosado = (double)desgloseCalculado.GetType().GetProperty("ScoreTotal")!
.GetValue(desgloseCalculado)!;
Check(Math.Abs(scoreCalculado - scoreDesglosado) < 0.0001,
"El desglose y el ranking usan exactamente el mismo score");
var formatearEtiqueta = typeof(PlanificadorRutas).GetMethod("FormatearEtiquetaAlternativaTarjeta", flags)!;
Check((string)formatearEtiqueta.Invoke(page, new object[]
{ new AlternativaRuta { Etiqueta = "Equilibrada" }, 0 })! == "Opción 1",
@@ -206,6 +256,12 @@ Check(!(bool)typeof(PlanificadorRutas).GetField("_activarRangoLineas", flags)!.G
(int)typeof(PlanificadorRutas).GetField("_itinerarioMin", flags)!.GetValue(page)! == defaults.ItinerarioMin &&
(int)typeof(PlanificadorRutas).GetField("_itinerarioMax", flags)!.GetValue(page)! == defaults.ItinerarioMax,
"Restaurar aplica tambien los valores de lineas e itinerarios");
var campoModoHistorial = typeof(PlanificadorRutas).GetField("_modoConfiguracionHistorial", flags)!;
var modoGuardada = Enum.Parse(campoModoHistorial.FieldType, "Guardada");
campoModoHistorial.SetValue(page, modoGuardada);
typeof(PlanificadorRutas).GetMethod("AplicarValoresFabricaConservandoSeleccion", flags)!.Invoke(page, null);
Check(Equals(campoModoHistorial.GetValue(page), modoGuardada),
"Restaurar valores conserva el modo de configuracion del historial");
var options = (List<AlternativaRuta>)typeof(PlanificadorRutas).GetField("_opcionesRuta", flags)!.GetValue(page)!;
var selected = typeof(PlanificadorRutas).GetField("_indiceAlternativaSeleccionada", flags)!;
var remember = typeof(PlanificadorRutas).GetMethod("ObtenerProveedorSoloAPieParaRecalculo", flags)!;
@@ -221,6 +277,26 @@ selected.SetValue(page, 0);
Check(Remember(true) is null, "Seleccionar bus libera la preferencia andando");
options.Clear();
Check(Remember(false) is null, "Nueva seleccion de criterio no hereda la preferencia andando");
var osmHandler = new OsmWidthHandler();
using var osmCache = new MemoryCache(new MemoryCacheOptions());
var osmConfig = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
{
["Caminata:Osm:BaseUrl"] = "https://osm.test/api/0.6"
}).Build();
var osmClient = new ClienteAtributosOsm(new HttpClient(osmHandler), osmCache, osmConfig);
var anchos = await osmClient.ObtenerAnchurasAsync([101, 102, 103]);
Check(anchos[101] == new AnchuraViaOsm("4.5", false) &&
anchos[102] == new AnchuraViaOsm("2", true) &&
!anchos.ContainsKey(103),
"La anchura exacta y la estimada se leen de las etiquetas OSM");
await osmClient.ObtenerAnchurasAsync([101, 102, 103]);
Check(osmHandler.Calls == 1, "Las anchuras OSM se reutilizan desde cache");
var formatearSuperficieSinDatos = typeof(PlanificadorRutas).GetMethod(
"FormatearSuperficieSegmento", BindingFlags.Static | BindingFlags.NonPublic)!;
var superficieSinDatos = (string)formatearSuperficieSinDatos.Invoke(null, [null])!;
Check(superficieSinDatos.Contains("Carriles: -") &&
superficieSinDatos.Contains("Anchura: -"),
"El tooltip mantiene todos los atributos cuando no hay datos de via");
Console.WriteLine("Pruebas completadas.");
sealed class FakeValhalla : IClienteValhalla
@@ -246,6 +322,31 @@ sealed class FakeValhalla : IClienteValhalla
}
}
sealed class OsmWidthHandler : HttpMessageHandler
{
public int Calls { get; private set; }
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
Calls++;
const string contenido = """
{
"elements": [
{ "type": "way", "id": 101, "tags": { "width": "4.5" } },
{ "type": "way", "id": 102, "tags": { "est_width": "2" } },
{ "type": "way", "id": 103, "tags": { "highway": "residential" } }
]
}
""";
return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(contenido, System.Text.Encoding.UTF8, "application/json")
});
}
}
sealed class RetryValhallaHandler : HttpMessageHandler
{
public List<string> Bodies { get; } = new();