150 lines
4.8 KiB
C#
150 lines
4.8 KiB
C#
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Windows.Data;
|
|
using CursorLang.Core.Services;
|
|
|
|
namespace CursorLang.Core.Tests.Services;
|
|
|
|
public sealed class LocalizationServiceTests
|
|
{
|
|
[Fact]
|
|
public void The_interface_starts_out_in_English()
|
|
{
|
|
Assert.Equal("en", new LocalizationService().CurrentLanguage);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_string_comes_from_the_resources_of_the_chosen_language()
|
|
{
|
|
var localization = new LocalizationService();
|
|
|
|
string english = localization["SettingsTitle"];
|
|
localization.CurrentLanguage = "ru";
|
|
string russian = localization["SettingsTitle"];
|
|
|
|
Assert.False(string.IsNullOrWhiteSpace(english));
|
|
Assert.False(string.IsNullOrWhiteSpace(russian));
|
|
Assert.NotEqual(english, russian);
|
|
}
|
|
|
|
// A missing key shows in the interface but does not bring the app down
|
|
[Fact]
|
|
public void An_unknown_key_comes_back_as_is()
|
|
{
|
|
var localization = new LocalizationService();
|
|
|
|
Assert.Equal("NoSuchKey", localization["NoSuchKey"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_language_change_is_announced_to_subscribers()
|
|
{
|
|
var localization = new LocalizationService();
|
|
List<string?> changed = [];
|
|
localization.PropertyChanged += (_, e) => changed.Add(e.PropertyName);
|
|
|
|
localization.CurrentLanguage = "ru";
|
|
|
|
Assert.Contains(nameof(LocalizationService.CurrentLanguage), changed);
|
|
|
|
// The indexer is announced separately: that is how the whole text refreshes
|
|
Assert.Contains(Binding.IndexerName, changed);
|
|
}
|
|
|
|
[Fact]
|
|
public void The_same_language_is_not_announced_again()
|
|
{
|
|
var localization = new LocalizationService { CurrentLanguage = "ru" };
|
|
List<string?> changed = [];
|
|
localization.PropertyChanged += (_, e) => changed.Add(e.PropertyName);
|
|
|
|
localization.CurrentLanguage = "ru";
|
|
|
|
Assert.Empty(changed);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
[InlineData(null)]
|
|
public void An_empty_language_changes_nothing(string? value)
|
|
{
|
|
var localization = new LocalizationService();
|
|
List<string?> changed = [];
|
|
localization.PropertyChanged += (_, e) => changed.Add(e.PropertyName);
|
|
|
|
localization.CurrentLanguage = value!;
|
|
|
|
Assert.Equal("en", localization.CurrentLanguage);
|
|
Assert.Empty(changed);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_language_with_a_country_falls_back_to_the_language_code()
|
|
{
|
|
var localization = new LocalizationService { CurrentLanguage = "ru-RU" };
|
|
|
|
Assert.Equal("ru", localization.CurrentLanguage);
|
|
}
|
|
|
|
// Changing the app language has to change the language of the thread as
|
|
// well: other texts, down to system messages, depend on it
|
|
[Fact]
|
|
public void A_language_change_changes_the_language_of_the_thread()
|
|
{
|
|
CultureInfo previous = CultureInfo.CurrentUICulture;
|
|
try
|
|
{
|
|
var localization = new LocalizationService { CurrentLanguage = "ru" };
|
|
|
|
Assert.Equal("ru", CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
|
|
Assert.Equal("ru", localization.CurrentLanguage);
|
|
}
|
|
finally
|
|
{
|
|
CultureInfo.CurrentUICulture = previous;
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void English_and_Russian_are_offered_for_choosing()
|
|
{
|
|
IReadOnlyList<LanguageOption> languages = new LocalizationService().AvailableLanguages;
|
|
|
|
Assert.Equal(2, languages.Count);
|
|
Assert.Contains(languages, language => language.Code == "en");
|
|
Assert.Contains(languages, language => language.Code == "ru");
|
|
}
|
|
|
|
// A language is named in itself: that way it is recognised even by someone
|
|
// who does not know the current interface language
|
|
[Fact]
|
|
public void The_languages_are_named_in_themselves()
|
|
{
|
|
IReadOnlyList<LanguageOption> languages = new LocalizationService().AvailableLanguages;
|
|
|
|
Assert.Equal("English", languages.Single(language => language.Code == "en").DisplayName);
|
|
Assert.Equal("Русский", languages.Single(language => language.Code == "ru").DisplayName);
|
|
}
|
|
|
|
// Accessibility tools take the name of a list item from ToString
|
|
[Fact]
|
|
public void A_language_presents_itself_by_its_name()
|
|
{
|
|
Assert.Equal("Русский", new LanguageOption("ru", "Русский").ToString());
|
|
}
|
|
|
|
[Fact]
|
|
public void Languages_with_the_same_code_and_name_are_equal()
|
|
{
|
|
Assert.Equal(new LanguageOption("ru", "Русский"), new LanguageOption("ru", "Русский"));
|
|
Assert.NotEqual(new LanguageOption("ru", "Русский"), new LanguageOption("en", "English"));
|
|
}
|
|
|
|
[Fact]
|
|
public void The_service_reports_changes_as_INotifyPropertyChanged()
|
|
{
|
|
Assert.IsAssignableFrom<INotifyPropertyChanged>(new LocalizationService());
|
|
}
|
|
}
|