public void GetOrAdd_UpdatesCache_IfFileExpirationTriggerExpires()
        {
            // Arrange
            var path = @"Views\Home\_ViewStart.cshtml";
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(path, "test content");
            using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider))
            {
                var expected1 = new ChunkTree();
                var expected2 = new ChunkTree();

                // Act 1
                var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => expected1);

                // Assert 1
                Assert.Same(expected1, result1);

                // Act 2
                fileProvider.GetChangeToken(path).HasChanged = true;
                var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected2);

                // Assert 2
                Assert.Same(expected2, result2);
            }
        }
Пример #2
0
        public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForViewImports(string globalImportPath)
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var cache        = new CompilerCache(fileProvider, _precompiledViews);

            // Act
            fileProvider.Watch(globalImportPath);
            fileProvider.GetChangeToken(globalImportPath).HasChanged = true;
            var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert
            Assert.True(result.Success);
            Assert.IsType <PreCompile>(result.PageFactory());
        }
Пример #3
0
        public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForPrecompiledFile()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var cache        = new CompilerCache(fileProvider, _precompiledViews);

            // Act
            fileProvider.Watch(PrecompiledViewsPath);
            fileProvider.GetChangeToken(PrecompiledViewsPath).HasChanged = true;
            var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert
            Assert.NotSame(CompilerCacheResult.FileNotFound, result);
            Assert.Same(typeof(PreCompile), result.CompilationResult.CompiledType);
        }
        public void GetChangeToken_WatchesViewImportsOutsidePagesRoot_WhenAreaFeatureIsDisabled()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var accessor     = Mock.Of <IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

            var templateEngine = new RazorTemplateEngine(
                RazorEngine.Create(),
                new FileProviderRazorProject(accessor));

            templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
            var options = Options.Create(new RazorPagesOptions {
                AllowAreas = false
            });

            var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);

            // Act & Assert
            var compositeChangeToken = Assert.IsType <CompositeChangeToken>(changeProvider.GetChangeToken());

            Assert.Collection(compositeChangeToken.ChangeTokens,
                              changeToken => Assert.Same(fileProvider.GetChangeToken("/_ViewImports.cshtml"), changeToken),
                              changeToken => Assert.Same(fileProvider.GetChangeToken("/Pages/**/*.cshtml"), changeToken));
        }
Пример #5
0
        public async Task CompileAsync_ReturnsResultWithNullAttribute_IfFileIsNotFoundInFileSystem()
        {
            // Arrange
            var path         = "/file/does-not-exist";
            var fileProvider = new TestFileProvider();
            var viewCompiler = GetViewCompiler(fileProvider);

            // Act
            var result1 = await viewCompiler.CompileAsync(path);

            var result2 = await viewCompiler.CompileAsync(path);

            // Assert
            Assert.Same(result1, result2);
            Assert.Null(result1.ViewAttribute);
            Assert.Collection(result1.ExpirationTokens,
                              token => Assert.Equal(fileProvider.GetChangeToken(path), token));
        }
Пример #6
0
        public void GetOrAdd_ReturnsSuccessfulCompilationResultIfTriggerExpires()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);

            // Act and Assert - 1
            Assert.Throws <InvalidTimeZoneException>(() =>
                                                     cache.GetOrAdd(ViewPath, _ => { throw new InvalidTimeZoneException(); }));

            // Act - 2
            fileProvider.GetChangeToken(ViewPath).HasChanged = true;
            var result = cache.GetOrAdd(ViewPath, _ => new CompilationResult(typeof(TestView)));

            // Assert - 2
            Assert.Same(typeof(TestView), result.CompilationResult.CompiledType);
        }
Пример #7
0
        public async Task CompileAsync_DoesNotRecompile_IfFileTriggerWasSetForPrecompiledView()
        {
            // Arrange
            var path            = "/Views/Home/Index.cshtml";
            var fileProvider    = new TestFileProvider();
            var fileInfo        = fileProvider.AddFile(path, "some content");
            var precompiledView = new CompiledViewDescriptor
            {
                RelativePath = path,
            };
            var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView });

            // Act
            fileProvider.Watch(path);
            fileProvider.GetChangeToken(path).HasChanged = true;
            var result = await viewCompiler.CompileAsync(path);

            // Assert
            Assert.Same(precompiledView, result);
        }
Пример #8
0
        public async Task CompileAsync_PrecompiledViewWithChecksum_CanRecompileWhenViewImportChanges()
        {
            // Arrange
            var path       = "/Views/Home/Index.cshtml";
            var importPath = "/Views/_ViewImports.cshtml";

            var fileProvider   = new TestFileProvider();
            var fileInfo       = fileProvider.AddFile(path, "some content");
            var importFileInfo = fileProvider.AddFile(importPath, "some import");

            var expected2 = new CompiledViewDescriptor();

            var precompiledView = new CompiledViewDescriptor
            {
                RelativePath = path,
                Item         = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", path, new object[]
                {
                    new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), path),
                    new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), importPath),
                }),
            };

            var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView });

            viewCompiler.AllowRecompilingViewsOnFileChange = true;

            // Act - 1
            var result = await viewCompiler.CompileAsync(path);

            // Assert - 1
            Assert.Same(precompiledView.Item, result.Item);

            // Act - 2
            importFileInfo.Content = "some import changed";
            fileProvider.GetChangeToken(importPath).HasChanged = true;
            viewCompiler.Compile = _ => expected2;
            result = await viewCompiler.CompileAsync(path);

            // Assert - 2
            Assert.Same(expected2, result);
        }
        public void AddFileVersionToPath_UpdatesEntryWhenCacheExpires_ForNonExistingFile()
        {
            // Arrange
            var fileProvider        = new TestFileProvider();
            var fileVersionProvider = GetFileVersionProvider(fileProvider);
            var requestPath         = GetRequestPathBase();

            // Act 1 - File does not exist
            var result = fileVersionProvider.AddFileVersionToPath(requestPath, "file.txt");

            // Assert 1
            Assert.Equal("file.txt", result);

            // Act 2 - File gets added
            fileProvider.AddFile("file.txt", "Hello World!");
            fileProvider.GetChangeToken("file.txt").HasChanged = true;
            result = fileVersionProvider.AddFileVersionToPath(requestPath, "file.txt");

            // Assert 2
            Assert.Equal("file.txt?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", result);
        }
Пример #10
0
        public async Task CompileAsync_ReturnsResultWithExpirationToken_WhenWatchingForFileChanges()
        {
            // Arrange
            var path         = "/file/does-not-exist";
            var fileProvider = new TestFileProvider();
            var viewCompiler = GetViewCompiler(fileProvider);

            viewCompiler.AllowRecompilingViewsOnFileChange = true;

            // Act
            var result1 = await viewCompiler.CompileAsync(path);

            var result2 = await viewCompiler.CompileAsync(path);

            // Assert
            Assert.Same(result1, result2);
            Assert.Null(result1.ViewAttribute);
            Assert.Collection(
                result1.ExpirationTokens,
                token => Assert.Equal(fileProvider.GetChangeToken(path), token));
        }
Пример #11
0
        public void GetOrAdd_UpdatesCacheWithValue_IfFileWasAdded()
        {
            // Arrange
            var path           = @"Views\Home\_ViewStart.cshtml";
            var fileProvider   = new TestFileProvider();
            var chunkTreeCache = new DefaultChunkTreeCache(fileProvider);
            var expected       = new ChunkTree();

            // Act 1
            var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); });

            // Assert 1
            Assert.Null(result1);

            // Act 2
            fileProvider.AddFile(path, "test content");
            fileProvider.GetChangeToken(path).HasChanged = true;
            var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected);

            // Assert 2
            Assert.Same(expected, result2);
        }
Пример #12
0
        public async Task CompileAsync_PrecompiledViewWithChecksum_CanReusePrecompiledViewIfContentChangesToMatch()
        {
            // Arrange
            var path = "/Views/Home/Index.cshtml";

            var fileProvider = new TestFileProvider();
            var file         = fileProvider.AddFile(path, "different content");

            var expected1 = new CompiledViewDescriptor();

            var precompiledView = new CompiledViewDescriptor
            {
                RelativePath = path,
                Item         = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", path, new object[]
                {
                    new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), path),
                }),
            };

            var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView });

            viewCompiler.Compile = _ => expected1;

            // Act - 1
            var result = await viewCompiler.CompileAsync(path);

            // Assert - 1
            Assert.Same(expected1, result);

            // Act - 2
            file.Content = "some content";
            fileProvider.GetChangeToken(path).HasChanged = true;
            result = await viewCompiler.CompileAsync(path);

            // Assert - 2
            Assert.Same(precompiledView.Item, result.Item);
        }
Пример #13
0
        public async Task CompileAsync_PrecompiledViewWithoutChecksumForMainSource_DoesNotSupportRecompilation()
        {
            // Arrange
            var path = "/Views/Home/Index.cshtml";

            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(path, "some content");

            var precompiledView = new CompiledViewDescriptor
            {
                RelativePath = path,
                Item         = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", path, new object[]
                {
                    new RazorSourceChecksumAttribute("sha1", GetChecksum("some content"), "/Views/Some-Other-View"),
                }),
            };

            var viewCompiler = GetViewCompiler(fileProvider, precompiledViews: new[] { precompiledView });

            // Act - 1
            var result = await viewCompiler.CompileAsync(path);

            // Assert - 1
            Assert.Same(precompiledView.Item, result.Item);

            // Act - 2
            fileProvider.Watch(path);
            fileProvider.GetChangeToken(path).HasChanged = true;
            result = await viewCompiler.CompileAsync(path);

            // Assert - 2
            Assert.Same(precompiledView.Item, result.Item);

            // This view doesn't have checksums so it can't be recompiled.
            Assert.Null(result.ExpirationTokens);
        }
Пример #14
0
        public async Task CompileAsync_DoesNotInvalidCache_IfChangeTokenChanges()
        {
            // Arrange
            var path         = "/Views/Home/Index.cshtml";
            var fileProvider = new TestFileProvider();
            var fileInfo     = fileProvider.AddFile(path, "some content");
            var viewCompiler = GetViewCompiler(fileProvider);
            var changeToken  = fileProvider.Watch(path);

            // Act 1
            var result1 = await viewCompiler.CompileAsync(path);

            // Assert 1
            Assert.NotNull(result1.ViewAttribute);

            // Act 2
            fileProvider.DeleteFile(path);
            fileProvider.GetChangeToken(path).HasChanged = true;
            viewCompiler.Compile = _ => throw new Exception("Can't call me");
            var result2 = await viewCompiler.CompileAsync(path);

            // Assert 2
            Assert.Same(result1, result2);
        }
Пример #15
0
        public void GetOrAdd_UpdatesCache_IfFileExpirationTriggerExpires()
        {
            // Arrange
            var path         = @"Views\Home\_ViewStart.cshtml";
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(path, "test content");
            var chunkTreeCache = new DefaultChunkTreeCache(fileProvider);
            var expected1      = new ChunkTree();
            var expected2      = new ChunkTree();

            // Act 1
            var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => expected1);

            // Assert 1
            Assert.Same(expected1, result1);

            // Act 2
            fileProvider.GetChangeToken(path).HasChanged = true;
            var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected2);

            // Assert 2
            Assert.Same(expected2, result2);
        }
        public async Task CompileAsync_ReturnsNewResult_IfAncestorViewImportsWereModified()
        {
            // Arrange
            var path         = "/Views/Home/Index.cshtml";
            var fileProvider = new TestFileProvider();
            var fileInfo     = fileProvider.AddFile(path, "some content");
            var viewCompiler = GetViewCompiler(fileProvider);
            var expected2    = new CompiledViewDescriptor();

            // Act 1
            var result1 = await viewCompiler.CompileAsync(path);

            // Assert 1
            Assert.NotNull(result1.ViewAttribute);

            // Act 2
            fileProvider.GetChangeToken("/Views/_ViewImports.cshtml").HasChanged = true;
            viewCompiler.Compile = _ => expected2;
            var result2 = await viewCompiler.CompileAsync(path);

            // Assert 2
            Assert.NotSame(result1, result2);
            Assert.Same(expected2, result2);
        }
Пример #17
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.IsType<TestView>(result1.PageFactory());

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

            // Assert 2
            Assert.True(result2.Success);
            Assert.IsType<TestView>(result2.PageFactory());

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

            // Assert 2
            Assert.True(result3.Success);
            Assert.IsType<DifferentView>(result3.PageFactory());
        }
Пример #18
0
        public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForViewImports(string globalImportPath)
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var cache = new CompilerCache(fileProvider, _precompiledViews);

            // Act
            fileProvider.Watch(globalImportPath);
            fileProvider.GetChangeToken(globalImportPath).HasChanged = true;
            var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert
            Assert.True(result.Success);
            Assert.IsType<PreCompile>(result.PageFactory());
        }
Пример #19
0
        public void GetOrAdd_ReturnsSuccessfulCompilationResultIfTriggerExpires()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);

            // Act and Assert - 1
            Assert.Throws<InvalidTimeZoneException>(() =>
                cache.GetOrAdd(ViewPath, _ => { throw new InvalidTimeZoneException(); }));

            // Act - 2
            fileProvider.GetChangeToken(ViewPath).HasChanged = true;
            var result = cache.GetOrAdd(ViewPath, _ => new CompilationResult(typeof(TestView)));

            // Assert - 2
            Assert.IsType<TestView>(result.PageFactory());
        }
Пример #20
0
        public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForPrecompiledFile()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var cache = new CompilerCache(fileProvider, _precompiledViews);

            // Act
            fileProvider.Watch(PrecompiledViewsPath);
            fileProvider.GetChangeToken(PrecompiledViewsPath).HasChanged = true;
            var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert
            Assert.True(result.Success);
            Assert.Same(typeof(PreCompile), result.CompilationResult.CompiledType);
        }
Пример #21
0
        public void GetOrAdd_ReturnsFailedCompilationResult_IfFileWasRemovedFromFileSystem()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(ViewPath, "some content");
            var cache = new CompilerCache(fileProvider);
            var expected = new CompilationResult(typeof(TestView));

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

            // Assert 1
            Assert.True(result1.Success);
            Assert.IsType<TestView>(result1.PageFactory());

            // 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);
        }
Пример #22
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 = 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);
        }
Пример #23
0
        public void GetOrAdd_DoesNotRecompile_IfFileTriggerWasSetForViewImports(string globalImportPath)
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            var cache = new CompilerCache(fileProvider, _precompiledViews);

            // Act
            fileProvider.Watch(globalImportPath);
            fileProvider.GetChangeToken(globalImportPath).HasChanged = true;
            var result = cache.GetOrAdd(PrecompiledViewsPath, ThrowsIfCalled);

            // Assert
            Assert.NotSame(CompilerCacheResult.FileNotFound, result);
            Assert.Same(typeof(PreCompile), result.CompilationResult.CompiledType);
        }
Пример #24
0
        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_UpdatesCacheWithNullValue_IfFileWasDeleted()
        {
            // Arrange
            var path = @"Views\Home\_ViewStart.cshtml";
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(path, "test content");
            using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider))
            {
                var expected1 = new ChunkTree();

                // Act 1
                var result1 = chunkTreeCache.GetOrAdd(path, fileInfo => expected1);

                // Assert 1
                Assert.Same(expected1, result1);

                // Act 2
                fileProvider.DeleteFile(path);
                fileProvider.GetChangeToken(path).HasChanged = true;
                var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); });

                // Assert 2
                Assert.Null(result2);
            }
        }
Пример #26
0
        public void GetOrAdd_ReturnsNewResultIfFileWasModified()
        {
            // 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(typeof(TestView), 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(ViewPath).HasChanged = true;
            var result3 = cache.GetOrAdd(ViewPath, _ => expected2);

            // Assert 3
            Assert.True(result3.Success);
            Assert.Same(expected2.CompiledType, result3.CompilationResult.CompiledType);
        }