From 3e9a592422f4fe9a64545b2b0ecc7884b725e7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 8 Mar 2019 00:42:29 +0100 Subject: [PATCH] Make the generic IStringLocalizer interface covariant (dotnet/extensions#1117) Make the generic IStringLocalizer interface covariant \n\nCommit migrated from https://github.com/dotnet/extensions/commit/90020a9608688a259c7e653b4096270568337290 --- ...ocalization.Abstractions.netstandard2.0.cs | 2 +- .../Abstractions/src/IStringLocalizerOfT.cs | 4 +- .../test/StringLocalizerOfTTest.cs | 159 ++++++++++++++++++ 3 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 src/Localization/Localization/test/StringLocalizerOfTTest.cs diff --git a/src/Localization/Abstractions/ref/Microsoft.Extensions.Localization.Abstractions.netstandard2.0.cs b/src/Localization/Abstractions/ref/Microsoft.Extensions.Localization.Abstractions.netstandard2.0.cs index 3f9f422021..174cac28e5 100644 --- a/src/Localization/Abstractions/ref/Microsoft.Extensions.Localization.Abstractions.netstandard2.0.cs +++ b/src/Localization/Abstractions/ref/Microsoft.Extensions.Localization.Abstractions.netstandard2.0.cs @@ -16,7 +16,7 @@ namespace Microsoft.Extensions.Localization Microsoft.Extensions.Localization.IStringLocalizer Create(string baseName, string location); Microsoft.Extensions.Localization.IStringLocalizer Create(System.Type resourceSource); } - public partial interface IStringLocalizer : Microsoft.Extensions.Localization.IStringLocalizer + public partial interface IStringLocalizer : Microsoft.Extensions.Localization.IStringLocalizer { } public partial class LocalizedString diff --git a/src/Localization/Abstractions/src/IStringLocalizerOfT.cs b/src/Localization/Abstractions/src/IStringLocalizerOfT.cs index 695678a900..bdc2a1c7b7 100644 --- a/src/Localization/Abstractions/src/IStringLocalizerOfT.cs +++ b/src/Localization/Abstractions/src/IStringLocalizerOfT.cs @@ -7,8 +7,8 @@ namespace Microsoft.Extensions.Localization /// Represents an that provides strings for . /// /// The to provide strings for. - public interface IStringLocalizer : IStringLocalizer + public interface IStringLocalizer : IStringLocalizer { } -} \ No newline at end of file +} diff --git a/src/Localization/Localization/test/StringLocalizerOfTTest.cs b/src/Localization/Localization/test/StringLocalizerOfTTest.cs new file mode 100644 index 0000000000..ce06e74d1c --- /dev/null +++ b/src/Localization/Localization/test/StringLocalizerOfTTest.cs @@ -0,0 +1,159 @@ +// 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.Globalization; +using Moq; +using Xunit; + +namespace Microsoft.Extensions.Localization +{ + public class StringLocalizerOfTTest + { + [Fact] + public void Constructor_ThrowsAnExceptionForNullFactory() + { + // Arrange, act and assert + var exception = Assert.Throws( + () => new StringLocalizer(factory: null)); + + Assert.Equal("factory", exception.ParamName); + } + + [Fact] + public void Constructor_ResolvesLocalizerFromFactory() + { + // Arrange + var factory = new Mock(); + + // Act + _ = new StringLocalizer(factory.Object); + + // Assert + factory.Verify(mock => mock.Create(typeof(object)), Times.Once()); + } + + [Fact] + public void WithCulture_InvokesWithCultureFromInnerLocalizer() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act +#pragma warning disable CS0618 + localizer.WithCulture(CultureInfo.GetCultureInfo("fr-FR")); +#pragma warning restore CS0618 + + // Assert +#pragma warning disable CS0618 + innerLocalizer.Verify(mock => mock.WithCulture(CultureInfo.GetCultureInfo("fr-FR")), Times.Once()); +#pragma warning restore CS0618 + } + + [Fact] + public void Indexer_ThrowsAnExceptionForNullName() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act and assert + var exception = Assert.Throws(() => localizer[name: null]); + + Assert.Equal("name", exception.ParamName); + } + + [Fact] + public void Indexer_InvokesIndexerFromInnerLocalizer() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act + _ = localizer["Hello world"]; + + // Assert + innerLocalizer.Verify(mock => mock["Hello world"], Times.Once()); + } + + [Fact] + public void Indexer_ThrowsAnExceptionForNullName_WithArguments() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act and assert + var exception = Assert.Throws(() => localizer[name: null]); + + Assert.Equal("name", exception.ParamName); + } + + [Fact] + public void Indexer_InvokesIndexerFromInnerLocalizer_WithArguments() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act + _ = localizer["Welcome, {0}", "Bob"]; + + // Assert + innerLocalizer.Verify(mock => mock["Welcome, {0}", "Bob"], Times.Once()); + } + + [Fact] + public void GetAllStrings_InvokesGetAllStringsFromInnerLocalizer() + { + // Arrange + var factory = new Mock(); + var innerLocalizer = new Mock(); + factory.Setup(mock => mock.Create(typeof(object))) + .Returns(innerLocalizer.Object); + + var localizer = new StringLocalizer(factory.Object); + + // Act + localizer.GetAllStrings(includeParentCultures: true); + + // Assert + innerLocalizer.Verify(mock => mock.GetAllStrings(true), Times.Once()); + } + + [Fact] + public void StringLocalizer_CanBeCastToBaseType() + { + // Arrange and act + IStringLocalizer localizer = new StringLocalizer(Mock.Of()); + + // Assert + Assert.NotNull(localizer); + } + + private class BaseType { } + private class DerivedType : BaseType { } + } +}