示例#1
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);
            }
        }
        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);
            }
        }
示例#3
0
        public void GetInheritedChunks_ReturnsEmptySequenceIfNoGlobalsArePresent()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(@"_ViewImports.cs", string.Empty);
            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_Layout.cshtml"), string.Empty);
            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_not-viewimports.cshtml"), string.Empty);
            var cache         = new DefaultChunkTreeCache(fileProvider);
            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.GetInheritedChunkTrees(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));

            // Assert
            Assert.Empty(chunkTrees);
        }
示例#4
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);
            }
        }
        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));
            }
        }
示例#6
0
        public void MergeInheritedChunks_MergesDefaultInheritedChunks()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
                                 "@inject DifferentHelper<TModel> Html");
            var cache         = new DefaultChunkTreeCache(fileProvider);
            var host          = new MvcRazorHost(cache);
            var defaultChunks = new Chunk[]
            {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk {
                    Namespace = "AppNamespace.Model"
                },
            };
            var inheritedChunkTrees = new ChunkTree[]
            {
                new ChunkTree
                {
                    Chunks = new Chunk[]
                    {
                        new UsingChunk {
                            Namespace = "InheritedNamespace"
                        },
                        new LiteralChunk {
                            Text = "some text"
                        }
                    }
                },
                new ChunkTree
                {
                    Chunks = 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.Equal(3, chunkTree.Chunks.Count);
            Assert.Same(inheritedChunkTrees[0].Chunks[0], chunkTree.Chunks[0]);
            Assert.Same(inheritedChunkTrees[1].Chunks[0], chunkTree.Chunks[1]);
            Assert.Same(defaultChunks[0], chunkTree.Chunks[2]);
        }
        public void GetOrAdd_ReturnsNullValues_IfFileDoesNotExistInFileProvider()
        {
            // Arrange
            var path = @"Views\_ViewStart.cshtml";
            var mockFileProvider = new Mock<TestFileProvider> { CallBase = true };
            var fileProvider = mockFileProvider.Object;
            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());
        }
        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");
            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());
        }
        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);
            }
        }
        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);
            }
        }
示例#11
0
        public void GetInheritedChunks_ReadsChunksFromGlobalFilesInPath()
        {
            // Arrange
            var fileProvider = new TestFileProvider();

            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\accounts\_ViewImports.cshtml"), "@using AccountModels");
            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\Shared\_ViewImports.cshtml"), "@inject SharedHelper Shared");
            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml"), "@using MyNamespace");
            fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"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);
            var host    = new MvcRazorHost(cache);
            var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

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

            // Assert
            Assert.Collection(chunkTrees,
                              chunkTree =>
            {
                var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
                Assert.Collection(chunkTree.Chunks,
                                  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);
                });
            },
                              chunkTree =>
            {
                var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml");
                Assert.Collection(chunkTree.Chunks,
                                  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);
                });
            });
        }
        public void MergeInheritedChunks_MergesDefaultInheritedChunks()
        {
            // Arrange
            var fileProvider = new TestFileProvider();
            fileProvider.AddFile(@"Views\_ViewImports.cshtml",
                               "@inject DifferentHelper<TModel> Html");
            var cache = new DefaultChunkTreeCache(fileProvider);
            var host = new MvcRazorHost(cache);
            var defaultChunks = new Chunk[]
            {
                new InjectChunk("MyTestHtmlHelper", "Html"),
                new UsingChunk { Namespace = "AppNamespace.Model" },
            };
            var inheritedChunkTrees = new ChunkTree[]
            {
                new ChunkTree
                {
                    Chunks = new Chunk[]
                    {
                        new UsingChunk { Namespace = "InheritedNamespace" },
                        new LiteralChunk { Text = "some text" }
                    }
                },
                new ChunkTree
                {
                    Chunks = 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.Equal(3, chunkTree.Chunks.Count);
            Assert.Same(inheritedChunkTrees[0].Chunks[0], chunkTree.Chunks[0]);
            Assert.Same(inheritedChunkTrees[1].Chunks[0], chunkTree.Chunks[1]);
            Assert.Same(defaultChunks[0], chunkTree.Chunks[2]);
        }
        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);
            var host = new MvcRazorHost(cache);
            var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);

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

            // Assert
            Assert.Collection(chunkTrees,
                chunkTree =>
                {
                    var viewImportsPath = @"Views\home\_ViewImports.cshtml";
                    Assert.Collection(chunkTree.Chunks,
                        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);
                        });
                },
                chunkTree =>
                {
                    var viewImportsPath = @"Views\_ViewImports.cshtml";
                    Assert.Collection(chunkTree.Chunks,
                        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);
                        });
                });
        }
        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);
            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.GetInheritedChunkTrees(@"Views\home\Index.cshtml");

            // Assert
            Assert.Empty(chunkTrees);
        }
示例#15
0
 private static CodeGeneratorContext CreateContext()
 {
     var chunkTreeCache = new DefaultChunkTreeCache(new TestFileProvider());
     return new CodeGeneratorContext(
         new ChunkGeneratorContext(
             new MvcRazorHost(chunkTreeCache),
             "MyClass",
             "MyNamespace",
             string.Empty,
             shouldGenerateLinePragmas: true),
         new ErrorSink());
 }
        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.GetTrigger(path).IsExpired = true;
            var result2 = chunkTreeCache.GetOrAdd(path, fileInfo => expected);

            // Assert 2
            Assert.Same(expected, result2);
        }