Modify ViewStartUtility to generate always view paths with forward slashes

Fixes #3294
This commit is contained in:
Pranav K 2015-10-12 11:44:13 -07:00
parent e943cdb57a
commit f4a6d634b5
7 changed files with 121 additions and 59 deletions

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Microsoft.AspNet.Mvc.Razor
{
@ -77,18 +78,31 @@ namespace Microsoft.AspNet.Mvc.Razor
// If the specified path is for the file hierarchy being constructed, then the first file that applies
// to it is in a parent directory.
relativePath = Path.GetDirectoryName(relativePath);
if (string.IsNullOrEmpty(relativePath))
{
return Enumerable.Empty<string>();
}
}
var locations = new List<string>();
while (!string.IsNullOrEmpty(relativePath))
var builder = new StringBuilder(relativePath);
builder.Replace('\\', '/');
if (builder.Length > 0 && builder[0] != '/')
{
relativePath = Path.GetDirectoryName(relativePath);
var path = Path.Combine(relativePath, fileName);
locations.Add(path);
builder.Insert(0, '/');
}
var locations = new List<string>();
for (var index = builder.Length - 1; index >= 0; index--)
{
if (builder[index] == '/')
{
builder.Length = index + 1;
builder.Append(fileName);
locations.Add(builder.ToString());
}
}
return locations;

View File

@ -58,10 +58,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
var content = await response.Content.ReadAsStringAsync();
Assert.Contains(
PlatformNormalizer.NormalizePath(@"Views\ErrorFromViewImports\_ViewImports.cshtml"),
content);
Assert.Contains("/Views/ErrorFromViewImports/_ViewImports.cshtml", content);
Assert.Contains(expectedMessage, content);
}
}

View File

@ -400,7 +400,7 @@ Partial that does not specify Layout
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
#else
Assert.Equal(
PlatformNormalizer.NormalizePath(expectedContent),
expectedContent,
responseContent,
ignoreLineEndingDifferences: true);
#endif

View File

@ -3,7 +3,7 @@
/Views/ViewWithPaths/Index.cshtml
</Layout>
<ViewStart>
Views\ViewWithPaths\_ViewStart.cshtml
/Views/ViewWithPaths/_ViewStart.cshtml
/Views/ViewWithPaths/Index.cshtml
</ViewStart>
<Index>

View File

@ -13,10 +13,10 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
{
// Arrange
var fileProvider = new TestFileProvider();
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\accounts\_ViewImports.cshtml"), "@using AccountModels");
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\Shared\_ViewImports.cshtml"), "@inject SharedHelper Shared");
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml"), "@using MyNamespace");
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
fileProvider.AddFile(@"/Views/accounts/_ViewImports.cshtml", "@using AccountModels");
fileProvider.AddFile(@"/Views/Shared/_ViewImports.cshtml", "@inject SharedHelper Shared");
fileProvider.AddFile(@"/Views/home/_ViewImports.cshtml", "@using MyNamespace");
fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
@"@inject MyHelper<TModel> Helper
@inherits MyBaseType
@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
Assert.Collection(chunkTreeResults,
chunkTreeResult =>
{
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml");
var viewImportsPath = @"/Views/_ViewImports.cshtml";
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
chunk =>
{
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
},
chunkTreeResult =>
{
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
var viewImportsPath = "/Views/home/_ViewImports.cshtml";
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
chunk =>
{
@ -113,9 +113,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
{
// Arrange
var fileProvider = new TestFileProvider();
fileProvider.AddFile(@"_ViewImports.cs", string.Empty);
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_Layout.cshtml"), string.Empty);
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_not-viewimports.cshtml"), string.Empty);
fileProvider.AddFile(@"/_ViewImports.cs", string.Empty);
fileProvider.AddFile(@"/Views/_Layout.cshtml", string.Empty);
fileProvider.AddFile(@"/Views/home/_not-viewimports.cshtml", string.Empty);
var cache = new DefaultChunkTreeCache(fileProvider);
var host = new MvcRazorHost(cache);
var defaultChunks = new Chunk[]
@ -137,7 +137,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
{
// Arrange
var fileProvider = new TestFileProvider();
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
"@inject DifferentHelper<TModel> Html");
var cache = new DefaultChunkTreeCache(fileProvider);
var host = new MvcRazorHost(cache);

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNet.Testing;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
@ -43,9 +42,34 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Views\_ViewStart.cshtml"),
@"_ViewStart.cshtml"
"/Views/Home/_ViewStart.cshtml",
"/Views/_ViewStart.cshtml",
"/_ViewStart.cshtml"
};
// Act
var result = ViewHierarchyUtility.GetViewStartLocations(inputPath);
// Assert
Assert.Equal(expected, result);
}
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux,
SkipReason = "Back slashes only work as path separators on Windows")]
[OSSkipCondition(OperatingSystems.MacOSX,
SkipReason = "Back slashes only work as path separators on Windows")]
[InlineData(@"~/Views\Home\MyView.cshtml")]
[InlineData(@"Views\Home\MyView.cshtml")]
public void GetViewStartLocations_ReturnsPotentialViewStartLocations_PathsContainBackSlash(
string inputPath)
{
// Arrange
var expected = new[]
{
"/Views/Home/_ViewStart.cshtml",
"/Views/_ViewStart.cshtml",
"/_ViewStart.cshtml"
};
// Act
@ -64,9 +88,9 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
@"_ViewImports.cshtml"
"/Views/Home/_ViewImports.cshtml",
"/Views/_ViewImports.cshtml",
"/_ViewImports.cshtml"
};
// Act
@ -85,8 +109,8 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Views\_ViewStart.cshtml"),
@"_ViewStart.cshtml"
"/Views/_ViewStart.cshtml",
"/_ViewStart.cshtml"
};
// Act
@ -105,9 +129,9 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
@"_ViewImports.cshtml"
"/Views/Home/_ViewImports.cshtml",
"/Views/_ViewImports.cshtml",
"/_ViewImports.cshtml"
};
// Act
@ -126,8 +150,8 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
@"_ViewImports.cshtml"
"/Views/_ViewImports.cshtml",
"/_ViewImports.cshtml"
};
// Act
@ -145,14 +169,42 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\Admin\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\_ViewStart.cshtml"),
@"_ViewStart.cshtml",
"/Areas/MyArea/Sub/Views/Admin/_ViewStart.cshtml",
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
"/Areas/MyArea/Sub/_ViewStart.cshtml",
"/Areas/MyArea/_ViewStart.cshtml",
"/Areas/_ViewStart.cshtml",
"/_ViewStart.cshtml",
};
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
// Act
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
// Assert
Assert.Equal(expected, result);
}
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux,
SkipReason = "Back slashes only work as path separators on Windows")]
[OSSkipCondition(OperatingSystems.MacOSX,
SkipReason = "Back slashes only work as path separators on Windows")]
[InlineData("Test.cshtml")]
[InlineData("ViewStart.cshtml")]
public void GetViewStartLocations_ReturnsPotentialViewStartLocations_ForPathsWithBackSlashes(string fileName)
{
// Arrange
var expected = new[]
{
"/Areas/MyArea/Sub/Views/Admin/_ViewStart.cshtml",
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
"/Areas/MyArea/Sub/_ViewStart.cshtml",
"/Areas/MyArea/_ViewStart.cshtml",
"/Areas/_ViewStart.cshtml",
"/_ViewStart.cshtml",
};
var viewPath = $"Areas\\MyArea\\Sub\\Views\\Admin/{fileName}";
// Act
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
@ -170,14 +222,14 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\Admin\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewImports.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\_ViewImports.cshtml"),
@"_ViewImports.cshtml",
"/Areas/MyArea/Sub/Views/Admin/_ViewImports.cshtml",
"/Areas/MyArea/Sub/Views/_ViewImports.cshtml",
"/Areas/MyArea/Sub/_ViewImports.cshtml",
"/Areas/MyArea/_ViewImports.cshtml",
"/Areas/_ViewImports.cshtml",
"/_ViewImports.cshtml",
};
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
// Act
var result = ViewHierarchyUtility.GetViewImportsLocations(viewPath);
@ -194,13 +246,13 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var expected = new[]
{
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewStart.cshtml"),
PlatformNormalizer.NormalizePath(@"Areas\_ViewStart.cshtml"),
@"_ViewStart.cshtml",
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
"/Areas/MyArea/Sub/_ViewStart.cshtml",
"/Areas/MyArea/_ViewStart.cshtml",
"/Areas/_ViewStart.cshtml",
"/_ViewStart.cshtml",
};
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
// Act
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using Moq;
using Xunit;
@ -21,9 +20,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
public static TheoryData ViewImportsPaths =>
new TheoryData<string>
{
Path.Combine("Views", "Home", "_ViewImports.cshtml"),
Path.Combine("Views", "_ViewImports.cshtml"),
"_ViewImports.cshtml",
"/Views/Home/_ViewImports.cshtml",
"/Views/_ViewImports.cshtml",
"/_ViewImports.cshtml",
};
[Fact]