Fix #2265 - Port Blazor testing improvements
The Blazor test infrastructure made a copy of the code in Razor and then added some more features. This change backports the features needed for the style of test we're using in Blazor. I updated the MVC integration tests to use the new style, but I think there's limited value in trying to rev all of the old tests. One feature in particular that I removed from the old infrastructure was the automatic inference of imports based on the file system. This feature was wierd and doesn't parallel how these features work in actuality. It's easy and more natural to test imports in new style tests.
This commit is contained in:
parent
f463325e9a
commit
f425134ffe
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());
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var document = engine.Process(projectItem);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Document -
|
|||
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel<MyModel> -
|
||||
DesignTimeDirective -
|
||||
DirectiveToken - (10:0,10 [19] InheritsWithViewImports_Imports0.cshtml) - MyPageModel<TModel>
|
||||
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
||||
DirectiveToken - (294:7,71 [4] ) - Html
|
||||
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 - (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 - (10:0,10 [19] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyPageModel<TModel>
|
||||
DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel
|
||||
CSharpCode -
|
||||
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.ViewFeatures;
|
||||
[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>
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
|
|
|
|||
|
|
@ -1,55 +1,78 @@
|
|||
// 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.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.IntegrationTests;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Emit;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.IntegrationTests
|
||||
{
|
||||
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]
|
||||
public void InvalidNamespaceAtEOF_DesignTime()
|
||||
{
|
||||
var compilation = BaseCompilation;
|
||||
RunDesignTimeTest(compilation);
|
||||
// Arrange
|
||||
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]
|
||||
public void IncompleteDirectives_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
public class MyService<TModel>
|
||||
{
|
||||
public string Html { get; set; }
|
||||
}
|
||||
";
|
||||
}");
|
||||
|
||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
||||
RunDesignTimeTest(compilation);
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// 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]
|
||||
public void InheritsViewModel_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
|
||||
|
|
@ -60,20 +83,28 @@ public class MyBasePageForViews<TModel> : RazorPage
|
|||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
public void InheritsWithViewImports_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
|
||||
|
|
@ -88,61 +119,102 @@ public class MyBasePageForViews<TModel> : RazorPage
|
|||
public class MyModel
|
||||
{
|
||||
|
||||
}
|
||||
";
|
||||
}");
|
||||
|
||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
||||
RunDesignTimeTest(compilation);
|
||||
AddProjectItemFromText(@"@inherits MyBasePageForViews<TModel>");
|
||||
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Basic_DesignTime()
|
||||
{
|
||||
var compilation = BaseCompilation;
|
||||
RunDesignTimeTest(compilation);
|
||||
// Arrange
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sections_DesignTime()
|
||||
{
|
||||
var appCode = $@"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree($@"
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
|
||||
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
||||
{{
|
||||
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]
|
||||
public void _ViewImports_DesignTime()
|
||||
{
|
||||
var compilation = BaseCompilation;
|
||||
RunDesignTimeTest(compilation);
|
||||
// Arrange
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Inject_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
public class MyApp
|
||||
{
|
||||
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]
|
||||
public void InjectWithModel_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
public class MyModel
|
||||
{
|
||||
|
||||
|
|
@ -156,75 +228,119 @@ public class MyService<TModel>
|
|||
public class MyApp
|
||||
{
|
||||
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]
|
||||
public void InjectWithSemicolon_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
public class MyModel
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class MyService<TModel>
|
||||
{
|
||||
public string Html { get; set; }
|
||||
}
|
||||
|
||||
public class MyApp
|
||||
{
|
||||
public string MyProperty { get; set; }
|
||||
}
|
||||
";
|
||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
||||
RunDesignTimeTest(compilation);
|
||||
|
||||
public class MyService<TModel>
|
||||
{
|
||||
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]
|
||||
public void Model_DesignTime()
|
||||
{
|
||||
var compilation = BaseCompilation;
|
||||
RunDesignTimeTest(compilation);
|
||||
// Arrange
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MultipleModels_DesignTime()
|
||||
{
|
||||
var appCode = @"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree(@"
|
||||
public class ThisShouldBeGenerated
|
||||
{
|
||||
|
||||
}";
|
||||
}");
|
||||
|
||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
||||
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("RZ2001", Assert.Single(diagnotics).Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModelExpressionTagHelper_DesignTime()
|
||||
{
|
||||
var appCode = $@"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree($@"
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
|
||||
public class InputTestTagHelper : {typeof(TagHelper).FullName}
|
||||
{{
|
||||
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]
|
||||
public void ViewComponentTagHelper_DesignTime()
|
||||
{
|
||||
var appCode = $@"
|
||||
// Arrange
|
||||
AddCSharpSyntaxTree($@"
|
||||
public class TestViewComponent
|
||||
{{
|
||||
public string Invoke(string firstName)
|
||||
|
|
@ -238,126 +354,17 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
|
|||
{{
|
||||
public string Bar {{ get; set; }}
|
||||
}}
|
||||
";
|
||||
");
|
||||
|
||||
var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(appCode));
|
||||
|
||||
RunDesignTimeTest(compilation);
|
||||
}
|
||||
|
||||
private void RunDesignTimeTest(
|
||||
CSharpCompilation baseCompilation,
|
||||
IEnumerable<string> expectedErrors = null)
|
||||
{
|
||||
Assert.Empty(baseCompilation.GetDiagnostics());
|
||||
|
||||
// Arrange
|
||||
var engine = CreateEngine(baseCompilation);
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var document = engine.ProcessDesignTime(projectItem);
|
||||
var compiled = CompileToAssembly(projectItem, designTime: true);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(document.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(document.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(document);
|
||||
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;
|
||||
}
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
|
||||
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Document -
|
|||
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyBasePageForViews<MyModel> -
|
||||
DesignTimeDirective -
|
||||
DirectiveToken - (10:0,10 [26] InheritsWithViewImports_Imports0.cshtml) - MyBasePageForViews<TModel>
|
||||
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
|
||||
DirectiveToken - (294:7,71 [4] ) - Html
|
||||
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 - (578:11,79 [23] ) - ModelExpressionProvider
|
||||
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
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - #pragma warning disable 0414
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
@inherits MyBasePageForViews<TModel>
|
||||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
{
|
||||
// Arrange
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
{
|
||||
// Arrange
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -53,65 +53,5 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// Assert
|
||||
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
|
||||
{
|
||||
|
||||
#region Runtime
|
||||
[Fact]
|
||||
public void IncompleteDirectives_Runtime()
|
||||
|
|
@ -23,12 +24,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
RunTimeTest();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BasicImports_Runtime()
|
||||
{
|
||||
RunTimeTest();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnfinishedExpressionInCode_Runtime()
|
||||
{
|
||||
|
|
@ -460,12 +455,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
DesignTimeTest();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BasicImports_DesignTime()
|
||||
{
|
||||
DesignTimeTest();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnfinishedExpressionInCode_DesignTime()
|
||||
{
|
||||
|
|
@ -896,7 +885,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.ProcessDesignTime(projectItem);
|
||||
|
|
@ -922,7 +911,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -947,7 +936,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
var imports = GetImports(projectEngine, projectItem);
|
||||
|
||||
// Act
|
||||
|
|
@ -973,7 +962,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
var imports = GetImports(projectEngine, projectItem);
|
||||
|
||||
// Act
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
builder.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddNamespaceToken()));
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = engine.ProcessDesignTime(projectItem);
|
||||
|
|
|
|||
|
|
@ -11,28 +11,26 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
public void HtmlWithDataDashAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
var compiled = CompileToCSharp(projectItem);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
||||
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HtmlWithConditionalAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
var compiled = CompileToCSharp(projectItem);
|
||||
|
||||
// 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 projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
};
|
||||
|
||||
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
};
|
||||
|
||||
var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
|
||||
var projectItem = CreateProjectItem();
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,9 @@ using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
|||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
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>();
|
||||
#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
|
||||
protected bool GenerateBaselines { get; set; } = true;
|
||||
protected bool GenerateBaselines { get; } = true;
|
||||
#else
|
||||
protected bool GenerateBaselines { get; set; } = false;
|
||||
protected bool GenerateBaselines { get; } = false;
|
||||
#endif
|
||||
|
||||
protected string TestProjectRoot { get; }
|
||||
|
|
@ -60,34 +129,62 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
#endif
|
||||
}
|
||||
|
||||
protected virtual RazorProjectEngine CreateProjectEngine() => CreateProjectEngine(configure: null);
|
||||
|
||||
protected virtual RazorProjectEngine CreateProjectEngine(Action<RazorProjectEngineBuilder> configure)
|
||||
protected virtual void ConfigureProjectEngine(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -102,12 +199,149 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
var fileContent = testFile.ReadAllText();
|
||||
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)
|
||||
|
|
@ -225,96 +459,93 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
Assert.Equal(baseline, actual);
|
||||
}
|
||||
|
||||
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(
|
||||
RazorProjectEngine innerEngine)
|
||||
: base(innerEngine.Configuration, innerEngine.Engine, innerEngine.FileSystem, innerEngine.ProjectFeatures)
|
||||
return Regex.Replace(content, "(?<!\r)\n", lineEnding, RegexOptions.None, TimeSpan.FromSeconds(10));
|
||||
}
|
||||
|
||||
// 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";
|
||||
|
||||
// This is to make tests work cross platform.
|
||||
codeDocument.Items[CodeRenderingContext.NewLineString] = "\r\n";
|
||||
|
||||
base.ProcessCore(codeDocument);
|
||||
codeDocument.Items[CodeRenderingContext.NewLineString] = LineEnding;
|
||||
}
|
||||
}
|
||||
|
||||
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 IImportProjectFeature _existingImportFeature;
|
||||
private readonly IImportProjectFeature _inner;
|
||||
private readonly string _lineEnding;
|
||||
|
||||
public IntegrationTestImportFeature(Assembly assembly, IImportProjectFeature existingImportFeature)
|
||||
public NormalizedDefaultImportFeature(IImportProjectFeature inner, string lineEnding)
|
||||
{
|
||||
_assembly = assembly;
|
||||
_existingImportFeature = existingImportFeature;
|
||||
_inner = inner;
|
||||
_lineEnding = lineEnding;
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_existingImportFeature.ProjectEngine = ProjectEngine;
|
||||
if (_inner != null)
|
||||
{
|
||||
_inner.ProjectEngine = ProjectEngine;
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
||||
{
|
||||
var imports = new List<RazorProjectItem>();
|
||||
|
||||
while (true)
|
||||
if (_inner == null)
|
||||
{
|
||||
var importsFileName = Path.ChangeExtension(projectItem.FilePathWithoutExtension + "_Imports" + imports.Count.ToString(), ".cshtml");
|
||||
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);
|
||||
return Array.Empty<RazorProjectItem>();
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public static IntegrationTestFileSystem Default = new IntegrationTestFileSystem();
|
||||
normalizedImports.Add(normalizedImport);
|
||||
}
|
||||
}
|
||||
|
||||
private IntegrationTestFileSystem()
|
||||
{
|
||||
}
|
||||
|
||||
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>();
|
||||
return normalizedImports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in New Issue