예제 #1
0
        public void GetCompilationFailedResult_ReadsRazorErrorsFromPage()
        {
            // Arrange
            var viewPath = "/Views/Home/Index.cshtml";

            var fileSystem  = new VirtualRazorProjectFileSystem();
            var projectItem = new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">");

            var razorEngine  = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine;
            var codeDocument = GetCodeDocument(projectItem);

            // Act
            razorEngine.Process(codeDocument);
            var csharpDocument    = codeDocument.GetCSharpDocument();
            var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics);

            // Assert
            var failure = Assert.Single(compilationResult.CompilationFailures);

            Assert.Equal(viewPath, failure.SourceFilePath);
            var orderedMessages = failure.Messages.OrderByDescending(messages => messages.Message);

            Assert.Collection(orderedMessages,
                              message => Assert.StartsWith(
                                  @"Unterminated string literal.",
                                  message.Message),
                              message => Assert.StartsWith(
                                  @"The explicit expression block is missing a closing "")"" character.",
                                  message.Message));
        }
예제 #2
0
        public void GetCompilationFailedResult_UsesPhysicalPath()
        {
            // Arrange
            var viewPath     = "/Views/Home/Index.cshtml";
            var physicalPath = @"x:\myapp\views\home\index.cshtml";

            var projectItem = new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">", physicalPath: physicalPath);

            var codeDocument   = GetCodeDocument(projectItem);
            var csharpDocument = codeDocument.GetCSharpDocument();

            // Act
            var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics);

            // Assert
            var failure = Assert.Single(compilationResult.CompilationFailures);

            Assert.Equal(physicalPath, failure.SourceFilePath);
        }
예제 #3
0
        protected virtual CompiledViewDescriptor CompileAndEmit(string relativePath)
        {
            var projectItem    = _projectEngine.FileSystem.GetItem(relativePath, fileKind: null);
            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).Single();

            return(new CompiledViewDescriptor(item));
        }
예제 #4
0
        public void GetCompilationFailedResult_ReadsContentFromImports()
        {
            // Arrange
            var viewPath       = "/Views/Home/Index.cshtml";
            var importsPath    = "/Views/_MyImports.cshtml";
            var fileContent    = "@ ";
            var importsContent = "@(abc";

            var projectItem    = new TestRazorProjectItem(viewPath, fileContent);
            var importsItem    = new TestRazorProjectItem(importsPath, importsContent);
            var codeDocument   = GetCodeDocument(projectItem, importsItem);
            var csharpDocument = codeDocument.GetCSharpDocument();

            // Act
            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);
                });
            });
        }
예제 #5
0
        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));
        }
예제 #6
0
        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);
                }
        }
예제 #7
0
        public void GetCompilationFailedResult_ReadsContentFromSourceDocuments()
        {
            // Arrange
            var viewPath    = "/Views/Home/Index.cshtml";
            var fileContent =
                @"
@if (User.IsAdmin)
{
    <span>
}
</span>";

            var projectItem    = new TestRazorProjectItem(viewPath, fileContent);
            var codeDocument   = GetCodeDocument(projectItem);
            var csharpDocument = codeDocument.GetCSharpDocument();

            // Act
            var compilationResult = CompilationFailedExceptionFactory.Create(codeDocument, csharpDocument.Diagnostics);

            // Assert
            var failure = Assert.Single(compilationResult.CompilationFailures);

            Assert.Equal(fileContent, failure.SourceFileContent);
        }
예제 #8
0
        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);
                });
            });
        }
예제 #9
0
        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(CultureInfo.CurrentCulture), 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(CultureInfo.CurrentCulture), 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(CultureInfo.CurrentCulture), 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(CultureInfo.CurrentCulture), 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);
                });
            });
        }