Propogate additional compilation data from RoslynCompilationService
* Update CompilationFailedException to include path of file being compiled * Pass in path being compiled to Rolsyn. * Adding doc comments for compilation pieces Fixes #869
This commit is contained in:
parent
d95b85d057
commit
5e010597cd
|
|
@ -4,38 +4,70 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.AspNet.FileSystems;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An exception thrown when accessing the result of a failed compilation.
|
||||||
|
/// </summary>
|
||||||
public class CompilationFailedException : Exception
|
public class CompilationFailedException : Exception
|
||||||
{
|
{
|
||||||
public CompilationFailedException(IEnumerable<CompilationMessage> messages, string generatedCode)
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="CompilationFailedException"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">The path of the Razor source file that was compiled.</param>
|
||||||
|
/// <param name="fileContent">The contents of the Razor source file.</param>
|
||||||
|
/// <param name="compiledContent">The generated C# content that was compiled.</param>
|
||||||
|
/// <param name="messages">A sequence of <see cref="CompilationMessage"/> encountered
|
||||||
|
/// during compilation.</param>
|
||||||
|
public CompilationFailedException(
|
||||||
|
[NotNull] string filePath,
|
||||||
|
[NotNull] string fileContent,
|
||||||
|
[NotNull] string compiledContent,
|
||||||
|
[NotNull] IEnumerable<CompilationMessage> messages)
|
||||||
: base(FormatMessage(messages))
|
: base(FormatMessage(messages))
|
||||||
{
|
{
|
||||||
|
FilePath = filePath;
|
||||||
|
FileContent = fileContent;
|
||||||
|
CompiledContent = compiledContent;
|
||||||
Messages = messages.ToList();
|
Messages = messages.ToList();
|
||||||
GeneratedCode = generatedCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GeneratedCode { get; private set; }
|
/// <summary>
|
||||||
|
/// Gets the path of the Razor source file that produced the compilation failure.
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a sequence of <see cref="CompilationMessage"/> instances encountered during compilation.
|
||||||
|
/// </summary>
|
||||||
public IEnumerable<CompilationMessage> Messages { get; private set; }
|
public IEnumerable<CompilationMessage> Messages { get; private set; }
|
||||||
|
|
||||||
public string CompilationSource
|
/// <summary>
|
||||||
{
|
/// Gets the content of the Razor source file.
|
||||||
get { return GeneratedCode; }
|
/// </summary>
|
||||||
}
|
public string FileContent { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the generated C# content that was compiled.
|
||||||
|
/// </summary>
|
||||||
|
public string CompiledContent { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override string Message
|
public override string Message
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return "Compilation Failed:" + FormatMessage(Messages);
|
return Resources.FormatCompilationFailed(FilePath) +
|
||||||
|
Environment.NewLine +
|
||||||
|
FormatMessage(Messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string FormatMessage(IEnumerable<CompilationMessage> messages)
|
private static string FormatMessage(IEnumerable<CompilationMessage> messages)
|
||||||
{
|
{
|
||||||
return String.Join(Environment.NewLine, messages);
|
return string.Join(Environment.NewLine, messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,30 @@
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a message encountered during compilation.
|
||||||
|
/// </summary>
|
||||||
public class CompilationMessage
|
public class CompilationMessage
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a <see cref="CompilationMessage"/> with the specified message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">A message <see cref="string"/> produced from compilation.</param>
|
||||||
public CompilationMessage(string message)
|
public CompilationMessage(string message)
|
||||||
{
|
{
|
||||||
Message = message;
|
Message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a message produced from compilation.
|
||||||
|
/// </summary>
|
||||||
public string Message { get; private set; }
|
public string Message { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="string"/> representation of this instance of <see cref="CompilationMessage"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="string"/> representing this <see cref="CompilationMessage"/> instance.</returns>
|
||||||
|
/// <remarks>Returns same value as <see cref="Message"/>.</remarks>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Message;
|
return Message;
|
||||||
|
|
|
||||||
|
|
@ -3,46 +3,145 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.IO;
|
||||||
|
using Microsoft.AspNet.FileSystems;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the result of compilation.
|
||||||
|
/// </summary>
|
||||||
public class CompilationResult
|
public class CompilationResult
|
||||||
{
|
{
|
||||||
private readonly Type _type;
|
private Type _type;
|
||||||
|
|
||||||
private CompilationResult(string generatedCode, Type type, IEnumerable<CompilationMessage> messages)
|
private CompilationResult()
|
||||||
{
|
{
|
||||||
_type = type;
|
|
||||||
GeneratedCode = generatedCode;
|
|
||||||
Messages = messages.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<CompilationMessage> Messages { get; private set; }
|
/// <summary>
|
||||||
|
/// Gets the path of the Razor file that was compiled.
|
||||||
public string GeneratedCode { get; private set; }
|
/// </summary>
|
||||||
|
public string FilePath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (File != null)
|
||||||
|
{
|
||||||
|
return File.PhysicalPath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a sequence of <see cref="CompilationMessage"/> instances encountered during compilation.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<CompilationMessage> Messages { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets additional information from compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// In the event of a compilation failure, values from this dictionary are copied to the
|
||||||
|
/// <see cref="Exception.Data"/> property of the <see cref="Exception"/> thrown.
|
||||||
|
/// </remarks>
|
||||||
|
public IDictionary<string, object> AdditionalInfo
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the generated C# content that was compiled.
|
||||||
|
/// </summary>
|
||||||
|
public string CompiledContent { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type produced as a result of compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="CompilationFailedException">An error occured during compilation.</exception>
|
||||||
public Type CompiledType
|
public Type CompiledType
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_type == null)
|
if (_type == null)
|
||||||
{
|
{
|
||||||
throw new CompilationFailedException(Messages, GeneratedCode);
|
throw CreateCompilationFailedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompilationResult Failed(string generatedCode, IEnumerable<CompilationMessage> messages)
|
private IFileInfo File { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="CompilationResult"/> that represents a failure in compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileInfo">The <see cref="IFileInfo"/> for the Razor file that was compiled.</param>
|
||||||
|
/// <param name="compilationContent">The generated C# content to be compiled.</param>
|
||||||
|
/// <param name="messages">The sequence of failure messages encountered during compilation.</param>
|
||||||
|
/// <param name="additionalInfo">Additional info about the compilation.</param>
|
||||||
|
/// <returns>A CompilationResult instance representing a failure.</returns>
|
||||||
|
public static CompilationResult Failed([NotNull] IFileInfo file,
|
||||||
|
[NotNull] string compilationContent,
|
||||||
|
[NotNull] IEnumerable<CompilationMessage> messages,
|
||||||
|
IDictionary<string, object> additionalInfo)
|
||||||
{
|
{
|
||||||
return new CompilationResult(generatedCode, type: null, messages: messages);
|
return new CompilationResult
|
||||||
|
{
|
||||||
|
File = file,
|
||||||
|
CompiledContent = compilationContent,
|
||||||
|
Messages = messages,
|
||||||
|
AdditionalInfo = additionalInfo
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompilationResult Successful(string generatedCode, Type type)
|
/// <summary>
|
||||||
|
/// Creates a <see cref="CompilationResult"/> that represents a success in compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The compiled type.</param>
|
||||||
|
/// <returns>A CompilationResult instance representing a success.</returns>
|
||||||
|
public static CompilationResult Successful([NotNull] Type type)
|
||||||
{
|
{
|
||||||
return new CompilationResult(generatedCode, type, Enumerable.Empty<CompilationMessage>());
|
return new CompilationResult
|
||||||
|
{
|
||||||
|
_type = type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompilationFailedException CreateCompilationFailedException()
|
||||||
|
{
|
||||||
|
var fileContent = ReadContent(File);
|
||||||
|
var exception = new CompilationFailedException(FilePath, fileContent, CompiledContent, Messages);
|
||||||
|
if (AdditionalInfo != null)
|
||||||
|
{
|
||||||
|
foreach (var item in AdditionalInfo)
|
||||||
|
{
|
||||||
|
exception.Data.Add(item.Key, item.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ReadContent(IFileInfo file)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var stream = file.CreateReadStream())
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
return reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
// Don't throw if reading the file fails.
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompilationResult.Successful(generatedCode: null, type: compiledType);
|
return CompilationResult.Successful(compiledType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,23 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using Microsoft.AspNet.FileSystems;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides methods for compilation of a Razor page.
|
||||||
|
/// </summary>
|
||||||
public interface ICompilationService
|
public interface ICompilationService
|
||||||
{
|
{
|
||||||
CompilationResult Compile(string content);
|
/// <summary>
|
||||||
|
/// Compiles content and returns the result of compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileInfo">The <see cref="IFileInfo"/> for the Razor file that was compiled.</param>
|
||||||
|
/// <param name="compilationContent">The generated C# content to be compiled.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="CompilationResult"/> representing the result of compilation.
|
||||||
|
/// </returns>
|
||||||
|
CompilationResult Compile(IFileInfo fileInfo, string compilationContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,22 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNet.FileSystems;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.Emit;
|
using Microsoft.CodeAnalysis.Emit;
|
||||||
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using Microsoft.Framework.Runtime;
|
using Microsoft.Framework.Runtime;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A type that uses Roslyn to compile C# content.
|
||||||
|
/// </summary>
|
||||||
public class RoslynCompilationService : ICompilationService
|
public class RoslynCompilationService : ICompilationService
|
||||||
{
|
{
|
||||||
|
public static readonly string CompilationResultDiagnosticsKey = "Diagnostics";
|
||||||
private static readonly ConcurrentDictionary<string, MetadataReference> _metadataFileCache =
|
private static readonly ConcurrentDictionary<string, MetadataReference> _metadataFileCache =
|
||||||
new ConcurrentDictionary<string, MetadataReference>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, MetadataReference>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|
@ -23,6 +30,12 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
private readonly IApplicationEnvironment _environment;
|
private readonly IApplicationEnvironment _environment;
|
||||||
private readonly IAssemblyLoaderEngine _loader;
|
private readonly IAssemblyLoaderEngine _loader;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initalizes a new instance of the <see cref="RoslynCompilationService"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="environment">The environment for the executing application.</param>
|
||||||
|
/// <param name="loaderEngine">The loader used to load compiled assemblies.</param>
|
||||||
|
/// <param name="libraryManager">The library manager that provides export and reference information.</param>
|
||||||
public RoslynCompilationService(IApplicationEnvironment environment,
|
public RoslynCompilationService(IApplicationEnvironment environment,
|
||||||
IAssemblyLoaderEngine loaderEngine,
|
IAssemblyLoaderEngine loaderEngine,
|
||||||
ILibraryManager libraryManager)
|
ILibraryManager libraryManager)
|
||||||
|
|
@ -32,9 +45,11 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompilationResult Compile(string content)
|
/// <inheritdoc />
|
||||||
|
public CompilationResult Compile(IFileInfo fileInfo, string compilationContent)
|
||||||
{
|
{
|
||||||
var syntaxTrees = new[] { CSharpSyntaxTree.ParseText(content) };
|
var sourceText = SourceText.From(compilationContent, Encoding.UTF8);
|
||||||
|
var syntaxTrees = new[] { CSharpSyntaxTree.ParseText(sourceText, path: fileInfo.PhysicalPath) };
|
||||||
var targetFramework = _environment.TargetFramework;
|
var targetFramework = _environment.TargetFramework;
|
||||||
|
|
||||||
var references = GetApplicationReferences();
|
var references = GetApplicationReferences();
|
||||||
|
|
@ -70,7 +85,11 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
.Select(d => GetCompilationMessage(formatter, d))
|
.Select(d => GetCompilationMessage(formatter, d))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return CompilationResult.Failed(content, messages);
|
var additionalInfo = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
{ CompilationResultDiagnosticsKey, result.Diagnostics }
|
||||||
|
};
|
||||||
|
return CompilationResult.Failed(fileInfo, compilationContent, messages, additionalInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assembly assembly;
|
Assembly assembly;
|
||||||
|
|
@ -89,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
var type = assembly.GetExportedTypes()
|
var type = assembly.GetExportedTypes()
|
||||||
.First();
|
.First();
|
||||||
|
|
||||||
return CompilationResult.Successful(string.Empty, type);
|
return CompilationResult.Successful(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +154,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompilationMessage GetCompilationMessage(DiagnosticFormatter formatter, Diagnostic diagnostic)
|
private static CompilationMessage GetCompilationMessage(DiagnosticFormatter formatter, Diagnostic diagnostic)
|
||||||
{
|
{
|
||||||
return new CompilationMessage(formatter.Format(diagnostic));
|
return new CompilationMessage(formatter.Format(diagnostic));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,22 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
return GetString("ArgumentCannotBeNullOrEmpty");
|
return GetString("ArgumentCannotBeNullOrEmpty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compilation for '{0}' failed:
|
||||||
|
/// </summary>
|
||||||
|
internal static string CompilationFailed
|
||||||
|
{
|
||||||
|
get { return GetString("CompilationFailed"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compilation for '{0}' failed:
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatCompilationFailed(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("CompilationFailed"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layout view '{0}' could not be located.
|
/// The layout view '{0}' could not be located.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
private readonly string _appRoot;
|
private readonly string _appRoot;
|
||||||
|
|
||||||
public RazorCompilationService(IApplicationEnvironment environment,
|
public RazorCompilationService(IApplicationEnvironment environment,
|
||||||
ICompilationService compilationService,
|
ICompilationService compilationService,
|
||||||
IMvcRazorHost razorHost)
|
IMvcRazorHost razorHost)
|
||||||
{
|
{
|
||||||
_environment = environment;
|
_environment = environment;
|
||||||
|
|
@ -49,10 +49,10 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
if (!results.Success)
|
if (!results.Success)
|
||||||
{
|
{
|
||||||
var messages = results.ParserErrors.Select(e => new CompilationMessage(e.Message));
|
var messages = results.ParserErrors.Select(e => new CompilationMessage(e.Message));
|
||||||
throw new CompilationFailedException(messages, results.GeneratedCode);
|
return CompilationResult.Failed(file, results.GeneratedCode, messages, additionalInfo: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _baseCompilationService.Compile(results.GeneratedCode);
|
return _baseCompilationService.Compile(file, results.GeneratedCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string EnsureTrailingSlash([NotNull]string path)
|
private static string EnsureTrailingSlash([NotNull]string path)
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,9 @@
|
||||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||||
<value>The value cannot be null or empty.</value>
|
<value>The value cannot be null or empty.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompilationFailed" xml:space="preserve">
|
||||||
|
<value>Compilation for '{0}' failed:</value>
|
||||||
|
</data>
|
||||||
<data name="LayoutCannotBeLocated" xml:space="preserve">
|
<data name="LayoutCannotBeLocated" xml:space="preserve">
|
||||||
<value>The layout view '{0}' could not be located.</value>
|
<value>The layout view '{0}' could not be located.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNet.FileSystems;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Razor.Test
|
||||||
|
{
|
||||||
|
public class CompilationResultTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void FailedResult_ThrowsWhenAccessingCompiledType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expected =
|
||||||
|
@"Compilation for 'myfile' failed:
|
||||||
|
hello
|
||||||
|
world";
|
||||||
|
var originalContent = "Original file content";
|
||||||
|
var fileInfo = new Mock<IFileInfo>();
|
||||||
|
fileInfo.SetupGet(f => f.PhysicalPath)
|
||||||
|
.Returns("myfile");
|
||||||
|
var contentBytes = Encoding.UTF8.GetBytes(originalContent);
|
||||||
|
fileInfo.Setup(f => f.CreateReadStream())
|
||||||
|
.Returns(new MemoryStream(contentBytes));
|
||||||
|
var messages = new[]
|
||||||
|
{
|
||||||
|
new CompilationMessage("hello"),
|
||||||
|
new CompilationMessage("world")
|
||||||
|
};
|
||||||
|
var additionalInfo = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "key", "value" }
|
||||||
|
};
|
||||||
|
var result = CompilationResult.Failed(fileInfo.Object,
|
||||||
|
"<h1>hello world</h1>",
|
||||||
|
messages,
|
||||||
|
additionalInfo);
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
var ex = Assert.Throws<CompilationFailedException>(() => result.CompiledType);
|
||||||
|
Assert.Equal(expected, ex.Message);
|
||||||
|
Assert.Equal("value", ex.Data["key"]);
|
||||||
|
Assert.Equal(originalContent, ex.FileContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
<Content Include="project.json" />
|
<Content Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Compilation\CompilationResultTest.cs" />
|
||||||
<Compile Include="BufferEntryCollectionTest.cs" />
|
<Compile Include="BufferEntryCollectionTest.cs" />
|
||||||
<Compile Include="MvcRazorCodeParserTest.cs" />
|
<Compile Include="MvcRazorCodeParserTest.cs" />
|
||||||
<Compile Include="RazorCompilationServiceTest.cs" />
|
<Compile Include="RazorCompilationServiceTest.cs" />
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
|
||||||
host.Setup(h => h.GenerateCode(@"views\index\home.cshtml", It.IsAny<Stream>()))
|
host.Setup(h => h.GenerateCode(@"views\index\home.cshtml", It.IsAny<Stream>()))
|
||||||
.Returns(new GeneratorResults(new Block(new BlockBuilder { Type = BlockType.Comment }), new RazorError[0], new CodeBuilderResult("", new LineMapping[0])))
|
.Returns(new GeneratorResults(new Block(new BlockBuilder { Type = BlockType.Comment }), new RazorError[0], new CodeBuilderResult("", new LineMapping[0])))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var compiler = new Mock<ICompilationService>();
|
|
||||||
compiler.Setup(c => c.Compile(It.IsAny<string>()))
|
|
||||||
.Returns(CompilationResult.Successful("", typeof(RazorCompilationServiceTest)));
|
|
||||||
|
|
||||||
var razorService = new RazorCompilationService(env.Object, compiler.Object, host.Object);
|
|
||||||
var fileInfo = new Mock<IFileInfo>();
|
var fileInfo = new Mock<IFileInfo>();
|
||||||
fileInfo.Setup(f => f.PhysicalPath).Returns(viewPath);
|
fileInfo.Setup(f => f.PhysicalPath).Returns(viewPath);
|
||||||
fileInfo.Setup(f => f.CreateReadStream()).Returns(Stream.Null);
|
fileInfo.Setup(f => f.CreateReadStream()).Returns(Stream.Null);
|
||||||
|
var compiler = new Mock<ICompilationService>();
|
||||||
|
compiler.Setup(c => c.Compile(fileInfo.Object, It.IsAny<string>()))
|
||||||
|
.Returns(CompilationResult.Successful(typeof(RazorCompilationServiceTest)));
|
||||||
|
var razorService = new RazorCompilationService(env.Object, compiler.Object, host.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
razorService.CompileCore(fileInfo.Object);
|
razorService.CompileCore(fileInfo.Object);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue