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:
damianedwards 2015-05-20 11:56:47 -07:00
parent 9384848cc7
commit 4ba159afe7
17 changed files with 166 additions and 143 deletions

View File

@ -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>");

View File

@ -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"/>

View File

@ -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=";

View File

@ -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);
}
}
}

View File

@ -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; }
}
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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; }
}
}

View File

@ -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"/>.

View File

@ -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);

View File

@ -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; }
}
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -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]
{

View File

@ -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();
}
}
}

View File

@ -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": { }
}
}