diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailedException.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailedException.cs
index 6c1530ad5a..5294bf8c5f 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailedException.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailedException.cs
@@ -3,13 +3,14 @@
using System;
using System.Collections.Generic;
-using Microsoft.AspNet.Diagnostics;
+using System.Linq;
+using Microsoft.Framework.Runtime;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Razor
{
///
- /// An exception thrown when accessing the result of a failed compilation.
+ /// An thrown when accessing the result of a failed compilation.
///
public class CompilationFailedException : Exception, ICompilationException
{
@@ -20,12 +21,19 @@ namespace Microsoft.AspNet.Mvc.Razor
/// details of the compilation failure.
public CompilationFailedException(
[NotNull] ICompilationFailure compilationFailure)
- : base(Resources.FormatCompilationFailed(compilationFailure.SourceFilePath))
+ : base(FormatMessage(compilationFailure))
{
CompilationFailures = new[] { compilationFailure };
}
///
public IEnumerable CompilationFailures { get; }
+
+ private static string FormatMessage(ICompilationFailure compilationFailure)
+ {
+ return Resources.CompilationFailed +
+ Environment.NewLine +
+ string.Join(Environment.NewLine, compilationFailure.Messages.Select(message => message.FormattedMessage));
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailure.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailure.cs
deleted file mode 100644
index 28cf5dac8f..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationFailure.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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 Microsoft.AspNet.Diagnostics;
-using Microsoft.Framework.Internal;
-
-namespace Microsoft.AspNet.Mvc.Razor
-{
- ///
- /// Default implementation of .
- ///
- public class CompilationFailure : ICompilationFailure
- {
- /// Initializes a new instance of .
- /// The path of the Razor source file that was compiled.
- /// The contents of the Razor source file.
- /// The generated C# content that was compiled.
- /// A sequence of encountered
- /// during compilation.
- public CompilationFailure(
- [NotNull] string filePath,
- [NotNull] string fileContent,
- [NotNull] string compiledContent,
- [NotNull] IEnumerable messages)
- {
- SourceFilePath = filePath;
- SourceFileContent = fileContent;
- Messages = messages;
- CompiledContent = compiledContent;
- }
-
- ///
- /// Gets the path of the Razor source file that produced the compilation failure.
- ///
- public string SourceFilePath { get; }
-
- ///
- /// Gets the content of the Razor source file.
- ///
- public string SourceFileContent { get; }
-
- ///
- /// Gets the generated C# content that was compiled.
- ///
- public string CompiledContent { get; }
-
- ///
- /// Gets a sequence of instances encountered during compilation.
- ///
- public IEnumerable Messages { get; }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationMessage.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationMessage.cs
deleted file mode 100644
index b0b6e615a2..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationMessage.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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 Microsoft.AspNet.Diagnostics;
-
-namespace Microsoft.AspNet.Mvc.Razor
-{
- ///
- /// Represents a message encountered during compilation.
- ///
- public class CompilationMessage : ICompilationMessage
- {
- ///
- /// Initializes a with the specified message.
- ///
- /// A message produced from compilation.
- public CompilationMessage(string message,
- int startColumn,
- int startLine,
- int endColumn,
- int endLine)
- {
- Message = message;
- StartColumn = startColumn;
- StartLine = startLine;
- EndColumn = endColumn;
- EndLine = endLine;
- }
-
- ///
- /// Gets a message produced from compilation.
- ///
- public string Message { get; }
-
- ///
- public int StartColumn { get; }
-
- ///
- public int StartLine { get; }
-
- ///
- public int EndColumn { get; }
-
- ///
- public int EndLine { get; }
-
- ///
- /// Returns a representation of this instance of .
- ///
- /// A representing this instance.
- /// Returns same value as .
- public override string ToString()
- {
- return Message;
- }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationResult.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationResult.cs
index ee4d1508d2..714d68404b 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationResult.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationResult.cs
@@ -2,9 +2,7 @@
// 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 Microsoft.AspNet.FileProviders;
+using Microsoft.Framework.Runtime;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Razor
@@ -14,8 +12,6 @@ namespace Microsoft.AspNet.Mvc.Razor
///
public class CompilationResult
{
- private Type _type;
-
///
/// Creates a new instance of .
///
@@ -24,24 +20,10 @@ namespace Microsoft.AspNet.Mvc.Razor
}
///
- /// Gets the path of the Razor file that was compiled.
+ /// Gets (or sets in derived types) the type produced as a result of compilation.
///
- public string FilePath
- {
- get
- {
- if (File != null)
- {
- return File.PhysicalPath;
- }
- return null;
- }
- }
-
- ///
- /// Gets a sequence of instances encountered during compilation.
- ///
- public IEnumerable Messages { get; private set; }
+ /// This property is null when compilation failed.
+ public Type CompiledType { get; protected set; }
///
/// Gets (or sets in derived types) the generated C# content that was compiled.
@@ -49,52 +31,45 @@ namespace Microsoft.AspNet.Mvc.Razor
public string CompiledContent { get; protected set; }
///
- /// Gets (or sets in derived types) the type produced as a result of compilation.
+ /// Gets the produced from parsing or compiling the Razor file.
///
- /// An error occured during compilation.
- public Type CompiledType
- {
- get
- {
- if (_type == null)
- {
- throw CreateCompilationFailedException();
- }
-
- return _type;
- }
- protected set
- {
- _type = value;
- }
- }
-
- private IFileInfo File { get; set; }
+ /// This property is null when compilation succeeded.
+ public ICompilationFailure CompilationFailure { get; private set; }
///
- /// Creates a that represents a failure in compilation.
+ /// Gets the .
///
- /// The for the Razor file that was compiled.
- /// The generated C# content to be compiled.
- /// The sequence of failure messages encountered during compilation.
- /// A CompilationResult instance representing a failure.
- public static CompilationResult Failed([NotNull] IFileInfo file,
- [NotNull] string compilationContent,
- [NotNull] IEnumerable messages)
+ /// The current instance.
+ /// Thrown if compilation failed.
+ public CompilationResult EnsureSuccessful()
+ {
+ if (CompilationFailure != null)
+ {
+ throw new CompilationFailedException(CompilationFailure);
+ }
+
+ return this;
+ }
+
+ ///
+ /// Creates a for a failed compilation.
+ ///
+ /// The produced from parsing or
+ /// compiling the Razor file.
+ /// A instance for a failed compilation.
+ public static CompilationResult Failed([NotNull] ICompilationFailure compilationFailure)
{
return new CompilationResult
{
- File = file,
- CompiledContent = compilationContent,
- Messages = messages,
+ CompilationFailure = compilationFailure
};
}
///
- /// Creates a that represents a success in compilation.
+ /// Creates a for a successful compilation.
///
/// The compiled type.
- /// A CompilationResult instance representing a success.
+ /// A instance for a successful compilation.
public static CompilationResult Successful([NotNull] Type type)
{
return new CompilationResult
@@ -102,31 +77,5 @@ namespace Microsoft.AspNet.Mvc.Razor
CompiledType = type
};
}
-
- private CompilationFailedException CreateCompilationFailedException()
- {
- var fileContent = ReadContent(File);
- var compilationFailure = new CompilationFailure(FilePath, fileContent, CompiledContent, Messages);
- return new CompilationFailedException(compilationFailure);
- }
-
- private static string ReadContent(IFileInfo file)
- {
- try
- {
- using (var stream = file.CreateReadStream())
- {
- using (var reader = new StreamReader(stream))
- {
- return reader.ReadToEnd();
- }
- }
- }
- catch (Exception)
- {
- // Don't throw if reading the file fails.
- return string.Empty;
- }
- }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilerCache.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilerCache.cs
index a1c3971e17..8012e29e6c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilerCache.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilerCache.cs
@@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Mvc.Razor
string normalizedPath,
Func compile)
{
- var compilationResult = compile(file);
+ var compilationResult = compile(file).EnsureSuccessful();
// Concurrent addition to MemoryCache with the same key result in safe race.
var cacheEntry = _cache.Set(normalizedPath,
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/ICompilationService.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/ICompilationService.cs
index 24ea983e3d..1d88cf4009 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/ICompilationService.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/ICompilationService.cs
@@ -1,8 +1,6 @@
// 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 Microsoft.AspNet.FileProviders;
-
namespace Microsoft.AspNet.Mvc.Razor
{
///
@@ -13,11 +11,11 @@ namespace Microsoft.AspNet.Mvc.Razor
///
/// Compiles content and returns the result of compilation.
///
- /// The for the Razor file that was compiled.
+ /// The for the Razor file that was compiled.
/// The generated C# content to be compiled.
///
/// A representing the result of compilation.
///
- CompilationResult Compile(IFileInfo fileInfo, string compilationContent);
+ CompilationResult Compile(RelativeFileInfo fileInfo, string compilationContent);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationFailure.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationFailure.cs
new file mode 100644
index 0000000000..a2268d62ed
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationFailure.cs
@@ -0,0 +1,42 @@
+// 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 Microsoft.Framework.Runtime;
+using Microsoft.Framework.Internal;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ ///
+ /// for Razor parse failures.
+ ///
+ public class RazorCompilationFailure : ICompilationFailure
+ {
+ /// Initializes a new instance of .
+ /// The path of the Razor source file that was compiled.
+ /// The contents of the Razor source file.
+ /// A sequence of encountered
+ /// during compilation.
+ public RazorCompilationFailure(
+ [NotNull] string sourceFilePath,
+ [NotNull] string sourceFileContent,
+ [NotNull] IEnumerable messages)
+ {
+ SourceFilePath = sourceFilePath;
+ SourceFileContent = sourceFileContent;
+ Messages = messages;
+ }
+
+ ///
+ public string SourceFilePath { get; }
+
+ ///
+ public string SourceFileContent { get; }
+
+ ///
+ public string CompiledContent { get; } = null;
+
+ ///
+ public IEnumerable Messages { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationMessage.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationMessage.cs
new file mode 100644
index 0000000000..90fb0a3655
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RazorCompilationMessage.cs
@@ -0,0 +1,74 @@
+// 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 Microsoft.AspNet.Razor.Parser.SyntaxTree;
+using Microsoft.Framework.Internal;
+using Microsoft.Framework.Runtime;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ ///
+ /// for a encountered during parsing.
+ ///
+ public class RazorCompilationMessage : ICompilationMessage
+ {
+ ///
+ /// Initializes a with the specified message.
+ ///
+ /// A .
+ /// The path of the Razor source file that was parsed.
+ public RazorCompilationMessage(
+ [NotNull] RazorError razorError,
+ string sourceFilePath)
+ {
+ SourceFilePath = sourceFilePath;
+ Message = razorError.Message;
+
+ var location = razorError.Location;
+ FormattedMessage =
+ $"{sourceFilePath} ({location.LineIndex},{location.CharacterIndex}) {razorError.Message}";
+
+ StartColumn = location.CharacterIndex;
+ StartLine = location.LineIndex;
+ EndColumn = location.CharacterIndex + razorError.Length;
+ EndLine = location.LineIndex;
+ }
+
+ ///
+ /// Gets a message produced from compilation.
+ ///
+ public string Message { get; }
+
+ ///
+ public int StartColumn { get; }
+
+ ///
+ public int StartLine { get; }
+
+ ///
+ public int EndColumn { get; }
+
+ ///
+ public int EndLine { get; }
+
+ ///
+ public string SourceFilePath { get; }
+
+ ///
+ public string FormattedMessage { get; }
+
+ ///
+ // All Razor diagnostics are errors
+ public CompilationMessageSeverity Severity { get; } = CompilationMessageSeverity.Error;
+
+ ///
+ /// Returns a representation of this instance of .
+ ///
+ /// A representing this instance.
+ /// Returns same value as .
+ public override string ToString()
+ {
+ return FormattedMessage;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs
index f2fd90a53e..2c7889e848 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs
@@ -60,12 +60,12 @@ namespace Microsoft.AspNet.Mvc.Razor
}
///
- public CompilationResult Compile([NotNull] IFileInfo fileInfo, [NotNull] string compilationContent)
+ public CompilationResult Compile([NotNull] RelativeFileInfo fileInfo, [NotNull] string compilationContent)
{
// The path passed to SyntaxTreeGenerator.Generate is used by the compiler to generate symbols (pdb) that
// map to the source file. If a file does not exist on a physical file system, PhysicalPath will be null.
// This prevents files that exist in a non-physical file system from being debugged.
- var path = fileInfo.PhysicalPath ?? fileInfo.Name;
+ var path = fileInfo.FileInfo.PhysicalPath ?? fileInfo.RelativePath;
var compilationSettings = _compilerOptionsProvider.GetCompilationSettings(_environment);
var syntaxTree = SyntaxTreeGenerator.Generate(compilationContent,
path,
@@ -98,14 +98,15 @@ namespace Microsoft.AspNet.Mvc.Razor
if (!result.Success)
{
- var formatter = new DiagnosticFormatter();
+ var failures = result.Diagnostics.Where(IsError);
+ var compilationFailure = new RoslynCompilationFailure(failures)
+ {
+ CompiledContent = compilationContent,
+ SourceFileContent = ReadFileContentsSafely(fileInfo.FileInfo),
+ SourceFilePath = fileInfo.RelativePath
+ };
- var messages = result.Diagnostics
- .Where(IsError)
- .Select(d => GetCompilationMessage(formatter, d))
- .ToList();
-
- return CompilationResult.Failed(fileInfo, compilationContent, messages);
+ return CompilationResult.Failed(compilationFailure);
}
Assembly assembly;
@@ -215,21 +216,25 @@ namespace Microsoft.AspNet.Mvc.Razor
return metadata.GetReference();
}
- private static CompilationMessage GetCompilationMessage(DiagnosticFormatter formatter, Diagnostic diagnostic)
- {
- var lineSpan = diagnostic.Location.GetMappedLineSpan();
- return new CompilationMessage(formatter.Format(diagnostic),
- startColumn: lineSpan.StartLinePosition.Character,
- startLine: lineSpan.StartLinePosition.Line,
- endColumn: lineSpan.EndLinePosition.Character,
- endLine: lineSpan.EndLinePosition.Line);
- }
-
private static bool IsError(Diagnostic diagnostic)
{
return diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error;
}
-
+ private static string ReadFileContentsSafely(IFileInfo fileInfo)
+ {
+ try
+ {
+ using (var reader = new StreamReader(fileInfo.CreateReadStream()))
+ {
+ return reader.ReadToEnd();
+ }
+ }
+ catch
+ {
+ // Ignore any failures
+ return null;
+ }
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
index c6e9045f13..692a9fc7b4 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
@@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
///
- /// Error compiling page at '{0}'.
+ /// One or more compilation failures occured:
///
internal static string CompilationFailed
{
@@ -35,11 +35,11 @@ namespace Microsoft.AspNet.Mvc.Razor
}
///
- /// Error compiling page at '{0}'.
+ /// One or more compilation failures occured:
///
- internal static string FormatCompilationFailed(object p0)
+ internal static string FormatCompilationFailed()
{
- return string.Format(CultureInfo.CurrentCulture, GetString("CompilationFailed"), p0);
+ return GetString("CompilationFailed");
}
///
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Razor/RazorCompilationService.cs b/src/Microsoft.AspNet.Mvc.Razor/Razor/RazorCompilationService.cs
index 556541c182..526a89e74f 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Razor/RazorCompilationService.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Razor/RazorCompilationService.cs
@@ -1,7 +1,9 @@
// 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.IO;
using System.Linq;
+using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Razor;
using Microsoft.Framework.Internal;
@@ -35,16 +37,32 @@ namespace Microsoft.AspNet.Mvc.Razor
if (!results.Success)
{
var messages = results.ParserErrors
- .Select(parseError =>
- new CompilationMessage(parseError.Message,
- parseError.Location.CharacterIndex,
- parseError.Location.LineIndex,
- parseError.Location.CharacterIndex + parseError.Length,
- parseError.Location.LineIndex));
- return CompilationResult.Failed(file.FileInfo, results.GeneratedCode, messages);
+ .Select(parseError => new RazorCompilationMessage(parseError, file.RelativePath));
+ var failure = new RazorCompilationFailure(
+ file.RelativePath,
+ ReadFileContentsSafely(file.FileInfo),
+ messages);
+
+ return CompilationResult.Failed(failure);
}
- return _compilationService.Compile(file.FileInfo, results.GeneratedCode);
+ return _compilationService.Compile(file, results.GeneratedCode);
+ }
+
+ private static string ReadFileContentsSafely(IFileInfo fileInfo)
+ {
+ try
+ {
+ using (var reader = new StreamReader(fileInfo.CreateReadStream()))
+ {
+ return reader.ReadToEnd();
+ }
+ }
+ catch
+ {
+ // Ignore any failures
+ return null;
+ }
}
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
index 5aaf28b864..4085f8eda8 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
@@ -121,7 +121,7 @@
Value cannot be null or empty.
- Error compiling page at '{0}'.
+ One or more compilation failures occured:
'{0}' cannot be invoked when a Layout page is set to be executed.
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilationResultTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilationResultTest.cs
index c3e36d28e2..d318326a91 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilationResultTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilationResultTest.cs
@@ -1,9 +1,7 @@
// 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.IO;
-using System.Text;
-using Microsoft.AspNet.FileProviders;
+using Microsoft.Framework.Runtime;
using Moq;
using Xunit;
@@ -12,32 +10,18 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
public class CompilationResultTest
{
[Fact]
- public void FailedResult_ThrowsWhenAccessingCompiledType()
+ public void EnsureSuccessful_ThrowsIfCompilationFailed()
{
// Arrange
- var expected = @"Error compiling page at 'myfile'.";
- var originalContent = "Original file content";
- var fileInfo = new Mock();
- 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", 1, 1, 2, 2),
- new CompilationMessage("world", 3, 3, 4, 3)
- };
- var result = CompilationResult.Failed(fileInfo.Object,
- "hello world
",
- messages);
+ var compilationFailure = Mock.Of();
+ var result = CompilationResult.Failed(compilationFailure);
// Act and Assert
- var ex = Assert.Throws(() => result.CompiledType);
- Assert.Equal(expected, ex.Message);
- var compilationFailure = Assert.Single(ex.CompilationFailures);
- Assert.Equal(originalContent, compilationFailure.SourceFileContent);
- Assert.Equal(messages, compilationFailure.Messages);
+ Assert.Null(result.CompiledType);
+ Assert.Same(compilationFailure, result.CompilationFailure);
+ var exception = Assert.Throws(() => result.EnsureSuccessful());
+ Assert.Collection(exception.CompilationFailures,
+ failure => Assert.Same(compilationFailure, failure));
}
}
}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilerCacheTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilerCacheTest.cs
index 00ba6b46b5..cd0025956b 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilerCacheTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/CompilerCacheTest.cs
@@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Mvc.Razor
// Assert
Assert.NotSame(CompilerCacheResult.FileNotFound, result);
- var actual = result.CompilationResult;
+ var actual = Assert.IsType(result.CompilationResult);
Assert.NotNull(actual);
Assert.Same(expected, actual);
Assert.Equal("hello world", actual.CompiledContent);
@@ -541,23 +541,18 @@ namespace Microsoft.AspNet.Mvc.Razor
// Act
cache.GetOrAdd("test", _ => uncachedResult);
- var result1 = cache.GetOrAdd("test", _ => uncachedResult);
- var result2 = cache.GetOrAdd("test", _ => uncachedResult);
+ var result1 = cache.GetOrAdd("test", _ => { throw new Exception("shouldn't be called."); });
+ var result2 = cache.GetOrAdd("test", _ => { throw new Exception("shouldn't be called."); });
// Assert
Assert.NotSame(CompilerCacheResult.FileNotFound, result1);
Assert.NotSame(CompilerCacheResult.FileNotFound, result2);
- var actual1 = result1.CompilationResult;
- var actual2 = result2.CompilationResult;
+ var actual1 = Assert.IsType(result1.CompilationResult);
+ var actual2 = Assert.IsType(result2.CompilationResult);
Assert.NotSame(uncachedResult, actual1);
Assert.NotSame(uncachedResult, actual2);
- var result = Assert.IsType(actual1);
- Assert.Null(actual1.CompiledContent);
Assert.Same(type, actual1.CompiledType);
-
- result = Assert.IsType(actual2);
- Assert.Null(actual2.CompiledContent);
Assert.Same(type, actual2.CompiledType);
}
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RazorCompilationServiceTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RazorCompilationServiceTest.cs
index 35ea01eea7..5b2c57f8ab 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RazorCompilationServiceTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RazorCompilationServiceTest.cs
@@ -31,14 +31,14 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
fileInfo.Setup(f => f.PhysicalPath).Returns(viewPath);
fileInfo.Setup(f => f.CreateReadStream()).Returns(Stream.Null);
+ var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");
+
var compiler = new Mock();
- compiler.Setup(c => c.Compile(fileInfo.Object, It.IsAny()))
+ compiler.Setup(c => c.Compile(relativeFileInfo, It.IsAny()))
.Returns(CompilationResult.Successful(typeof(RazorCompilationServiceTest)));
var razorService = new RazorCompilationService(compiler.Object, host.Object);
- var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");
-
// Act
razorService.Compile(relativeFileInfo);
@@ -75,9 +75,8 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
var result = razorService.Compile(relativeFileInfo);
// Assert
- var ex = Assert.Throws(() => result.CompiledType);
- var failure = Assert.Single(ex.CompilationFailures);
- var message = Assert.Single(failure.Messages);
+ Assert.NotNull(result.CompilationFailure);
+ var message = Assert.Single(result.CompilationFailure.Messages);
Assert.Equal("some message", message.Message);
host.Verify();
}
@@ -100,13 +99,13 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
var fileInfo = new Mock();
fileInfo.Setup(f => f.CreateReadStream())
.Returns(Stream.Null);
+ var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");
var compilationResult = CompilationResult.Successful(typeof(object));
var compiler = new Mock();
- compiler.Setup(c => c.Compile(fileInfo.Object, code))
+ compiler.Setup(c => c.Compile(relativeFileInfo, code))
.Returns(compilationResult)
.Verifiable();
- var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");
var razorService = new RazorCompilationService(compiler.Object, host.Object);
// Act
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RoslynCompilationServiceTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RoslynCompilationServiceTest.cs
index 42d078886d..0bf11f625d 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RoslynCompilationServiceTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/RoslynCompilationServiceTest.cs
@@ -5,6 +5,7 @@ using System;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
+using Microsoft.AspNet.FileProviders;
using Microsoft.Framework.Runtime;
using Moq;
using Xunit;
@@ -37,14 +38,126 @@ public class MyTestType {}";
libraryManager,
compilerOptionsProvider.Object,
mvcRazorHost.Object);
+ var relativeFileInfo = new RelativeFileInfo(new TestFileInfo { PhysicalPath = "SomePath" },
+ "some-relative-path");
// Act
- var result = compilationService.Compile(new TestFileInfo { PhysicalPath = "SomePath" }, content);
+ var result = compilationService.Compile(relativeFileInfo, content);
// Assert
var uncachedResult = Assert.IsType(result);
Assert.Equal("MyTestType", result.CompiledType.Name);
- Assert.Equal(content, result.CompiledContent);
+ Assert.Equal(content, uncachedResult.CompiledContent);
+ }
+
+ [Fact]
+ public void Compile_ReturnsCompilationFailureWithRelativePath()
+ {
+ // Arrange
+ var fileContent = "test file content";
+ var content = @"this should fail";
+ var applicationEnvironment = GetApplicationEnvironment();
+ var accessor = GetLoadContextAccessor();
+ var libraryManager = GetLibraryManager();
+
+ var compilerOptionsProvider = new Mock();
+ compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationBasePath,
+ applicationEnvironment.RuntimeFramework,
+ applicationEnvironment.Configuration))
+ .Returns(new CompilerOptions());
+ var mvcRazorHost = Mock.Of();
+
+ var compilationService = new RoslynCompilationService(applicationEnvironment,
+ accessor,
+ libraryManager,
+ compilerOptionsProvider.Object,
+ mvcRazorHost);
+ var fileInfo = new TestFileInfo
+ {
+ Content = fileContent,
+ PhysicalPath = "physical path"
+ };
+ var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path");
+
+ // Act
+ var result = compilationService.Compile(relativeFileInfo, content);
+
+ // Assert
+ Assert.IsType(result);
+ Assert.Null(result.CompiledType);
+ Assert.Equal(relativeFileInfo.RelativePath, result.CompilationFailure.SourceFilePath);
+ Assert.Equal(fileContent, result.CompilationFailure.SourceFileContent);
+ }
+
+ [Fact]
+ public void Compile_ReturnsApplicationRelativePath_IfPhyicalPathIsNotSpecified()
+ {
+ // Arrange
+ var fileContent = "file content";
+ var content = @"this should fail";
+ var applicationEnvironment = GetApplicationEnvironment();
+ var accessor = GetLoadContextAccessor();
+ var libraryManager = GetLibraryManager();
+
+ var compilerOptionsProvider = new Mock();
+ compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationBasePath,
+ applicationEnvironment.RuntimeFramework,
+ applicationEnvironment.Configuration))
+ .Returns(new CompilerOptions());
+ var mvcRazorHost = Mock.Of();
+
+ var compilationService = new RoslynCompilationService(applicationEnvironment,
+ accessor,
+ libraryManager,
+ compilerOptionsProvider.Object,
+ mvcRazorHost);
+ var relativeFileInfo = new RelativeFileInfo(new TestFileInfo { Content = fileContent },
+ "some-relative-path");
+
+ // Act
+ var result = compilationService.Compile(relativeFileInfo, content);
+
+ // Assert
+ Assert.IsType(result);
+ Assert.Null(result.CompiledType);
+ Assert.Equal("some-relative-path", result.CompilationFailure.SourceFilePath);
+ Assert.Equal(fileContent, result.CompilationFailure.SourceFileContent);
+ }
+
+ [Fact]
+ public void Compile_DoesNotThrow_IfFileCannotBeRead()
+ {
+ // Arrange
+ var content = @"this should fail";
+ var applicationEnvironment = GetApplicationEnvironment();
+ var accessor = GetLoadContextAccessor();
+ var libraryManager = GetLibraryManager();
+
+ var compilerOptionsProvider = new Mock();
+ compilerOptionsProvider.Setup(p => p.GetCompilerOptions(applicationEnvironment.ApplicationBasePath,
+ applicationEnvironment.RuntimeFramework,
+ applicationEnvironment.Configuration))
+ .Returns(new CompilerOptions());
+ var mvcRazorHost = Mock.Of();
+
+ var compilationService = new RoslynCompilationService(applicationEnvironment,
+ accessor,
+ libraryManager,
+ compilerOptionsProvider.Object,
+ mvcRazorHost);
+ var mockFileInfo = new Mock();
+ mockFileInfo.Setup(f => f.CreateReadStream())
+ .Throws(new Exception());
+ var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, "some-relative-path");
+
+ // Act
+ var result = compilationService.Compile(relativeFileInfo, content);
+
+ // Assert
+ Assert.IsType(result);
+ Assert.Null(result.CompiledType);
+ Assert.Equal("some-relative-path", result.CompilationFailure.SourceFilePath);
+ Assert.Null(result.CompilationFailure.SourceFileContent);
}
[Fact]
@@ -76,9 +189,11 @@ public class MyNonCustomDefinedClass {}
libraryManager,
compilerOptionsProvider.Object,
mvcRazorHost.Object);
+ var relativeFileInfo = new RelativeFileInfo(new TestFileInfo { PhysicalPath = "SomePath" },
+ "some-relative-path");
// Act
- var result = compilationService.Compile(new TestFileInfo { PhysicalPath = "SomePath" }, content);
+ var result = compilationService.Compile(relativeFileInfo, content);
// Assert
Assert.NotNull(result.CompiledType);
@@ -111,8 +226,11 @@ public class NotRazorPrefixType {}";
compilerOptionsProvider.Object,
mvcRazorHost.Object);
+ var relativeFileInfo = new RelativeFileInfo(new TestFileInfo { PhysicalPath = "SomePath" },
+ "some-relative-path");
+
// Act
- var result = compilationService.Compile(new TestFileInfo { PhysicalPath = "SomePath" }, content);
+ var result = compilationService.Compile(relativeFileInfo, content);
// Assert
Assert.NotNull(result.CompiledType);