Premiere commit - Omika

This commit is contained in:
2026-10-23 18:46:50 +02:00
commit 8ea76c1b24
2155 changed files with 984301 additions and 0 deletions
@@ -0,0 +1,64 @@
using Omika.App.Controls;
using Xunit;
namespace Omika.Tests.Controls;
/// <summary>
/// Règle d'ajout du texte dicté : le texte reconnu est toujours AJOUTÉ À LA FIN
/// du contenu du champ, sans jamais écraser ce qui était déjà saisi ou dicté.
/// </summary>
public sealed class DictationTextMergerTests
{
[Fact]
public void ChampVide_RecoitLaDictee()
=> Assert.Equal("Remplacement de la pièce", DictationTextMerger.Append(null, "Remplacement de la pièce"));
[Fact]
public void ChampVideAvecEspaces_RecoitLaDicteeSeule_Detoureee()
=> Assert.Equal("Paris", DictationTextMerger.Append(" ", " Paris "));
[Fact]
public void TexteExistant_AjouteAvecUneEspace()
=> Assert.Equal(
"Travaux réalisés. Remplacement de la pièce.",
DictationTextMerger.Append("Travaux réalisés.", "Remplacement de la pièce."));
[Fact]
public void TexteQuiFinitParUneEspace_PasDeDoubleEspace()
=> Assert.Equal("Travaux réalisés. Remplacement.", DictationTextMerger.Append("Travaux réalisés. ", "Remplacement."));
[Fact]
public void TexteQuiFinitParUnRetourLigne_PasDEspaceAjoutee()
=> Assert.Equal("Ligne 1\nLigne 2", DictationTextMerger.Append("Ligne 1\n", "Ligne 2"));
[Fact]
public void DicteeVide_NeModifieRien()
=> Assert.Equal("Travaux", DictationTextMerger.Append("Travaux", " "));
[Fact]
public void DicteeNulle_NeModifieRien()
=> Assert.Equal("Travaux", DictationTextMerger.Append("Travaux", null));
[Fact]
public void DicteeNulleSurChampVide_RendUneChaineVide()
=> Assert.Equal(string.Empty, DictationTextMerger.Append(null, null));
[Fact]
public void DicteeAvecRetoursDeBord_EstDetoureee()
=> Assert.Equal("Note", DictationTextMerger.Append(string.Empty, " Note\n"));
[Fact]
public void DicteeMultiLignes_ConserveLesRetoursInternes()
=> Assert.Equal("A\nB", DictationTextMerger.Append(null, "A\nB"));
[Fact]
public void AjoutsSuccessifs_NePerdentAucunePhrase()
{
// Cas d'usage réel : un compte rendu dicté en trois fois.
string texte = DictationTextMerger.Append(null, "Première phrase.");
texte = DictationTextMerger.Append(texte, "Deuxième phrase.");
texte = DictationTextMerger.Append(texte, "Troisième phrase.");
Assert.Equal("Première phrase. Deuxième phrase. Troisième phrase.", texte);
}
}
@@ -0,0 +1,120 @@
using Avalonia;
using Omika.App.Controls;
using Xunit;
namespace Omika.Tests.Controls;
/// <summary>
/// Tests de la machine à états du tracé de signature (mono-pointeur). La logique
/// est extraite du contrôle visuel <see cref="SignaturePad"/> pour être testable
/// sans plateforme de rendu Avalonia (environnement headless).
/// </summary>
public sealed class SignatureStrokeTrackerTests
{
[Fact]
public void TryBeginStroke_PremierPointeur_ActiveLeTrait()
{
var tracker = new SignatureStrokeTracker();
bool started = tracker.TryBeginStroke(pointerId: 1, new Point(5, 5));
Assert.True(started);
Assert.True(tracker.IsDrawing);
Assert.Equal(1, tracker.ActivePointerId);
Assert.Single(tracker.Points);
Assert.Equal(new Point(5, 5), tracker.Points[0]);
}
[Fact]
public void TryBeginStroke_SecondPointeurPendantTrait_EstIgnore()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(5, 5));
bool started = tracker.TryBeginStroke(pointerId: 2, new Point(99, 99));
Assert.False(started);
Assert.Equal(1, tracker.ActivePointerId);
Assert.Single(tracker.Points);
Assert.Equal(new Point(5, 5), tracker.Points[0]);
}
[Fact]
public void TryAddPoint_PointeurActif_AjoutePointEtRetournePrecedent()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(0, 0));
Point? previous = tracker.TryAddPoint(pointerId: 1, new Point(10, 20));
Assert.True(previous.HasValue);
Assert.Equal(new Point(0, 0), previous!.Value);
Assert.Equal(2, tracker.Points.Count);
Assert.Equal(new Point(10, 20), tracker.Points[1]);
}
[Fact]
public void TryAddPoint_PointeurNonActif_EstIgnore()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(0, 0));
Point? previous = tracker.TryAddPoint(pointerId: 2, new Point(99, 99));
Assert.Null(previous);
Assert.Single(tracker.Points);
}
[Fact]
public void EndStroke_ReinitialiseEtatComplet()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(0, 0));
tracker.TryAddPoint(pointerId: 1, new Point(10, 10));
tracker.EndStroke();
Assert.False(tracker.IsDrawing);
Assert.Null(tracker.ActivePointerId);
Assert.Empty(tracker.Points);
}
[Fact]
public void NouveauTraitApresEndStroke_Fonctionne()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(0, 0));
tracker.EndStroke();
bool started = tracker.TryBeginStroke(pointerId: 3, new Point(7, 7));
Assert.True(started);
Assert.Equal(3, tracker.ActivePointerId);
Assert.Single(tracker.Points);
Assert.Equal(new Point(7, 7), tracker.Points[0]);
}
[Fact]
public void IsActivePointer_MauvaisPointeur_NeTerminePasLeTraitActif()
{
var tracker = new SignatureStrokeTracker();
tracker.TryBeginStroke(pointerId: 1, new Point(0, 0));
// Le relâchement d'un mauvais PointerId (second doigt) ne doit pas être
// interprété comme la fin du trait actif.
Assert.True(tracker.IsActivePointer(1));
Assert.False(tracker.IsActivePointer(2));
Assert.True(tracker.IsDrawing);
}
[Fact]
public void TryAddPoint_SansTraitActif_RetourneNull()
{
var tracker = new SignatureStrokeTracker();
Point? previous = tracker.TryAddPoint(pointerId: 1, new Point(10, 10));
Assert.Null(previous);
Assert.False(tracker.IsDrawing);
}
}