Skip to content

Commit

Permalink
Respect NeutralResourcesLanguageAttribute. Fix #19
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanLarsson committed Aug 6, 2016
1 parent fee3de8 commit 6a0ebfa
Show file tree
Hide file tree
Showing 24 changed files with 785 additions and 49 deletions.
9 changes: 8 additions & 1 deletion Gu.Localization.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{867813BE-358B-4C9E-9FA6-07168882AA9D}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EFFBB24C-1
.paket\Readme.paket.md = .paket\Readme.paket.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gu.Wpf.Localization.WithNeutralLanguage", "Gu.Wpf.Localization.WithNeutralLanguage\Gu.Wpf.Localization.WithNeutralLanguage.csproj", "{8F238B89-C06A-4935-8EE9-1E84D297DC4E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -79,6 +81,10 @@ Global
{24A5D9D2-60D8-47B7-8750-48E85A2218DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24A5D9D2-60D8-47B7-8750-48E85A2218DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24A5D9D2-60D8-47B7-8750-48E85A2218DE}.Release|Any CPU.Build.0 = Release|Any CPU
{8F238B89-C06A-4935-8EE9-1E84D297DC4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F238B89-C06A-4935-8EE9-1E84D297DC4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F238B89-C06A-4935-8EE9-1E84D297DC4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F238B89-C06A-4935-8EE9-1E84D297DC4E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -87,5 +93,6 @@ Global
{85009EF0-C922-4EDB-9648-495B56B30CFC} = {7C464917-49E0-40F2-BB85-EB16977B87A5}
{A8722CC6-E477-43B6-A1A0-B7A062FBB290} = {7C464917-49E0-40F2-BB85-EB16977B87A5}
{D77D4706-D218-4DC6-B117-611AF843FED9} = {7C464917-49E0-40F2-BB85-EB16977B87A5}
{8F238B89-C06A-4935-8EE9-1E84D297DC4E} = {7C464917-49E0-40F2-BB85-EB16977B87A5}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions Gu.Localization/Internals/Culture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ internal static bool Exists(string name)
return CultureNames.Contains(name);
}

internal static bool TryGet(string name, out CultureInfo culture)
{
if (Exists(name))
{
culture = CultureInfo.GetCultureInfo(name);
return true;
}

culture = null;
return false;
}

internal static bool NameEquals(CultureInfo first, CultureInfo other)
{
return CultureInfoComparer.ByName.Equals(first, other);
Expand Down
35 changes: 29 additions & 6 deletions Gu.Localization/Internals/ResourceCultures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;

/// <summary>Utility class for finding resources.</summary>
internal static class ResourceCultures
Expand All @@ -17,7 +19,7 @@ internal static class ResourceCultures
/// 2) Check that the folder contains resource files
/// The result is not cached
/// </summary>
/// <param name="executingDirectory">The directory to chek</param>
/// <param name="executingDirectory">The directory to check</param>
/// <returns>The cultures found. If none an empty list is returned.</returns>
internal static IReadOnlyList<CultureInfo> GetAllCultures(DirectoryInfo executingDirectory)
{
Expand All @@ -26,8 +28,8 @@ internal static IReadOnlyList<CultureInfo> GetAllCultures(DirectoryInfo executin
return EmptyCultures;
}

List<CultureInfo> cultures = null;
foreach (var directory in executingDirectory.EnumerateDirectories())
HashSet<CultureInfo> cultures = null;
foreach (var directory in executingDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
{
var cultureName = directory.Name;
if (!Culture.Exists(directory.Name))
Expand All @@ -36,17 +38,38 @@ internal static IReadOnlyList<CultureInfo> GetAllCultures(DirectoryInfo executin
}

if (directory.EnumerateFiles("*.resources.dll", SearchOption.TopDirectoryOnly).Any())
{
CultureInfo culture;
if (Culture.TryGet(cultureName, out culture))
{
if (cultures == null)
{
cultures = new HashSet<CultureInfo>(CultureInfoComparer.ByName);
}

cultures.Add(culture);
}
}
}

var entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null)
{
var neutralLanguageAttribute = (NeutralResourcesLanguageAttribute)Attribute.GetCustomAttribute(entryAssembly, typeof(NeutralResourcesLanguageAttribute));
var name = neutralLanguageAttribute?.CultureName;
CultureInfo neutralCulture;
if (name != null && Culture.TryGet(name, out neutralCulture))
{
if (cultures == null)
{
cultures = new List<CultureInfo>();
cultures = new HashSet<CultureInfo>(CultureInfoComparer.ByName);
}

cultures.Add(CultureInfo.GetCultureInfo(cultureName));
cultures.Add(neutralCulture);
}
}

return cultures ?? EmptyCultures;
return cultures?.OrderBy(x => x.Name).ToArray() ?? EmptyCultures;
}

internal static DirectoryInfo DefaultResourceDirectory()
Expand Down
3 changes: 0 additions & 3 deletions Gu.Wpf.Localization.Demo/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
using System.Threading;
using System.Windows;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Xaml" />
<Reference Include="UIAutomationClient" />
<Reference Include="WindowsBase" />
</ItemGroup>
<Choose>
Expand All @@ -49,10 +50,12 @@
</When>
</Choose>
<ItemGroup>
<Compile Include="StartInfo.cs" />
<Compile Include="Helpers\StartInfo.cs" />
<Compile Include="Helpers\UiItemExt.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Todo.cs" />
<Compile Include="Translates.cs" />
<Compile Include="TranslatesDemoProject.cs" />
<Compile Include="TranslatesWithNeutralLanguage.cs" />
</ItemGroup>
<ItemGroup>
<None Include="paket.references" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=helpers/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
37 changes: 37 additions & 0 deletions Gu.Wpf.Localization.UiTests/Helpers/StartInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace Gu.Wpf.Localization.UiTests
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;

public static class StartInfo
{
public static ProcessStartInfo DemoProject { get; } = CreateStartUpInfo("Gu.Wpf.Localization.Demo", CultureInfo.GetCultureInfo("en"));

public static ProcessStartInfo WithNeutralLanguageProject { get; } = CreateStartUpInfo("Gu.Wpf.Localization.WithNeutralLanguage", CultureInfo.GetCultureInfo("en"));

private static ProcessStartInfo CreateStartUpInfo(string assemblyName, CultureInfo culture)
{
var processStartInfo = new ProcessStartInfo
{
Arguments = culture.Name,
FileName = GetExeFileName(assemblyName),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
return processStartInfo;
}

private static string GetExeFileName(string assemblyName)
{
var testAssembnly = Assembly.GetExecutingAssembly();
var testDirestory = Path.GetDirectoryName(new Uri(testAssembnly.CodeBase).AbsolutePath);
var exeDirectory = testDirestory.Replace(testAssembnly.GetName().Name, assemblyName);
var fileName = Path.Combine(exeDirectory, $"{assemblyName}.exe");
return fileName;
}
}
}
19 changes: 19 additions & 0 deletions Gu.Wpf.Localization.UiTests/Helpers/UiItemExt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Gu.Wpf.Localization.UiTests
{
using TestStack.White.UIItems;
using TestStack.White.UIItems.Finders;

public static class UiItemExt
{
public static string ItemStatus(this IUIItem item)
{
return (string)item.AutomationElement.Current.ItemStatus;
}

public static T GetByText<T>(this UIItemContainer container, string text)
where T : UIItem
{
return container.Get<T>(SearchCriteria.ByText(text));
}
}
}
27 changes: 0 additions & 27 deletions Gu.Wpf.Localization.UiTests/StartInfo.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using TestStack.White.UIItems;
using TestStack.White.UIItems.WindowItems;

public class Translates
public class TranslatesDemoProject
{
private Application application;
private Window window;
Expand Down
48 changes: 48 additions & 0 deletions Gu.Wpf.Localization.UiTests/TranslatesWithNeutralLanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace Gu.Wpf.Localization.UiTests
{
using NUnit.Framework;
using TestStack.White;
using TestStack.White.UIItems;
using TestStack.White.UIItems.WindowItems;

public class TranslatesWithNeutralLanguage
{
private Application application;
private Window window;

[OneTimeSetUp]
public void OneTimeSetUp()
{
this.application = Application.AttachOrLaunch(StartInfo.WithNeutralLanguageProject);
this.window = this.application.GetWindow("MainWindow");
}

[OneTimeTearDown]
public void OneTimeTearDown()
{
this.application?.Dispose();
}

[Test]
public void EffectiveCulture()
{
Assert.AreEqual("en", this.window.Get<Label>("CurrentCultureTextBlock").Text);
this.window.Get<RadioButton>("pt").Click();
Assert.AreEqual("pt", this.window.Get<Label>("CurrentCultureTextBlock").Text);
}

[Test]
public void VanillaXaml()
{
this.window.Get<RadioButton>("en").Click();
var groupBox = this.window.GetByText<GroupBox>("Vanilla xaml");
Assert.AreEqual("English", groupBox.Get<Label>("AllLanguagesTextBlock").Text);

this.window.Get<RadioButton>("pt").Click();
Assert.AreEqual("Português", groupBox.Get<Label>("AllLanguagesTextBlock").Text);

this.window.Get<RadioButton>("en").Click();
Assert.AreEqual("English", groupBox.Get<Label>("AllLanguagesTextBlock").Text);
}
}
}
6 changes: 6 additions & 0 deletions Gu.Wpf.Localization.WithNeutralLanguage/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
9 changes: 9 additions & 0 deletions Gu.Wpf.Localization.WithNeutralLanguage/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Application x:Class="Gu.Wpf.Localization.WithNeutralLanguage.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Gu.Wpf.Localization.WithNeutralLanguage"
StartupUri="MainWindow.xaml">
<Application.Resources>

</Application.Resources>
</Application>
19 changes: 19 additions & 0 deletions Gu.Wpf.Localization.WithNeutralLanguage/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Gu.Wpf.Localization.WithNeutralLanguage
{
using System.Globalization;
using System.Threading;
using System.Windows;

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (e.Args.Length == 1)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(e.Args[0]);
}

base.OnStartup(e);
}
}
}
Loading

0 comments on commit 6a0ebfa

Please sign in to comment.