Example #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="CompilerCacheResult"/> with the specified
        /// <see cref="CompilationResult"/>.
        /// </summary>
        /// <param name="compilationResult">The <see cref="Compilation.CompilationResult"/> </param>
        public CompilerCacheResult(CompilationResult compilationResult)
        {
            if (compilationResult == null)
            {
                throw new ArgumentNullException(nameof(compilationResult));
            }

            CompilationResult = compilationResult;
        }
        /// <summary>
        /// Initializes a new instance of <see cref="CompilerCacheResult"/> with the specified
        /// <see cref="Compilation.CompilationResult"/>.
        /// </summary>
        /// <param name="compilationResult">The <see cref="Compilation.CompilationResult"/>.</param>
        /// <param name="expirationTokens">One or more <see cref="IChangeToken"/> instances that indicate when
        /// this result has expired.</param>
        public CompilerCacheResult(CompilationResult compilationResult, IList<IChangeToken> expirationTokens)
        {
            if (expirationTokens == null)
            {
                throw new ArgumentNullException(nameof(expirationTokens));
            }

            CompilationResult = compilationResult;
            Success = true;
            ExpirationTokens = expirationTokens;
        }
Example #3
0
        public void GetOrAdd_ReturnsCompilationResultFromFactory()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);
            var type = typeof(TestView);
            var expected = new CompilationResult(type);

            // Act
            var result = cache.GetOrAdd(ViewPath, _ => expected);

            // Assert
            Assert.True(result.Success);
            Assert.Same(type, result.CompilationResult.CompiledType);
        }
        public void EnsureSuccessful_ThrowsIfCompilationFailed()
        {
            // Arrange
            var compilationFailure = new CompilationFailure(
                "test",
                sourceFileContent: string.Empty,
                compiledContent: string.Empty,
                messages: Enumerable.Empty<AspNet.Diagnostics.DiagnosticMessage>());
            var failures = new[] { compilationFailure };
            var result = new CompilationResult(failures);

            // Act and Assert
            Assert.Null(result.CompiledType);
            Assert.Same(failures, result.CompilationFailures);
            var exception = Assert.Throws<CompilationFailedException>(() => result.EnsureSuccessful());
            var failure = Assert.Single(exception.CompilationFailures);
            Assert.Same(compilationFailure, failure);
        }
Example #5
0
        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 = new CompilationResult(type);

            // Act - 1
            var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected);

            // Assert - 1
            Assert.Same(type, result1.CompilationResult.CompiledType);

            // Act - 2
            var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled);

            // Assert - 2
            Assert.Same(type, result2.CompilationResult.CompiledType);
        }
Example #6
0
        // Internal for unit testing
        internal CompilationResult GetCompilationFailedResult(
            string relativePath,
            string compilationContent,
            string assemblyName,
            IEnumerable <Diagnostic> diagnostics)
        {
            var diagnosticGroups = diagnostics
                                   .Where(IsError)
                                   .GroupBy(diagnostic => GetFilePath(relativePath, diagnostic), StringComparer.Ordinal);

            var failures = new List <ICompilationFailure>();

            foreach (var group in diagnosticGroups)
            {
                var    sourceFilePath = group.Key;
                string sourceFileContent;
                if (string.Equals(assemblyName, sourceFilePath, StringComparison.Ordinal))
                {
                    // The error is in the generated code and does not have a mapping line pragma
                    sourceFileContent = compilationContent;
                    sourceFilePath    = Resources.GeneratedCodeFileName;
                }
                else
                {
                    sourceFileContent = ReadFileContentsSafely(_fileProvider, sourceFilePath);
                }

                var compilationFailure = new RoslynCompilationFailure(group)
                {
                    CompiledContent   = compilationContent,
                    SourceFileContent = sourceFileContent,
                    SourceFilePath    = sourceFilePath
                };

                failures.Add(compilationFailure);
            }

            return(CompilationResult.Failed(failures));
        }
Example #7
0
        public void Compile_ReturnsResultFromCompilationServiceIfParseSucceeds()
        {
            // Arrange
            var code            = "compiled-content";
            var generatorResult = new GeneratorResults(
                new Block(new BlockBuilder {
                Type = BlockType.Comment
            }),
                Enumerable.Empty <TagHelperDescriptor>(),
                new ErrorSink(),
                new CodeGeneratorResult(code, new LineMapping[0]),
                new ChunkTree());
            var host = new Mock <IMvcRazorHost>();

            host.Setup(h => h.GenerateCode(It.IsAny <string>(), It.IsAny <Stream>()))
            .Returns(generatorResult);

            var fileInfo = new Mock <IFileInfo>();

            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 <ICompilationService>();

            compiler.Setup(c => c.Compile(relativeFileInfo, code))
            .Returns(compilationResult)
            .Verifiable();
            var razorService = new RazorCompilationService(compiler.Object, host.Object, GetOptions());

            // Act
            var result = razorService.Compile(relativeFileInfo);

            // Assert
            Assert.Same(compilationResult, result);
            compiler.Verify();
        }
Example #8
0
        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 = new CompilationResult(type);

            // Act - 1
            var result1 = cache.GetOrAdd(@"Areas\Finances\Views\Home\Index.cshtml", _ => expected);

            // Assert - 1
            Assert.Same(type, result1.CompilationResult.CompiledType);

            // Act - 2
            var result2 = cache.GetOrAdd(relativePath, ThrowsIfCalled);

            // Assert - 2
            Assert.Same(type, result2.CompilationResult.CompiledType);
        }
Example #9
0
        // Internal for unit testing
        internal CompilationResult GetCompilationFailedResult(RelativeFileInfo file, IEnumerable <RazorError> errors)
        {
            // If a SourceLocation does not specify a file path, assume it is produced
            // from parsing the current file.
            var messageGroups = errors
                                .GroupBy(razorError =>
                                         razorError.Location.FilePath ?? file.RelativePath,
                                         StringComparer.Ordinal);

            var failures = new List <RazorCompilationFailure>();

            foreach (var group in messageGroups)
            {
                var filePath           = group.Key;
                var fileContent        = ReadFileContentsSafely(filePath);
                var compilationFailure = new RazorCompilationFailure(
                    filePath,
                    fileContent,
                    group.Select(parserError => new RazorCompilationMessage(parserError, filePath)));
                failures.Add(compilationFailure);
            }

            return(CompilationResult.Failed(failures));
        }
 /// <summary>
 /// Initializes a new instance of <see cref="CompilerCacheResult"/> with the specified
 /// <see cref="Compilation.CompilationResult"/>.
 /// </summary>
 /// <param name="compilationResult">The <see cref="Compilation.CompilationResult"/>.</param>
 public CompilerCacheResult(CompilationResult compilationResult)
     : this(compilationResult, new IChangeToken[0])
 {
 }
Example #11
0
        /// <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));
                }
            }
        }
Example #12
0
        /// <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));
                }
            }
        }
Example #13
0
        private GetOrAddResult GetOrAddCore(string relativePath,
                                            Func <RelativeFileInfo, CompilationResult> compile)
        {
            var normalizedPath = NormalizePath(relativePath);
            var cacheEntry     = _cache.Get <CompilerCacheEntry>(normalizedPath);

            if (cacheEntry == null)
            {
                var fileInfo = _fileProvider.GetFileInfo(relativePath);
                if (!fileInfo.Exists)
                {
                    return(null);
                }

                var relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath);
                return(OnCacheMiss(relativeFileInfo, normalizedPath, compile));
            }
            else if (cacheEntry.IsPreCompiled && !cacheEntry.IsValidatedPreCompiled)
            {
                // For precompiled views, the first time the entry is read, we need to ensure that no changes were made
                // either to the file associated with this entry, or any _ViewImports associated with it between the time
                // the View was precompiled and the time EnsureInitialized was called. For later iterations, we can
                // rely on expiration triggers ensuring the validity of the entry.

                var fileInfo = _fileProvider.GetFileInfo(relativePath);
                if (!fileInfo.Exists)
                {
                    return(null);
                }

                var relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath);
                if (cacheEntry.Length != fileInfo.Length)
                {
                    // Recompile if the file lengths differ
                    return(OnCacheMiss(relativeFileInfo, normalizedPath, compile));
                }

                if (AssociatedGlobalFilesChanged(cacheEntry, compile))
                {
                    // Recompile if _ViewImports have changed since the entry was created.
                    return(OnCacheMiss(relativeFileInfo, normalizedPath, compile));
                }

                if (cacheEntry.LastModified == fileInfo.LastModified)
                {
                    // Assigning to IsValidatedPreCompiled is an atomic operation and will result in a safe race
                    // if it is being concurrently updated and read.
                    cacheEntry.IsValidatedPreCompiled = true;
                    return(new GetOrAddResult
                    {
                        CompilationResult = CompilationResult.Successful(cacheEntry.CompiledType),
                        CompilerCacheEntry = cacheEntry
                    });
                }

                // Timestamp doesn't match but it might be because of deployment, compare the hash.
                if (cacheEntry.IsPreCompiled &&
                    string.Equals(cacheEntry.Hash,
                                  RazorFileHash.GetHash(fileInfo, cacheEntry.HashAlgorithmVersion),
                                  StringComparison.Ordinal))
                {
                    // Cache hit, but we need to update the entry.
                    // Assigning to LastModified and IsValidatedPreCompiled are atomic operations and will result in safe race
                    // if the entry is being concurrently read or updated.
                    cacheEntry.LastModified           = fileInfo.LastModified;
                    cacheEntry.IsValidatedPreCompiled = true;
                    return(new GetOrAddResult
                    {
                        CompilationResult = CompilationResult.Successful(cacheEntry.CompiledType),
                        CompilerCacheEntry = cacheEntry
                    });
                }

                // it's not a match, recompile
                return(OnCacheMiss(relativeFileInfo, normalizedPath, compile));
            }

            return(new GetOrAddResult
            {
                CompilationResult = CompilationResult.Successful(cacheEntry.CompiledType),
                CompilerCacheEntry = cacheEntry
            });
        }
Example #14
0
        public void GetOrAdd_IgnoresCachedValueIfFileIsIdentical_ButGlobalWasDeletedSinceCacheWasCreated()
        {
            // Arrange
            var expectedType = typeof(RuntimeCompileDifferent);
            var lastModified = DateTime.UtcNow;
            var fileProvider = new TestFileProvider();

            var viewCollection  = new ViewCollection();
            var precompiledView = viewCollection.FileInfos[0];

            precompiledView.RelativePath = "Views\\Index.cshtml";
            var viewFileInfo = new TestFileInfo
            {
                Content      = new PreCompile().Content,
                LastModified = precompiledView.LastModified,
                PhysicalPath = precompiledView.RelativePath
            };

            fileProvider.AddFile(viewFileInfo.PhysicalPath, viewFileInfo);

            var globalFileInfo = new TestFileInfo
            {
                PhysicalPath = "Views\\_ViewImports.cshtml",
                Content      = "viewstart-content",
                LastModified = lastModified
            };
            var globalFile = new RazorFileInfo
            {
                FullTypeName         = typeof(RuntimeCompileIdentical).FullName,
                RelativePath         = globalFileInfo.PhysicalPath,
                LastModified         = globalFileInfo.LastModified,
                Hash                 = RazorFileHash.GetHash(globalFileInfo, hashAlgorithmVersion: 1),
                HashAlgorithmVersion = 1,
                Length               = globalFileInfo.Length
            };

            fileProvider.AddFile(globalFileInfo.PhysicalPath, globalFileInfo);

            viewCollection.Add(globalFile);
            var cache = new CompilerCache(new[] { viewCollection }, TestLoadContext, fileProvider);

            // Act 1
            var result1 = cache.GetOrAdd(viewFileInfo.PhysicalPath,
                                         compile: _ => { throw new Exception("should not be called"); });

            // Assert 1
            Assert.NotSame(CompilerCacheResult.FileNotFound, result1);
            var actual1 = result1.CompilationResult;

            Assert.NotNull(actual1);
            Assert.Equal(typeof(PreCompile), actual1.CompiledType);

            // Act 2
            var trigger = fileProvider.GetTrigger(globalFileInfo.PhysicalPath);

            trigger.IsExpired = true;
            var result2 = cache.GetOrAdd(viewFileInfo.PhysicalPath,
                                         compile: _ => CompilationResult.Successful(expectedType));

            // Assert 2
            Assert.NotSame(CompilerCacheResult.FileNotFound, result2);
            var actual2 = result2.CompilationResult;

            Assert.NotNull(actual2);
            Assert.Equal(expectedType, actual2.CompiledType);
        }
Example #15
0
 /// <summary>
 /// Initializes a new instance of <see cref="CompilerCacheResult"/> with the specified
 /// <see cref="CompilationResult"/>.
 /// </summary>
 /// <param name="compilationResult">The <see cref="Compilation.CompilationResult"/> </param>
 public CompilerCacheResult([NotNull] CompilationResult compilationResult)
 {
     CompilationResult = compilationResult;
 }
Example #16
0
        public void GetOrAdd_ReturnsNewResult_IfAncestorViewImportsWereModified(string globalImportPath)
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);
            var expected1 = new CompilationResult(typeof(TestView));
            var expected2 = new CompilationResult(typeof(DifferentView));

            // Act 1
            var result1 = cache.GetOrAdd(ViewPath, _ => expected1);

            // Assert 1
            Assert.True(result1.Success);
            Assert.Same(expected1.CompiledType, result1.CompilationResult.CompiledType);

            // Act 2
            // Verify we're getting cached results.
            var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled);

            // Assert 2
            Assert.True(result2.Success);
            Assert.Same(expected1.CompiledType, result2.CompilationResult.CompiledType);

            // Act 3
            fileProvider.GetChangeToken(globalImportPath).HasChanged = true;
            var result3 = cache.GetOrAdd(ViewPath, _ => expected2);

            // Assert 2
            Assert.True(result3.Success);
            Assert.Same(expected2.CompiledType, result3.CompilationResult.CompiledType);
        }
 /// <summary>
 /// Initializes a new instance of <see cref="CompilerCacheResult"/> with the specified
 /// <see cref="Compilation.CompilationResult"/>.
 /// </summary>
 /// <param name="compilationResult">The <see cref="Compilation.CompilationResult"/>.</param>
 public CompilerCacheResult(CompilationResult compilationResult)
     : this(compilationResult, new IChangeToken[0])
 {
 }
Example #18
0
        public CompilationResult Compile(string content)
        {
            var syntaxTrees     = new[] { CSharpSyntaxTree.ParseText(content) };
            var targetFramework = _environment.TargetFramework;

            var references = GetApplicationReferences();

            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(content, 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(CompilationResult.Successful(string.Empty, type));
                }
            }
        }
Example #19
0
        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(fileProvider);
            var type = typeof(TestView);
            var expected = new CompilationResult(type);

            // Act 1
            var result1 = cache.GetOrAdd(ViewPath, _ => expected);

            // Assert 1
            Assert.True(result1.Success);
            Assert.Same(type, result1.CompilationResult.CompiledType);

            // Act 2
            var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled);

            // Assert 2
            Assert.True(result2.Success);
            Assert.Same(type, result2.CompilationResult.CompiledType);
            mockFileProvider.Verify(v => v.GetFileInfo(ViewPath), Times.Once());
        }
        public void Compile_ReturnsResultFromCompilationServiceIfParseSucceeds()
        {
            // Arrange
            var code = "compiled-content";
            var generatorResult = new GeneratorResults(
                    new Block(new BlockBuilder { Type = BlockType.Comment }),
                    Enumerable.Empty<TagHelperDescriptor>(),
                    new ErrorSink(),
                    new CodeGeneratorResult(code, new LineMapping[0]),
                    new ChunkTree());
            var host = new Mock<IMvcRazorHost>();
            host.Setup(h => h.GenerateCode(It.IsAny<string>(), It.IsAny<Stream>()))
                .Returns(generatorResult);

            var fileInfo = new Mock<IFileInfo>();
            fileInfo.Setup(f => f.CreateReadStream())
                    .Returns(Stream.Null);
            var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");

            var compilationResult = new CompilationResult(typeof(object));
            var compiler = new Mock<ICompilationService>();
            compiler.Setup(c => c.Compile(relativeFileInfo, code))
                    .Returns(compilationResult)
                    .Verifiable();
            var razorService = new RazorCompilationService(compiler.Object, host.Object, GetFileProviderAccessor(), NullLoggerFactory.Instance);

            // Act
            var result = razorService.Compile(relativeFileInfo);

            // Assert
            Assert.Same(compilationResult.CompiledType, result.CompiledType);
            compiler.Verify();
        }
Example #21
0
        public void GetOrAdd_ReturnsFailedCompilationResult_IfFileWasRemovedFromFileSystem()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);
            var type = typeof(TestView);
            var expected = new CompilationResult(type);

            // Act 1
            var result1 = cache.GetOrAdd(ViewPath, _ => expected);

            // Assert 1
            Assert.True(result1.Success);
            Assert.Same(expected.CompiledType, result1.CompilationResult.CompiledType);

            // 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.False(result2.Success);
        }
Example #22
0
        public void GetOrAdd_ReturnsRuntimeCompiledAndPrecompiledViews()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider, _precompiledViews);
            var expected = new CompilationResult(typeof(TestView));

            // Act 1
            var result1 = cache.GetOrAdd(ViewPath, _ => expected);

            // Assert 1
            Assert.Same(typeof(TestView), result1.CompilationResult.CompiledType);

            // Act 2
            var result2 = cache.GetOrAdd(ViewPath, ThrowsIfCalled);

            // Assert 2
            Assert.True(result2.Success);
            Assert.Same(typeof(TestView), result2.CompilationResult.CompiledType);

            // Act 3
            var result3 = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert 3
            Assert.True(result2.Success);
            Assert.Same(typeof(PreCompile), result3.CompilationResult.CompiledType);
        }
Example #23
0
        public void GetOrAdd_CachesExceptionsInCompilationResult()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);
            var diagnosticMessages = new[]
            {
                new AspNet.Diagnostics.DiagnosticMessage("message", "message", ViewPath, 1, 1, 1, 1)
            };
            var compilationResult = new CompilationResult(new[]
            {
                new CompilationFailure(ViewPath, "some content", "compiled content", diagnosticMessages)
            });

            // Act and Assert - 1
            var ex = Assert.Throws<CompilationFailedException>(() => cache.GetOrAdd(ViewPath, _ => compilationResult));
            Assert.Same(compilationResult.CompilationFailures, ex.CompilationFailures);

            // Act and Assert - 2
            ex = Assert.Throws<CompilationFailedException>(() => cache.GetOrAdd(ViewPath, ThrowsIfCalled));
            Assert.Same(compilationResult.CompilationFailures, ex.CompilationFailures);
        }