public void GetOrAdd_ReturnsNewResultIfFileWasModified() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var expected1 = UncachedCompilationResult.Successful(typeof(TestView), "hello world"); var expected2 = UncachedCompilationResult.Successful(typeof(DifferentView), "different content"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected1); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected1, result1.CompilationResult); // Act 2 // Verify we're getting cached results. var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.Same(expected1.CompiledType, result2.CompilationResult.CompiledType); // Act 3 fileProvider.GetTrigger(ViewPath).IsExpired = true; var result3 = cache.GetOrAdd(ViewPath, _ => expected2); // Assert 3 Assert.NotSame(CompilerCacheResult.FileNotFound, result3); Assert.Same(expected2, result3.CompilationResult); }
public void GetOrAdd_NormalizesPathSepartorForPaths(string relativePath) { // Arrange var viewPath = "/Areas/Finances/Views/Home/Index.cshtml"; var fileProvider = new TestFileProvider(); fileProvider.AddFile(viewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act - 1 var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected); // Assert - 1 var compilationResult = Assert.IsType <UncachedCompilationResult>(result1.CompilationResult); Assert.Same(expected, compilationResult); Assert.Same(type, compilationResult.CompiledType); // Act - 2 var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled); // Assert - 2 Assert.Same(type, result2.CompilationResult.CompiledType); }
public void GetOrAdd_ReturnsFileNotFoundIfFileWasDeleted() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected, result1.CompilationResult); // Act 2 // Delete the file from the file system and set it's expiration trigger. fileProvider.DeleteFile(ViewPath); fileProvider.GetTrigger(ViewPath).IsExpired = true; var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.Same(CompilerCacheResult.FileNotFound, result2); Assert.Null(result2.CompilationResult); }
public void GetOrAdd_DoesNotQueryFileSystem_IfCachedFileTriggerWasNotSet() { // Arrange var mockFileProvider = new Mock <TestFileProvider> { CallBase = true }; var fileProvider = mockFileProvider.Object; fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected, result1.CompilationResult); // Act 2 var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.IsType <CompilationResult>(result2.CompilationResult); Assert.Same(type, result2.CompilationResult.CompiledType); mockFileProvider.Verify(v => v.GetFileInfo(ViewPath), Times.Once()); }
public void GetOrAdd_ReturnsFileNotFoundIfFileWasDeleted() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected, result1.CompilationResult); // Act 2 // Delete the file from the file system and set it's expiration token. fileProvider.DeleteFile(ViewPath); fileProvider.GetChangeToken(ViewPath).HasChanged = true; var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.Same(CompilerCacheResult.FileNotFound, result2); Assert.Null(result2.CompilationResult); }
public void GetOrAdd_ReturnsNewResult_IfAncestorViewImportsWereModified(string globalImportPath) { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(fileProvider); var expected1 = UncachedCompilationResult.Successful(typeof(TestView), "hello world"); var expected2 = UncachedCompilationResult.Successful(typeof(DifferentView), "different content"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected1); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected1, result1.CompilationResult); // Act 2 // Verify we're getting cached results. var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.Same(expected1.CompiledType, result2.CompilationResult.CompiledType); // Act 3 fileProvider.GetChangeToken(globalImportPath).HasChanged = true; var result3 = cache.GetOrAdd(ViewPath, _ => expected2); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result3); Assert.Same(expected2, result3.CompilationResult); }
public void GetOrAdd_ReturnsNewResultIfFileWasModified() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = typeof(RuntimeCompileIdentical); var expected1 = UncachedCompilationResult.Successful(type, "hello world"); var expected2 = UncachedCompilationResult.Successful(type, "different content"); // Act 1 var result1 = cache.GetOrAdd(ViewPath, _ => expected1); // Assert 1 Assert.NotSame(CompilerCacheResult.FileNotFound, result1); Assert.Same(expected1, result1.CompilationResult); // Act 2 fileProvider.GetTrigger(ViewPath).IsExpired = true; var result2 = cache.GetOrAdd(ViewPath, _ => expected2); // Assert 2 Assert.NotSame(CompilerCacheResult.FileNotFound, result2); Assert.Same(expected2, result2.CompilationResult); }
public void GetOrAdd_DoesNotCacheCompiledContent_OnCallsAfterInitial() { // Arrange var lastModified = DateTime.UtcNow; var fileProvider = new TestFileProvider(); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var fileInfo = new TestFileInfo { PhysicalPath = "test", LastModified = lastModified }; fileProvider.AddFile("test", fileInfo); var type = GetType(); var uncachedResult = UncachedCompilationResult.Successful(type, "hello world"); // Act 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 = Assert.IsType <CompilationResult>(result1.CompilationResult); var actual2 = Assert.IsType <CompilationResult>(result2.CompilationResult); Assert.NotSame(uncachedResult, actual1); Assert.NotSame(uncachedResult, actual2); Assert.Same(type, actual1.CompiledType); Assert.Same(type, actual2.CompiledType); }
public void GetOrAdd_ReturnsCompilationResultFromFactory() { // Arrange var fileProvider = new TestFileProvider(); fileProvider.AddFile(ViewPath, "some content"); var cache = new CompilerCache(Enumerable.Empty <RazorFileInfoCollection>(), TestLoadContext, fileProvider); var type = typeof(TestView); var expected = UncachedCompilationResult.Successful(type, "hello world"); // Act var result = cache.GetOrAdd(ViewPath, _ => expected); // Assert Assert.NotSame(CompilerCacheResult.FileNotFound, result); var actual = Assert.IsType <UncachedCompilationResult>(result.CompilationResult); Assert.NotNull(actual); Assert.Same(expected, actual); Assert.Equal("hello world", actual.CompiledContent); Assert.Same(type, actual.CompiledType); }
/// <inheritdoc /> public CompilationResult Compile(IFileInfo fileInfo, string compilationContent) { var sourceText = SourceText.From(compilationContent, Encoding.UTF8); var syntaxTrees = new[] { CSharpSyntaxTree.ParseText(sourceText, path: fileInfo.PhysicalPath) }; var references = _applicationReferences.Value; var assemblyName = Path.GetRandomFileName(); var compilation = CSharpCompilation.Create(assemblyName, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary), syntaxTrees: syntaxTrees, references: references); using (var ms = new MemoryStream()) { using (var pdb = new MemoryStream()) { EmitResult result; if (PlatformHelper.IsMono) { result = compilation.Emit(ms, pdbStream: null); } else { result = compilation.Emit(ms, pdbStream: pdb); } if (!result.Success) { var formatter = new DiagnosticFormatter(); var messages = result.Diagnostics .Where(IsError) .Select(d => GetCompilationMessage(formatter, d)) .ToList(); return(CompilationResult.Failed(fileInfo, compilationContent, messages)); } Assembly assembly; ms.Seek(0, SeekOrigin.Begin); if (PlatformHelper.IsMono) { assembly = _loader.LoadStream(ms, pdbStream: null); } else { pdb.Seek(0, SeekOrigin.Begin); assembly = _loader.LoadStream(ms, pdb); } var type = assembly.GetExportedTypes() .First(); return(UncachedCompilationResult.Successful(type, compilationContent)); } } }
/// <inheritdoc /> public CompilationResult Compile([NotNull] RelativeFileInfo fileInfo, [NotNull] string compilationContent) { var assemblyName = Path.GetRandomFileName(); var compilationSettings = _compilerOptionsProvider.GetCompilationSettings(_environment); var syntaxTree = SyntaxTreeGenerator.Generate(compilationContent, assemblyName, compilationSettings); var references = _applicationReferences.Value; var compilationOptions = compilationSettings.CompilationOptions .WithOutputKind(OutputKind.DynamicallyLinkedLibrary); var compilation = CSharpCompilation.Create(assemblyName, options: compilationOptions, syntaxTrees: new[] { syntaxTree }, references: references); using (var ms = new MemoryStream()) { using (var pdb = new MemoryStream()) { EmitResult result; if (_supportsPdbGeneration.Value) { result = compilation.Emit(ms, pdbStream: pdb); } else { result = compilation.Emit(ms); } if (!result.Success) { return(GetCompilationFailedResult( fileInfo.RelativePath, compilationContent, assemblyName, result.Diagnostics)); } Assembly assembly; ms.Seek(0, SeekOrigin.Begin); if (_supportsPdbGeneration.Value) { pdb.Seek(0, SeekOrigin.Begin); assembly = _loader.LoadStream(ms, pdb); } else { assembly = _loader.LoadStream(ms, assemblySymbols: null); } var type = assembly.GetExportedTypes() .First(t => t.Name.StartsWith(_classPrefix, StringComparison.Ordinal)); return(UncachedCompilationResult.Successful(type, compilationContent)); } } }
/// <inheritdoc /> public CompilationResult Compile(IFileInfo fileInfo, string compilationContent) { var syntaxTrees = new[] { SyntaxTreeGenerator.Generate(compilationContent, fileInfo.PhysicalPath) }; var references = _applicationReferences.Value; var assemblyName = Path.GetRandomFileName(); var compilation = CSharpCompilation.Create(assemblyName, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary), syntaxTrees: syntaxTrees, references: references); using (var ms = new MemoryStream()) { using (var pdb = new MemoryStream()) { EmitResult result; if (_supportsPdbGeneration.Value) { result = compilation.Emit(ms, pdbStream: pdb); } else { result = compilation.Emit(ms); } if (!result.Success) { var formatter = new DiagnosticFormatter(); var messages = result.Diagnostics .Where(IsError) .Select(d => GetCompilationMessage(formatter, d)) .ToList(); return(CompilationResult.Failed(fileInfo, compilationContent, messages)); } Assembly assembly; ms.Seek(0, SeekOrigin.Begin); if (_supportsPdbGeneration.Value) { pdb.Seek(0, SeekOrigin.Begin); assembly = _loader.LoadStream(ms, pdb); } else { assembly = _loader.LoadStream(ms, assemblySymbols: null); } var type = assembly.GetExportedTypes() .First(t => t.Name. StartsWith(_classPrefix, StringComparison.Ordinal)); return(UncachedCompilationResult.Successful(type)); } } }