Trim quotes from template (#5838)

This commit is contained in:
Ryan Brandenburg 2017-03-03 09:52:36 -08:00 committed by GitHub
parent 7cadb58e12
commit 85e28ae478
8 changed files with 336 additions and 18 deletions

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
}
string template;
if (!PageDirectiveFeature.TryGetRouteTemplate(item, out template))
if (!PageDirectiveFeature.TryGetPageDirective(item, out template))
{
// .cshtml pages without @page are not RazorPages.
continue;

View File

@ -9,25 +9,46 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
{
public static class PageDirectiveFeature
{
public static bool TryGetRouteTemplate(RazorProjectItem projectItem, out string template)
public static bool TryGetPageDirective(RazorProjectItem projectItem, out string template)
{
if (projectItem == null)
{
throw new ArgumentNullException(nameof(projectItem));
}
const string PageDirective = "@page";
string content;
using (var streamReader = new StreamReader(projectItem.Read()))
var stream = projectItem.Read();
string content = null;
using (var streamReader = new StreamReader(stream))
{
content = streamReader.ReadToEnd();
do
{
content = streamReader.ReadLine();
} while (content != null && string.IsNullOrWhiteSpace(content));
content = content?.Trim();
}
if (content.StartsWith(PageDirective, StringComparison.Ordinal))
if (content == null || !content.StartsWith(PageDirective, StringComparison.Ordinal))
{
var newLineIndex = content.IndexOf(Environment.NewLine, PageDirective.Length);
template = content.Substring(PageDirective.Length, newLineIndex - PageDirective.Length).Trim();
return true;
template = null;
return false;
}
template = null;
return false;
template = content.Substring(PageDirective.Length, content.Length - PageDirective.Length).TrimStart();
if (template.StartsWith("\"") && template.EndsWith("\""))
{
template = template.Substring(1, template.Length - 2);
}
// If it's not in quotes it's not our template
else
{
template = string.Empty;
}
return true;
}
}
}

View File

@ -1,7 +1,6 @@
// 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.Linq;
using System.Net;
using System.Net.Http;
@ -19,6 +18,19 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
public HttpClient Client { get; }
[Fact]
public async Task NoPage_NotFound()
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/NoPage");
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact]
public async Task HelloWorld_CanGetContent()
{
@ -83,16 +95,32 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("Hello, pagemodel!", content.Trim());
}
[Fact]
public async Task PageWithoutContent()
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/PageWithoutContent/No/Content/Path");
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal("", content);
}
[Fact]
public async Task TempData_SetTempDataInPage_CanReadValue()
{
// Arrange 1
var url = "http://localhost/TempData/SetTempDataOnPageAndRedirect?message=Hi1";
var request = new HttpRequestMessage(HttpMethod.Get, url);
// Act 1
var response = await Client.SendAsync(request);
// Assert 1
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);

View File

@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
razorProject.Setup(p => p.EnumerateItems("/"))
.Returns(new[]
{
GetProjectItem("/", "/Test.cshtml", $"@page Home {Environment.NewLine}<h1>Hello world</h1>"),
GetProjectItem("/", "/Test.cshtml", $"@page \"Home\" {Environment.NewLine}<h1>Hello world</h1>"),
});
var provider = new PageActionDescriptorProvider(
razorProject.Object,
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
razorProject.Setup(p => p.EnumerateItems("/"))
.Returns(new[]
{
GetProjectItem("/", "/Test.cshtml", $"@page {template} {Environment.NewLine}<h1>Hello world</h1>"),
GetProjectItem("/", "/Test.cshtml", $"@page \"{template}\" {Environment.NewLine}<h1>Hello world</h1>"),
});
var provider = new PageActionDescriptorProvider(
razorProject.Object,
@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
razorProject.Setup(p => p.EnumerateItems("/"))
.Returns(new[]
{
GetProjectItem("", "/Catalog/Details/Index.cshtml", $"@page {{id:int?}} {Environment.NewLine}"),
GetProjectItem("", "/Catalog/Details/Index.cshtml", $"@page \"{{id:int?}}\" {Environment.NewLine}"),
});
var provider = new PageActionDescriptorProvider(
razorProject.Object,

View File

@ -0,0 +1,267 @@
// 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.Text;
using Microsoft.AspNetCore.Razor.Evolution;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
{
public class PageDirectiveFeatureTest
{
[Fact]
public void TryGetPageDirective_FindsTemplate()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""
The rest of the thing");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal("Some/Path/{value}", template);
}
[Fact]
public void TryGetPageDirective_NoNewLine()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal("Some/Path/{value}", template);
}
[Fact]
public void TryGetPageDirective_JunkBeforeDirective()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"Not a directive @page ""Some/Path/{value}""");
// Act & Assert
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Null(template);
}
[Fact]
public void TryGetPageDirective_MultipleQuotes()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page """"template""""");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal(@"""template""", template);
}
[Theory]
[InlineData(@"""Some/Path/{value}")]
[InlineData(@"Some/Path/{value}""")]
public void TryGetPageDirective_RequiresBothQuotes(string inTemplate)
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem($@"@page {inTemplate}");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal(string.Empty, template);
}
[Fact]
public void TryGetPageDirective_NoQuotesAroundPath_IsNotTemplate()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page Some/Path/{value}");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal(string.Empty, template);
}
[Fact]
public void TryGetPageDirective_WrongNewLine()
{
// Arrange
var wrongNewLine = Environment.NewLine == "\r\n" ? "\n" : "\r\n";
string template;
var projectItem = new TestRazorProjectItem($"@page \"Some/Path/{{value}}\" {wrongNewLine}");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal("Some/Path/{value}", template);
}
[Fact]
public void TryGetPageDirective_NewLineBeforeDirective()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem("\n @page \"Some/Path/{value}\"");
// Act
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal("Some/Path/{value}", template);
}
[Fact]
public void TryGetPageDirective_WhitespaceBeforeDirective()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@" @page ""Some/Path/{value}""
");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Equal("Some/Path/{value}", template);
}
[Fact(Skip = "Re-evaluate this scenario after we use Razor to parse this stuff")]
public void TryGetPageDirective_JunkBeforeNewline()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}"" things that are not the path
a new line");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Empty(template);
}
[Fact]
public void TryGetPageDirective_Directive_WithoutPathOrContent()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Empty(template);
}
[Fact]
public void TryGetPageDirective_DirectiveWithContent_WithoutPath()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"@page
Non-path things");
// Act & Assert
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Empty(template);
}
[Fact]
public void TryGetPageDirective_NoDirective()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(@"This is junk
Nobody will use it");
// Act & Assert
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Null(template);
}
[Fact]
public void TryGetPageDirective_EmptyStream()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(string.Empty);
// Act
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
Assert.Null(template);
}
[Fact]
public void TryGetPageDirective_NullProject()
{
// Arrange
string template;
// Act & Assert
Assert.Throws<ArgumentNullException>(() => PageDirectiveFeature.TryGetPageDirective(projectItem: null, template: out template));
}
[Fact]
public void TryGetPageDirective_NullStream()
{
// Arrange
string template;
var projectItem = new TestRazorProjectItem(content: null);
// Act & Assert
Assert.Throws<ArgumentNullException>(() => PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
}
}
public class TestRazorProjectItem : RazorProjectItem
{
private string _content;
public TestRazorProjectItem(string content)
{
_content = content;
}
public override string BasePath
{
get
{
throw new NotImplementedException();
}
}
public override bool Exists
{
get
{
throw new NotImplementedException();
}
}
public override string Path
{
get
{
throw new NotImplementedException();
}
}
public override string PhysicalPath
{
get
{
throw new NotImplementedException();
}
}
public override Stream Read()
{
if (_content == null)
{
return null;
}
else
{
return new MemoryStream(Encoding.UTF8.GetBytes(_content));
}
}
}
}

View File

@ -1,3 +1,3 @@
@page Some/Path/{text}
@page "Some/Path/{text}"
Hello, @(ViewContext.RouteData.Values["text"])!

View File

@ -0,0 +1 @@
This isn't a razor page

View File

@ -0,0 +1 @@
@page "No/Content/Path"