diff --git a/src/SIL.Machine.AspNetCore/SIL.Machine.AspNetCore.csproj b/src/SIL.Machine.AspNetCore/SIL.Machine.AspNetCore.csproj index 53bb4ea7f..57d9a9cb9 100644 --- a/src/SIL.Machine.AspNetCore/SIL.Machine.AspNetCore.csproj +++ b/src/SIL.Machine.AspNetCore/SIL.Machine.AspNetCore.csproj @@ -47,6 +47,7 @@ + diff --git a/src/SIL.Machine.AspNetCore/Services/ILanguageTagService.cs b/src/SIL.Machine.AspNetCore/Services/ILanguageTagService.cs index d35861f7d..95a65985f 100644 --- a/src/SIL.Machine.AspNetCore/Services/ILanguageTagService.cs +++ b/src/SIL.Machine.AspNetCore/Services/ILanguageTagService.cs @@ -2,5 +2,5 @@ public interface ILanguageTagService { - string ConvertToFlores200Code(string languageTag); + bool ConvertToFlores200Code(string languageTag, out string flores200Code); } diff --git a/src/SIL.Machine.AspNetCore/Services/ITranslationEngineService.cs b/src/SIL.Machine.AspNetCore/Services/ITranslationEngineService.cs index 51750dedc..2fea94301 100644 --- a/src/SIL.Machine.AspNetCore/Services/ITranslationEngineService.cs +++ b/src/SIL.Machine.AspNetCore/Services/ITranslationEngineService.cs @@ -41,4 +41,6 @@ Task StartBuildAsync( Task CancelBuildAsync(string engineId, CancellationToken cancellationToken = default); Task GetQueueSizeAsync(CancellationToken cancellationToken = default); + + bool IsLanguageNativeToModel(string language, out string internalCode); } diff --git a/src/SIL.Machine.AspNetCore/Services/LanguageTagService.cs b/src/SIL.Machine.AspNetCore/Services/LanguageTagService.cs index 73b25b7e0..bc665e7eb 100644 --- a/src/SIL.Machine.AspNetCore/Services/LanguageTagService.cs +++ b/src/SIL.Machine.AspNetCore/Services/LanguageTagService.cs @@ -7,6 +7,8 @@ public class LanguageTagService : ILanguageTagService private readonly Dictionary _defaultScripts; + private readonly Dictionary _flores200Languages; + private static readonly Regex LangTagPattern = new Regex( "(?'language'[a-zA-Z]{2,8})([_-](?'script'[a-zA-Z]{4}))?", RegexOptions.ExplicitCapture @@ -16,6 +18,7 @@ public LanguageTagService() { // initialise SLDR language tags to retrieve latest langtags.json file _defaultScripts = InitializeDefaultScripts(); + _flores200Languages = InitializeFlores200Languages(); } private static Dictionary InitializeDefaultScripts() @@ -56,7 +59,40 @@ private static Dictionary InitializeDefaultScripts() return tempDefaultScripts; } - public string ConvertToFlores200Code(string languageTag) + private static Dictionary InitializeFlores200Languages() + { + var tempFlores200Languages = new Dictionary(); + using var floresStream = Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("SIL.Machine.AspNetCore.data.flores200languages.csv"); + Debug.Assert(floresStream is not null); + var reader = new StreamReader(floresStream); + var firstLine = reader.ReadLine(); + Debug.Assert(firstLine == "language, code"); + while (!reader.EndOfStream) + { + string? line = reader.ReadLine(); + if (line is null) + continue; + string[] values = line.Split(','); + tempFlores200Languages[values[1].Trim()] = values[0].Trim(); + } + return tempFlores200Languages; + } + + /** + * Converts a language tag to a Flores 200 code + * @param {string} languageTag - The language tag to convert + * @param out {string} flores200Code - The converted Flores 200 code + * @returns {bool} is the langauge is the Flores 200 list + */ + public bool ConvertToFlores200Code(string languageTag, out string flores200Code) + { + flores200Code = ResolveLanguageTag(languageTag); + return _flores200Languages.ContainsKey(flores200Code); + } + + private string ResolveLanguageTag(string languageTag) { // Try to find a pattern of {language code}_{script} Match langTagMatch = LangTagPattern.Match(languageTag); diff --git a/src/SIL.Machine.AspNetCore/Services/NmtClearMLBuildJobFactory.cs b/src/SIL.Machine.AspNetCore/Services/NmtClearMLBuildJobFactory.cs index 22da69721..927310e72 100644 --- a/src/SIL.Machine.AspNetCore/Services/NmtClearMLBuildJobFactory.cs +++ b/src/SIL.Machine.AspNetCore/Services/NmtClearMLBuildJobFactory.cs @@ -40,13 +40,15 @@ public async Task CreateJobScriptAsync( Uri sharedFileUri = _sharedFileService.GetBaseUri(); string baseUri = sharedFileUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped); string folder = sharedFileUri.GetComponents(UriComponents.Path, UriFormat.Unescaped); + _languageTagService.ConvertToFlores200Code(engine.SourceLanguage, out string srcLang); + _languageTagService.ConvertToFlores200Code(engine.TargetLanguage, out string trgLang); return "from machine.jobs.build_nmt_engine import run\n" + "args = {\n" + $" 'model_type': '{_options.CurrentValue.ModelType}',\n" + $" 'engine_id': '{engineId}',\n" + $" 'build_id': '{buildId}',\n" - + $" 'src_lang': '{_languageTagService.ConvertToFlores200Code(engine.SourceLanguage)}',\n" - + $" 'trg_lang': '{_languageTagService.ConvertToFlores200Code(engine.TargetLanguage)}',\n" + + $" 'src_lang': '{srcLang}',\n" + + $" 'trg_lang': '{trgLang}',\n" + $" 'shared_file_uri': '{baseUri}',\n" + $" 'shared_file_folder': '{folder}',\n" + (buildOptions is not null ? $" 'build_options': '''{buildOptions}''',\n" : "") diff --git a/src/SIL.Machine.AspNetCore/Services/NmtEngineService.cs b/src/SIL.Machine.AspNetCore/Services/NmtEngineService.cs index 74a2cec11..287ab94fa 100644 --- a/src/SIL.Machine.AspNetCore/Services/NmtEngineService.cs +++ b/src/SIL.Machine.AspNetCore/Services/NmtEngineService.cs @@ -7,31 +7,23 @@ public static class NmtBuildStages public const string Postprocess = "postprocess"; } -public class NmtEngineService : ITranslationEngineService +public class NmtEngineService( + IPlatformService platformService, + IDistributedReaderWriterLockFactory lockFactory, + IDataAccessContext dataAccessContext, + IRepository engines, + IBuildJobService buildJobService, + ILanguageTagService languageTagService, + ClearMLMonitorService clearMLMonitorService + ) : ITranslationEngineService { - private readonly IDistributedReaderWriterLockFactory _lockFactory; - private readonly IPlatformService _platformService; - private readonly IDataAccessContext _dataAccessContext; - private readonly IRepository _engines; - private readonly IBuildJobService _buildJobService; - private readonly ClearMLMonitorService _clearMLMonitorService; - - public NmtEngineService( - IPlatformService platformService, - IDistributedReaderWriterLockFactory lockFactory, - IDataAccessContext dataAccessContext, - IRepository engines, - IBuildJobService buildJobService, - ClearMLMonitorService clearMLMonitorService - ) - { - _lockFactory = lockFactory; - _platformService = platformService; - _dataAccessContext = dataAccessContext; - _engines = engines; - _buildJobService = buildJobService; - _clearMLMonitorService = clearMLMonitorService; - } + private readonly IDistributedReaderWriterLockFactory _lockFactory = lockFactory; + private readonly IPlatformService _platformService = platformService; + private readonly IDataAccessContext _dataAccessContext = dataAccessContext; + private readonly IRepository _engines = engines; + private readonly IBuildJobService _buildJobService = buildJobService; + private readonly ILanguageTagService _languageTagService = languageTagService; + private readonly ClearMLMonitorService _clearMLMonitorService = clearMLMonitorService; public TranslationEngineType Type => TranslationEngineType.Nmt; @@ -151,6 +143,11 @@ public Task GetQueueSizeAsync(CancellationToken cancellationToken = default return Task.FromResult(_clearMLMonitorService.QueueSize); } + public bool IsLanguageNativeToModel(string language, out string internalCode) + { + return _languageTagService.ConvertToFlores200Code(language, out internalCode); + } + private async Task CancelBuildJobAsync(string engineId, CancellationToken cancellationToken) { (string? buildId, BuildJobState jobState) = await _buildJobService.CancelBuildJobAsync( diff --git a/src/SIL.Machine.AspNetCore/Services/NmtPreprocessBuildJob.cs b/src/SIL.Machine.AspNetCore/Services/NmtPreprocessBuildJob.cs index 540a49438..29239ad80 100644 --- a/src/SIL.Machine.AspNetCore/Services/NmtPreprocessBuildJob.cs +++ b/src/SIL.Machine.AspNetCore/Services/NmtPreprocessBuildJob.cs @@ -47,14 +47,11 @@ CancellationToken cancellationToken TranslationEngine? engine = await Engines.GetAsync(e => e.EngineId == engineId, cancellationToken); if (engine is null) throw new OperationCanceledException($"Engine {engineId} does not exist. Build canceled."); - _buildPreprocessSummary.Add( - "SourceLanguageResolved", - _languageTagService.ConvertToFlores200Code(engine.SourceLanguage) - ); - _buildPreprocessSummary.Add( - "TargetLanguageResolved", - _languageTagService.ConvertToFlores200Code(engine.TargetLanguage) - ); + + _languageTagService.ConvertToFlores200Code(engine.SourceLanguage, out string srcLang); + _buildPreprocessSummary.Add("SourceLanguageResolved", srcLang); + _languageTagService.ConvertToFlores200Code(engine.TargetLanguage, out string trgLang); + _buildPreprocessSummary.Add("TargetLanguageResolved", trgLang); Logger.LogInformation("{summary}", _buildPreprocessSummary.ToJsonString()); await using (await @lock.WriterLockAsync(cancellationToken: cancellationToken)) diff --git a/src/SIL.Machine.AspNetCore/Services/ServalTranslationEngineServiceV1.cs b/src/SIL.Machine.AspNetCore/Services/ServalTranslationEngineServiceV1.cs index fb87853c6..d1357013f 100644 --- a/src/SIL.Machine.AspNetCore/Services/ServalTranslationEngineServiceV1.cs +++ b/src/SIL.Machine.AspNetCore/Services/ServalTranslationEngineServiceV1.cs @@ -3,22 +3,16 @@ namespace SIL.Machine.AspNetCore.Services; -public class ServalTranslationEngineServiceV1 : TranslationEngineApi.TranslationEngineApiBase +public class ServalTranslationEngineServiceV1( + IEnumerable engineServices, + HealthCheckService healthCheckService + ) : TranslationEngineApi.TranslationEngineApiBase { private static readonly Empty Empty = new(); - private readonly Dictionary _engineServices; + private readonly Dictionary _engineServices = engineServices.ToDictionary(es => es.Type); - private readonly HealthCheckService _healthCheckService; - - public ServalTranslationEngineServiceV1( - IEnumerable engineServices, - HealthCheckService healthCheckService - ) - { - _engineServices = engineServices.ToDictionary(es => es.Type); - _healthCheckService = healthCheckService; - } + private readonly HealthCheckService _healthCheckService = healthCheckService; public override async Task Create(CreateRequest request, ServerCallContext context) { @@ -133,6 +127,22 @@ ServerCallContext context return new GetQueueSizeResponse { Size = await engineService.GetQueueSizeAsync(context.CancellationToken) }; } + public override Task GetLanguageInfo( + GetLanguageInfoRequest request, + ServerCallContext context + ) + { + ITranslationEngineService engineService = GetEngineService(request.EngineType); + bool isNative = engineService.IsLanguageNativeToModel(request.Language, out string internalCode); + return Task.FromResult( + new GetLanguageInfoResponse + { + InternalCode = internalCode, + IsNative = isNative, + } + ); + } + public override async Task HealthCheck(Empty request, ServerCallContext context) { HealthReport healthReport = await _healthCheckService.CheckHealthAsync(); diff --git a/src/SIL.Machine.AspNetCore/Services/SmtTransferEngineService.cs b/src/SIL.Machine.AspNetCore/Services/SmtTransferEngineService.cs index 3f1ffaf7f..9baadb2cf 100644 --- a/src/SIL.Machine.AspNetCore/Services/SmtTransferEngineService.cs +++ b/src/SIL.Machine.AspNetCore/Services/SmtTransferEngineService.cs @@ -210,6 +210,11 @@ public Task GetQueueSizeAsync(CancellationToken cancellationToken = default return Task.FromResult(Convert.ToInt32(_jobStorage.GetMonitoringApi().EnqueuedCount("smt_transfer"))); } + public bool IsLanguageNativeToModel(string language, out string internalCode) + { + throw new NotSupportedException("SMT transfer engines do not support language info."); + } + private async Task CancelBuildJobAsync(string engineId, CancellationToken cancellationToken) { (string? buildId, BuildJobState jobState) = await _buildJobService.CancelBuildJobAsync( diff --git a/src/SIL.Machine.AspNetCore/data/flores200languages.csv b/src/SIL.Machine.AspNetCore/data/flores200languages.csv new file mode 100644 index 000000000..a97345541 --- /dev/null +++ b/src/SIL.Machine.AspNetCore/data/flores200languages.csv @@ -0,0 +1,205 @@ +language, code +Acehnese (Arabic script), ace_Arab +Acehnese (Latin script), ace_Latn +Mesopotamian Arabic, acm_Arab +Ta’izzi-Adeni Arabic, acq_Arab +Tunisian Arabic, aeb_Arab +Afrikaans, afr_Latn +South Levantine Arabic, ajp_Arab +Akan, aka_Latn +Amharic, amh_Ethi +North Levantine Arabic, apc_Arab +Modern Standard Arabic, arb_Arab +Modern Standard Arabic (Romanized), arb_Latn +Najdi Arabic, ars_Arab +Moroccan Arabic, ary_Arab +Egyptian Arabic, arz_Arab +Assamese, asm_Beng +Asturian, ast_Latn +Awadhi, awa_Deva +Central Aymara, ayr_Latn +South Azerbaijani, azb_Arab +North Azerbaijani, azj_Latn +Bashkir, bak_Cyrl +Bambara, bam_Latn +Balinese, ban_Latn +Belarusian, bel_Cyrl +Bemba, bem_Latn +Bengali, ben_Beng +Bhojpuri, bho_Deva +Banjar (Arabic script), bjn_Arab +Banjar (Latin script), bjn_Latn +Standard Tibetan, bod_Tibt +Bosnian, bos_Latn +Buginese, bug_Latn +Bulgarian, bul_Cyrl +Catalan, cat_Latn +Cebuano, ceb_Latn +Czech, ces_Latn +Chokwe, cjk_Latn +Central Kurdish, ckb_Arab +Crimean Tatar, crh_Latn +Welsh, cym_Latn +Danish, dan_Latn +German, deu_Latn +Southwestern Dinka, dik_Latn +Dyula, dyu_Latn +Dzongkha, dzo_Tibt +Greek, ell_Grek +English, eng_Latn +Esperanto, epo_Latn +Estonian, est_Latn +Basque, eus_Latn +Ewe, ewe_Latn +Faroese, fao_Latn +Fijian, fij_Latn +Finnish, fin_Latn +Fon, fon_Latn +French, fra_Latn +Friulian, fur_Latn +Nigerian Fulfulde, fuv_Latn +Scottish Gaelic, gla_Latn +Irish, gle_Latn +Galician, glg_Latn +Guarani, grn_Latn +Gujarati, guj_Gujr +Haitian Creole, hat_Latn +Hausa, hau_Latn +Hebrew, heb_Hebr +Hindi, hin_Deva +Chhattisgarhi, hne_Deva +Croatian, hrv_Latn +Hungarian, hun_Latn +Armenian, hye_Armn +Igbo, ibo_Latn +Ilocano, ilo_Latn +Indonesian, ind_Latn +Icelandic, isl_Latn +Italian, ita_Latn +Javanese, jav_Latn +Japanese, jpn_Jpan +Kabyle, kab_Latn +Jingpho, kac_Latn +Kamba, kam_Latn +Kannada, kan_Knda +Kashmiri (Arabic script), kas_Arab +Kashmiri (Devanagari script), kas_Deva +Georgian, kat_Geor +Central Kanuri (Arabic script), knc_Arab +Central Kanuri (Latin script), knc_Latn +Kazakh, kaz_Cyrl +Kabiyè, kbp_Latn +Kabuverdianu, kea_Latn +Khmer, khm_Khmr +Kikuyu, kik_Latn +Kinyarwanda, kin_Latn +Kyrgyz, kir_Cyrl +Kimbundu, kmb_Latn +Northern Kurdish, kmr_Latn +Kikongo, kon_Latn +Korean, kor_Hang +Lao, lao_Laoo +Ligurian, lij_Latn +Limburgish, lim_Latn +Lingala, lin_Latn +Lithuanian, lit_Latn +Lombard, lmo_Latn +Latgalian, ltg_Latn +Luxembourgish, ltz_Latn +Luba-Kasai, lua_Latn +Ganda, lug_Latn +Luo, luo_Latn +Mizo, lus_Latn +Standard Latvian, lvs_Latn +Magahi, mag_Deva +Maithili, mai_Deva +Malayalam, mal_Mlym +Marathi, mar_Deva +Minangkabau (Arabic script), min_Arab +Minangkabau (Latin script), min_Latn +Macedonian, mkd_Cyrl +Plateau Malagasy, plt_Latn +Maltese, mlt_Latn +Meitei (Bengali script), mni_Beng +Halh Mongolian, khk_Cyrl +Mossi, mos_Latn +Maori, mri_Latn +Burmese, mya_Mymr +Dutch, nld_Latn +Norwegian Nynorsk, nno_Latn +Norwegian Bokmål, nob_Latn +Nepali, npi_Deva +Northern Sotho, nso_Latn +Nuer, nus_Latn +Nyanja, nya_Latn +Occitan, oci_Latn +West Central Oromo, gaz_Latn +Odia, ory_Orya +Pangasinan, pag_Latn +Eastern Panjabi, pan_Guru +Papiamento, pap_Latn +Western Persian, pes_Arab +Polish, pol_Latn +Portuguese, por_Latn +Dari, prs_Arab +Southern Pashto, pbt_Arab +Ayacucho Quechua, quy_Latn +Romanian, ron_Latn +Rundi, run_Latn +Russian, rus_Cyrl +Sango, sag_Latn +Sanskrit, san_Deva +Santali, sat_Olck +Sicilian, scn_Latn +Shan, shn_Mymr +Sinhala, sin_Sinh +Slovak, slk_Latn +Slovenian, slv_Latn +Samoan, smo_Latn +Shona, sna_Latn +Sindhi, snd_Arab +Somali, som_Latn +Southern Sotho, sot_Latn +Spanish, spa_Latn +Tosk Albanian, als_Latn +Sardinian, srd_Latn +Serbian, srp_Cyrl +Swati, ssw_Latn +Sundanese, sun_Latn +Swedish, swe_Latn +Swahili, swh_Latn +Silesian, szl_Latn +Tamil, tam_Taml +Tatar, tat_Cyrl +Telugu, tel_Telu +Tajik, tgk_Cyrl +Tagalog, tgl_Latn +Thai, tha_Thai +Tigrinya, tir_Ethi +Tamasheq (Latin script), taq_Latn +Tamasheq (Tifinagh script), taq_Tfng +Tok Pisin, tpi_Latn +Tswana, tsn_Latn +Tsonga, tso_Latn +Turkmen, tuk_Latn +Tumbuka, tum_Latn +Turkish, tur_Latn +Twi, twi_Latn +Central Atlas Tamazight, tzm_Tfng +Uyghur, uig_Arab +Ukrainian, ukr_Cyrl +Umbundu, umb_Latn +Urdu, urd_Arab +Northern Uzbek, uzn_Latn +Venetian, vec_Latn +Vietnamese, vie_Latn +Waray, war_Latn +Wolof, wol_Latn +Xhosa, xho_Latn +Eastern Yiddish, ydd_Hebr +Yoruba, yor_Latn +Yue Chinese, yue_Hant +Chinese (Simplified), zho_Hans +Chinese (Traditional), zho_Hant +Standard Malay, zsm_Latn +Zulu, zul_Latn \ No newline at end of file diff --git a/tests/SIL.Machine.AspNetCore.Tests/Services/LanguageTagServiceTests.cs b/tests/SIL.Machine.AspNetCore.Tests/Services/LanguageTagServiceTests.cs index 781873d31..db7cae47d 100644 --- a/tests/SIL.Machine.AspNetCore.Tests/Services/LanguageTagServiceTests.cs +++ b/tests/SIL.Machine.AspNetCore.Tests/Services/LanguageTagServiceTests.cs @@ -13,93 +13,37 @@ public LanguageTagServiceTests() } [Test] - public void ConvertToFlores200Code_Iso639_1Code() - { - string code = _languageTagService.ConvertToFlores200Code("es"); - Assert.That(code, Is.EqualTo("spa_Latn")); - } - - [Test] - public void ConvertToFlores200Code_Iso639_3Code() - { - string code = _languageTagService.ConvertToFlores200Code("hne"); - Assert.That(code, Is.EqualTo("hne_Deva")); - } - - [Test] - public void ConvertToFlores200Code_ScriptCode() - { - string code = _languageTagService.ConvertToFlores200Code("ks-Arab"); - Assert.That(code, Is.EqualTo("kas_Arab")); - } - - [Test] - public void ConvertToFlores200Code_InvalidLangTag() - { - string code = _languageTagService.ConvertToFlores200Code("srp_Cyrl"); - Assert.That(code, Is.EqualTo("srp_Cyrl")); - } - - [Test] - public void ConvertToFlores200Code_ChineseNoScript() - { - string code = _languageTagService.ConvertToFlores200Code("zh"); - Assert.That(code, Is.EqualTo("zho_Hans")); - } - - [Test] - public void ConvertToFlores200Code_ChineseScript() - { - string code = _languageTagService.ConvertToFlores200Code("zh-Hant"); - Assert.That(code, Is.EqualTo("zho_Hant")); - } - - [Test] - public void ConvertToFlores200Code_ChineseRegion() - { - string code = _languageTagService.ConvertToFlores200Code("zh-TW"); - Assert.That(code, Is.EqualTo("zho_Hant")); - } - - [Test] - public void ConvertToFlores200Code_MandarinChineseNoScript() - { - string code = _languageTagService.ConvertToFlores200Code("cmn"); - Assert.That(code, Is.EqualTo("zho_Hans")); - } - - [Test] - public void ConvertToFlores200Code_MandarinChineseScript() - { - string code = _languageTagService.ConvertToFlores200Code("cmn-Hant"); - Assert.That(code, Is.EqualTo("zho_Hant")); - } - - [Test] - public void ConvertToFlores200Code_Macrolanguage() - { - string code = _languageTagService.ConvertToFlores200Code("ms"); - Assert.That(code, Is.EqualTo("zsm_Latn")); - } - - [Test] - public void ConvertToFlores200Code_Arabic() - { - string code = _languageTagService.ConvertToFlores200Code("arb"); - Assert.That(code, Is.EqualTo("arb_Arab")); - } - - [Test] - public void ConvertToFlores200Code_HandleISO639_3_InsteadOfISO639_1() - { - string code = _languageTagService.ConvertToFlores200Code("eng"); - Assert.That(code, Is.EqualTo("eng_Latn")); - } - - [Test] - public void ConvertToFlores200Code_DashToUnderscore() - { - string code = _languageTagService.ConvertToFlores200Code("eng-Latn"); - Assert.That(code, Is.EqualTo("eng_Latn")); + [TestCase("es", "spa_Latn", Description = "Iso639_1Code")] + [TestCase("hne", "hne_Deva", Description = "Iso639_3Code")] + [TestCase("ks-Arab", "kas_Arab", Description = "ScriptCode")] + [TestCase("srp_Cyrl", "srp_Cyrl", Description = "InvalidLangTag")] + [TestCase("zh", "zho_Hans", Description = "ChineseNoScript")] + [TestCase("zh-Hant", "zho_Hant", Description = "ChineseScript")] + [TestCase("zh-TW", "zho_Hant", Description = "ChineseRegion")] + [TestCase("cmn", "zho_Hans", Description = "MandarinChineseNoScript")] + [TestCase("cmn-Hant", "zho_Hant", Description = "MandarinChineseScript")] + [TestCase("ms", "zsm_Latn", Description = "Macrolanguage")] + [TestCase("arb", "arb_Arab", Description = "Arabic")] + [TestCase("eng", "eng_Latn", Description = "InsteadOfISO639_1")] + [TestCase("eng-Latn", "eng_Latn", Description = "DashToUnderscore")] + public void ConvertToFlores200CodeTest(string language, string internalCodeTruth) + { + _languageTagService.ConvertToFlores200Code(language, out string internalCode); + Assert.That(internalCode, Is.EqualTo(internalCodeTruth)); + } + + [Test] + [TestCase("en", "eng_Latn", true)] + [TestCase("ms", "zsm_Latn", true)] + [TestCase("cmn", "zho_Hans", true)] + [TestCase("xyz", "xyz", false)] + public void GetLanguageInfoAsync(string languageCode, string? resolvedLanguageCode, bool nativeLanguageSupport) + { + bool isNative = _languageTagService.ConvertToFlores200Code(languageCode, out string internalCode); + Assert.Multiple(() => + { + Assert.That(internalCode, Is.EqualTo(resolvedLanguageCode)); + Assert.That(isNative, Is.EqualTo(nativeLanguageSupport)); + }); } } diff --git a/tests/SIL.Machine.AspNetCore.Tests/Services/NmtClearMLBuildJobFactoryTests.cs b/tests/SIL.Machine.AspNetCore.Tests/Services/NmtClearMLBuildJobFactoryTests.cs index 34b10e5da..ef8f3ffb9 100644 --- a/tests/SIL.Machine.AspNetCore.Tests/Services/NmtClearMLBuildJobFactoryTests.cs +++ b/tests/SIL.Machine.AspNetCore.Tests/Services/NmtClearMLBuildJobFactoryTests.cs @@ -86,8 +86,10 @@ public TestEnvironment() SharedFileService = Substitute.For(); SharedFileService.GetBaseUri().Returns(new Uri("s3://bucket/folder1/folder2")); LanguageTagService = Substitute.For(); - LanguageTagService.ConvertToFlores200Code("es").Returns("spa_Latn"); - LanguageTagService.ConvertToFlores200Code("en").Returns("eng_Latn"); + LanguageTagService.ConvertToFlores200Code("es", out string spa); + Assert.That(spa, Is.EqualTo("spa_Latn")); + LanguageTagService.ConvertToFlores200Code("en", out string eng); + Assert.That(eng, Is.EqualTo("eng_Latn")); BuildJobFactory = new NmtClearMLBuildJobFactory(SharedFileService, LanguageTagService, Engines, Options); } } diff --git a/tests/SIL.Machine.AspNetCore.Tests/Services/NmtEngineServiceTests.cs b/tests/SIL.Machine.AspNetCore.Tests/Services/NmtEngineServiceTests.cs index 52cb1f672..4aff145a8 100644 --- a/tests/SIL.Machine.AspNetCore.Tests/Services/NmtEngineServiceTests.cs +++ b/tests/SIL.Machine.AspNetCore.Tests/Services/NmtEngineServiceTests.cs @@ -196,6 +196,7 @@ private NmtEngineService CreateService() new MemoryDataAccessContext(), Engines, BuildJobService, + new LanguageTagService(), ClearMLMonitorService ); }