Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
using Omika.App.Local.Models;
|
||||
using Omika.App.Local.Services;
|
||||
|
||||
namespace Omika.Tests.Mobile;
|
||||
|
||||
/// <summary>
|
||||
/// Tests du jeton de cible des modèles multilingues : lecture du fichier
|
||||
/// <c>modele.json</c> d'un sens, validation (un jeton malformé est refusé, jamais
|
||||
/// ignoré en silence) et composition du texte effectivement envoyé au modèle.
|
||||
///
|
||||
/// <para>
|
||||
/// Le pipeline ONNX complet n'est pas exerçable ici : il exige un vocabulaire
|
||||
/// SentencePiece réel et le moteur d'inférence. La preuve de bout en bout se fait
|
||||
/// avec <c>Omika.LanguesProbe traduire --dossier <pack></c>, qui exécute le
|
||||
/// vrai moteur sur un vrai pack.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class ModelePackMetadonneesTests
|
||||
{
|
||||
[Fact]
|
||||
public void DepuisJson_JetonPresent_EstLuAvecSonModele()
|
||||
{
|
||||
string json = """
|
||||
{
|
||||
"version": 1,
|
||||
"modeleSource": "Helsinki-NLP/opus-mt-tc-big-itc-itc",
|
||||
"famille": "itc",
|
||||
"jetonCible": ">>fra<<"
|
||||
}
|
||||
""";
|
||||
|
||||
ModelePackMetadonnees? metadonnees = ModelePackMetadonnees.DepuisJson(json);
|
||||
|
||||
Assert.NotNull(metadonnees);
|
||||
Assert.True(metadonnees.AjouteUnJeton);
|
||||
Assert.Equal(">>fra<<", metadonnees.JetonCible);
|
||||
Assert.Equal("Helsinki-NLP/opus-mt-tc-big-itc-itc", metadonnees.ModeleSource);
|
||||
Assert.Equal("itc", metadonnees.Famille);
|
||||
Assert.Equal(1, metadonnees.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_SansJeton_EstUnModeleDedie()
|
||||
{
|
||||
string json = """{ "modeleSource": "Helsinki-NLP/opus-mt-es-fr" }""";
|
||||
|
||||
ModelePackMetadonnees? metadonnees = ModelePackMetadonnees.DepuisJson(json);
|
||||
|
||||
Assert.NotNull(metadonnees);
|
||||
Assert.False(metadonnees.AjouteUnJeton);
|
||||
Assert.Equal(string.Empty, metadonnees.JetonCible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_VersionAbsente_VautUn()
|
||||
{
|
||||
ModelePackMetadonnees? metadonnees = ModelePackMetadonnees.DepuisJson("""{ "jetonCible": ">>fra<<" }""");
|
||||
|
||||
Assert.NotNull(metadonnees);
|
||||
Assert.Equal(1, metadonnees.Version);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
public void DepuisJson_ContenuVide_EstTraiteCommeAbsent(string? json)
|
||||
{
|
||||
Assert.Null(ModelePackMetadonnees.DepuisJson(json));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_JetonEntoureDEspaces_EstNettoye()
|
||||
{
|
||||
ModelePackMetadonnees? metadonnees = ModelePackMetadonnees.DepuisJson("""{ "jetonCible": " >>fra<< " }""");
|
||||
|
||||
Assert.NotNull(metadonnees);
|
||||
Assert.Equal(">>fra<<", metadonnees.JetonCible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_JetonAvecEspaceInterne_EstRefuse()
|
||||
{
|
||||
// Un jeton contenant un espace serait découpé par le tokeniseur : le modèle
|
||||
// ne le reconnaîtrait pas et produirait sa langue par défaut, sans erreur.
|
||||
FormatException ex = Assert.Throws<FormatException>(
|
||||
() => ModelePackMetadonnees.DepuisJson("""{ "jetonCible": ">>fra<< x" }"""));
|
||||
|
||||
Assert.Contains("espace", ex.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_JetonTropLong_EstRefuse()
|
||||
{
|
||||
string jeton = ">>" + new string('a', ModelePackMetadonnees.LongueurMaxJeton) + "<<";
|
||||
|
||||
FormatException ex = Assert.Throws<FormatException>(
|
||||
() => ModelePackMetadonnees.DepuisJson($$"""{ "jetonCible": "{{jeton}}" }"""));
|
||||
|
||||
Assert.Contains("trop long", ex.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_VersionFuture_EstRefusee()
|
||||
{
|
||||
// Une version inconnue peut changer le SENS du champ : la lire à l'aveugle
|
||||
// reviendrait à deviner.
|
||||
FormatException ex = Assert.Throws<FormatException>(
|
||||
() => ModelePackMetadonnees.DepuisJson("""{ "version": 99, "jetonCible": ">>fra<<" }"""));
|
||||
|
||||
Assert.Contains("version", ex.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_JsonInvalide_EstRefuse()
|
||||
{
|
||||
Assert.Throws<FormatException>(() => ModelePackMetadonnees.DepuisJson("{ pas du json"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DepuisJson_ProprieteInconnue_EstIgnoree()
|
||||
{
|
||||
// Compatibilité ascendante : un pack plus récent peut ajouter des champs.
|
||||
ModelePackMetadonnees? metadonnees = ModelePackMetadonnees.DepuisJson(
|
||||
"""{ "jetonCible": ">>fra<<", "champFutur": 42 }""");
|
||||
|
||||
Assert.NotNull(metadonnees);
|
||||
Assert.Equal(">>fra<<", metadonnees.JetonCible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InsererJetonCible_AvecIdentifiant_LePlaceEnTete()
|
||||
{
|
||||
// Valeurs réelles d'opus-mt-tc-big-itc-itc : >>fra<< = 14666, et la suite
|
||||
// d'identifiants du modèle (jamais ceux du .spm).
|
||||
IReadOnlyList<int> ids = OnnxTranslationService.InsererJetonCible([6636, 5, 7228], 14666);
|
||||
|
||||
Assert.Equal([14666, 6636, 5, 7228], ids);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InsererJetonCible_SansIdentifiant_RendLaSequenceTelleQuelle()
|
||||
{
|
||||
IReadOnlyList<int> ids = OnnxTranslationService.InsererJetonCible([6636, 5], -1);
|
||||
|
||||
Assert.Equal([6636, 5], ids);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InsererJetonCible_NeModifiePasLaSequenceDOrigine()
|
||||
{
|
||||
int[] origine = [6636, 5];
|
||||
IReadOnlyList<int> resultat = OnnxTranslationService.InsererJetonCible(origine, 14666);
|
||||
|
||||
Assert.Equal([6636, 5], origine);
|
||||
Assert.NotSame(origine, resultat);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user