Add support for generating baseline output files while testing
- baselines include both expected output and design-time line mappings - controlled by GENERATE_BASELINES - assertions related to file content are not checked in this mode - add design-time test of Basic.cshtml to `MvcRazorHostTest` - regenerate all files to avoid BOM and blank line noise in future PRs - update out-of-date design-time Basic.cs file nits: - make a few variable names more consistent - make `Assembly` fields `static` - remove unused `_resourcesAssembly` field from `ErrorPageTests` - remove `ResourceHelpers` which was specific to functional tests
This commit is contained in:
parent
386562c269
commit
ffd1dc1fb0
|
|
@ -20,14 +20,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class BasicTests
|
||||
{
|
||||
private const string SiteName = nameof(BasicWebSite);
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
// Some tests require comparing the actual response body against an expected response baseline
|
||||
// so they require a reference to the assembly on which the resources are located, in order to
|
||||
// make the tests less verbose, we get a reference to the assembly with the resources and we
|
||||
// use it on all the rest of the tests.
|
||||
private readonly Assembly _resourcesAssembly = typeof(BasicTests).GetTypeInfo().Assembly;
|
||||
private static readonly Assembly _resourcesAssembly = typeof(BasicTests).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://localhost/")]
|
||||
|
|
@ -39,13 +40,11 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync("compiler/resources/BasicWebSite.Home.Index.html");
|
||||
var outputFile = "compiler/resources/BasicWebSite.Home.Index.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
var response = await client.GetAsync(url);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
|
@ -53,7 +52,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -62,9 +66,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync("compiler/resources/BasicWebSite.Home.PlainView.html");
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
var outputFile = "compiler/resources/BasicWebSite.Home.PlainView.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/Home/PlainView");
|
||||
|
|
@ -73,7 +78,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -82,8 +92,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/BasicWebSite.Home.ViewWithPrefixedAttributeValue.html");
|
||||
var outputFile = "compiler/resources/BasicWebSite.Home.ViewWithPrefixedAttributeValue.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/Home/ViewWithPrefixedAttributeValue");
|
||||
|
|
@ -91,7 +102,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using ErrorPageMiddlewareWebSite;
|
||||
using Microsoft.AspNet.Builder;
|
||||
|
|
@ -22,8 +21,6 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
private readonly Assembly _resourcesAssembly = typeof(ErrorPageTests).GetTypeInfo().Assembly;
|
||||
|
||||
[Theory]
|
||||
[InlineData("CompilationFailure", "Cannot implicitly convert type 'int' to 'string'")]
|
||||
[InlineData("ParserError", "The code block is missing a closing "}" character. Make sure you " +
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class LinkGenerationTests
|
||||
{
|
||||
private const string SiteName = nameof(BasicWebSite);
|
||||
private readonly Action<IApplicationBuilder> _app = new BasicWebSite.Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new BasicWebSite.Startup().ConfigureServices;
|
||||
|
||||
|
||||
// Some tests require comparing the actual response body against an expected response baseline
|
||||
// so they require a reference to the assembly on which the resources are located, in order to
|
||||
// make the tests less verbose, we get a reference to the assembly with the resources and we
|
||||
// use it on all the rest of the tests.
|
||||
private readonly Assembly _resourcesAssembly = typeof(LinkGenerationTests).GetTypeInfo().Assembly;
|
||||
private static readonly Assembly _resourcesAssembly = typeof(LinkGenerationTests).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new BasicWebSite.Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new BasicWebSite.Startup().ConfigureServices;
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://pingüino/Home/RedirectToActionReturningTaskAction", "/Home/ActionReturningTask")]
|
||||
|
|
@ -55,13 +55,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
var expectedContent = await _resourcesAssembly
|
||||
.ReadResourceAsStringAsync("compiler/resources/BasicWebSite.Home.ActionLinkView.html");
|
||||
var outputFile = "compiler/resources/BasicWebSite.Home.ActionLinkView.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
var response = await client.GetAsync("http://localhost/Home/ActionLinkView");
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
|
@ -69,7 +68,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using ModelBindingWebSite.Controllers;
|
||||
using ModelBindingWebSite.Models;
|
||||
using ModelBindingWebSite.ViewModels;
|
||||
using Newtonsoft.Json;
|
||||
|
|
@ -24,6 +23,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class ModelBindingTest
|
||||
{
|
||||
private const string SiteName = nameof(ModelBindingWebSite);
|
||||
private static readonly Assembly _assembly = typeof(ModelBindingTest).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new ModelBindingWebSite.Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new ModelBindingWebSite.Startup().ConfigureServices;
|
||||
|
||||
|
|
@ -1383,10 +1384,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public async Task UpdateDealerVehicle_PopulatesPropertyErrorsInViews()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/UpdateDealerVehicle_PopulatesPropertyErrorsInViews.txt");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/UpdateDealerVehicle_PopulatesPropertyErrorsInViews.txt";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var postedContent = new
|
||||
{
|
||||
Year = 9001,
|
||||
|
|
@ -1406,18 +1407,23 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateDealerVehicle_PopulatesValidationSummary()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/UpdateDealerVehicle_PopulatesValidationSummary.txt");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/UpdateDealerVehicle_PopulatesValidationSummary.txt";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var postedContent = new
|
||||
{
|
||||
Year = 2013,
|
||||
|
|
@ -1437,18 +1443,23 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateDealerVehicle_UsesDefaultValuesForOptionalProperties()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/UpdateDealerVehicle_UpdateSuccessful.txt");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/UpdateDealerVehicle_UpdateSuccessful.txt";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var postedContent = new
|
||||
{
|
||||
Year = 2013,
|
||||
|
|
@ -1468,8 +1479,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -1603,10 +1619,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public async Task HtmlHelper_DisplayFor_ShowsPropertiesInModelMetadataOrder()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/ModelBindingWebSite.Vehicle.Details.html");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/ModelBindingWebSite.Vehicle.Details.html";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var url = "http://localhost/vehicles/42";
|
||||
|
||||
// Act
|
||||
|
|
@ -1615,18 +1631,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HtmlHelper_EditorFor_ShowsPropertiesInModelMetadataOrder()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/ModelBindingWebSite.Vehicle.Edit.html");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/ModelBindingWebSite.Vehicle.Edit.html";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var url = "http://localhost/vehicles/42/edit";
|
||||
|
||||
// Act
|
||||
|
|
@ -1635,18 +1655,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HtmlHelper_EditorFor_ShowsPropertiesAndErrorsInModelMetadataOrder()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContent = await GetType().GetTypeInfo().Assembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/ModelBindingWebSite.Vehicle.Edit.Invalid.html");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/ModelBindingWebSite.Vehicle.Edit.Invalid.html";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
var url = "http://localhost/vehicles/42/edit";
|
||||
var contentDictionary = new Dictionary<string, string>
|
||||
{
|
||||
|
|
@ -1674,8 +1698,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, body);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class MvcTagHelpersTest
|
||||
{
|
||||
private const string SiteName = nameof(MvcTagHelpersWebSite);
|
||||
private static readonly Assembly _resourcesAssembly = typeof(MvcTagHelpersTest).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
private static readonly Assembly _resourcesAssembly = typeof(MvcTagHelpersTest).GetTypeInfo().Assembly;
|
||||
|
||||
[Theory]
|
||||
[InlineData("Index", null)]
|
||||
|
|
@ -57,11 +58,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".html");
|
||||
var outputFile = "compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
|
|
@ -72,13 +71,27 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
if (antiForgeryPath != null)
|
||||
responseContent = responseContent.Trim();
|
||||
if (antiForgeryPath == null)
|
||||
{
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath);
|
||||
#if GENERATE_BASELINES
|
||||
// Reverse usual substitution and insert a format item into the new file content.
|
||||
responseContent = responseContent.Replace(forgeryToken, "{0}");
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
expectedContent = string.Format(expectedContent, forgeryToken);
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -101,11 +114,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
});
|
||||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".Encoded.html");
|
||||
var outputFile = "compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".Encoded.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
|
|
@ -116,13 +127,27 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
if (antiForgeryPath != null)
|
||||
responseContent = responseContent.Trim();
|
||||
if (antiForgeryPath == null)
|
||||
{
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath);
|
||||
#if GENERATE_BASELINES
|
||||
// Reverse usual substitution and insert a format item into the new file content.
|
||||
responseContent = responseContent.Replace(forgeryToken, "{0}");
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
expectedContent = string.Format(expectedContent, forgeryToken);
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -131,8 +156,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Customer.Index.html");
|
||||
var outputFile = "compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Customer.Index.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/MvcTagHelper_Customer");
|
||||
var nameValueCollection = new List<KeyValuePair<string, string>>
|
||||
|
|
@ -152,9 +178,18 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, "Customer/MvcTagHelper_Customer");
|
||||
responseContent = responseContent.Trim();
|
||||
var forgeryToken =
|
||||
AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, "Customer/MvcTagHelper_Customer");
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
// Reverse usual substitution and insert a format item into the new file content.
|
||||
responseContent = responseContent.Replace(forgeryToken, "{0}");
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
expectedContent = string.Format(expectedContent, forgeryToken);
|
||||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -168,6 +203,16 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
client.BaseAddress = new Uri("http://localhost");
|
||||
client.DefaultRequestHeaders.Add("Locale", "North");
|
||||
|
||||
var outputFile1 = assertFile + "1.txt";
|
||||
var expected1 =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile1, sourceFile: false);
|
||||
var outputFile2 = assertFile + "2.txt";
|
||||
var expected2 =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile2, sourceFile: false);
|
||||
var outputFile3 = assertFile + "3.txt";
|
||||
var expected3 =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile3, sourceFile: false);
|
||||
|
||||
// Act - 1
|
||||
// Verify that content gets cached based on vary-by-params
|
||||
var targetUrl = "/catalog?categoryId=1&correlationid=1";
|
||||
|
|
@ -175,10 +220,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var response2 = await client.GetStringAsync(targetUrl);
|
||||
|
||||
// Assert - 1
|
||||
var expected1 = await _resourcesAssembly.ReadResourceAsStringAsync(assertFile + "1.txt");
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile1, expected1, response1.Trim());
|
||||
#else
|
||||
Assert.Equal(expected1, response1.Trim());
|
||||
Assert.Equal(expected1, response2.Trim());
|
||||
#endif
|
||||
|
||||
// Act - 2
|
||||
// Verify content gets changed in partials when one of the vary by parameters is changed
|
||||
|
|
@ -187,10 +234,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var response4 = await client.GetStringAsync(targetUrl);
|
||||
|
||||
// Assert - 2
|
||||
var expected2 = await _resourcesAssembly.ReadResourceAsStringAsync(assertFile + "2.txt");
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile2, expected2, response3.Trim());
|
||||
#else
|
||||
Assert.Equal(expected2, response3.Trim());
|
||||
Assert.Equal(expected2, response4.Trim());
|
||||
#endif
|
||||
|
||||
// Act - 3
|
||||
// Verify content gets changed in a View Component when the Vary-by-header parameters is changed
|
||||
|
|
@ -202,10 +251,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var response6 = await client.GetStringAsync(targetUrl);
|
||||
|
||||
// Assert - 3
|
||||
var expected3 = await _resourcesAssembly.ReadResourceAsStringAsync(assertFile + "3.txt");
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile3, expected3, response5.Trim());
|
||||
#else
|
||||
Assert.Equal(expected3, response5.Trim());
|
||||
Assert.Equal(expected3, response6.Trim());
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -424,26 +475,36 @@ Products: Laptops (3)";
|
|||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var resourceName = string.Format(
|
||||
var outputFile = string.Format(
|
||||
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home.Form.Options.AntiForgery.{0}.html",
|
||||
optionsAntiForgery?.ToString() ?? "null"
|
||||
);
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(resourceName);
|
||||
optionsAntiForgery?.ToString() ?? "null");
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
var response = await client.GetAsync("http://localhost/MvcTagHelper_Home/Form");
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var forgeryTokens = AntiForgeryTestHelper.RetrieveAntiForgeryTokens(responseContent);
|
||||
expectedContent = string.Format(expectedContent, forgeryTokens.ToArray());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
|
||||
responseContent = responseContent.Trim();
|
||||
var forgeryTokens = AntiForgeryTestHelper.RetrieveAntiForgeryTokens(responseContent).ToArray();
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
// Reverse usual substitutions and insert format items into the new file content.
|
||||
for (var index = 0; index < forgeryTokens.Length; index++)
|
||||
{
|
||||
responseContent = responseContent.Replace(forgeryTokens[index], $"{{{ index }}}");
|
||||
}
|
||||
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
expectedContent = string.Format(expectedContent, forgeryTokens);
|
||||
Assert.Equal(expectedContent.Trim(), responseContent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
private const string SiteName = nameof(ValidationWebSite);
|
||||
private static readonly Assembly _resourcesAssembly =
|
||||
typeof(RemoteAttributeValidationTest).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new ValidationWebSite.Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new ValidationWebSite.Startup().ConfigureServices;
|
||||
|
||||
|
|
@ -29,8 +30,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/ValidationWebSite." + areaName + ".RemoteAttribute_Home.Create.html");
|
||||
var outputFile = "compiler/resources/ValidationWebSite." + areaName + ".RemoteAttribute_Home.Create.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
var url = "http://localhost" + pathSegment + "/RemoteAttribute_Home/Create";
|
||||
|
||||
// Act
|
||||
|
|
@ -40,8 +42,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("text/html", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("utf-8", response.Content.Headers.ContentType.CharSet);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
// 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 System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
// This class contains helper methods for reading resources from a given assembly in order
|
||||
// to make tests that require comparing against baseline files embedded as resources less
|
||||
// verbose.
|
||||
public static class ResourceHelpers
|
||||
{
|
||||
public static async Task<string> ReadResourceAsStringAsync(this Assembly assembly, string resourceName)
|
||||
{
|
||||
resourceName = assembly.GetName().Name + "." + resourceName.Replace('/', '.');
|
||||
|
||||
using (var resourceStream = assembly.GetManifestResourceStream(resourceName))
|
||||
{
|
||||
using (var streamReader = new StreamReader(resourceStream))
|
||||
{
|
||||
return await streamReader.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,14 +18,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class TagHelpersTests
|
||||
{
|
||||
private const string SiteName = nameof(TagHelpersWebSite);
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
// Some tests require comparing the actual response body against an expected response baseline
|
||||
// so they require a reference to the assembly on which the resources are located, in order to
|
||||
// make the tests less verbose, we get a reference to the assembly with the resources and we
|
||||
// use it on all the rest of the tests.
|
||||
private readonly Assembly _resourcesAssembly = typeof(TagHelpersTests).GetTypeInfo().Assembly;
|
||||
private static readonly Assembly _resourcesAssembly = typeof(TagHelpersTests).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
[Theory]
|
||||
[InlineData("Index")]
|
||||
|
|
@ -37,22 +38,24 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/TagHelpersWebSite.Home." + action + ".html");
|
||||
var outputFile = "compiler/resources/TagHelpersWebSite.Home." + action + ".html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
var response = await client.GetAsync("http://localhost/Home/" + action);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static TheoryData TagHelpersAreInheritedFromViewImportsPagesData
|
||||
|
|
@ -129,16 +132,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/TagHelpersWebSite.Employee.Create.html");
|
||||
var outputFile = "compiler/resources/TagHelpersWebSite.Employee.Create.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/Employee/Create");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -147,8 +156,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/TagHelpersWebSite.Employee.Details.AfterCreate.html");
|
||||
var outputFile = "compiler/resources/TagHelpersWebSite.Employee.Details.AfterCreate.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
var validPostValues = new Dictionary<string, string>
|
||||
{
|
||||
{ "FullName", "Boo" },
|
||||
|
|
@ -165,8 +175,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -175,8 +190,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/TagHelpersWebSite.Employee.Create.Invalid.html");
|
||||
var outputFile = "compiler/resources/TagHelpersWebSite.Employee.Create.Invalid.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
var validPostValues = new Dictionary<string, string>
|
||||
{
|
||||
{ "FullName", "Boo" },
|
||||
|
|
@ -193,8 +209,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
public class ViewEngineTests
|
||||
{
|
||||
private const string SiteName = nameof(RazorWebSite);
|
||||
private static readonly Assembly _assembly = typeof(ViewEngineTests).GetTypeInfo().Assembly;
|
||||
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
private readonly Action<IServiceCollection> _configureServices = new Startup().ConfigureServices;
|
||||
|
||||
|
|
@ -318,7 +320,7 @@ View With Layout
|
|||
public async Task ViewStartsCanUseDirectivesInjectedFromParentGlobals()
|
||||
{
|
||||
// Arrange
|
||||
var expected =
|
||||
var expected =
|
||||
@"<view-start>Hello Controller-Person</view-start>
|
||||
<page>Hello Controller-Person</page>";
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
|
|
@ -426,16 +428,21 @@ Partial that does not specify Layout
|
|||
public async Task RazorView_SetsViewPathAndExecutingPagePath()
|
||||
{
|
||||
// Arrange
|
||||
var expected = await GetType().GetTypeInfo().Assembly
|
||||
.ReadResourceAsStringAsync("compiler/resources/ViewEngineController.ViewWithPaths.txt");
|
||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||
var client = server.CreateClient();
|
||||
var outputFile = "compiler/resources/ViewEngineController.ViewWithPaths.txt";
|
||||
var expectedContent = await ResourceFile.ReadResourceAsync(_assembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var body = await client.GetStringAsync("http://localhost/ViewWithPaths");
|
||||
var responseContent = await client.GetStringAsync("http://localhost/ViewWithPaths");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, body.Trim());
|
||||
responseContent = responseContent.Trim();
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!doctype html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Action Link with non unicode host</title>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Plain View
|
||||
Plain View
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<h2>Category: Laptops</h2>
|
||||
<h2>Category: Laptops</h2>
|
||||
<h2>Region: North</h2>
|
||||
|
||||
<h2>Cached content</h2>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<h2>Category: Phones</h2>
|
||||
<h2>Category: Phones</h2>
|
||||
<h2>Region: North</h2>
|
||||
|
||||
<h2>Cached content</h2>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<h2>Category: Phones</h2>
|
||||
<h2>Category: Phones</h2>
|
||||
<h2>Region: East</h2>
|
||||
|
||||
<h2>Cached content</h2>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="/Customer/MvcTagHelper_Customer" method="post">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="/MvcTagHelper_Home/CreateWarehouse" method="post"> <div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="/Customer/MvcTagHelper_Customer" method="post">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="HtmlEncode[[/MvcTagHelper_Home/EditWarehouse]]" method="HtmlEncode[[post]]">
|
||||
|
|
@ -44,4 +41,4 @@ HtmlEncode[[Address_1]]</textarea>;
|
|||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="/MvcTagHelper_Home/EditWarehouse" method="post">
|
||||
|
|
@ -44,4 +41,4 @@ Address_1</textarea>;
|
|||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="/MvcTagHelper_Home/EmployeeList" method="post">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
@ -57,4 +56,4 @@
|
|||
Product_2 description</textarea>
|
||||
</div> <input type="submit" />
|
||||
</form></body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div>
|
||||
<div>
|
||||
<span class="bold">TestCarDealer</span>
|
||||
<em>SE</em>
|
||||
<input data-val="true" data-val-required="The Id field is required." id="Dealer_Id" name="Dealer.Id" type="hidden" value="32" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div>
|
||||
<div>
|
||||
<span class="bold">TestCarDealer</span>
|
||||
<em>SE</em>
|
||||
<input data-val="true" data-val-required="The Id field is required." id="Dealer_Id" name="Dealer.Id" type="hidden" value="43" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="left">
|
||||
<div class="left">
|
||||
<ul>
|
||||
<li>
|
||||
Vin: 8chars
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Layout>
|
||||
<Layout>
|
||||
/Views/ViewWithPaths/_Layout.cshtml
|
||||
/Views/ViewWithPaths/Index.cshtml
|
||||
</Layout>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"../Microsoft.AspNet.Mvc.Xml.Test/XmlAssert.cs"
|
||||
],
|
||||
"compilationOptions": {
|
||||
"define": [ "__RemoveThisBitTo__GENERATE_BASELINES" ],
|
||||
"warningsAsErrors": "true"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Mvc.Razor.Directives;
|
||||
using Microsoft.AspNet.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNet.Razor;
|
||||
|
|
@ -19,6 +22,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
public class MvcRazorHostTest
|
||||
{
|
||||
private static Assembly _assembly = typeof(MvcRazorHostTest).Assembly;
|
||||
|
||||
[Theory]
|
||||
[InlineData("//")]
|
||||
[InlineData("C:/")]
|
||||
|
|
@ -159,6 +164,40 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
RunRuntimeTest(host, scenarioName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BasicVisitor_GeneratesCorrectLineMappings()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var host = new MvcRazorHost(new DefaultChunkTreeCache(fileProvider))
|
||||
{
|
||||
DesignTimeMode = true
|
||||
};
|
||||
host.NamespaceImports.Clear();
|
||||
var expectedLineMappings = new[]
|
||||
{
|
||||
BuildLineMapping(
|
||||
documentAbsoluteIndex: 13,
|
||||
documentLineIndex: 0,
|
||||
documentCharacterIndex: 13,
|
||||
generatedAbsoluteIndex: 1269,
|
||||
generatedLineIndex: 32,
|
||||
generatedCharacterIndex: 13,
|
||||
contentLength: 4),
|
||||
BuildLineMapping(
|
||||
documentAbsoluteIndex: 43,
|
||||
documentLineIndex: 2,
|
||||
documentCharacterIndex: 5,
|
||||
generatedAbsoluteIndex: 1353,
|
||||
generatedLineIndex: 37,
|
||||
generatedCharacterIndex: 6,
|
||||
contentLength: 21),
|
||||
};
|
||||
|
||||
// Act and Assert
|
||||
RunDesignTimeTest(host, "Basic", expectedLineMappings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InjectVisitor_GeneratesCorrectLineMappings()
|
||||
{
|
||||
|
|
@ -246,19 +285,25 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
string testName)
|
||||
{
|
||||
var inputFile = "TestFiles/Input/" + testName + ".cshtml";
|
||||
var expectedCode = ReadResource("TestFiles/Output/Runtime/" + testName + ".cs");
|
||||
var outputFile = "TestFiles/Output/Runtime/" + testName + ".cs";
|
||||
var expectedCode = ResourceFile.ReadResource(_assembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
GeneratorResults results;
|
||||
using (var stream = GetResourceStream(inputFile))
|
||||
using (var stream = ResourceFile.GetResourceStream(_assembly, inputFile, sourceFile: true))
|
||||
{
|
||||
results = host.GenerateCode(inputFile, stream);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.True(results.Success);
|
||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
||||
Assert.Empty(results.ParserErrors);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedCode, results.GeneratedCode);
|
||||
#else
|
||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void RunDesignTimeTest(MvcRazorHost host,
|
||||
|
|
@ -266,39 +311,60 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
IEnumerable<LineMapping> expectedLineMappings)
|
||||
{
|
||||
var inputFile = "TestFiles/Input/" + testName + ".cshtml";
|
||||
var expectedCode = ReadResource("TestFiles/Output/DesignTime/" + testName + ".cs");
|
||||
var outputFile = "TestFiles/Output/DesignTime/" + testName + ".cs";
|
||||
var expectedCode = ResourceFile.ReadResource(_assembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
GeneratorResults results;
|
||||
using (var stream = GetResourceStream(inputFile))
|
||||
using (var stream = ResourceFile.GetResourceStream(_assembly, inputFile, sourceFile: true))
|
||||
{
|
||||
results = host.GenerateCode(inputFile, stream);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.True(results.Success);
|
||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
||||
Assert.Empty(results.ParserErrors);
|
||||
Assert.Equal(expectedLineMappings, results.DesignTimeLineMappings);
|
||||
}
|
||||
|
||||
private static string ReadResource(string resourceName)
|
||||
{
|
||||
using (var stream = GetResourceStream(resourceName))
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedCode, results.GeneratedCode);
|
||||
|
||||
Assert.NotNull(results.DesignTimeLineMappings); // Guard
|
||||
if (expectedLineMappings == null ||
|
||||
!Enumerable.SequenceEqual(expectedLineMappings, results.DesignTimeLineMappings))
|
||||
{
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
var lineMappings = new StringBuilder();
|
||||
lineMappings.AppendLine($"// !!! Do not check in. Instead paste content into test method. !!!");
|
||||
lineMappings.AppendLine();
|
||||
|
||||
var indent = " ";
|
||||
lineMappings.AppendLine($"{ indent }var expectedLineMappings = new[]");
|
||||
lineMappings.AppendLine($"{ indent }{{");
|
||||
foreach (var lineMapping in results.DesignTimeLineMappings)
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
var innerIndent = indent + " ";
|
||||
var documentLocation = lineMapping.DocumentLocation;
|
||||
var generatedLocation = lineMapping.GeneratedLocation;
|
||||
lineMappings.AppendLine($"{ innerIndent }{ nameof(BuildLineMapping) }(");
|
||||
|
||||
innerIndent += " ";
|
||||
lineMappings.AppendLine($"{ innerIndent }documentAbsoluteIndex: { documentLocation.AbsoluteIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }documentLineIndex: { documentLocation.LineIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }documentCharacterIndex: { documentLocation.CharacterIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedAbsoluteIndex: { generatedLocation.AbsoluteIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedLineIndex: { generatedLocation.LineIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedCharacterIndex: { generatedLocation.CharacterIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }contentLength: { generatedLocation.ContentLength }),");
|
||||
}
|
||||
|
||||
lineMappings.AppendLine($"{ indent }}};");
|
||||
|
||||
var lineMappingFile = Path.ChangeExtension(outputFile, "lineMappings.cs");
|
||||
ResourceFile.UpdateFile(_assembly, lineMappingFile, previousContent: null, content: lineMappings.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream GetResourceStream(string resourceName)
|
||||
{
|
||||
resourceName = "Microsoft.AspNet.Mvc.Razor.Host.Test." + resourceName.Replace('/', '.');
|
||||
|
||||
var assembly = typeof(MvcRazorHostTest).Assembly;
|
||||
return assembly.GetManifestResourceStream(resourceName);
|
||||
#else
|
||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
||||
Assert.Equal(expectedLineMappings, results.DesignTimeLineMappings);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static LineMapping BuildLineMapping(int documentAbsoluteIndex,
|
||||
|
|
@ -345,36 +411,43 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
public TestMvcRazorHost(IChunkTreeCache ChunkTreeCache)
|
||||
: base(ChunkTreeCache)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
public override CodeGenerator DecorateCodeGenerator(CodeGenerator incomingBuilder, CodeGeneratorContext context)
|
||||
public override CodeGenerator DecorateCodeGenerator(
|
||||
CodeGenerator incomingBuilder,
|
||||
CodeGeneratorContext context)
|
||||
{
|
||||
base.DecorateCodeGenerator(incomingBuilder, context);
|
||||
|
||||
return new TestCSharpCodeGenerator(context,
|
||||
DefaultModel,
|
||||
"Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute",
|
||||
new GeneratedTagHelperAttributeContext
|
||||
{
|
||||
ModelExpressionTypeName = ModelExpressionType,
|
||||
CreateModelExpressionMethodName = CreateModelExpressionMethod
|
||||
});
|
||||
return new TestCSharpCodeGenerator(
|
||||
context,
|
||||
DefaultModel,
|
||||
"Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute",
|
||||
new GeneratedTagHelperAttributeContext
|
||||
{
|
||||
ModelExpressionTypeName = ModelExpressionType,
|
||||
CreateModelExpressionMethodName = CreateModelExpressionMethod
|
||||
});
|
||||
}
|
||||
|
||||
protected class TestCSharpCodeGenerator : MvcCSharpCodeGenerator
|
||||
{
|
||||
private readonly GeneratedTagHelperAttributeContext _tagHelperAttributeContext;
|
||||
|
||||
public TestCSharpCodeGenerator(CodeGeneratorContext context,
|
||||
string defaultModel,
|
||||
string activateAttribute,
|
||||
GeneratedTagHelperAttributeContext tagHelperAttributeContext)
|
||||
public TestCSharpCodeGenerator(
|
||||
CodeGeneratorContext context,
|
||||
string defaultModel,
|
||||
string activateAttribute,
|
||||
GeneratedTagHelperAttributeContext tagHelperAttributeContext)
|
||||
: base(context, defaultModel, activateAttribute, tagHelperAttributeContext)
|
||||
{
|
||||
_tagHelperAttributeContext = tagHelperAttributeContext;
|
||||
}
|
||||
|
||||
protected override CSharpCodeVisitor CreateCSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context)
|
||||
protected override CSharpCodeVisitor CreateCSharpCodeVisitor(
|
||||
CSharpCodeWriter writer,
|
||||
CodeGeneratorContext context)
|
||||
{
|
||||
var visitor = base.CreateCSharpCodeVisitor(writer, context);
|
||||
visitor.TagHelperRenderer = new NoUniqueIdsTagHelperCodeRenderer(visitor, writer, context)
|
||||
|
|
@ -387,11 +460,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
private class NoUniqueIdsTagHelperCodeRenderer : CSharpTagHelperCodeRenderer
|
||||
{
|
||||
public NoUniqueIdsTagHelperCodeRenderer(IChunkVisitor bodyVisitor,
|
||||
CSharpCodeWriter writer,
|
||||
CodeGeneratorContext context)
|
||||
public NoUniqueIdsTagHelperCodeRenderer(
|
||||
IChunkVisitor bodyVisitor,
|
||||
CSharpCodeWriter writer,
|
||||
CodeGeneratorContext context)
|
||||
: base(bodyVisitor, writer, context)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
protected override string GenerateUniqueId()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class ASPV_TestFiles_Input_Basic_cshtml : Microsoft.AspNet.Mvc.Razor.RazorPage<dynamic>
|
||||
{
|
||||
private static object @__o;
|
||||
private void @__RazorDesignTimeHelpers__()
|
||||
{
|
||||
#pragma warning disable 219
|
||||
#pragma warning restore 219
|
||||
}
|
||||
#line hidden
|
||||
public ASPV_TestFiles_Input_Basic_cshtml()
|
||||
{
|
||||
|
|
@ -28,33 +29,16 @@
|
|||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
PageExecutionContext.BeginContext(0, 4, true);
|
||||
WriteLiteral("<div");
|
||||
PageExecutionContext.EndContext();
|
||||
WriteAttribute("class", Tuple.Create(" class=\"", 4), Tuple.Create("\"", 17),
|
||||
Tuple.Create(Tuple.Create("", 12), Tuple.Create<System.Object, System.Int32>(
|
||||
#line 1 "TestFiles/Input/Basic.cshtml"
|
||||
logo
|
||||
__o = logo;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
, 12), false));
|
||||
PageExecutionContext.BeginContext(18, 24, true);
|
||||
WriteLiteral(">\r\n Hello world\r\n ");
|
||||
PageExecutionContext.EndContext();
|
||||
PageExecutionContext.BeginContext(43, 21, false);
|
||||
Write(
|
||||
#line 3 "TestFiles/Input/Basic.cshtml"
|
||||
Html.Input("SomeKey")
|
||||
__o = Html.Input("SomeKey");
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
);
|
||||
|
||||
PageExecutionContext.EndContext();
|
||||
PageExecutionContext.BeginContext(64, 8, true);
|
||||
WriteLiteral("\r\n</div>");
|
||||
PageExecutionContext.EndContext();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
#line 1 "TestFiles/Input/Inject.cshtml"
|
||||
using MyNamespace
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Asp
|
||||
namespace Asp
|
||||
{
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "63d2634be31f68aa89a0c1561d67c73cc446f3d4"
|
||||
#pragma checksum "TestFiles/Input/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "63d2634be31f68aa89a0c1561d67c73cc446f3d4"
|
||||
namespace Asp
|
||||
{
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/Inject.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "424b7fe9f12352c59210b5fa8c74ca8c9c67de81"
|
||||
#pragma checksum "TestFiles/Input/Inject.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "424b7fe9f12352c59210b5fa8c74ca8c9c67de81"
|
||||
namespace Asp
|
||||
{
|
||||
#line 1 "TestFiles/Input/Inject.cshtml"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0c0e10d3fd8f5bf30eabc22ca0ee91355a13426d"
|
||||
#pragma checksum "TestFiles/Input/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0c0e10d3fd8f5bf30eabc22ca0ee91355a13426d"
|
||||
namespace Asp
|
||||
{
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b753615982659a9805e6213ceced76ba06782038"
|
||||
#pragma checksum "TestFiles/Input/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b753615982659a9805e6213ceced76ba06782038"
|
||||
namespace Asp
|
||||
{
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/Model.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2c1e88396568d309c236020e59bf2abacfadd612"
|
||||
#pragma checksum "TestFiles/Input/Model.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2c1e88396568d309c236020e59bf2abacfadd612"
|
||||
namespace Asp
|
||||
{
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "TestFiles/Input/ModelExpressionTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3b1d4af116a70f83c556ece1980f2e9364e6baa7"
|
||||
#pragma checksum "TestFiles/Input/ModelExpressionTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3b1d4af116a70f83c556ece1980f2e9364e6baa7"
|
||||
namespace Asp
|
||||
{
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
"commands": {
|
||||
"test": "xunit.runner.aspnet"
|
||||
},
|
||||
"compilationOptions": {
|
||||
"define": [ "__RemoveThisBitTo__GENERATE_BASELINES" ]
|
||||
},
|
||||
"frameworks": {
|
||||
"dnx451": {
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,245 @@
|
|||
// 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.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Reader and, if GENERATE_BASELINES is defined, writer for files compiled into an assembly as resources.
|
||||
/// </summary>
|
||||
/// <remarks>Inspired by Razor's BaselineWriter and TestFile test classes.</remarks>
|
||||
public static class ResourceFile
|
||||
{
|
||||
private static object writeLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Return <see cref="Stream"/> for <paramref name="resourceName"/> from <paramref name="assembly"/>'s
|
||||
/// manifest.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> containing <paramref name="resourceName"/>.</param>
|
||||
/// <param name="resourceName">
|
||||
/// Name of the manifest resource in <paramref name="assembly"/>. A path relative to the test project
|
||||
/// directory.
|
||||
/// </param>
|
||||
/// <param name="sourceFile">
|
||||
/// If <c>true</c> <paramref name="resourceName"/> is used as a source file and must exist. Otherwise
|
||||
/// <paramref name="resourceName"/> is an output file and, if <c>GENERATE_BASELINES</c> is defined, it will
|
||||
/// soon be generated if missing.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see cref="Stream"/> for <paramref name="resourceName"/> from <paramref name="assembly"/>'s
|
||||
/// manifest. <c>null</c> if <c>GENERATE_BASELINES</c> is defined, <paramref name="sourceFile"/> is
|
||||
/// <c>false</c>, and <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="Xunit.Sdk.TrueException">
|
||||
/// Thrown if <c>GENERATE_BASELINES</c> is not defined or <paramref name="sourceFile"/> is <c>true</c> and
|
||||
/// <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </exception>
|
||||
public static Stream GetResourceStream(Assembly assembly, string resourceName, bool sourceFile)
|
||||
{
|
||||
// The DNX runtime compiles every file under the resources folder as a resource available at runtime with
|
||||
// the same name as the file name.
|
||||
var fullName = $"{ assembly.GetName().Name }.{ resourceName.Replace('/', '.') }";
|
||||
if (!Exists(assembly, fullName))
|
||||
{
|
||||
#if GENERATE_BASELINES
|
||||
if (sourceFile)
|
||||
{
|
||||
// Even when generating baselines, a missing source file is a serious problem.
|
||||
Assert.True(false, $"Manifest resource: { fullName } not found.");
|
||||
}
|
||||
#else
|
||||
// When not generating baselines, a missing source or output file is always an error.
|
||||
Assert.True(false, $"Manifest resource '{ fullName }' not found.");
|
||||
#endif
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return assembly.GetManifestResourceStream(fullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return <see cref="string"/> content of <paramref name="resourceName"/> from <paramref name="assembly"/>'s
|
||||
/// manifest.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> containing <paramref name="resourceName"/>.</param>
|
||||
/// <param name="resourceName">
|
||||
/// Name of the manifest resource in <paramref name="assembly"/>. A path relative to the test project
|
||||
/// directory.
|
||||
/// </param>
|
||||
/// <param name="sourceFile">
|
||||
/// If <c>true</c> <paramref name="resourceName"/> is used as a source file and must exist. Otherwise
|
||||
/// <paramref name="resourceName"/> is an output file and, if <c>GENERATE_BASELINES</c> is defined, it will
|
||||
/// soon be generated if missing.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{string}"/> which on completion returns the <see cref="string"/> content of
|
||||
/// <paramref name="resourceName"/> from <paramref name="assembly"/>'s manifest. <c>null</c> if
|
||||
/// <c>GENERATE_BASELINES</c> is defined, <paramref name="sourceFile"/> is <c>false</c>, and
|
||||
/// <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="Xunit.Sdk.TrueException">
|
||||
/// Thrown if <c>GENERATE_BASELINES</c> is not defined or <paramref name="sourceFile"/> is <c>true</c> and
|
||||
/// <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </exception>
|
||||
/// <remarks>Normalizes line endings to <see cref="Environment.NewLine"/>.</remarks>
|
||||
public static async Task<string> ReadResourceAsync(Assembly assembly, string resourceName, bool sourceFile)
|
||||
{
|
||||
using (var stream = GetResourceStream(assembly, resourceName, sourceFile))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
var content = await streamReader.ReadToEndAsync();
|
||||
|
||||
// Normalize line endings to Environment.NewLine. This removes core.autocrlf, core.eol,
|
||||
// core.safecrlf, and .gitattributes from the equation and matches what MVC returns.
|
||||
return content
|
||||
.Replace("\r", string.Empty)
|
||||
.Replace("\n", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return <see cref="string"/> content of <paramref name="resourceName"/> from <paramref name="assembly"/>'s
|
||||
/// manifest.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> containing <paramref name="resourceName"/>.</param>
|
||||
/// <param name="resourceName">
|
||||
/// Name of the manifest resource in <paramref name="assembly"/>. A path relative to the test project
|
||||
/// directory.
|
||||
/// </param>
|
||||
/// <param name="sourceFile">
|
||||
/// If <c>true</c> <paramref name="resourceName"/> is used as a source file and must exist. Otherwise
|
||||
/// <paramref name="resourceName"/> is an output file and, if <c>GENERATE_BASELINES</c> is defined, it will
|
||||
/// soon be generated if missing.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/> content of <paramref name="resourceName"/> from <paramref name="assembly"/>'s
|
||||
/// manifest. <c>null</c> if <c>GENERATE_BASELINES</c> is defined, <paramref name="sourceFile"/> is
|
||||
/// <c>false</c>, and <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="Xunit.Sdk.TrueException">
|
||||
/// Thrown if <c>GENERATE_BASELINES</c> is not defined or <paramref name="sourceFile"/> is <c>true</c> and
|
||||
/// <paramref name="resourceName"/> is not found in <paramref name="assembly"/>.
|
||||
/// </exception>
|
||||
/// <remarks>Normalizes line endings to <see cref="Environment.NewLine"/>.</remarks>
|
||||
public static string ReadResource(Assembly assembly, string resourceName, bool sourceFile)
|
||||
{
|
||||
using (var stream = GetResourceStream(assembly, resourceName, sourceFile))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
var content = streamReader.ReadToEnd();
|
||||
|
||||
// Normalize line endings to Environment.NewLine. This removes core.autocrlf, core.eol,
|
||||
// core.safecrlf, and .gitattributes from the equation and matches what MVC returns.
|
||||
return content
|
||||
.Replace("\r", string.Empty)
|
||||
.Replace("\n", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write <paramref name="content"/> to file that will become <paramref name="resourceName"/> in
|
||||
/// <paramref name="assembly"/> the next time the project is built. Does nothing if
|
||||
/// <paramref name="previousContent"/> and <paramref name="content"/> already match.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> containing <paramref name="resourceName"/>.</param>
|
||||
/// <param name="resourceName">
|
||||
/// Name of the manifest resource in <paramref name="assembly"/>. A path relative to the test project
|
||||
/// directory.
|
||||
/// </param>
|
||||
/// <param name="previousContent">
|
||||
/// Current content of <paramref name="resourceName"/>. <c>null</c> if <paramref name="resourceName"/> does
|
||||
/// not currently exist in <paramref name="assembly"/>.
|
||||
/// </param>
|
||||
/// <param name="content">
|
||||
/// New content of <paramref name="resourceName"/> in <paramref name="assembly"/>.
|
||||
/// </param>
|
||||
[Conditional("GENERATE_BASELINES")]
|
||||
public static void UpdateFile(Assembly assembly, string resourceName, string previousContent, string content)
|
||||
{
|
||||
if (!string.Equals(previousContent, content, StringComparison.Ordinal))
|
||||
{
|
||||
// The DNX runtime compiles every file under the resources folder as a resource available at runtime with
|
||||
// the same name as the file name. Need to update this file on disc.
|
||||
var projectName = assembly.GetName().Name;
|
||||
var projectPath = GetProjectPath(projectName);
|
||||
var fullPath = Path.Combine(projectPath, resourceName);
|
||||
WriteFile(fullPath, content);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Exists(Assembly assembly, string fullName)
|
||||
{
|
||||
var resourceNames = assembly.GetManifestResourceNames();
|
||||
foreach (var resourceName in resourceNames)
|
||||
{
|
||||
// Resource names are case-sensitive.
|
||||
if (string.Equals(fullName, resourceName, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetProjectPath(string projectName)
|
||||
{
|
||||
// Initial guess: Already in the project directory.
|
||||
var projectPath = Path.GetFullPath(".");
|
||||
|
||||
var currentDirectoryName = new DirectoryInfo(projectPath).Name;
|
||||
if (!string.Equals(projectName, currentDirectoryName, StringComparison.Ordinal))
|
||||
{
|
||||
// Not running from test project directory. Should be in "test" or solution directory.
|
||||
if (string.Equals("test", currentDirectoryName, StringComparison.Ordinal))
|
||||
{
|
||||
projectPath = Path.Combine(projectPath, projectName);
|
||||
}
|
||||
else
|
||||
{
|
||||
projectPath = Path.Combine(projectPath, "test", projectName);
|
||||
}
|
||||
}
|
||||
|
||||
return projectPath;
|
||||
}
|
||||
|
||||
private static void WriteFile(string fullPath, string content)
|
||||
{
|
||||
// Serialize writes to minimize contention for file handles and directory access.
|
||||
lock (writeLock)
|
||||
{
|
||||
// Write content to the file, creating it if necessary.
|
||||
using (var stream = File.Open(fullPath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
writer.Write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue