Skip to content

Commit

Permalink
Merge pull request #68 from sillsdev/avoid-substitution-if-no-transla…
Browse files Browse the repository at this point in the history
…tion

In LanguageChoosingDialog, handle off-line case where translator just returns source string
  • Loading branch information
tombogle authored Jul 9, 2019
2 parents 1a4c8ed + 9d468b3 commit ad557c6
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed

- If translator returns an unmodified source string, don't substitute the English language name for the vernacular name.

## [4.0.1] - 2019-07-08

Expand Down
2 changes: 1 addition & 1 deletion src/L10NSharp/UI/LanguageChoosingDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public LanguageChoosingDialog(L10NCultureInfo requestedCulture, Icon icon)
void Application_Idle(object sender, EventArgs e)
{
Application.Idle -= Application_Idle;
_model.SetTranslator(new BingTranslator("en", _model.RequestedCultureTwoLetterISOLanguageName));
_model.TranslateStrings(new BingTranslator("en", _model.RequestedCultureTwoLetterISOLanguageName));
_messageLabel.Text = _model.Message;
_OKButton.Text = _model.AcceptButtonText;
Text = _model.WindowTitle;
Expand Down
33 changes: 25 additions & 8 deletions src/L10NSharp/UI/LanguageChoosingDialogViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
using System;
using System.Diagnostics;
using L10NSharp.Translators;

namespace L10NSharp.UI
{
public class LanguageChoosingDialogViewModel
internal class LanguageChoosingDialogViewModel
{
private readonly L10NCultureInfo _requestedCulture;
private readonly string _messageLabelFormat;
private readonly string _acceptButtonText;
private readonly string _windowTitle;

public LanguageChoosingDialogViewModel(string messageLabelFormat, string acceptButtonText, string windowTitle,
/// <summary>
/// Creates a new LanguageChoosingDialogViewModel object to handle (asynchronous) translation of message and other UI strings
/// displayed in the LanguageChoosingDialog.
/// </summary>
/// <param name="messageLabelFormat">Format string where param {0} is the native name of the requested UI language/culture and
/// param {1} is the English name of the requested UI language/culture</param>
/// <param name="acceptButtonText">The "OK" button text (not a format string)</param>
/// <param name="windowTitle">The dialog's title (not a format string)</param>
/// <param name="requestedCulture">The requested UI language/culture. Typically, this will not be English (though in some of
/// the tests it is)</param>
/// <param name="nonEnglishUiAction">An action that should be performed only if the requested culture is not English. In
/// production, this action will set up an action to be performed (once) on idle so that TranslateStrings can be called and
/// the UI can be updated to reflect the newly translated strings, if appropriate.</param>
internal LanguageChoosingDialogViewModel(string messageLabelFormat, string acceptButtonText, string windowTitle,
L10NCultureInfo requestedCulture, Action nonEnglishUiAction)
{
_messageLabelFormat = messageLabelFormat;
Expand All @@ -27,11 +41,14 @@ public LanguageChoosingDialogViewModel(string messageLabelFormat, string acceptB
nonEnglishUiAction?.Invoke();
}

public void SetTranslator(TranslatorBase translator)
internal void TranslateStrings(TranslatorBase translator)
{
try
{
var s = translator.TranslateText(string.Format(_messageLabelFormat, _requestedCulture.EnglishName, "{0}"));
var sourceString = string.Format(_messageLabelFormat, _requestedCulture.EnglishName, "{0}");
var s = translator.TranslateText(sourceString);
if (s == sourceString)
return;
if (s.Contains("{0}") && s.Length > 5) // If we just get back "{0} or "({0})", we won't consider that useful.
{
// Bing will presumably have translated the English string into the native language, so now we want
Expand Down Expand Up @@ -62,9 +79,9 @@ public void SetTranslator(TranslatorBase translator)
}
}

public string RequestedCultureTwoLetterISOLanguageName => _requestedCulture.TwoLetterISOLanguageName;
public string Message { get; private set; }
public string AcceptButtonText { get; private set; }
public string WindowTitle { get; private set; }
internal string RequestedCultureTwoLetterISOLanguageName => _requestedCulture.TwoLetterISOLanguageName;
internal string Message { get; private set; }
internal string AcceptButtonText { get; private set; }
internal string WindowTitle { get; private set; }
}
}
36 changes: 25 additions & 11 deletions src/L10NSharpTests/LanguageChoosingDialogViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,58 +85,58 @@ public void Constructor_BogusFormatString_Throws(string format)
}

[Test]
public void SetTranslator_RequestedCultureEnglish_TranslationAppliedOnceToEachString()
public void TranslateStrings_RequestedCultureEnglish_TranslationAppliedOnceToEachString()
{
var model = new LanguageChoosingDialogViewModel("Blah {0} ({1}) yup!", "OK", "Choose a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "en"),
null);
Assert.AreEqual("Blah English yup!", model.Message);
var translator = new TestTranslatorBumpyFrog();
model.SetTranslator(translator);
model.TranslateStrings(translator);
Assert.AreEqual("Bumpy frog Blah English yup!", model.Message);
Assert.AreEqual("Bumpy frog OK", model.AcceptButtonText);
Assert.AreEqual("Bumpy frog Choose a Language", model.WindowTitle);
Assert.IsTrue(translator.SourceStrings.SequenceEqual(new[] { "Blah English yup!", "OK", "Choose a Language" }));
}

[Test]
public void SetTranslator_RequestedCultureGermanNormalTranslation_TranslationAppliedOnceToEachString()
public void TranslateStrings_RequestedCultureGermanNormalTranslation_TranslationAppliedOnceToEachString()
{
var model = new LanguageChoosingDialogViewModel("No localization for {0} ({1})", "OK", "Choose a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "de"),
null);
Assert.AreEqual("No localization for German (Deutsch)", model.Message);
var translator = new TestTranslatorGerman();
model.SetTranslator(translator);
model.TranslateStrings(translator);
Assert.AreEqual("Ich spreche No localization for Deutsch (German)", model.Message);
Assert.AreEqual("Ich spreche OK", model.AcceptButtonText);
Assert.AreEqual("Ich spreche Choose a Language", model.WindowTitle);
Assert.IsTrue(translator.SourceStrings.SequenceEqual(new[] { "No localization for German ({0})", "OK", "Choose a Language" }));
}

[Test]
public void SetTranslator_ChangeTranslator_TranslationAppliedToOriginalString()
public void TranslateStrings_ChangeTranslator_TranslationAppliedToOriginalString()
{
var model = new LanguageChoosingDialogViewModel("No localization for {0} ({1})", "OK", "Choose a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "de"),
null);
Assert.AreEqual("No localization for German (Deutsch)", model.Message);
model.SetTranslator(new TestTranslatorBumpyFrog());
model.SetTranslator(new TestTranslatorGerman());
model.TranslateStrings(new TestTranslatorBumpyFrog());
model.TranslateStrings(new TestTranslatorGerman());
Assert.AreEqual("Ich spreche No localization for Deutsch (German)", model.Message);
Assert.AreEqual("Ich spreche OK", model.AcceptButtonText);
Assert.AreEqual("Ich spreche Choose a Language", model.WindowTitle);
}

[Test]
public void SetTranslator_RequestedCultureSpanishChokesOnFormatParam_TranslationReappliedToStringWithoutParam()
public void TranslateStrings_RequestedCultureSpanishChokesOnFormatParam_TranslationReappliedToStringWithoutParam()
{
var model = new LanguageChoosingDialogViewModel("No localization for {0} ({1})", "OK", "Choose a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "es"),
null);
Assert.AreEqual("No localization for Spanish (español)", model.Message);
var translator = new TestTranslatorSpanishChokesOnFormatParam();
model.SetTranslator(translator);
model.TranslateStrings(translator);
// Note: the test translator mimics Bing's behavior of replacing the English name of the requested language with the word "English" in the translation.
Assert.AreEqual("No choke No localization for English (español)", model.Message);
Assert.AreEqual("No choke OK", model.AcceptButtonText);
Expand All @@ -145,13 +145,27 @@ public void SetTranslator_RequestedCultureSpanishChokesOnFormatParam_Translation
}

[Test]
public void SetTranslator_TranslatorThrowsException_ExceptionSwallowedAndNoAttemptToTranslateOtherStrings()
public void TranslateStrings_TranslatorThrowsException_ExceptionSwallowedAndNoAttemptToTranslateOtherStrings()
{
var model = new LanguageChoosingDialogViewModel("No localization for {0} ({1})", "Okey-dokey", "Select a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "es"),
null);
var translator = new TestTranslatorThrowsException();
model.SetTranslator(translator);
model.TranslateStrings(translator);
Assert.AreEqual("No localization for Spanish (español)", model.Message);
Assert.AreEqual("Okey-dokey", model.AcceptButtonText);
Assert.AreEqual("Select a Language", model.WindowTitle);
Assert.IsTrue(translator.SourceStrings.SequenceEqual(new[] { "No localization for Spanish ({0})" }));
}

[Test]
public void TranslateStrings_TranslatorReturnsSourceString_NoAttemptToSubstituteEnglishNameOrTranslateOtherStrings()
{
var model = new LanguageChoosingDialogViewModel("No localization for {0} ({1})", "Okey-dokey", "Select a Language",
L10NCultureInfo.GetCultures(CultureTypes.NeutralCultures).First(c => c.TwoLetterISOLanguageName == "es"),
null);
var translator = new TestTranslatorBase(); // This translator just returns unmodified source string
model.TranslateStrings(translator);
Assert.AreEqual("No localization for Spanish (español)", model.Message);
Assert.AreEqual("Okey-dokey", model.AcceptButtonText);
Assert.AreEqual("Select a Language", model.WindowTitle);
Expand Down

0 comments on commit ad557c6

Please sign in to comment.