Esempio n. 1
0
        public void GetInheritedChunks_ReturnsEmptySequenceIfNoGlobalsArePresent()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(@"/_ViewImports.cs", string.Empty);
            fileProvider.AddFile(@"/Views/_Layout.cshtml", string.Empty);
            fileProvider.AddFile(@"/Views/home/_not-viewimports.cshtml", string.Empty);
            var cache = new DefaultChunkTreeCache(fileProvider);

            using (var host = new MvcRazorHost(cache))
            {
                var defaultChunks = new Chunk[]
                {
                    new InjectChunk("MyTestHtmlHelper", "Html"),
                    new UsingChunk {
                        Namespace = "AppNamespace.Model"
                    },
                };
                var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

                // Act
                var chunkTrees = utility.GetInheritedChunkTreeResults(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));

                // Assert
                Assert.Empty(chunkTrees);
            }
        }
Esempio n. 2
0
        public void DecorateCodeGenerator_DesignTimeRazorPathNormalizer_NormalizesChunkInheritanceUtilityPaths(
            string rootPrefix)
        {
            // Arrange
            var rootedAppPath = $"{rootPrefix}SomeComputer/Location/Project/";
            var rootedFilePath = $"{rootPrefix}SomeComputer/Location/Project/src/file.cshtml";
            var chunkTreeCache = new DefaultChunkTreeCache(new TestFileProvider());
            using (var host = new MvcRazorHost(
                chunkTreeCache,
                pathNormalizer: new DesignTimeRazorPathNormalizer(rootedAppPath)))
            {
                var chunkInheritanceUtility = new PathValidatingChunkInheritanceUtility(host, chunkTreeCache);
                var codeGeneratorContext = new CodeGeneratorContext(
                    new ChunkGeneratorContext(
                        host,
                        host.DefaultClassName,
                        host.DefaultNamespace,
                        rootedFilePath,
                        shouldGenerateLinePragmas: true),
                    new ErrorSink());
                var codeGenerator = new CSharpCodeGenerator(codeGeneratorContext);
                host.ChunkInheritanceUtility = chunkInheritanceUtility;

                // Act
                host.DecorateCodeGenerator(codeGenerator, codeGeneratorContext);

                // Assert
                Assert.Equal("src/file.cshtml", chunkInheritanceUtility.InheritedChunkTreePagePath, StringComparer.Ordinal);
            }
        }
Esempio n. 3
0
        public void DecorateRazorParser_DesignTimeRazorPathNormalizer_NormalizesChunkInheritanceUtilityPaths(
            string rootPrefix)
        {
            // Arrange
            var rootedAppPath = $"{rootPrefix}SomeComputer/Location/Project/";
            var rootedFilePath = $"{rootPrefix}SomeComputer/Location/Project/src/file.cshtml";
            var chunkTreeCache = new DefaultChunkTreeCache(new TestFileProvider());
            using (var host = new MvcRazorHost(
                chunkTreeCache,
                pathNormalizer: new DesignTimeRazorPathNormalizer(rootedAppPath)))
            {
                var parser = new RazorParser(
                    host.CodeLanguage.CreateCodeParser(),
                    host.CreateMarkupParser(),
                    tagHelperDescriptorResolver: null);
                var chunkInheritanceUtility = new PathValidatingChunkInheritanceUtility(host, chunkTreeCache);
                host.ChunkInheritanceUtility = chunkInheritanceUtility;

                // Act
                host.DecorateRazorParser(parser, rootedFilePath);

                // Assert
                Assert.Equal("src/file.cshtml", chunkInheritanceUtility.InheritedChunkTreePagePath, StringComparer.Ordinal);
            }
        }
Esempio n. 4
0
        public void MergeInheritedChunks_MergesDefaultInheritedChunks()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
                                 "@inject DifferentHelper<TModel> Html");
            var cache = new DefaultChunkTreeCache(fileProvider);

            using (var host = new MvcRazorHost(cache))
            {
                var defaultChunks = new Chunk[]
                {
                    new InjectChunk("MyTestHtmlHelper", "Html"),
                    new UsingChunk {
                        Namespace = "AppNamespace.Model"
                    },
                };
                var inheritedChunkTrees = new ChunkTree[]
                {
                    new ChunkTree
                    {
                        Children = new Chunk[]
                        {
                            new UsingChunk {
                                Namespace = "InheritedNamespace"
                            },
                            new LiteralChunk {
                                Text = "some text"
                            }
                        }
                    },
                    new ChunkTree
                    {
                        Children = new Chunk[]
                        {
                            new UsingChunk {
                                Namespace = "AppNamespace.Model"
                            },
                        }
                    }
                };

                var utility   = new ChunkInheritanceUtility(host, cache, defaultChunks);
                var chunkTree = new ChunkTree();

                // Act
                utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic");

                // Assert
                Assert.Collection(chunkTree.Children,
                                  chunk => Assert.Same(defaultChunks[1], chunk),
                                  chunk => Assert.Same(inheritedChunkTrees[0].Children[0], chunk),
                                  chunk => Assert.Same(defaultChunks[0], chunk));
            }
        }
Esempio n. 5
0
        public void GetOrAdd_ReturnsCachedEntriesOnSubsequentCalls()
        {
            // Arrange
            var path = @"Views\_ViewStart.cshtml";
            var mockFileProvider = new Mock<TestFileProvider> { CallBase = true };
            var fileProvider = mockFileProvider.Object;
            fileProvider.AddFile(path, "test content");
            using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider))
            {
                var expected = new ChunkTree();

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

                // Assert
                Assert.Same(expected, result1);
                Assert.Same(expected, result2);
                mockFileProvider.Verify(f => f.GetFileInfo(It.IsAny<string>()), Times.Once());
            }
        }
Esempio n. 6
0
        public void GetOrAdd_ExpiresEntriesAfterOneMinute()
        {
            // Arrange
            var path = @"Views\Home\_ViewStart.cshtml";
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(path, "some content");
            var clock = new Mock<ISystemClock>();
            var utcNow = DateTimeOffset.UtcNow;
            clock.SetupGet(c => c.UtcNow)
                 .Returns(() => utcNow);
            var options = new MemoryCacheOptions { Clock = clock.Object };
            using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider, options))
            {
                var chunkTree1 = new ChunkTree();
                var chunkTree2 = new ChunkTree();

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

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

                // Act 2
                utcNow = utcNow.AddSeconds(59);
                var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => { throw new Exception("Shouldn't be called."); });

                // Assert 2
                Assert.Same(chunkTree1, result2);

                // Act 3
                utcNow = utcNow.AddSeconds(65);
                var result3 = chunkTreeCache.GetOrAdd(path, fileInfo => chunkTree2);

                // Assert 3
                Assert.Same(chunkTree2, result3);
            }
        }
Esempio n. 7
0
        public void GetOrAdd_ReturnsNullValues_IfFileDoesNotExistInFileProvider()
        {
            // Arrange
            var path = @"Views\_ViewStart.cshtml";
            var mockFileProvider = new Mock<TestFileProvider> { CallBase = true };
            var fileProvider = mockFileProvider.Object;
            using (var chunkTreeCache = new DefaultChunkTreeCache(fileProvider))
            {
                var expected = new ChunkTree();

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

                // Assert
                Assert.Null(result1);
                Assert.Null(result2);
                mockFileProvider.Verify(f => f.GetFileInfo(It.IsAny<string>()), Times.Once());
            }
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
        public void GetOrAdd_UpdatesCacheWithValue_IfFileWasAdded()
        {
            // Arrange
            var path = @"Views\Home\_ViewStart.cshtml";
            var fileProvider = new TestFileProvider();
            using (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);
            }
        }
Esempio n. 10
0
        public void GetInheritedChunks_ReadsChunksFromGlobalFilesInPath()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(@"/Views/accounts/_ViewImports.cshtml", "@using AccountModels");
            fileProvider.AddFile(@"/Views/Shared/_ViewImports.cshtml", "@inject SharedHelper Shared");
            fileProvider.AddFile(@"/Views/home/_ViewImports.cshtml", "@using MyNamespace");
            fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
                                 @"@inject MyHelper<TModel> Helper
@inherits MyBaseType

@{
    Layout = ""test.cshtml"";
}

");
            var defaultChunks = new Chunk[]
            {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk {
                    Namespace = "AppNamespace.Model"
                },
            };
            var cache = new DefaultChunkTreeCache(fileProvider);

            using (var host = new MvcRazorHost(cache))
            {
                var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

                // Act
                var chunkTreeResults = utility.GetInheritedChunkTreeResults(
                    PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));

                // Assert
                Assert.Collection(chunkTreeResults,
                                  chunkTreeResult =>
                {
                    var viewImportsPath = @"/Views/_ViewImports.cshtml";
                    Assert.Collection(chunkTreeResult.ChunkTree.Children,
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        var injectChunk = Assert.IsType <InjectChunk>(chunk);
                        Assert.Equal("MyHelper<TModel>", injectChunk.TypeName);
                        Assert.Equal("Helper", injectChunk.MemberName);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        var setBaseTypeChunk = Assert.IsType <SetBaseTypeChunk>(chunk);
                        Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        Assert.IsType <StatementChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    });
                    Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
                },
                                  chunkTreeResult =>
                {
                    var viewImportsPath = "/Views/home/_ViewImports.cshtml";
                    Assert.Collection(chunkTreeResult.ChunkTree.Children,
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        var usingChunk = Assert.IsType <UsingChunk>(chunk);
                        Assert.Equal("MyNamespace", usingChunk.Namespace);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    },
                                      chunk =>
                    {
                        Assert.IsType <LiteralChunk>(chunk);
                        Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                    });
                    Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
                });
            }
        }
        public void MergeInheritedChunks_MergesDefaultInheritedChunks()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
                               "@inject DifferentHelper<TModel> Html");
            var cache = new DefaultChunkTreeCache(fileProvider);
            using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false)))
            {
                var defaultChunks = new Chunk[]
                {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk { Namespace = "AppNamespace.Model" },
                };
                var inheritedChunkTrees = new ChunkTree[]
                {
                new ChunkTree
                {
                    Children = new Chunk[]
                    {
                        new UsingChunk { Namespace = "InheritedNamespace" },
                        new LiteralChunk { Text = "some text" }
                    }
                },
                new ChunkTree
                {
                    Children = new Chunk[]
                    {
                        new UsingChunk { Namespace = "AppNamespace.Model" },
                    }
                }
                };

                var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);
                var chunkTree = new ChunkTree();

                // Act
                utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic");

                // Assert
                Assert.Collection(chunkTree.Children,
                    chunk => Assert.Same(defaultChunks[1], chunk),
                    chunk => Assert.Same(inheritedChunkTrees[0].Children[0], chunk),
                    chunk => Assert.Same(defaultChunks[0], chunk));
            }
        }
        public void GetInheritedChunks_ReadsChunksFromGlobalFilesInPath()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(@"/Views/accounts/_ViewImports.cshtml", "@using AccountModels");
            fileProvider.AddFile(@"/Views/Shared/_ViewImports.cshtml", "@inject SharedHelper Shared");
            fileProvider.AddFile(@"/Views/home/_ViewImports.cshtml", "@using MyNamespace");
            fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
@"@inject MyHelper<TModel> Helper
@inherits MyBaseType

@{
    Layout = ""test.cshtml"";
}

");
            var defaultChunks = new Chunk[]
            {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk { Namespace = "AppNamespace.Model" },
            };
            var cache = new DefaultChunkTreeCache(fileProvider);
            using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false)))
            {
                var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

                // Act
                var chunkTreeResults = utility.GetInheritedChunkTreeResults(
                    PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));

                // Assert
                Assert.Collection(chunkTreeResults,
                    chunkTreeResult =>
                    {
                        var viewImportsPath = @"/Views/_ViewImports.cshtml";
                        Assert.Collection(chunkTreeResult.ChunkTree.Children,
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                var injectChunk = Assert.IsType<InjectChunk>(chunk);
                                Assert.Equal("MyHelper<TModel>", injectChunk.TypeName);
                                Assert.Equal("Helper", injectChunk.MemberName);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk);
                                Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                Assert.IsType<StatementChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            });
                        Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
                    },
                    chunkTreeResult =>
                    {
                        var viewImportsPath = "/Views/home/_ViewImports.cshtml";
                        Assert.Collection(chunkTreeResult.ChunkTree.Children,
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                var usingChunk = Assert.IsType<UsingChunk>(chunk);
                                Assert.Equal("MyNamespace", usingChunk.Namespace);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            },
                            chunk =>
                            {
                                Assert.IsType<LiteralChunk>(chunk);
                                Assert.Equal(viewImportsPath, chunk.Start.FilePath);
                            });
                        Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
                    });
            }
        }
        public void GetInheritedChunks_ReturnsEmptySequenceIfNoGlobalsArePresent()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(@"/_ViewImports.cs", string.Empty);
            fileProvider.AddFile(@"/Views/_Layout.cshtml", string.Empty);
            fileProvider.AddFile(@"/Views/home/_not-viewimports.cshtml", string.Empty);
            var cache = new DefaultChunkTreeCache(fileProvider);
            using (var host = new MvcRazorHost(cache, new TagHelperDescriptorResolver(designTime: false)))
            {
                var defaultChunks = new Chunk[]
                {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk { Namespace = "AppNamespace.Model" },
                };
                var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

                // Act
                var chunkTrees = utility.GetInheritedChunkTreeResults(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));

                // Assert
                Assert.Empty(chunkTrees);
            }
        }
Esempio n. 14
0
 private static CodeGeneratorContext CreateContext()
 {
     var chunkTreeCache = new DefaultChunkTreeCache(new TestFileProvider());
     return new CodeGeneratorContext(
         new ChunkGeneratorContext(
             new MvcRazorHost(chunkTreeCache, new TagHelperDescriptorResolver(designTime: false)),
             "MyClass",
             "MyNamespace",
             string.Empty,
             shouldGenerateLinePragmas: true),
         new ErrorSink());
 }