Пример #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
        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);

            var loader    = new RazorCompiledItemLoader();
            var item      = loader.LoadItems(assembly).SingleOrDefault();
            var attribute = assembly.GetCustomAttribute <RazorViewAttribute>();

            return(new CompiledViewDescriptor(item, attribute));
        }
Пример #5
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);
            });
        });
    }
Пример #6
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));
    }
Пример #7
0
    internal Assembly CompileAndEmit(RazorCodeDocument codeDocument, string generatedCode)
    {
        Log.GeneratedCodeToAssemblyCompilationStart(_logger, 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());
                Log.GeneratedCodeToAssemblyCompilationEnd(_logger, codeDocument.Source.FilePath, startTimestamp);

                return(assembly);
            }
    }
Пример #8
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);
    }
Пример #9
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);
            });
        });
    }
Пример #10
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);
            });
        });
    }