diff --git a/Localization.sln b/Localization.sln
index 64cb290f7e..903a81a931 100644
--- a/Localization.sln
+++ b/Localization.sln
@@ -1,4 +1,3 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
@@ -30,6 +29,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.Locali
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Localization.Tests", "test\Microsoft.AspNet.Localization.Tests\Microsoft.AspNet.Localization.Tests.xproj", "{19A2A931-5C60-47A0-816A-0DC9C4CE5736}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LocalizationWebsite", "test\LocalizationWebsite\LocalizationWebsite.xproj", "{EF6C7431-2FB8-4396-8947-F50F31689AF4}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Localization.FunctionalTests", "test\Microsoft.AspNet.Localization.FunctionalTests\Microsoft.AspNet.Localization.FunctionalTests.xproj", "{B1B441BA-3AC8-49F8-850D-E5A178E77DE2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -68,6 +71,14 @@ Global
{19A2A931-5C60-47A0-816A-0DC9C4CE5736}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19A2A931-5C60-47A0-816A-0DC9C4CE5736}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19A2A931-5C60-47A0-816A-0DC9C4CE5736}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EF6C7431-2FB8-4396-8947-F50F31689AF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF6C7431-2FB8-4396-8947-F50F31689AF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF6C7431-2FB8-4396-8947-F50F31689AF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF6C7431-2FB8-4396-8947-F50F31689AF4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1B441BA-3AC8-49F8-850D-E5A178E77DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1B441BA-3AC8-49F8-850D-E5A178E77DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1B441BA-3AC8-49F8-850D-E5A178E77DE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1B441BA-3AC8-49F8-850D-E5A178E77DE2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -81,5 +92,7 @@ Global
{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A} = {FB313677-BAB3-4E49-8CDB-4FA4A9564767}
{287AD58D-DF34-4F16-8616-FD78FA1CADF9} = {B723DB83-A670-4BCB-95FB-195361331AD2}
{19A2A931-5C60-47A0-816A-0DC9C4CE5736} = {B723DB83-A670-4BCB-95FB-195361331AD2}
+ {EF6C7431-2FB8-4396-8947-F50F31689AF4} = {B723DB83-A670-4BCB-95FB-195361331AD2}
+ {B1B441BA-3AC8-49F8-850D-E5A178E77DE2} = {B723DB83-A670-4BCB-95FB-195361331AD2}
EndGlobalSection
EndGlobal
diff --git a/test/LocalizationWebsite/LocalizationWebsite.xproj b/test/LocalizationWebsite/LocalizationWebsite.xproj
new file mode 100644
index 0000000000..a3312ce5b3
--- /dev/null
+++ b/test/LocalizationWebsite/LocalizationWebsite.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ ef6c7431-2fb8-4396-8947-f50f31689af4
+ LocalizationWebsite
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+ 5198
+
+
+
\ No newline at end of file
diff --git a/test/LocalizationWebsite/Resources/StartupResourcesInFolder.fr-FR.resx b/test/LocalizationWebsite/Resources/StartupResourcesInFolder.fr-FR.resx
new file mode 100644
index 0000000000..04d53a1b2e
--- /dev/null
+++ b/test/LocalizationWebsite/Resources/StartupResourcesInFolder.fr-FR.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bonjour from StartupResourcesInFolder
+
+
\ No newline at end of file
diff --git a/test/LocalizationWebsite/Resources/Test.fr-FR.resx b/test/LocalizationWebsite/Resources/Test.fr-FR.resx
new file mode 100644
index 0000000000..31789167b1
--- /dev/null
+++ b/test/LocalizationWebsite/Resources/Test.fr-FR.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bonjour from Test in resources folder
+
+
\ No newline at end of file
diff --git a/test/LocalizationWebsite/StartupResourcesAtRootFolder.cs b/test/LocalizationWebsite/StartupResourcesAtRootFolder.cs
new file mode 100644
index 0000000000..79f58625ef
--- /dev/null
+++ b/test/LocalizationWebsite/StartupResourcesAtRootFolder.cs
@@ -0,0 +1,39 @@
+// 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 Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+
+namespace LocalizationWebsite
+{
+ public class StartupResourcesAtRootFolder
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddLocalization();
+ }
+
+ public void Configure(
+ IApplicationBuilder app,
+ ILoggerFactory loggerFactory,
+ IStringLocalizerFactory stringLocalizerFactory,
+ IStringLocalizer startupStringLocalizer)
+ {
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
+
+ app.UseRequestLocalization();
+
+ var stringLocalizer = stringLocalizerFactory.Create("Test", location: null);
+
+ app.Run(async (context) =>
+ {
+ await context.Response.WriteAsync(startupStringLocalizer["Hello"]);
+ await context.Response.WriteAsync(" ");
+ await context.Response.WriteAsync(stringLocalizer["Hello"]);
+ });
+ }
+ }
+}
diff --git a/test/LocalizationWebsite/StartupResourcesAtRootFolder.fr-FR.resx b/test/LocalizationWebsite/StartupResourcesAtRootFolder.fr-FR.resx
new file mode 100644
index 0000000000..42b36579eb
--- /dev/null
+++ b/test/LocalizationWebsite/StartupResourcesAtRootFolder.fr-FR.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bonjour from StartupResourcesAtRootFolder
+
+
\ No newline at end of file
diff --git a/test/LocalizationWebsite/StartupResourcesInFolder.cs b/test/LocalizationWebsite/StartupResourcesInFolder.cs
new file mode 100644
index 0000000000..75158873a1
--- /dev/null
+++ b/test/LocalizationWebsite/StartupResourcesInFolder.cs
@@ -0,0 +1,39 @@
+// 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 Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+
+namespace LocalizationWebsite
+{
+ public class StartupResourcesInFolder
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddLocalization(options => options.ResourcesPath = "Resources");
+ }
+
+ public void Configure(
+ IApplicationBuilder app,
+ ILoggerFactory loggerFactory,
+ IStringLocalizerFactory stringLocalizerFactory,
+ IStringLocalizer startupStringLocalizer)
+ {
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
+
+ app.UseRequestLocalization();
+
+ var stringLocalizer = stringLocalizerFactory.Create("Test", location: null);
+
+ app.Run(async (context) =>
+ {
+ await context.Response.WriteAsync(startupStringLocalizer["Hello"]);
+ await context.Response.WriteAsync(" ");
+ await context.Response.WriteAsync(stringLocalizer["Hello"]);
+ });
+ }
+ }
+}
diff --git a/test/LocalizationWebsite/Test.fr-FR.resx b/test/LocalizationWebsite/Test.fr-FR.resx
new file mode 100644
index 0000000000..08f4fc8656
--- /dev/null
+++ b/test/LocalizationWebsite/Test.fr-FR.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bonjour from Test in root folder
+
+
\ No newline at end of file
diff --git a/test/LocalizationWebsite/project.json b/test/LocalizationWebsite/project.json
new file mode 100644
index 0000000000..5a1cb05f51
--- /dev/null
+++ b/test/LocalizationWebsite/project.json
@@ -0,0 +1,38 @@
+{
+ "webroot": "wwwroot",
+ "version": "1.0.0-*",
+
+ "compilationOptions": {
+ "warningsAsErrors": true
+ },
+
+ "dependencies": {
+ "Microsoft.AspNet.Localization": "1.0.0-*",
+ "Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
+ "Microsoft.Extensions.Localization": "1.0.0-*",
+ "Microsoft.Extensions.Logging.Console": "1.0.0-*"
+ },
+
+ "commands": {
+ "web": "Microsoft.AspNet.Server.Kestrel",
+ "kestrel": "Microsoft.AspNet.Server.Kestrel"
+ },
+
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": { }
+ },
+
+ "exclude": [
+ "wwwroot",
+ "node_modules",
+ "bower_components"
+ ],
+ "publishExclude": [
+ "node_modules",
+ "bower_components",
+ "**.xproj",
+ "**.user",
+ "**.vspscc"
+ ]
+}
diff --git a/test/Microsoft.AspNet.Localization.FunctionalTests/LocalizationTest.cs b/test/Microsoft.AspNet.Localization.FunctionalTests/LocalizationTest.cs
new file mode 100644
index 0000000000..a33c69b21e
--- /dev/null
+++ b/test/Microsoft.AspNet.Localization.FunctionalTests/LocalizationTest.cs
@@ -0,0 +1,91 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNet.Server.Testing;
+using Microsoft.AspNet.Testing.xunit;
+using Xunit;
+
+namespace Microsoft.AspNet.Localization.FunctionalTests
+{
+ public class LocalizationTest
+ {
+ [ConditionalTheory]
+ [OSSkipCondition(OperatingSystems.Linux)]
+ [OSSkipCondition(OperatingSystems.MacOSX)]
+ [InlineData(RuntimeFlavor.Clr, "http://localhost:5070/", RuntimeArchitecture.x86)]
+ [InlineData(RuntimeFlavor.CoreClr, "http://localhost:5071/", RuntimeArchitecture.x86)]
+ public Task Localization_ResourcesInFolder_ReturnLocalizedValue_Windows(
+ RuntimeFlavor runtimeFlavor,
+ string applicationBaseUrl,
+ RuntimeArchitecture runtimeArchitechture)
+ {
+ var testRunner = new TestRunner();
+ return testRunner.RunTestAndVerifyResponse(
+ runtimeFlavor,
+ runtimeArchitechture,
+ applicationBaseUrl,
+ "ResourcesInFolder",
+ "fr-FR",
+ "Bonjour from StartupResourcesInFolder Bonjour from Test in resources folder");
+ }
+
+ [ConditionalTheory]
+ [OSSkipCondition(OperatingSystems.Windows)]
+ [InlineData(RuntimeFlavor.Mono, "http://localhost:5072/", RuntimeArchitecture.x86)]
+ [InlineData(RuntimeFlavor.CoreClr, "http://localhost:5073/", RuntimeArchitecture.x64)]
+ public Task Localization_ResourcesInFolder_ReturnLocalizedValue_Mono(
+ RuntimeFlavor runtimeFlavor,
+ string applicationBaseUrl,
+ RuntimeArchitecture runtimeArchitechture)
+ {
+ var testRunner = new TestRunner();
+ return testRunner.RunTestAndVerifyResponse(
+ runtimeFlavor,
+ runtimeArchitechture,
+ applicationBaseUrl,
+ "ResourcesInFolder",
+ "fr-FR",
+ "Bonjour from StartupResourcesInFolder Bonjour from Test in resources folder");
+ }
+
+ [ConditionalTheory]
+ [OSSkipCondition(OperatingSystems.Linux)]
+ [OSSkipCondition(OperatingSystems.MacOSX)]
+ [InlineData(RuntimeFlavor.Clr, "http://localhost:5074/", RuntimeArchitecture.x86)]
+ [InlineData(RuntimeFlavor.CoreClr, "http://localhost:5075/", RuntimeArchitecture.x86)]
+ public Task Localization_ResourcesAtRootFolder_ReturnLocalizedValue_Windows(
+ RuntimeFlavor runtimeFlavor,
+ string applicationBaseUrl,
+ RuntimeArchitecture runtimeArchitechture)
+ {
+ var testRunner = new TestRunner();
+ return testRunner.RunTestAndVerifyResponse(
+ runtimeFlavor,
+ runtimeArchitechture,
+ applicationBaseUrl,
+ "ResourcesAtRootFolder",
+ "fr-FR",
+ "Bonjour from StartupResourcesAtRootFolder Bonjour from Test in root folder");
+ }
+
+ [ConditionalTheory]
+ [OSSkipCondition(OperatingSystems.Windows)]
+ [InlineData(RuntimeFlavor.Mono, "http://localhost:5076/", RuntimeArchitecture.x86)]
+ [InlineData(RuntimeFlavor.CoreClr, "http://localhost:5077/", RuntimeArchitecture.x64)]
+ public Task Localization_ResourcesAtRootFolder_ReturnLocalizedValue_Mono(
+ RuntimeFlavor runtimeFlavor,
+ string applicationBaseUrl,
+ RuntimeArchitecture runtimeArchitechture)
+ {
+ var testRunner = new TestRunner();
+ return testRunner.RunTestAndVerifyResponse(
+ runtimeFlavor,
+ runtimeArchitechture,
+ applicationBaseUrl,
+ "ResourcesAtRootFolder",
+ "fr-FR",
+ "Bonjour from StartupResourcesAtRootFolder Bonjour from Test in root folder");
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.Localization.FunctionalTests/Microsoft.AspNet.Localization.FunctionalTests.xproj b/test/Microsoft.AspNet.Localization.FunctionalTests/Microsoft.AspNet.Localization.FunctionalTests.xproj
new file mode 100644
index 0000000000..9e239fe686
--- /dev/null
+++ b/test/Microsoft.AspNet.Localization.FunctionalTests/Microsoft.AspNet.Localization.FunctionalTests.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ b1b441ba-3ac8-49f8-850d-e5a178e77de2
+ Microsoft.AspNet.Localization.FunctionalTests
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Localization.FunctionalTests/TestRunner.cs b/test/Microsoft.AspNet.Localization.FunctionalTests/TestRunner.cs
new file mode 100644
index 0000000000..05153279e0
--- /dev/null
+++ b/test/Microsoft.AspNet.Localization.FunctionalTests/TestRunner.cs
@@ -0,0 +1,69 @@
+// 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.IO;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Server.Testing;
+using Microsoft.Extensions.Logging;
+using Xunit;
+
+namespace Microsoft.AspNet.Localization.FunctionalTests
+{
+ public class TestRunner
+ {
+ public async Task RunTestAndVerifyResponse(
+ RuntimeFlavor runtimeFlavor,
+ RuntimeArchitecture runtimeArchitechture,
+ string applicationBaseUrl,
+ string environmentName,
+ string locale,
+ string expectedText)
+ {
+ var logger = new LoggerFactory()
+ .AddConsole()
+ .CreateLogger(string.Format("Localization Test Site:{0}:{1}:{2}", ServerType.Kestrel, runtimeFlavor, runtimeArchitechture));
+
+ using (logger.BeginScope("LocalizationTest"))
+ {
+ var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel, runtimeFlavor, runtimeArchitechture)
+ {
+ ApplicationBaseUriHint = applicationBaseUrl,
+ Command = "web",
+ EnvironmentName = environmentName
+ };
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger))
+ {
+ var deploymentResult = deployer.Deploy();
+
+ var cookie = new Cookie("ASPNET_CULTURE", "c=" + locale + "|uic=" + locale);
+ var cookieContainer = new CookieContainer();
+ cookieContainer.Add(new Uri(deploymentResult.ApplicationBaseUri), cookie);
+
+ var httpClientHandler = new HttpClientHandler();
+ httpClientHandler.CookieContainer = cookieContainer;
+
+ var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) };
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ var response = await RetryHelper.RetryRequest(() =>
+ {
+ return httpClient.GetAsync(string.Empty);
+ }, logger, deploymentResult.HostShutdownToken);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ Console.WriteLine("Response Text " + responseText);
+ Assert.Equal(expectedText, responseText);
+ }
+ }
+ }
+
+ public string GetApplicationPath()
+ {
+ return Path.GetFullPath(Path.Combine("..", "LocalizationWebsite"));
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.Localization.FunctionalTests/project.json b/test/Microsoft.AspNet.Localization.FunctionalTests/project.json
new file mode 100644
index 0000000000..4b912e2910
--- /dev/null
+++ b/test/Microsoft.AspNet.Localization.FunctionalTests/project.json
@@ -0,0 +1,25 @@
+{
+ "compilationOptions": {
+ "warningsAsErrors": true
+ },
+ "commands": {
+ "test": "xunit.runner.aspnet"
+ },
+ "dependencies": {
+ "Microsoft.AspNet.Server.Testing": "1.0.0-*",
+ "Microsoft.Extensions.Logging.Console": "1.0.0-*",
+ "xunit.runner.aspnet": "2.0.0-aspnet-*"
+ },
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": {
+ "dependencies": {
+ "Microsoft.CSharp": "4.0.1-beta-*",
+ "System.Collections": "4.0.11-beta-*",
+ "System.Linq": "4.0.1-beta-*",
+ "System.Runtime": "4.0.21-beta-*",
+ "System.Threading": "4.0.11-beta-*"
+ }
+ }
+ }
+}