public void GetCompilationFailedResult_ReadsRazorErrorsFromPage() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">")); var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem); var codeDocument = templateEngine.CreateCodeDocument(viewPath); // Act var csharpDocument = templateEngine.GenerateCode(codeDocument); var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert var failure = Assert.Single(compilationResult.CompilationFailures); Assert.Equal(viewPath, failure.SourceFilePath); Assert.Collection(failure.Messages, message => Assert.StartsWith( @"Unterminated string literal.", message.Message), message => Assert.StartsWith( @"The explicit expression block is missing a closing "")"" character.", message.Message)); }
public void GetCompilationFailedResult_ReadsContentFromSourceDocuments() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var fileContent = @" @if (User.IsAdmin) { <span> } </span>"; var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(new TestRazorProjectItem(viewPath, fileContent)); var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem); var codeDocument = templateEngine.CreateCodeDocument(viewPath); // Act var csharpDocument = templateEngine.GenerateCode(codeDocument); var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert var failure = Assert.Single(compilationResult.CompilationFailures); Assert.Equal(fileContent, failure.SourceFileContent); }
public void GetCompilationFailedResult_ReadsContentFromImports() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var importsPath = "/Views/_MyImports.cshtml"; var fileContent = "@ "; var importsContent = "@(abc"; var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(new TestRazorProjectItem(viewPath, fileContent)); fileSystem.Add(new TestRazorProjectItem("/Views/_MyImports.cshtml", importsContent)); var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem) { Options = { ImportsFileName = "_MyImports.cshtml", } }; var codeDocument = templateEngine.CreateCodeDocument(viewPath); // Act var csharpDocument = templateEngine.GenerateCode(codeDocument); var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert Assert.Collection( compilationResult.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Collection(failure.Messages, message => { Assert.Equal(@"A space or line break was encountered after the ""@"" character. Only valid identifiers, keywords, comments, ""("" and ""{"" are valid at the start of a code block and they must occur immediately following ""@"" with no space in between.", message.Message); }); }, failure => { Assert.Equal(importsPath, failure.SourceFilePath); Assert.Collection(failure.Messages, message => { Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.", message.Message); }); }); }
public void GetCompilationFailedResult_WithMissingReferences() { // Arrange var expected = "One or more compilation references may be missing. If you're seeing this in a published application, set 'CopyRefAssembliesToPublishDirectory' to true in your project file to ensure files in the refs directory are published."; var compilation = CSharpCompilation.Create("Test", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); var syntaxTree = CSharpSyntaxTree.ParseText("@class Test { public string Test { get; set; } }"); compilation = compilation.AddSyntaxTrees(syntaxTree); var emitResult = compilation.Emit(new MemoryStream()); // Act var exception = CompilationFailedExceptionFactory.Create( RazorCodeDocument.Create(RazorSourceDocument.Create("Test", "Index.cshtml"), Enumerable.Empty <RazorSourceDocument>()), syntaxTree.ToString(), "Test", emitResult.Diagnostics); // Assert Assert.Collection( exception.CompilationFailures, failure => Assert.Equal(expected, failure.FailureSummary)); }
protected virtual CompiledViewDescriptor CompileAndEmit(string relativePath) { var projectItem = _projectEngine.FileSystem.GetItem(relativePath); var codeDocument = _projectEngine.Process(projectItem); var cSharpDocument = codeDocument.GetCSharpDocument(); if (cSharpDocument.Diagnostics.Count > 0) { throw CompilationFailedExceptionFactory.Create( codeDocument, cSharpDocument.Diagnostics); } var assembly = CompileAndEmit(codeDocument, cSharpDocument.GeneratedCode); // Anything we compile from source will use Razor 2.1 and so should have the new metadata. var loader = new RazorCompiledItemLoader(); var item = loader.LoadItems(assembly).SingleOrDefault(); var attribute = assembly.GetCustomAttribute <RazorViewAttribute>(); return(new CompiledViewDescriptor(item, attribute)); }
internal Assembly CompileAndEmit(RazorCodeDocument codeDocument, string generatedCode) { _logger.GeneratedCodeToAssemblyCompilationStart(codeDocument.Source.FilePath); var startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0; var assemblyName = Path.GetRandomFileName(); var compilation = CreateCompilation(generatedCode, assemblyName); var emitOptions = _csharpCompiler.EmitOptions; var emitPdbFile = _csharpCompiler.EmitPdb && emitOptions.DebugInformationFormat != DebugInformationFormat.Embedded; using (var assemblyStream = new MemoryStream()) using (var pdbStream = emitPdbFile ? new MemoryStream() : null) { var result = compilation.Emit( assemblyStream, pdbStream, options: emitOptions); if (!result.Success) { throw CompilationFailedExceptionFactory.Create( codeDocument, generatedCode, assemblyName, result.Diagnostics); } assemblyStream.Seek(0, SeekOrigin.Begin); pdbStream?.Seek(0, SeekOrigin.Begin); var assembly = Assembly.Load(assemblyStream.ToArray(), pdbStream?.ToArray()); _logger.GeneratedCodeToAssemblyCompilationEnd(codeDocument.Source.FilePath, startTimestamp); return(assembly); } }
public void GetCompilationFailedResult_UsesPhysicalPath() { // Arrange var viewPath = "/Views/Home/Index.cshtml"; var physicalPath = @"x:\myapp\views\home\index.cshtml"; var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">", physicalPath: physicalPath)); var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem); var codeDocument = templateEngine.CreateCodeDocument(viewPath); // Act var csharpDocument = templateEngine.GenerateCode(codeDocument); var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics); // Assert var failure = Assert.Single(compilationResult.CompilationFailures); Assert.Equal(physicalPath, failure.SourceFilePath); }
public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages() { // Arrange var viewPath = "Views/Home/Index"; var generatedCodeFileName = "Generated Code"; var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("view-content", viewPath)); var assemblyName = "random-assembly-name"; var diagnostics = new[] { Diagnostic.Create( GetRoslynDiagnostic("message-1"), Location.Create( viewPath, new TextSpan(10, 5), new LinePositionSpan(new LinePosition(10, 1), new LinePosition(10, 2)))), Diagnostic.Create( GetRoslynDiagnostic("message-2"), Location.Create( assemblyName, new TextSpan(1, 6), new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))), Diagnostic.Create( GetRoslynDiagnostic("message-3"), Location.Create( viewPath, new TextSpan(40, 50), new LinePositionSpan(new LinePosition(30, 5), new LinePosition(40, 12)))), }; // Act var compilationResult = CompilationFailedExceptionFactory.Create( codeDocument, "compilation-content", assemblyName, diagnostics); // Assert Assert.Collection(compilationResult.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Equal("view-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-1", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(11, message.StartLine); Assert.Equal(2, message.StartColumn); Assert.Equal(11, message.EndLine); Assert.Equal(3, message.EndColumn); }, message => { Assert.Equal("message-3", message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(31, message.StartLine); Assert.Equal(6, message.StartColumn); Assert.Equal(41, message.EndLine); Assert.Equal(13, message.EndColumn); }); }, failure => { Assert.Equal(generatedCodeFileName, failure.SourceFilePath); Assert.Equal("compilation-content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal("message-2", message.Message); Assert.Equal(assemblyName, message.SourceFilePath); Assert.Equal(2, message.StartLine); Assert.Equal(3, message.StartColumn); Assert.Equal(4, message.EndLine); Assert.Equal(5, message.EndColumn); }); }); }
public void GetCompilationFailedResult_GroupsMessages() { // Arrange var viewPath = "views/index.razor"; var viewImportsPath = "views/global.import.cshtml"; var codeDocument = RazorCodeDocument.Create( Create(viewPath, "View Content"), new[] { Create(viewImportsPath, "Global Import Content") }); var diagnostics = new[] { GetRazorDiagnostic("message-1", new SourceLocation(1, 2, 17), length: 1), GetRazorDiagnostic("message-2", new SourceLocation(viewPath, 1, 4, 6), length: 7), GetRazorDiagnostic("message-3", SourceLocation.Undefined, length: -1), GetRazorDiagnostic("message-4", new SourceLocation(viewImportsPath, 1, 3, 8), length: 4), }; // Act var result = CompilationFailedExceptionFactory.Create(codeDocument, diagnostics); // Assert Assert.Collection(result.CompilationFailures, failure => { Assert.Equal(viewPath, failure.SourceFilePath); Assert.Equal("View Content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal(diagnostics[0].GetMessage(), message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(3, message.StartLine); Assert.Equal(17, message.StartColumn); Assert.Equal(3, message.EndLine); Assert.Equal(18, message.EndColumn); }, message => { Assert.Equal(diagnostics[1].GetMessage(), message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(5, message.StartLine); Assert.Equal(6, message.StartColumn); Assert.Equal(5, message.EndLine); Assert.Equal(13, message.EndColumn); }, message => { Assert.Equal(diagnostics[2].GetMessage(), message.Message); Assert.Equal(viewPath, message.SourceFilePath); Assert.Equal(0, message.StartLine); Assert.Equal(-1, message.StartColumn); Assert.Equal(0, message.EndLine); Assert.Equal(-2, message.EndColumn); }); }, failure => { Assert.Equal(viewImportsPath, failure.SourceFilePath); Assert.Equal("Global Import Content", failure.SourceFileContent); Assert.Collection(failure.Messages, message => { Assert.Equal(diagnostics[3].GetMessage(), message.Message); Assert.Equal(viewImportsPath, message.SourceFilePath); Assert.Equal(4, message.StartLine); Assert.Equal(8, message.StartColumn); Assert.Equal(4, message.EndLine); Assert.Equal(12, message.EndColumn); }); }); }