Removed Moq from tests & enabled .NET Core
- Introduced AssemblyWrapper to enable testing - Cleaned up properties on ResourceManagerStringLocalizer - #15 Change "Strategy" to "Provider" - #19
This commit is contained in:
parent
9384848cc7
commit
4ba159afe7
|
|
@ -36,9 +36,9 @@ namespace LocalizationSample
|
|||
//}
|
||||
};
|
||||
|
||||
// Optionally create an app-specific strategy with just a delegate, e.g. look up user preference from DB.
|
||||
// Inserting it as position 0 ensures it has priority over any of the default strategies.
|
||||
//options.RequestCultureStrategies.Insert(0, new CustomRequestCultureStrategy(async context =>
|
||||
// Optionally create an app-specific provider with just a delegate, e.g. look up user preference from DB.
|
||||
// Inserting it as position 0 ensures it has priority over any of the default providers.
|
||||
//options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
|
||||
//{
|
||||
|
||||
//}));
|
||||
|
|
@ -74,13 +74,13 @@ $@"<!doctype html>
|
|||
function useCookie() {{
|
||||
var culture = document.getElementById('culture');
|
||||
var uiCulture = document.getElementById('uiCulture');
|
||||
var cookieValue = '{CookieRequestCultureStrategy.DefaultCookieName}=c='+culture.options[culture.selectedIndex].value+'|uic='+uiCulture.options[uiCulture.selectedIndex].value;
|
||||
var cookieValue = '{CookieRequestCultureProvider.DefaultCookieName}=c='+culture.options[culture.selectedIndex].value+'|uic='+uiCulture.options[uiCulture.selectedIndex].value;
|
||||
document.cookie = cookieValue;
|
||||
window.location = window.location.href.split('?')[0];
|
||||
}}
|
||||
|
||||
function clearCookie() {{
|
||||
document.cookie='{CookieRequestCultureStrategy.DefaultCookieName}=""""';
|
||||
document.cookie='{CookieRequestCultureProvider.DefaultCookieName}=""""';
|
||||
}}
|
||||
</script>
|
||||
</head>
|
||||
|
|
@ -101,7 +101,7 @@ $@"<!doctype html>
|
|||
await context.Response.WriteAsync("</form>");
|
||||
await context.Response.WriteAsync("<br />");
|
||||
await context.Response.WriteAsync("<table><tbody>");
|
||||
await context.Response.WriteAsync($"<tr><th>Winning strategy:</th><td>{requestCultureFeature.Strategy.GetType().Name}</td></tr>");
|
||||
await context.Response.WriteAsync($"<tr><th>Winning provider:</th><td>{requestCultureFeature.Provider.GetType().Name}</td></tr>");
|
||||
await context.Response.WriteAsync($"<tr><th>{SR["Current request culture:"]}</th><td>{requestCulture.Culture.DisplayName} ({requestCulture.Culture})</td></tr>");
|
||||
await context.Response.WriteAsync($"<tr><th>{SR["Current request UI culture:"]}</th><td>{requestCulture.UICulture.DisplayName} ({requestCulture.UICulture})</td></tr>");
|
||||
await context.Response.WriteAsync($"<tr><th>{SR["Current thread culture:"]}</th><td>{CultureInfo.CurrentCulture.DisplayName} ({CultureInfo.CurrentCulture})</td></tr>");
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Localization
|
|||
/// <summary>
|
||||
/// Determines the culture information for a request via the value of the Accept-Language header.
|
||||
/// </summary>
|
||||
public class AcceptLanguageHeaderRequestCultureStrategy : RequestCultureStrategy
|
||||
public class AcceptLanguageHeaderRequestCultureProvider : RequestCultureProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum number of values in the Accept-Language header to attempt to create a <see cref="System.Globalization.CultureInfo"/>
|
||||
|
|
@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Localization
|
|||
/// <summary>
|
||||
/// Determines the culture information for a request via the value of a cookie.
|
||||
/// </summary>
|
||||
public class CookieRequestCultureStrategy : RequestCultureStrategy
|
||||
public class CookieRequestCultureProvider : RequestCultureProvider
|
||||
{
|
||||
private static readonly char[] _cookieSeparator = new[] { '|' };
|
||||
private static readonly string _culturePrefix = "c=";
|
||||
|
|
@ -11,23 +11,23 @@ namespace Microsoft.AspNet.Localization
|
|||
/// <summary>
|
||||
/// Determines the culture information for a request via the configured delegate.
|
||||
/// </summary>
|
||||
public class CustomRequestCultureStrategy : RequestCultureStrategy
|
||||
public class CustomRequestCultureProvider : RequestCultureProvider
|
||||
{
|
||||
private readonly Func<HttpContext, Task<RequestCulture>> _strategy;
|
||||
private readonly Func<HttpContext, Task<RequestCulture>> _provider;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CustomRequestCultureStrategy"/> using the specified delegate.
|
||||
/// Creates a new <see cref="CustomRequestCultureProvider"/> using the specified delegate.
|
||||
/// </summary>
|
||||
/// <param name="strategy">The strategy delegate.</param>
|
||||
public CustomRequestCultureStrategy([NotNull] Func<HttpContext, Task<RequestCulture>> strategy)
|
||||
/// <param name="provider">The provider delegate.</param>
|
||||
public CustomRequestCultureProvider([NotNull] Func<HttpContext, Task<RequestCulture>> provider)
|
||||
{
|
||||
_strategy = strategy;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<RequestCulture> DetermineRequestCulture([NotNull] HttpContext httpContext)
|
||||
{
|
||||
return _strategy(httpContext);
|
||||
return _provider(httpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,10 +14,10 @@ namespace Microsoft.AspNet.Localization
|
|||
RequestCulture RequestCulture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IRequestCultureStrategy"/> that determined the request's culture information.
|
||||
/// If the value is <c>null</c> then no strategy was used and the request's culture was set to the value of
|
||||
/// The <see cref="IRequestCultureProvider"/> that determined the request's culture information.
|
||||
/// If the value is <c>null</c> then no provider was used and the request's culture was set to the value of
|
||||
/// <see cref="RequestLocalizationOptions.DefaultRequestCulture"/>.
|
||||
/// </summary>
|
||||
IRequestCultureStrategy Strategy { get; }
|
||||
IRequestCultureProvider Provider { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -7,17 +7,17 @@ using Microsoft.AspNet.Http;
|
|||
namespace Microsoft.AspNet.Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a strategy for determining the culture information of an <see cref="HttpRequest"/>.
|
||||
/// Represents a provider for determining the culture information of an <see cref="HttpRequest"/>.
|
||||
/// </summary>
|
||||
public interface IRequestCultureStrategy
|
||||
public interface IRequestCultureProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the strategy to determine the culture of the given request.
|
||||
/// Implements the provider to determine the culture of the given request.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> for the request.</param>
|
||||
/// <returns>
|
||||
/// The determined <see cref="RequestCulture"/>.
|
||||
/// Returns <c>null</c> if the strategy couldn't determine a <see cref="RequestCulture"/>.
|
||||
/// Returns <c>null</c> if the provider couldn't determine a <see cref="RequestCulture"/>.
|
||||
/// </returns>
|
||||
Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext);
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Localization
|
|||
/// <summary>
|
||||
/// Determines the culture information for a request via values in the query string.
|
||||
/// </summary>
|
||||
public class QueryStringRequestCultureStrategy : RequestCultureStrategy
|
||||
public class QueryStringRequestCultureProvider : RequestCultureProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The key that contains the culture name.
|
||||
|
|
@ -14,16 +14,16 @@ namespace Microsoft.AspNet.Localization
|
|||
/// Creates a new <see cref="RequestCultureFeature"/> with the specified <see cref="Localization.RequestCulture"/>.
|
||||
/// </summary>
|
||||
/// <param name="requestCulture">The <see cref="Localization.RequestCulture"/>.</param>
|
||||
public RequestCultureFeature([NotNull] RequestCulture requestCulture, IRequestCultureStrategy strategy)
|
||||
public RequestCultureFeature([NotNull] RequestCulture requestCulture, IRequestCultureProvider provider)
|
||||
{
|
||||
RequestCulture = requestCulture;
|
||||
Strategy = strategy;
|
||||
Provider = provider;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestCulture RequestCulture { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestCultureStrategy Strategy { get; }
|
||||
public IRequestCultureProvider Provider { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract base class strategy for determining the culture information of an <see cref="HttpRequest"/>.
|
||||
/// An abstract base class provider for determining the culture information of an <see cref="HttpRequest"/>.
|
||||
/// </summary>
|
||||
public abstract class RequestCultureStrategy : IRequestCultureStrategy
|
||||
public abstract class RequestCultureProvider : IRequestCultureProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The current options for the <see cref="RequestLocalizationMiddleware"/>.
|
||||
|
|
@ -40,23 +40,23 @@ namespace Microsoft.AspNet.Localization
|
|||
var requestCulture = _options.DefaultRequestCulture ??
|
||||
new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);
|
||||
|
||||
IRequestCultureStrategy winningStrategy = null;
|
||||
IRequestCultureProvider winningProvider = null;
|
||||
|
||||
if (_options.RequestCultureStrategies != null)
|
||||
if (_options.RequestCultureProviders != null)
|
||||
{
|
||||
foreach (var strategy in _options.RequestCultureStrategies)
|
||||
foreach (var provider in _options.RequestCultureProviders)
|
||||
{
|
||||
var result = await strategy.DetermineRequestCulture(context);
|
||||
var result = await provider.DetermineRequestCulture(context);
|
||||
if (result != null)
|
||||
{
|
||||
requestCulture = result;
|
||||
winningStrategy = strategy;
|
||||
winningProvider = provider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningStrategy));
|
||||
context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider));
|
||||
|
||||
SetCurrentThreadCulture(requestCulture);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@ namespace Microsoft.AspNet.Localization
|
|||
{
|
||||
DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);
|
||||
|
||||
RequestCultureStrategies = new List<IRequestCultureStrategy>
|
||||
RequestCultureProviders = new List<IRequestCultureProvider>
|
||||
{
|
||||
new QueryStringRequestCultureStrategy { Options = this },
|
||||
new CookieRequestCultureStrategy { Options = this },
|
||||
new AcceptLanguageHeaderRequestCultureStrategy { Options = this }
|
||||
new QueryStringRequestCultureProvider { Options = this },
|
||||
new CookieRequestCultureProvider { Options = this },
|
||||
new AcceptLanguageHeaderRequestCultureProvider { Options = this }
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default <see cref="RequestCulture"/> to use. This value will be used if none of the configured
|
||||
/// <see cref="IRequestCultureStrategy"/> options result in a non-<c>null</c> result.
|
||||
/// <see cref="IRequestCultureProvider"/> options result in a non-<c>null</c> result.
|
||||
/// Defaults to <see cref="RequestCulture.Culture"/> set to <see cref="CultureInfo.DefaultThreadCurrentCulture"/>
|
||||
/// and <see cref="RequestCulture.UICulture"/> set to <see cref="CultureInfo.DefaultThreadCurrentUICulture"/>.
|
||||
/// </summary>
|
||||
|
|
@ -54,16 +54,16 @@ namespace Microsoft.AspNet.Localization
|
|||
public IList<CultureInfo> SupportedUICultures { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An ordered list of strategies used to determine a request's culture information. The first strategy that
|
||||
/// An ordered list of providers used to determine a request's culture information. The first provider that
|
||||
/// returns a non-<c>null</c> result for a given request will be used.
|
||||
/// Defaults to the following:
|
||||
/// <list type="number">
|
||||
/// <item><description><see cref="QueryStringRequestCultureStrategy"/></description></item>
|
||||
/// <item><description><see cref="CookieRequestCultureStrategy"/></description></item>
|
||||
/// <item><description><see cref="AcceptLanguageHeaderRequestCultureStrategy"/></description></item>
|
||||
/// <item><description><see cref="QueryStringRequestCultureProvider"/></description></item>
|
||||
/// <item><description><see cref="CookieRequestCultureProvider"/></description></item>
|
||||
/// <item><description><see cref="AcceptLanguageHeaderRequestCultureProvider"/></description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Improves usability")]
|
||||
public IList<IRequestCultureStrategy> RequestCultureStrategies { get; set; }
|
||||
public IList<IRequestCultureProvider> RequestCultureProviders { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.Framework.Localization.Internal
|
||||
{
|
||||
public class AssemblyWrapper
|
||||
{
|
||||
public AssemblyWrapper([NotNull] Assembly assembly)
|
||||
{
|
||||
Assembly = assembly;
|
||||
}
|
||||
|
||||
public Assembly Assembly { get; }
|
||||
|
||||
public virtual string FullName => Assembly.FullName;
|
||||
|
||||
public virtual Stream GetManifestResourceStream(string name) => Assembly.GetManifestResourceStream(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ using System.Globalization;
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.Localization.Internal;
|
||||
|
||||
namespace Microsoft.Framework.Localization
|
||||
{
|
||||
|
|
@ -18,12 +19,16 @@ namespace Microsoft.Framework.Localization
|
|||
/// </summary>
|
||||
public class ResourceManagerStringLocalizer : IStringLocalizer
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, IList<string>> _resourceNamesCache =
|
||||
new ConcurrentDictionary<string, IList<string>>();
|
||||
|
||||
private readonly ConcurrentDictionary<string, object> _missingManifestCache =
|
||||
new ConcurrentDictionary<string, object>();
|
||||
|
||||
private static readonly ConcurrentDictionary<string, IList<string>> _resourceNamesCache =
|
||||
new ConcurrentDictionary<string, IList<string>>();
|
||||
|
||||
private readonly ResourceManager _resourceManager;
|
||||
private readonly AssemblyWrapper _resourceAssemblyWrapper;
|
||||
private readonly string _resourceBaseName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ResourceManagerStringLocalizer"/>.
|
||||
/// </summary>
|
||||
|
|
@ -34,26 +39,23 @@ namespace Microsoft.Framework.Localization
|
|||
[NotNull] ResourceManager resourceManager,
|
||||
[NotNull] Assembly resourceAssembly,
|
||||
[NotNull] string baseName)
|
||||
: this(resourceManager, new AssemblyWrapper(resourceAssembly), baseName)
|
||||
{
|
||||
ResourceManager = resourceManager;
|
||||
ResourceAssembly = resourceAssembly;
|
||||
ResourceBaseName = baseName;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Resources.ResourceManager"/> to read strings from.
|
||||
/// Intended for testing purposes only.
|
||||
/// </summary>
|
||||
protected ResourceManager ResourceManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Assembly"/> that contains the strings as embedded resources.
|
||||
/// </summary>
|
||||
protected Assembly ResourceAssembly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The base name of the embedded resource in the <see cref="Assembly"/> that contains the strings.
|
||||
/// </summary>
|
||||
protected string ResourceBaseName { get; }
|
||||
public ResourceManagerStringLocalizer(
|
||||
[NotNull] ResourceManager resourceManager,
|
||||
[NotNull] AssemblyWrapper resourceAssemblyWrapper,
|
||||
[NotNull] string baseName)
|
||||
{
|
||||
_resourceAssemblyWrapper = resourceAssemblyWrapper;
|
||||
_resourceManager = resourceManager;
|
||||
_resourceBaseName = baseName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual LocalizedString this[[NotNull] string name]
|
||||
|
|
@ -84,16 +86,15 @@ namespace Microsoft.Framework.Localization
|
|||
public IStringLocalizer WithCulture(CultureInfo culture)
|
||||
{
|
||||
return culture == null
|
||||
? new ResourceManagerStringLocalizer(ResourceManager, ResourceAssembly, ResourceBaseName)
|
||||
: new ResourceManagerWithCultureStringLocalizer(
|
||||
ResourceManager,
|
||||
ResourceAssembly,
|
||||
ResourceBaseName,
|
||||
? new ResourceManagerStringLocalizer(_resourceManager, _resourceAssemblyWrapper, _resourceBaseName)
|
||||
: new ResourceManagerWithCultureStringLocalizer(_resourceManager,
|
||||
_resourceAssemblyWrapper,
|
||||
_resourceBaseName,
|
||||
culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a resource string from the <see cref="ResourceManager"/> and returns <c>null</c> instead of
|
||||
/// Gets a resource string from the <see cref="_resourceManager"/> and returns <c>null</c> instead of
|
||||
/// throwing exceptions if a match isn't found.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the string resource.</param>
|
||||
|
|
@ -110,7 +111,7 @@ namespace Microsoft.Framework.Localization
|
|||
|
||||
try
|
||||
{
|
||||
return culture == null ? ResourceManager.GetString(name) : ResourceManager.GetString(name, culture);
|
||||
return culture == null ? _resourceManager.GetString(name) : _resourceManager.GetString(name, culture);
|
||||
}
|
||||
catch (MissingManifestResourceException)
|
||||
{
|
||||
|
|
@ -150,10 +151,7 @@ namespace Microsoft.Framework.Localization
|
|||
}
|
||||
|
||||
// Internal to allow testing
|
||||
internal static void ClearResourceNamesCache()
|
||||
{
|
||||
_resourceNamesCache.Clear();
|
||||
}
|
||||
internal static void ClearResourceNamesCache() => _resourceNamesCache.Clear();
|
||||
|
||||
private IEnumerable<string> GetResourceNamesFromCultureHierarchy(CultureInfo startingCulture)
|
||||
{
|
||||
|
|
@ -186,19 +184,19 @@ namespace Microsoft.Framework.Localization
|
|||
|
||||
private IList<string> GetResourceNamesForCulture(CultureInfo culture)
|
||||
{
|
||||
var resourceStreamName = ResourceBaseName;
|
||||
var resourceStreamName = _resourceBaseName;
|
||||
if (!string.IsNullOrEmpty(culture.Name))
|
||||
{
|
||||
resourceStreamName += "." + culture.Name;
|
||||
}
|
||||
resourceStreamName += ".resources";
|
||||
|
||||
var cacheKey = $"assembly={ResourceAssembly.FullName};resourceStreamName={resourceStreamName}";
|
||||
var cacheKey = $"assembly={_resourceAssemblyWrapper.FullName};resourceStreamName={resourceStreamName}";
|
||||
|
||||
var cultureResourceNames = _resourceNamesCache.GetOrAdd(cacheKey, key =>
|
||||
{
|
||||
var names = new List<string>();
|
||||
using (var cultureResourceStream = ResourceAssembly.GetManifestResourceStream(key))
|
||||
using (var cultureResourceStream = _resourceAssemblyWrapper.GetManifestResourceStream(key))
|
||||
using (var resources = new ResourceReader(cultureResourceStream))
|
||||
{
|
||||
foreach (DictionaryEntry entry in resources)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.Localization.Internal;
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.Framework.Localization
|
||||
|
|
@ -34,7 +35,7 @@ namespace Microsoft.Framework.Localization
|
|||
public IStringLocalizer Create([NotNull] Type resourceSource)
|
||||
{
|
||||
var typeInfo = resourceSource.GetTypeInfo();
|
||||
var assembly = typeInfo.Assembly;
|
||||
var assembly = new AssemblyWrapper(typeInfo.Assembly);
|
||||
var baseName = typeInfo.FullName;
|
||||
return new ResourceManagerStringLocalizer(new ResourceManager(resourceSource), assembly, baseName);
|
||||
}
|
||||
|
|
@ -49,7 +50,10 @@ namespace Microsoft.Framework.Localization
|
|||
{
|
||||
var assembly = Assembly.Load(new AssemblyName(location ?? _applicationEnvironment.ApplicationName));
|
||||
|
||||
return new ResourceManagerStringLocalizer(new ResourceManager(baseName, assembly), assembly, baseName);
|
||||
return new ResourceManagerStringLocalizer(
|
||||
new ResourceManager(baseName, assembly),
|
||||
new AssemblyWrapper(assembly),
|
||||
baseName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.Localization.Internal;
|
||||
|
||||
namespace Microsoft.Framework.Localization
|
||||
{
|
||||
|
|
@ -35,6 +35,19 @@ namespace Microsoft.Framework.Localization
|
|||
_culture = culture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intended for testing purposes only.
|
||||
/// </summary>
|
||||
public ResourceManagerWithCultureStringLocalizer(
|
||||
[NotNull] ResourceManager resourceManager,
|
||||
[NotNull] AssemblyWrapper assemblyWrapper,
|
||||
[NotNull] string baseName,
|
||||
[NotNull] CultureInfo culture)
|
||||
: base(resourceManager, assemblyWrapper, baseName)
|
||||
{
|
||||
_culture = culture;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override LocalizedString this[[NotNull] string name]
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using Moq;
|
||||
using Microsoft.Framework.Localization.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Framework.Localization.Test
|
||||
|
|
@ -18,19 +18,11 @@ namespace Microsoft.Framework.Localization.Test
|
|||
{
|
||||
// Arrange
|
||||
ResourceManagerStringLocalizer.ClearResourceNamesCache();
|
||||
var resourceManager = new Mock<ResourceManager>();
|
||||
var resourceAssembly = new Mock<TestAssembly1>();
|
||||
resourceAssembly.Setup(rm => rm.GetManifestResourceStream(It.IsAny<string>()))
|
||||
.Returns(() => MakeResourceStream());
|
||||
var baseName = "test";
|
||||
var localizer1 = new ResourceManagerStringLocalizer(
|
||||
resourceManager.Object,
|
||||
resourceAssembly.Object,
|
||||
baseName);
|
||||
var localizer2 = new ResourceManagerStringLocalizer(
|
||||
resourceManager.Object,
|
||||
resourceAssembly.Object,
|
||||
baseName);
|
||||
var resourceAssembly = new TestAssemblyWrapper();
|
||||
var resourceManager = new TestResourceManager(baseName, resourceAssembly.Assembly);
|
||||
var localizer1 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
|
||||
var localizer2 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
|
||||
|
||||
// Act
|
||||
for (int i = 0; i < 5; i++)
|
||||
|
|
@ -41,9 +33,7 @@ namespace Microsoft.Framework.Localization.Test
|
|||
|
||||
// Assert
|
||||
var expectedCallCount = GetCultureInfoDepth(CultureInfo.CurrentUICulture);
|
||||
resourceAssembly.Verify(
|
||||
rm => rm.GetManifestResourceStream(It.IsAny<string>()),
|
||||
Times.Exactly(expectedCallCount));
|
||||
Assert.Equal(expectedCallCount, resourceAssembly.GetManifestResourceStreamCallCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -51,24 +41,13 @@ namespace Microsoft.Framework.Localization.Test
|
|||
{
|
||||
// Arrange
|
||||
ResourceManagerStringLocalizer.ClearResourceNamesCache();
|
||||
var resourceManager = new Mock<ResourceManager>();
|
||||
var resourceAssembly1 = new Mock<TestAssembly1>();
|
||||
resourceAssembly1.CallBase = true;
|
||||
var resourceAssembly2 = new Mock<TestAssembly2>();
|
||||
resourceAssembly2.CallBase = true;
|
||||
resourceAssembly1.Setup(rm => rm.GetManifestResourceStream(It.IsAny<string>()))
|
||||
.Returns(() => MakeResourceStream());
|
||||
resourceAssembly2.Setup(rm => rm.GetManifestResourceStream(It.IsAny<string>()))
|
||||
.Returns(() => MakeResourceStream());
|
||||
var baseName = "test";
|
||||
var localizer1 = new ResourceManagerStringLocalizer(
|
||||
resourceManager.Object,
|
||||
resourceAssembly1.Object,
|
||||
baseName);
|
||||
var localizer2 = new ResourceManagerStringLocalizer(
|
||||
resourceManager.Object,
|
||||
resourceAssembly2.Object,
|
||||
baseName);
|
||||
var resourceAssembly1 = new TestAssemblyWrapper("Assembly1");
|
||||
var resourceAssembly2 = new TestAssemblyWrapper("Assembly2");
|
||||
var resourceManager1 = new TestResourceManager(baseName, resourceAssembly1.Assembly);
|
||||
var resourceManager2 = new TestResourceManager(baseName, resourceAssembly2.Assembly);
|
||||
var localizer1 = new ResourceManagerStringLocalizer(resourceManager1, resourceAssembly1, baseName);
|
||||
var localizer2 = new ResourceManagerStringLocalizer(resourceManager2, resourceAssembly2, baseName);
|
||||
|
||||
// Act
|
||||
localizer1.ToList();
|
||||
|
|
@ -76,12 +55,8 @@ namespace Microsoft.Framework.Localization.Test
|
|||
|
||||
// Assert
|
||||
var expectedCallCount = GetCultureInfoDepth(CultureInfo.CurrentUICulture);
|
||||
resourceAssembly1.Verify(
|
||||
rm => rm.GetManifestResourceStream(It.IsAny<string>()),
|
||||
Times.Exactly(expectedCallCount));
|
||||
resourceAssembly2.Verify(
|
||||
rm => rm.GetManifestResourceStream(It.IsAny<string>()),
|
||||
Times.Exactly(expectedCallCount));
|
||||
Assert.Equal(expectedCallCount, resourceAssembly1.GetManifestResourceStreamCallCount);
|
||||
Assert.Equal(expectedCallCount, resourceAssembly2.GetManifestResourceStreamCallCount);
|
||||
}
|
||||
|
||||
private static Stream MakeResourceStream()
|
||||
|
|
@ -114,25 +89,35 @@ namespace Microsoft.Framework.Localization.Test
|
|||
return result;
|
||||
}
|
||||
|
||||
public class TestAssembly1 : Assembly
|
||||
public class TestResourceManager : ResourceManager
|
||||
{
|
||||
public override string FullName
|
||||
public TestResourceManager(string baseName, Assembly assembly)
|
||||
: base(baseName, assembly)
|
||||
{
|
||||
get
|
||||
{
|
||||
return nameof(TestAssembly1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override string GetString(string name, CultureInfo culture) => null;
|
||||
}
|
||||
|
||||
public class TestAssembly2 : Assembly
|
||||
public class TestAssemblyWrapper : AssemblyWrapper
|
||||
{
|
||||
public override string FullName
|
||||
private readonly string _name;
|
||||
|
||||
public TestAssemblyWrapper(string name = nameof(TestAssemblyWrapper))
|
||||
: base(typeof(TestAssemblyWrapper).GetTypeInfo().Assembly)
|
||||
{
|
||||
get
|
||||
{
|
||||
return nameof(TestAssembly2);
|
||||
}
|
||||
_name = name;
|
||||
}
|
||||
|
||||
public int GetManifestResourceStreamCallCount { get; private set; }
|
||||
|
||||
public override string FullName => _name;
|
||||
|
||||
public override Stream GetManifestResourceStream(string name)
|
||||
{
|
||||
GetManifestResourceStreamCallCount++;
|
||||
return MakeResourceStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Moq": "4.2.1502.911",
|
||||
"xunit": "2.1.0-*",
|
||||
"xunit.runner.dnx": "2.1.0-*",
|
||||
"Microsoft.Framework.Localization": "1.0.0-*"
|
||||
},
|
||||
"dependencies": {
|
||||
"xunit": "2.1.0-*",
|
||||
"xunit.runner.dnx": "2.1.0-*",
|
||||
"Microsoft.Framework.Localization": "1.0.0-*",
|
||||
"System.Reflection": "4.0.10-*"
|
||||
},
|
||||
|
||||
"commands": {
|
||||
"test": "xunit.runner.dnx"
|
||||
},
|
||||
"commands": {
|
||||
"test": "xunit.runner.dnx"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"dnx451": { }
|
||||
}
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnxcore50": { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue