Merge branch 'release/2.2'
This commit is contained in:
commit
fb9a02ef5a
File diff suppressed because it is too large
Load Diff
|
|
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests
|
||||||
b.AddTargetExtension(new TemplateTargetExtension());
|
b.AddTargetExtension(new TemplateTargetExtension());
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var document = engine.Process(projectItem);
|
var document = engine.Process(projectItem);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ Document -
|
||||||
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel<MyModel> -
|
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel<MyModel> -
|
||||||
DesignTimeDirective -
|
DesignTimeDirective -
|
||||||
DirectiveToken - (10:0,10 [19] InheritsWithViewImports_Imports0.cshtml) - MyPageModel<TModel>
|
|
||||||
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
||||||
DirectiveToken - (294:7,71 [4] ) - Html
|
DirectiveToken - (294:7,71 [4] ) - Html
|
||||||
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
|
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
|
||||||
|
|
@ -24,6 +23,7 @@ Document -
|
||||||
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
||||||
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
||||||
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
||||||
|
DirectiveToken - (10:0,10 [19] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyPageModel<TModel>
|
||||||
DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel
|
DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel
|
||||||
CSharpCode -
|
CSharpCode -
|
||||||
IntermediateToken - - CSharp - #pragma warning disable 0414
|
IntermediateToken - - CSharp - #pragma warning disable 0414
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
@inherits MyPageModel<TModel>
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace AspNetCore
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d196fc1c66d46d35e35af9b01c737e12bcce6782", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")]
|
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d196fc1c66d46d35e35af9b01c737e12bcce6782", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")]
|
||||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"30a9e14edcefbf4970c45de29d8870cf1a9b90b5", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_Imports0.cshtml")]
|
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f311ecbb5c4d63980a59c24af5ffe8baa1c3f99a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")]
|
||||||
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel<MyModel>
|
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel<MyModel>
|
||||||
{
|
{
|
||||||
#pragma warning disable 1998
|
#pragma warning disable 1998
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,78 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
|
using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
|
||||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.Emit;
|
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
|
||||||
using Microsoft.Extensions.DependencyModel;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.IntegrationTests
|
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.IntegrationTests
|
||||||
{
|
{
|
||||||
public class CodeGenerationIntegrationTest : IntegrationTestBase
|
public class CodeGenerationIntegrationTest : IntegrationTestBase
|
||||||
{
|
{
|
||||||
private static readonly RazorSourceDocument DefaultImports = MvcRazorTemplateEngine.GetDefaultImports();
|
private readonly static CSharpCompilation DefaultBaseCompilation = MvcShim.BaseCompilation.WithAssemblyName("AppCode");
|
||||||
|
|
||||||
private CSharpCompilation BaseCompilation => MvcShim.BaseCompilation.WithAssemblyName("AppCode");
|
public CodeGenerationIntegrationTest()
|
||||||
|
: base(generateBaselines: null)
|
||||||
|
{
|
||||||
|
Configuration = RazorConfiguration.Create(
|
||||||
|
RazorLanguageVersion.Version_1_1,
|
||||||
|
"MVC-1.1",
|
||||||
|
new[] { new AssemblyExtension("MVC-1.1", typeof(ExtensionInitializer).Assembly) });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation;
|
||||||
|
|
||||||
|
protected override RazorConfiguration Configuration { get; }
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InvalidNamespaceAtEOF_DesignTime()
|
public void InvalidNamespaceAtEOF_DesignTime()
|
||||||
{
|
{
|
||||||
var compilation = BaseCompilation;
|
// Arrange
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToCSharp(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
|
|
||||||
|
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
|
||||||
|
Assert.Equal("RZ1007", Assert.Single(diagnotics).Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void IncompleteDirectives_DesignTime()
|
public void IncompleteDirectives_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
public class MyService<TModel>
|
public class MyService<TModel>
|
||||||
{
|
{
|
||||||
public string Html { get; set; }
|
public string Html { get; set; }
|
||||||
}
|
}");
|
||||||
";
|
|
||||||
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
var projectItem = CreateProjectItemFromFile();
|
||||||
RunDesignTimeTest(compilation);
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToCSharp(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
|
|
||||||
|
// We expect this test to generate a bunch of errors.
|
||||||
|
Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InheritsViewModel_DesignTime()
|
public void InheritsViewModel_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
|
||||||
|
|
@ -60,20 +83,28 @@ public class MyBasePageForViews<TModel> : RazorPage
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MyModel
|
public class MyModel
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
";
|
");
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InheritsWithViewImports_DesignTime()
|
public void InheritsWithViewImports_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
|
||||||
|
|
@ -88,61 +119,102 @@ public class MyBasePageForViews<TModel> : RazorPage
|
||||||
public class MyModel
|
public class MyModel
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}");
|
||||||
";
|
|
||||||
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
AddProjectItemFromText(@"@inherits MyBasePageForViews<TModel>");
|
||||||
RunDesignTimeTest(compilation);
|
|
||||||
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Basic_DesignTime()
|
public void Basic_DesignTime()
|
||||||
{
|
{
|
||||||
var compilation = BaseCompilation;
|
// Arrange
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Sections_DesignTime()
|
public void Sections_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = $@"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree($@"
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
|
||||||
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
||||||
{{
|
{{
|
||||||
public ModelExpression For {{ get; set; }}
|
public ModelExpression For {{ get; set; }}
|
||||||
}}
|
}}
|
||||||
";
|
");
|
||||||
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
RunDesignTimeTest(compilation);
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void _ViewImports_DesignTime()
|
public void _ViewImports_DesignTime()
|
||||||
{
|
{
|
||||||
var compilation = BaseCompilation;
|
// Arrange
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Inject_DesignTime()
|
public void Inject_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
public class MyApp
|
public class MyApp
|
||||||
{
|
{
|
||||||
public string MyProperty { get; set; }
|
public string MyProperty { get; set; }
|
||||||
}
|
}
|
||||||
";
|
");
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InjectWithModel_DesignTime()
|
public void InjectWithModel_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
public class MyModel
|
public class MyModel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -156,75 +228,119 @@ public class MyService<TModel>
|
||||||
public class MyApp
|
public class MyApp
|
||||||
{
|
{
|
||||||
public string MyProperty { get; set; }
|
public string MyProperty { get; set; }
|
||||||
}
|
}");
|
||||||
";
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
var projectItem = CreateProjectItemFromFile();
|
||||||
RunDesignTimeTest(compilation);
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InjectWithSemicolon_DesignTime()
|
public void InjectWithSemicolon_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
public class MyModel
|
public class MyModel
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MyService<TModel>
|
|
||||||
{
|
|
||||||
public string Html { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MyApp
|
public class MyApp
|
||||||
{
|
{
|
||||||
public string MyProperty { get; set; }
|
public string MyProperty { get; set; }
|
||||||
}
|
}
|
||||||
";
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
public class MyService<TModel>
|
||||||
RunDesignTimeTest(compilation);
|
{
|
||||||
|
public string Html { get; set; }
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Model_DesignTime()
|
public void Model_DesignTime()
|
||||||
{
|
{
|
||||||
var compilation = BaseCompilation;
|
// Arrange
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void MultipleModels_DesignTime()
|
public void MultipleModels_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = @"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree(@"
|
||||||
public class ThisShouldBeGenerated
|
public class ThisShouldBeGenerated
|
||||||
{
|
{
|
||||||
|
|
||||||
}";
|
}");
|
||||||
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
var projectItem = CreateProjectItemFromFile();
|
||||||
RunDesignTimeTest(compilation);
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToCSharp(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
|
|
||||||
|
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
|
||||||
|
Assert.Equal("RZ2001", Assert.Single(diagnotics).Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ModelExpressionTagHelper_DesignTime()
|
public void ModelExpressionTagHelper_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = $@"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree($@"
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
|
||||||
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
||||||
{{
|
{{
|
||||||
public ModelExpression For {{ get; set; }}
|
public ModelExpression For {{ get; set; }}
|
||||||
}}
|
}}
|
||||||
";
|
");
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
|
||||||
|
|
||||||
RunDesignTimeTest(compilation);
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ViewComponentTagHelper_DesignTime()
|
public void ViewComponentTagHelper_DesignTime()
|
||||||
{
|
{
|
||||||
var appCode = $@"
|
// Arrange
|
||||||
|
AddCSharpSyntaxTree($@"
|
||||||
public class TestViewComponent
|
public class TestViewComponent
|
||||||
{{
|
{{
|
||||||
public string Invoke(string firstName)
|
public string Invoke(string firstName)
|
||||||
|
|
@ -238,126 +354,17 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
|
||||||
{{
|
{{
|
||||||
public string Bar {{ get; set; }}
|
public string Bar {{ get; set; }}
|
||||||
}}
|
}}
|
||||||
";
|
");
|
||||||
|
|
||||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
RunDesignTimeTest(compilation);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RunDesignTimeTest(
|
|
||||||
CSharpCompilation baseCompilation,
|
|
||||||
IEnumerable<string> expectedErrors = null)
|
|
||||||
{
|
|
||||||
Assert.Empty(baseCompilation.GetDiagnostics());
|
|
||||||
|
|
||||||
// Arrange
|
|
||||||
var engine = CreateEngine(baseCompilation);
|
|
||||||
var projectItem = CreateProjectItem();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var document = engine.ProcessDesignTime(projectItem);
|
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
AssertDocumentNodeMatchesBaseline(document.GetDocumentIntermediateNode());
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
AssertCSharpDocumentMatchesBaseline(document.GetCSharpDocument());
|
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||||
AssertSourceMappingsMatchBaseline(document);
|
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||||
AssertDocumentCompiles(document, baseCompilation, expectedErrors);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AssertDocumentCompiles(
|
|
||||||
RazorCodeDocument document,
|
|
||||||
CSharpCompilation baseCompilation,
|
|
||||||
IEnumerable<string> expectedErrors = null)
|
|
||||||
{
|
|
||||||
var cSharp = document.GetCSharpDocument().GeneratedCode;
|
|
||||||
|
|
||||||
var syntaxTree = CSharpSyntaxTree.ParseText(cSharp);
|
|
||||||
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
|
|
||||||
|
|
||||||
var references = baseCompilation.References.Concat(new[] { baseCompilation.ToMetadataReference() });
|
|
||||||
var compilation = CSharpCompilation.Create("CodeGenerationTestAssembly", new[] { syntaxTree }, references, options);
|
|
||||||
|
|
||||||
var diagnostics = compilation.GetDiagnostics();
|
|
||||||
|
|
||||||
var errors = diagnostics.Where(d => d.Severity >= DiagnosticSeverity.Warning);
|
|
||||||
|
|
||||||
if (expectedErrors == null)
|
|
||||||
{
|
|
||||||
Assert.Empty(errors.Select(e => e.GetMessage()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedErrors, errors.Select(e => e.GetMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected RazorProjectEngine CreateEngine(CSharpCompilation compilation)
|
|
||||||
{
|
|
||||||
var references = compilation.References.Concat(new[] { compilation.ToMetadataReference() });
|
|
||||||
|
|
||||||
return CreateProjectEngine(b =>
|
|
||||||
{
|
|
||||||
RazorExtensions.Register(b);
|
|
||||||
RazorExtensions.RegisterViewComponentTagHelpers(b);
|
|
||||||
|
|
||||||
var existingImportFeature = b.Features.OfType<IImportProjectFeature>().Single();
|
|
||||||
b.SetImportFeature(new NormalizedDefaultImportFeature(existingImportFeature));
|
|
||||||
|
|
||||||
b.Features.Add(GetMetadataReferenceFeature(references));
|
|
||||||
b.Features.Add(new CompilationTagHelperFeature());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IRazorEngineFeature GetMetadataReferenceFeature(IEnumerable<MetadataReference> references)
|
|
||||||
{
|
|
||||||
return new DefaultMetadataReferenceFeature()
|
|
||||||
{
|
|
||||||
References = references.ToList()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NormalizedDefaultImportFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
|
|
||||||
{
|
|
||||||
private IImportProjectFeature _existingFeature;
|
|
||||||
|
|
||||||
public NormalizedDefaultImportFeature(IImportProjectFeature existingFeature)
|
|
||||||
{
|
|
||||||
_existingFeature = existingFeature;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
_existingFeature.ProjectEngine = ProjectEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
|
||||||
{
|
|
||||||
var normalizedImports = new List<RazorProjectItem>();
|
|
||||||
var imports = _existingFeature.GetImports(projectItem);
|
|
||||||
foreach (var import in imports)
|
|
||||||
{
|
|
||||||
var text = string.Empty;
|
|
||||||
using (var stream = import.Read())
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
text = reader.ReadToEnd().Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's important that we normalize the newlines in the default imports. The default imports will
|
|
||||||
// be created with Environment.NewLine, but we need to normalize to `\r\n` so that the indices
|
|
||||||
// are the same on xplat.
|
|
||||||
var normalizedText = Regex.Replace(text, "(?<!\r)\n", "\r\n", RegexOptions.None, TimeSpan.FromSeconds(10));
|
|
||||||
var normalizedImport = new TestRazorProjectItem(import.FilePath, import.PhysicalPath, import.RelativePhysicalPath, import.BasePath)
|
|
||||||
{
|
|
||||||
Content = normalizedText
|
|
||||||
};
|
|
||||||
|
|
||||||
normalizedImports.Add(normalizedImport);
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizedImports;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ Document -
|
||||||
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyBasePageForViews<MyModel> -
|
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyBasePageForViews<MyModel> -
|
||||||
DesignTimeDirective -
|
DesignTimeDirective -
|
||||||
DirectiveToken - (10:0,10 [26] InheritsWithViewImports_Imports0.cshtml) - MyBasePageForViews<TModel>
|
|
||||||
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
||||||
DirectiveToken - (294:7,71 [4] ) - Html
|
DirectiveToken - (294:7,71 [4] ) - Html
|
||||||
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
|
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
|
||||||
|
|
@ -22,6 +21,7 @@ Document -
|
||||||
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
|
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
|
||||||
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
|
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
|
||||||
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
|
||||||
|
DirectiveToken - (10:0,10 [26] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyBasePageForViews<TModel>
|
||||||
DirectiveToken - (7:0,7 [7] InheritsWithViewImports.cshtml) - MyModel
|
DirectiveToken - (7:0,7 [7] InheritsWithViewImports.cshtml) - MyModel
|
||||||
CSharpCode -
|
CSharpCode -
|
||||||
IntermediateToken - - CSharp - #pragma warning disable 0414
|
IntermediateToken - - CSharp - #pragma warning disable 0414
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
@inherits MyBasePageForViews<TModel>
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var projectEngine = CreateProjectEngine();
|
var projectEngine = CreateProjectEngine();
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var projectEngine = CreateProjectEngine();
|
var projectEngine = CreateProjectEngine();
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
|
b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -53,65 +53,5 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
// Assert
|
// Assert
|
||||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void BuildEngine_CallProcess()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var projectEngine = CreateProjectEngine();
|
|
||||||
var projectItem = new TestRazorProjectItem("Index.cshtml");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.NotNull(codeDocument.GetSyntaxTree());
|
|
||||||
Assert.NotNull(codeDocument.GetDocumentIntermediateNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CSharpDocument_Runtime_PreservesParserErrors()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var projectEngine = CreateProjectEngine();
|
|
||||||
var projectItem = new TestRazorProjectItem("test.cshtml")
|
|
||||||
{
|
|
||||||
Content = "@!!!"
|
|
||||||
};
|
|
||||||
|
|
||||||
var expected = RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
|
|
||||||
new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1),
|
|
||||||
"!");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var csharpDocument = codeDocument.GetCSharpDocument();
|
|
||||||
var error = Assert.Single(csharpDocument.Diagnostics);
|
|
||||||
Assert.Equal(expected, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CSharpDocument_DesignTime_PreservesParserErrors()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var projectEngine = CreateProjectEngine();
|
|
||||||
var projectItem = new TestRazorProjectItem("test.cshtml")
|
|
||||||
{
|
|
||||||
Content = "@{"
|
|
||||||
};
|
|
||||||
|
|
||||||
var expected = RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
|
|
||||||
new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var codeDocument = projectEngine.ProcessDesignTime(projectItem);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var csharpDocument = codeDocument.GetCSharpDocument();
|
|
||||||
var error = Assert.Single(csharpDocument.Diagnostics);
|
|
||||||
Assert.Equal(expected, error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
{
|
{
|
||||||
public class CodeGenerationIntegrationTest : IntegrationTestBase
|
public class CodeGenerationIntegrationTest : IntegrationTestBase
|
||||||
{
|
{
|
||||||
|
|
||||||
#region Runtime
|
#region Runtime
|
||||||
[Fact]
|
[Fact]
|
||||||
public void IncompleteDirectives_Runtime()
|
public void IncompleteDirectives_Runtime()
|
||||||
|
|
@ -23,12 +24,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
RunTimeTest();
|
RunTimeTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void BasicImports_Runtime()
|
|
||||||
{
|
|
||||||
RunTimeTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UnfinishedExpressionInCode_Runtime()
|
public void UnfinishedExpressionInCode_Runtime()
|
||||||
{
|
{
|
||||||
|
|
@ -460,12 +455,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
DesignTimeTest();
|
DesignTimeTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void BasicImports_DesignTime()
|
|
||||||
{
|
|
||||||
DesignTimeTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UnfinishedExpressionInCode_DesignTime()
|
public void UnfinishedExpressionInCode_DesignTime()
|
||||||
{
|
{
|
||||||
|
|
@ -896,7 +885,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
SectionDirective.Register(builder);
|
SectionDirective.Register(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.ProcessDesignTime(projectItem);
|
var codeDocument = projectEngine.ProcessDesignTime(projectItem);
|
||||||
|
|
@ -922,7 +911,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
SectionDirective.Register(builder);
|
SectionDirective.Register(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -947,7 +936,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
SectionDirective.Register(builder);
|
SectionDirective.Register(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
var imports = GetImports(projectEngine, projectItem);
|
var imports = GetImports(projectEngine, projectItem);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -973,7 +962,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
SectionDirective.Register(builder);
|
SectionDirective.Register(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
var imports = GetImports(projectEngine, projectItem);
|
var imports = GetImports(projectEngine, projectItem);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
builder.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddNamespaceToken()));
|
builder.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddNamespaceToken()));
|
||||||
});
|
});
|
||||||
|
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = engine.ProcessDesignTime(projectItem);
|
var codeDocument = engine.ProcessDesignTime(projectItem);
|
||||||
|
|
|
||||||
|
|
@ -11,28 +11,26 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
public void HtmlWithDataDashAttribute()
|
public void HtmlWithDataDashAttribute()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var projectEngine = CreateProjectEngine();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
var projectItem = CreateProjectItem();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var compiled = CompileToCSharp(projectItem);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HtmlWithConditionalAttribute()
|
public void HtmlWithConditionalAttribute()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var projectEngine = CreateProjectEngine();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
var projectItem = CreateProjectItem();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var compiled = CompileToCSharp(projectItem);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
};
|
};
|
||||||
|
|
||||||
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
};
|
};
|
||||||
|
|
||||||
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
};
|
};
|
||||||
|
|
||||||
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
||||||
var projectItem = CreateProjectItem();
|
var projectItem = CreateProjectItemFromFile();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var codeDocument = projectEngine.Process(projectItem);
|
var codeDocument = projectEngine.Process(projectItem);
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<p>Hi there!</p>
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
// <auto-generated/>
|
|
||||||
#pragma warning disable 1591
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
|
|
||||||
{
|
|
||||||
#line hidden
|
|
||||||
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
|
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml"
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_DesignTime : Hello
|
|
||||||
{
|
|
||||||
#pragma warning disable 219
|
|
||||||
private void __RazorDirectiveTokenHelpers__() {
|
|
||||||
}
|
|
||||||
#pragma warning restore 219
|
|
||||||
#pragma warning disable 0414
|
|
||||||
private static System.Object __o = null;
|
|
||||||
#pragma warning restore 0414
|
|
||||||
#pragma warning disable 1998
|
|
||||||
public async System.Threading.Tasks.Task ExecuteAsync()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#pragma warning restore 1998
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#pragma warning restore 1591
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
Document -
|
|
||||||
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
|
|
||||||
UsingDirective - (1:0,1 [26] BasicImports_Imports0.cshtml) - System.Globalization
|
|
||||||
UsingDirective - (30:1,1 [27] BasicImports_Imports0.cshtml) - System.ComponentModel
|
|
||||||
UsingDirective - (23:1,1 [18] BasicImports_Imports1.cshtml) - System.Text
|
|
||||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_DesignTime - Hello -
|
|
||||||
DesignTimeDirective -
|
|
||||||
DirectiveToken - (69:2,10 [5] BasicImports_Imports0.cshtml) - Hello
|
|
||||||
CSharpCode -
|
|
||||||
IntermediateToken - - CSharp - #pragma warning disable 0414
|
|
||||||
CSharpCode -
|
|
||||||
IntermediateToken - - CSharp - private static System.Object __o = null;
|
|
||||||
CSharpCode -
|
|
||||||
IntermediateToken - - CSharp - #pragma warning restore 0414
|
|
||||||
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
|
|
||||||
HtmlContent - (0:0,0 [18] BasicImports.cshtml)
|
|
||||||
IntermediateToken - (0:0,0 [3] BasicImports.cshtml) - Html - <p>
|
|
||||||
IntermediateToken - (3:0,3 [9] BasicImports.cshtml) - Html - Hi there!
|
|
||||||
IntermediateToken - (12:0,12 [4] BasicImports.cshtml) - Html - </p>
|
|
||||||
IntermediateToken - (16:0,16 [2] BasicImports.cshtml) - Html - \n
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
@using System.Globalization
|
|
||||||
@using System.ComponentModel
|
|
||||||
@inherits Hello
|
|
||||||
@("And also this")
|
|
||||||
<p>This will get ignored</p>
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
@section ignored { }
|
|
||||||
@using System.Text;
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d5e5d28c0c504a7b0c5207a5230a5b7327ce5e09"
|
|
||||||
// <auto-generated/>
|
|
||||||
#pragma warning disable 1591
|
|
||||||
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml")]
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
|
|
||||||
{
|
|
||||||
#line hidden
|
|
||||||
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
|
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml"
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d5e5d28c0c504a7b0c5207a5230a5b7327ce5e09", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml")]
|
|
||||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"39c22940acc420eb6d46b6ff85ef6d5a2ab35fa1", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml")]
|
|
||||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"ede697b6fb90aac312d589ae96a93289cdeb506f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml")]
|
|
||||||
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime : Hello
|
|
||||||
{
|
|
||||||
#pragma warning disable 1998
|
|
||||||
public async System.Threading.Tasks.Task ExecuteAsync()
|
|
||||||
{
|
|
||||||
WriteLiteral("<p>Hi there!</p>\r\n");
|
|
||||||
}
|
|
||||||
#pragma warning restore 1998
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#pragma warning restore 1591
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
Document -
|
|
||||||
RazorCompiledItemAttribute -
|
|
||||||
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
|
|
||||||
UsingDirective - (1:0,1 [28] BasicImports_Imports0.cshtml) - System.Globalization
|
|
||||||
UsingDirective - (30:1,1 [29] BasicImports_Imports0.cshtml) - System.ComponentModel
|
|
||||||
UsingDirective - (23:1,1 [20] BasicImports_Imports1.cshtml) - System.Text
|
|
||||||
RazorSourceChecksumAttribute -
|
|
||||||
RazorSourceChecksumAttribute -
|
|
||||||
RazorSourceChecksumAttribute -
|
|
||||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime - Hello -
|
|
||||||
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
|
|
||||||
HtmlContent - (0:0,0 [18] BasicImports.cshtml)
|
|
||||||
IntermediateToken - (0:0,0 [3] BasicImports.cshtml) - Html - <p>
|
|
||||||
IntermediateToken - (3:0,3 [9] BasicImports.cshtml) - Html - Hi there!
|
|
||||||
IntermediateToken - (12:0,12 [4] BasicImports.cshtml) - Html - </p>
|
|
||||||
IntermediateToken - (16:0,16 [2] BasicImports.cshtml) - Html - \n
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Xunit.Sdk;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
|
{
|
||||||
|
public class CompilationFailedException : XunitException
|
||||||
|
{
|
||||||
|
public CompilationFailedException(Compilation compilation, Diagnostic[] diagnostics)
|
||||||
|
{
|
||||||
|
Compilation = compilation;
|
||||||
|
Diagnostics = diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Compilation Compilation { get; }
|
||||||
|
|
||||||
|
public Diagnostic[] Diagnostics { get; }
|
||||||
|
|
||||||
|
public override string Message
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
builder.AppendLine("Compilation failed: ");
|
||||||
|
|
||||||
|
var syntaxTreesWithErrors = new HashSet<SyntaxTree>();
|
||||||
|
foreach (var diagnostic in Diagnostics)
|
||||||
|
{
|
||||||
|
builder.AppendLine(diagnostic.ToString());
|
||||||
|
|
||||||
|
if (diagnostic.Location.IsInSource)
|
||||||
|
{
|
||||||
|
syntaxTreesWithErrors.Add(diagnostic.Location.SourceTree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syntaxTreesWithErrors.Any())
|
||||||
|
{
|
||||||
|
builder.AppendLine();
|
||||||
|
builder.AppendLine();
|
||||||
|
|
||||||
|
foreach (var syntaxTree in syntaxTreesWithErrors)
|
||||||
|
{
|
||||||
|
builder.AppendLine($"File {syntaxTree.FilePath ?? "unknown"}:");
|
||||||
|
builder.AppendLine(syntaxTree.GetText().ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 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.Reflection;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
|
{
|
||||||
|
public class CompiledAssembly
|
||||||
|
{
|
||||||
|
public CompiledAssembly(Compilation compilation, RazorCodeDocument codeDocument, Assembly assembly)
|
||||||
|
{
|
||||||
|
Compilation = compilation;
|
||||||
|
CodeDocument = codeDocument;
|
||||||
|
Assembly = assembly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Assembly Assembly { get; }
|
||||||
|
|
||||||
|
public RazorCodeDocument CodeDocument { get; }
|
||||||
|
|
||||||
|
public Compilation Compilation { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
|
{
|
||||||
|
public class CompiledCSharpCode
|
||||||
|
{
|
||||||
|
public CompiledCSharpCode(Compilation baseCompilation, RazorCodeDocument codeDocument)
|
||||||
|
{
|
||||||
|
BaseCompilation = baseCompilation;
|
||||||
|
CodeDocument = codeDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A compilation that can be used *with* this code to compile an assembly
|
||||||
|
public Compilation BaseCompilation { get; set; }
|
||||||
|
|
||||||
|
public RazorCodeDocument CodeDocument { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,11 +13,14 @@ using System.Runtime.Remoting.Messaging;
|
||||||
#else
|
#else
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
#endif
|
#endif
|
||||||
|
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||||
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
||||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Sdk;
|
using Xunit.Sdk;
|
||||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
{
|
{
|
||||||
|
|
@ -28,15 +31,81 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
private static readonly AsyncLocal<string> _fileName = new AsyncLocal<string>();
|
private static readonly AsyncLocal<string> _fileName = new AsyncLocal<string>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected IntegrationTestBase()
|
private static readonly CSharpCompilation DefaultBaseCompilation;
|
||||||
|
|
||||||
|
static IntegrationTestBase()
|
||||||
{
|
{
|
||||||
TestProjectRoot = TestProject.GetProjectDirectory(GetType());
|
var referenceAssemblyRoots = new[]
|
||||||
|
{
|
||||||
|
typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly, // System.Runtime
|
||||||
|
};
|
||||||
|
|
||||||
|
var referenceAssemblies = referenceAssemblyRoots
|
||||||
|
.SelectMany(assembly => assembly.GetReferencedAssemblies().Concat(new[] { assembly.GetName() }))
|
||||||
|
.Distinct()
|
||||||
|
.Select(Assembly.Load)
|
||||||
|
.Select(assembly => MetadataReference.CreateFromFile(assembly.Location))
|
||||||
|
.ToList();
|
||||||
|
DefaultBaseCompilation = CSharpCompilation.Create(
|
||||||
|
"TestAssembly",
|
||||||
|
Array.Empty<SyntaxTree>(),
|
||||||
|
referenceAssemblies,
|
||||||
|
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IntegrationTestBase(bool? generateBaselines = null)
|
||||||
|
{
|
||||||
|
TestProjectRoot = TestProject.GetProjectDirectory(GetType());
|
||||||
|
|
||||||
|
if (generateBaselines.HasValue)
|
||||||
|
{
|
||||||
|
GenerateBaselines = generateBaselines.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="CSharpCompilation"/> that will be used as the 'app' compilation.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual CSharpCompilation BaseCompilation => DefaultBaseCompilation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the parse options applied when using <see cref="AddCSharpSyntaxTree(string, string)"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual CSharpParseOptions CSharpParseOptions { get; } = new CSharpParseOptions(LanguageVersion.Latest);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the compilation options applied when compiling assemblies.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual CSharpCompilationOptions CSharpCompilationOptions { get; } = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of CSharp syntax trees used that are considered part of the 'app'.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual List<CSharpSyntaxTree> CSharpSyntaxTrees { get; } = new List<CSharpSyntaxTree>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="RazorConfiguration"/> that will be used for code generation.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual RazorConfiguration Configuration { get; } = RazorConfiguration.Default;
|
||||||
|
|
||||||
|
protected virtual bool DesignTime { get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the
|
||||||
|
/// </summary>
|
||||||
|
internal VirtualRazorProjectFileSystem FileSystem { get; } = new VirtualRazorProjectFileSystem();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to force a specific style of line-endings for testing. This matters for the baseline tests that exercise line mappings.
|
||||||
|
/// Even though we normalize newlines for testing, the difference between platforms affects the data through the *count* of
|
||||||
|
/// characters written.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual string LineEnding { get; } = "\r\n";
|
||||||
|
|
||||||
#if GENERATE_BASELINES
|
#if GENERATE_BASELINES
|
||||||
protected bool GenerateBaselines { get; set; } = true;
|
protected bool GenerateBaselines { get; } = true;
|
||||||
#else
|
#else
|
||||||
protected bool GenerateBaselines { get; set; } = false;
|
protected bool GenerateBaselines { get; } = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected string TestProjectRoot { get; }
|
protected string TestProjectRoot { get; }
|
||||||
|
|
@ -60,34 +129,62 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual RazorProjectEngine CreateProjectEngine() => CreateProjectEngine(configure: null);
|
protected virtual void ConfigureProjectEngine(RazorProjectEngineBuilder builder)
|
||||||
|
|
||||||
protected virtual RazorProjectEngine CreateProjectEngine(Action<RazorProjectEngineBuilder> configure)
|
|
||||||
{
|
{
|
||||||
if (FileName == null)
|
|
||||||
{
|
|
||||||
var message = $"{nameof(CreateProjectEngine)} should only be called from an integration test, ({nameof(FileName)} is null).";
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var assembly = GetType().GetTypeInfo().Assembly;
|
|
||||||
var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, IntegrationTestFileSystem.Default, b =>
|
|
||||||
{
|
|
||||||
configure?.Invoke(b);
|
|
||||||
|
|
||||||
var existingImportFeature = b.Features.OfType<IImportProjectFeature>().Single();
|
|
||||||
b.SetImportFeature(new IntegrationTestImportFeature(assembly, existingImportFeature));
|
|
||||||
});
|
|
||||||
var testProjectEngine = new IntegrationTestProjectEngine(projectEngine);
|
|
||||||
|
|
||||||
return testProjectEngine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual RazorProjectItem CreateProjectItem()
|
protected CSharpSyntaxTree AddCSharpSyntaxTree(string text, string filePath = null)
|
||||||
|
{
|
||||||
|
var syntaxTree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText(text, CSharpParseOptions, path: filePath);
|
||||||
|
CSharpSyntaxTrees.Add(syntaxTree);
|
||||||
|
return syntaxTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RazorProjectItem AddProjectItemFromText(string text, string filePath = "_ViewImports.cshtml")
|
||||||
|
{
|
||||||
|
var projectItem = CreateProjectItemFromText(text, filePath);
|
||||||
|
FileSystem.Add(projectItem);
|
||||||
|
return projectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RazorProjectItem CreateProjectItemFromText(string text, string filePath)
|
||||||
|
{
|
||||||
|
// Consider the file path to be relative to the 'FileName' of the test.
|
||||||
|
var workingDirectory = Path.GetDirectoryName(FileName);
|
||||||
|
|
||||||
|
// Since these paths are used in baselines, we normalize them to windows style. We
|
||||||
|
// use "" as the base path by convention to avoid baking in an actual file system
|
||||||
|
// path.
|
||||||
|
var basePath = "";
|
||||||
|
var physicalPath = Path.Combine(workingDirectory, filePath).Replace('/', '\\');
|
||||||
|
var relativePhysicalPath = physicalPath;
|
||||||
|
|
||||||
|
// FilePaths in Razor are **always** are of the form '/a/b/c.cshtml'
|
||||||
|
filePath = physicalPath.Replace('\\', '/');
|
||||||
|
if (!filePath.StartsWith("/"))
|
||||||
|
{
|
||||||
|
filePath = '/' + filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
text = NormalizeNewLines(text);
|
||||||
|
|
||||||
|
var projectItem = new TestRazorProjectItem(
|
||||||
|
basePath: basePath,
|
||||||
|
filePath: filePath,
|
||||||
|
physicalPath: physicalPath,
|
||||||
|
relativePhysicalPath: relativePhysicalPath)
|
||||||
|
{
|
||||||
|
Content = text,
|
||||||
|
};
|
||||||
|
|
||||||
|
return projectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RazorProjectItem CreateProjectItemFromFile(string filePath = null)
|
||||||
{
|
{
|
||||||
if (FileName == null)
|
if (FileName == null)
|
||||||
{
|
{
|
||||||
var message = $"{nameof(CreateProjectItem)} should only be called from an integration test, ({nameof(FileName)} is null).";
|
var message = $"{nameof(CreateProjectItemFromFile)} should only be called from an integration test, ({nameof(FileName)} is null).";
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,12 +199,149 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
var fileContent = testFile.ReadAllText();
|
var fileContent = testFile.ReadAllText();
|
||||||
var normalizedContent = NormalizeNewLines(fileContent);
|
var normalizedContent = NormalizeNewLines(fileContent);
|
||||||
|
|
||||||
var projectItem = new TestRazorProjectItem(sourceFileName)
|
var workingDirectory = Path.GetDirectoryName(FileName);
|
||||||
|
var fullPath = sourceFileName;
|
||||||
|
|
||||||
|
// Normalize to forward-slash - these strings end up in the baselines.
|
||||||
|
fullPath = fullPath.Replace('\\', '/');
|
||||||
|
sourceFileName = sourceFileName.Replace('\\', '/');
|
||||||
|
|
||||||
|
// FilePaths in Razor are **always** are of the form '/a/b/c.cshtml'
|
||||||
|
filePath = filePath ?? sourceFileName;
|
||||||
|
if (!filePath.StartsWith("/"))
|
||||||
{
|
{
|
||||||
Content = normalizedContent,
|
filePath = '/' + filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
var projectItem = new TestRazorProjectItem(
|
||||||
|
basePath: workingDirectory,
|
||||||
|
filePath: filePath,
|
||||||
|
physicalPath: fullPath,
|
||||||
|
relativePhysicalPath: sourceFileName)
|
||||||
|
{
|
||||||
|
Content = fileContent,
|
||||||
|
};
|
||||||
|
|
||||||
|
return projectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompiledCSharpCode CompileToCSharp(string text, string path = "test.cshtml", bool? designTime = null)
|
||||||
|
{
|
||||||
|
var projectItem = CreateProjectItemFromText(text, path);
|
||||||
|
return CompileToCSharp(projectItem, designTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompiledCSharpCode CompileToCSharp(RazorProjectItem projectItem, bool? designTime = null)
|
||||||
|
{
|
||||||
|
var compilation = CreateCompilation();
|
||||||
|
var references = compilation.References.Concat(new[] { compilation.ToMetadataReference(), }).ToArray();
|
||||||
|
|
||||||
|
var projectEngine = CreateProjectEngine(Configuration, references, ConfigureProjectEngine);
|
||||||
|
var codeDocument = (designTime ?? DesignTime) ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem);
|
||||||
|
|
||||||
|
return new CompiledCSharpCode(CSharpCompilation.Create(compilation.AssemblyName + ".Views", references: references, options: CSharpCompilationOptions), codeDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompiledAssembly CompileToAssembly(string text, string path = "test.cshtml", bool? designTime = null, bool throwOnFailure = true)
|
||||||
|
{
|
||||||
|
var compiled = CompileToCSharp(text, path, designTime);
|
||||||
|
return CompileToAssembly(compiled);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompiledAssembly CompileToAssembly(RazorProjectItem projectItem, bool? designTime = null, bool throwOnFailure = true)
|
||||||
|
{
|
||||||
|
var compiled = CompileToCSharp(projectItem, designTime);
|
||||||
|
return CompileToAssembly(compiled, throwOnFailure: throwOnFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompiledAssembly CompileToAssembly(CompiledCSharpCode code, bool throwOnFailure = true)
|
||||||
|
{
|
||||||
|
var cSharpDocument = code.CodeDocument.GetCSharpDocument();
|
||||||
|
if (cSharpDocument.Diagnostics.Any())
|
||||||
|
{
|
||||||
|
var diagnosticsLog = string.Join(Environment.NewLine, cSharpDocument.Diagnostics.Select(d => d.ToString()).ToArray());
|
||||||
|
throw new InvalidOperationException($"Aborting compilation to assembly because RazorCompiler returned nonempty diagnostics: {diagnosticsLog}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var syntaxTrees = new[]
|
||||||
|
{
|
||||||
|
(CSharpSyntaxTree)CSharpSyntaxTree.ParseText(cSharpDocument.GeneratedCode, CSharpParseOptions, path: code.CodeDocument.Source.FilePath),
|
||||||
};
|
};
|
||||||
|
|
||||||
return projectItem;
|
var compilation = code.BaseCompilation.AddSyntaxTrees(syntaxTrees);
|
||||||
|
|
||||||
|
var diagnostics = compilation
|
||||||
|
.GetDiagnostics()
|
||||||
|
.Where(d => d.Severity >= DiagnosticSeverity.Warning)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (diagnostics.Length > 0 && throwOnFailure)
|
||||||
|
{
|
||||||
|
throw new CompilationFailedException(compilation, diagnostics);
|
||||||
|
}
|
||||||
|
else if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
|
||||||
|
{
|
||||||
|
return new CompiledAssembly(compilation, code.CodeDocument, assembly: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var peStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
var emit = compilation.Emit(peStream);
|
||||||
|
diagnostics = emit
|
||||||
|
.Diagnostics
|
||||||
|
.Where(d => d.Severity >= DiagnosticSeverity.Warning)
|
||||||
|
.ToArray();
|
||||||
|
if (diagnostics.Length > 0 && throwOnFailure)
|
||||||
|
{
|
||||||
|
throw new CompilationFailedException(compilation, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CompiledAssembly(compilation, code.CodeDocument, Assembly.Load(peStream.ToArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CSharpCompilation CreateCompilation()
|
||||||
|
{
|
||||||
|
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTrees);
|
||||||
|
var diagnostics = compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning).ToArray();
|
||||||
|
if (diagnostics.Length > 0)
|
||||||
|
{
|
||||||
|
throw new CompilationFailedException(compilation, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
return compilation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RazorProjectEngine CreateProjectEngine(Action<RazorProjectEngineBuilder> configure = null)
|
||||||
|
{
|
||||||
|
var compilation = CreateCompilation();
|
||||||
|
var references = compilation.References.Concat(new[] { compilation.ToMetadataReference(), }).ToArray();
|
||||||
|
return CreateProjectEngine(Configuration, references, configure);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RazorProjectEngine CreateProjectEngine(RazorConfiguration configuration, MetadataReference[] references, Action<RazorProjectEngineBuilder> configure)
|
||||||
|
{
|
||||||
|
return RazorProjectEngine.Create(configuration, FileSystem, b =>
|
||||||
|
{
|
||||||
|
b.Phases.Insert(0, new ConfigureCodeRenderingPhase(LineEnding));
|
||||||
|
|
||||||
|
configure?.Invoke(b);
|
||||||
|
|
||||||
|
// Allow the test to do custom things with tag helpers, but do the default thing most of the time.
|
||||||
|
if (!b.Features.OfType<ITagHelperFeature>().Any())
|
||||||
|
{
|
||||||
|
b.Features.Add(new CompilationTagHelperFeature());
|
||||||
|
b.Features.Add(new DefaultMetadataReferenceFeature()
|
||||||
|
{
|
||||||
|
References = references,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decorate the import feature so we can normalize line endings.
|
||||||
|
var importFeature = b.Features.OfType<IImportProjectFeature>().FirstOrDefault();
|
||||||
|
b.Features.Add(new NormalizedDefaultImportFeature(importFeature, LineEnding));
|
||||||
|
b.Features.Remove(importFeature);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AssertDocumentNodeMatchesBaseline(DocumentIntermediateNode document)
|
protected void AssertDocumentNodeMatchesBaseline(DocumentIntermediateNode document)
|
||||||
|
|
@ -318,96 +552,93 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||||
.Replace("\t", "\\t");
|
.Replace("\t", "\\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NormalizeNewLines(string content)
|
private string NormalizeNewLines(string content)
|
||||||
{
|
{
|
||||||
return Regex.Replace(content, "(?<!\r)\n", "\r\n", RegexOptions.None, TimeSpan.FromSeconds(10));
|
return NormalizeNewLines(content, LineEnding);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IntegrationTestProjectEngine : DefaultRazorProjectEngine
|
private static string NormalizeNewLines(string content, string lineEnding)
|
||||||
{
|
{
|
||||||
public IntegrationTestProjectEngine(
|
return Regex.Replace(content, "(?<!\r)\n", lineEnding, RegexOptions.None, TimeSpan.FromSeconds(10));
|
||||||
RazorProjectEngine innerEngine)
|
}
|
||||||
: base(innerEngine.Configuration, innerEngine.Engine, innerEngine.FileSystem, innerEngine.ProjectFeatures)
|
|
||||||
|
// This is to prevent you from accidentally checking in with GenerateBaselines = true
|
||||||
|
[Fact]
|
||||||
|
public void GenerateBaselinesMustBeFalse()
|
||||||
|
{
|
||||||
|
Assert.False(GenerateBaselines, "GenerateBaselines should be set back to false before you check in!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConfigureCodeRenderingPhase : RazorEnginePhaseBase
|
||||||
|
{
|
||||||
|
public ConfigureCodeRenderingPhase(string lineEnding)
|
||||||
{
|
{
|
||||||
|
LineEnding = lineEnding;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ProcessCore(RazorCodeDocument codeDocument)
|
public string LineEnding { get; }
|
||||||
|
|
||||||
|
protected override void ExecuteCore(RazorCodeDocument codeDocument)
|
||||||
{
|
{
|
||||||
// This will ensure that we're not putting any randomly generated data in a baseline.
|
|
||||||
codeDocument.Items[CodeRenderingContext.SuppressUniqueIds] = "test";
|
codeDocument.Items[CodeRenderingContext.SuppressUniqueIds] = "test";
|
||||||
|
codeDocument.Items[CodeRenderingContext.NewLineString] = LineEnding;
|
||||||
// This is to make tests work cross platform.
|
|
||||||
codeDocument.Items[CodeRenderingContext.NewLineString] = "\r\n";
|
|
||||||
|
|
||||||
base.ProcessCore(codeDocument);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IntegrationTestImportFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
|
// 'Default' imports won't have normalized line-endings, which is unfriendly for testing.
|
||||||
|
private class NormalizedDefaultImportFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
|
||||||
{
|
{
|
||||||
private Assembly _assembly;
|
private readonly IImportProjectFeature _inner;
|
||||||
private IImportProjectFeature _existingImportFeature;
|
private readonly string _lineEnding;
|
||||||
|
|
||||||
public IntegrationTestImportFeature(Assembly assembly, IImportProjectFeature existingImportFeature)
|
public NormalizedDefaultImportFeature(IImportProjectFeature inner, string lineEnding)
|
||||||
{
|
{
|
||||||
_assembly = assembly;
|
_inner = inner;
|
||||||
_existingImportFeature = existingImportFeature;
|
_lineEnding = lineEnding;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_existingImportFeature.ProjectEngine = ProjectEngine;
|
if (_inner != null)
|
||||||
|
{
|
||||||
|
_inner.ProjectEngine = ProjectEngine;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
||||||
{
|
{
|
||||||
var imports = new List<RazorProjectItem>();
|
if (_inner == null)
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
var importsFileName = Path.ChangeExtension(projectItem.FilePathWithoutExtension + "_Imports" + imports.Count.ToString(), ".cshtml");
|
return Array.Empty<RazorProjectItem>();
|
||||||
var importsFile = TestFile.Create(importsFileName, _assembly);
|
|
||||||
if (!importsFile.Exists())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var importContent = importsFile.ReadAllText();
|
|
||||||
var normalizedContent = NormalizeNewLines(importContent);
|
|
||||||
var importItem = new TestRazorProjectItem(importsFileName)
|
|
||||||
{
|
|
||||||
Content = normalizedContent
|
|
||||||
};
|
|
||||||
imports.Add(importItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imports.AddRange(_existingImportFeature.GetImports(projectItem));
|
var normalizedImports = new List<RazorProjectItem>();
|
||||||
|
var imports = _inner.GetImports(projectItem);
|
||||||
|
foreach (var import in imports)
|
||||||
|
{
|
||||||
|
if (import.Exists)
|
||||||
|
{
|
||||||
|
var text = string.Empty;
|
||||||
|
using (var stream = import.Read())
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
text = reader.ReadToEnd().Trim();
|
||||||
|
}
|
||||||
|
|
||||||
return imports;
|
// It's important that we normalize the newlines in the default imports. The default imports will
|
||||||
}
|
// be created with Environment.NewLine, but we need to normalize to `\r\n` so that the indices
|
||||||
}
|
// are the same on xplat.
|
||||||
|
var normalizedText = NormalizeNewLines(text, _lineEnding);
|
||||||
|
var normalizedImport = new TestRazorProjectItem(import.FilePath, import.PhysicalPath, import.RelativePhysicalPath, import.BasePath)
|
||||||
|
{
|
||||||
|
Content = normalizedText
|
||||||
|
};
|
||||||
|
|
||||||
private class IntegrationTestFileSystem : RazorProjectFileSystem
|
normalizedImports.Add(normalizedImport);
|
||||||
{
|
}
|
||||||
public static IntegrationTestFileSystem Default = new IntegrationTestFileSystem();
|
}
|
||||||
|
|
||||||
private IntegrationTestFileSystem()
|
return normalizedImports;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
|
|
||||||
{
|
|
||||||
return Enumerable.Empty<RazorProjectItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override RazorProjectItem GetItem(string path)
|
|
||||||
{
|
|
||||||
return new NotFoundProjectItem(string.Empty, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<RazorProjectItem> FindHierarchicalItems(string basePath, string path, string fileName)
|
|
||||||
{
|
|
||||||
return Enumerable.Empty<RazorProjectItem>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue