Пример #1
0
        /// <inheritdoc />
        public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            if (inheritedChunks == null)
            {
                throw new ArgumentNullException(nameof(inheritedChunks));
            }

            if (!_isBaseTypeSet)
            {
                for (var i = inheritedChunks.Count - 1; i >= 0; i--)
                {
                    var baseTypeChunk = inheritedChunks[i] as SetBaseTypeChunk;
                    if (baseTypeChunk != null)
                    {
                        chunkTree.Chunks.Add(TransformChunk(baseTypeChunk));
                        break;
                    }
                }
            }
        }
Пример #2
0
        public void Merge_MatchesPropertyNameInCaseSensitiveManner()
        {
            // Arrange
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new InjectChunk("MyTypeB", "different-property"),
                new InjectChunk("MyType", "myproperty"),
            };

            // Act
            merger.VisitChunk(new InjectChunk("MyType", "MyProperty"));
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            Assert.Equal(2, chunkTree.Children.Count);
            var injectChunk = Assert.IsType<InjectChunk>(chunkTree.Children[0]);
            Assert.Equal("MyType", injectChunk.TypeName);
            Assert.Equal("myproperty", injectChunk.MemberName);

            injectChunk = Assert.IsType<InjectChunk>(chunkTree.Children[1]);
            Assert.Equal("MyTypeB", injectChunk.TypeName);
            Assert.Equal("different-property", injectChunk.MemberName);
        }
        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);
            }
        }
        protected override void AcceptTreeCore(ChunkTree tree)
        {
            base.AcceptTreeCore(tree);

            if (_modelChunk != null)
            {
                WriteModelChunkLineMapping();
            }
        }
Пример #5
0
        public void Merge_IgnoresSetBaseTypeChunksIfChunkTreeContainsOne()
        {
            // Arrange
            var merger = new SetBaseTypeChunkMerger("dynamic");
            var chunkTree = new ChunkTree();

            // Act
            merger.VisitChunk(new SetBaseTypeChunk { TypeName = "MyBaseType1" });
            merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = "MyBaseType2" });

            // Assert
            Assert.Empty(chunkTree.Chunks);
        }
Пример #6
0
        public void Merge_IgnoresChunkIfChunkWithMatchingPropertyNameWasVisitedInChunkTree()
        {
            // Arrange
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();

            // Act
            merger.VisitChunk(new InjectChunk("MyTypeA", "MyProperty"));
            merger.Merge(chunkTree, new InjectChunk("MyTypeB", "MyProperty"));

            // Assert
            Assert.Empty(chunkTree.Chunks);
        }
Пример #7
0
        public void Merge_IgnoresNamespacesThatHaveBeenVisitedInChunkTree()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();

            // Act
            merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
            merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });

            // Assert
            Assert.Empty(chunkTree.Chunks);
        }
Пример #8
0
        /// <summary>
        /// Returns the <see cref="ModelChunk"/> used to determine the model name for the page generated
        /// using the specified <paramref name="chunkTree"/>
        /// </summary>
        /// <param name="chunkTree">The <see cref="ChunkTree"/> to scan for <see cref="ModelChunk"/>s in.</param>
        /// <returns>The last <see cref="ModelChunk"/> in the <see cref="ChunkTree"/> if found, <c>null</c> otherwise.
        /// </returns>
        public static ModelChunk GetModelChunk(ChunkTree chunkTree)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            // If there's more than 1 model chunk there will be a Razor error BUT we want intellisense to show up on
            // the current model chunk that the user is typing.
            return chunkTree
                .Children
                .OfType<ModelChunk>()
                .LastOrDefault();
        }
Пример #9
0
        /// <summary>
        /// Initializes a new instance of <see cref="ChunkTreeResult"/>.
        /// </summary>
        /// <param name="chunkTree">The <see cref="AspNet.Razor.Chunks.ChunkTree"/> generated from the file at the
        /// given <paramref name="filePath"/>.</param>
        /// <param name="filePath">The path to the file that generated the given <paramref name="chunkTree"/>.</param>
        public ChunkTreeResult(ChunkTree chunkTree, string filePath)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            if (filePath == null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            ChunkTree = chunkTree;
            FilePath = filePath;
        }
Пример #10
0
        public void Merge_SetsBaseTypeIfItHasNotBeenSetInChunkTree()
        {
            // Arrange
            var expected = "MyApp.Razor.MyBaseType";
            var merger = new SetBaseTypeChunkMerger("dynamic");
            var chunkTree = new ChunkTree();

            // Act
            merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = expected });

            // Assert
            var chunk = Assert.Single(chunkTree.Chunks);
            var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk);
            Assert.Equal(expected, setBaseTypeChunk.TypeName);
        }
Пример #11
0
        public void Merge_AddsNamespacesThatHaveNotBeenVisitedInChunkTree()
        {
            // Arrange
            var expected = "MyApp.Models";
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();

            // Act
            merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
            merger.Merge(chunkTree, new UsingChunk { Namespace = expected });

            // Assert
            var chunk = Assert.Single(chunkTree.Chunks);
            var usingChunk = Assert.IsType<UsingChunk>(chunk);
            Assert.Equal(expected, usingChunk.Namespace);
        }
Пример #12
0
        public void Merge_AddsChunkIfChunkWithMatchingPropertyNameWasNotVisitedInChunkTree()
        {
            // Arrange
            var expectedType = "MyApp.MyHelperType";
            var expectedProperty = "MyHelper";
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();

            // Act
            merger.Merge(chunkTree, new InjectChunk(expectedType, expectedProperty));

            // Assert
            var chunk = Assert.Single(chunkTree.Chunks);
            var injectChunk = Assert.IsType<InjectChunk>(chunk);
            Assert.Equal(expectedType, injectChunk.TypeName);
            Assert.Equal(expectedProperty, injectChunk.MemberName);
        }
Пример #13
0
        /// <summary>
        /// Returns the type name of the Model specified via a <see cref="ModelChunk"/> in the
        /// <paramref name="chunkTree"/> if specified or the default model type.
        /// </summary>
        /// <param name="chunkTree">The <see cref="ChunkTree"/> to scan for <see cref="ModelChunk"/>s in.</param>
        /// <param name="defaultModelName">The <see cref="Type"/> name of the default model.</param>
        /// <returns>The model type name for the generated page.</returns>
        public static string GetModelTypeName(
            ChunkTree chunkTree,
            string defaultModelName)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            if (defaultModelName == null)
            {
                throw new ArgumentNullException(nameof(defaultModelName));
            }

            var modelChunk = GetModelChunk(chunkTree);
            return modelChunk != null ? modelChunk.ModelType : defaultModelName;
        }
Пример #14
0
        public void Merge_IgnoresNamespacesThatHaveBeenVisitedDuringMerge()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();

            // Act
            merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
            merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
            merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc.Razor" });

            // Assert
            Assert.Equal(2, chunkTree.Chunks.Count);
            var chunk = Assert.IsType<UsingChunk>(chunkTree.Chunks[0]);
            Assert.Equal("Microsoft.AspNet.Mvc", chunk.Namespace);
            chunk = Assert.IsType<UsingChunk>(chunkTree.Chunks[1]);
            Assert.Equal("Microsoft.AspNet.Mvc.Razor", chunk.Namespace);
        }
Пример #15
0
        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());
        }
Пример #16
0
        public void Merge_IgnoresNamespacesThatHaveBeenVisitedInChunkTree()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
                new InjectChunk("Foo", "Bar")
            };

            // Act
            merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            Assert.Empty(chunkTree.Children);
        }
Пример #17
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");
            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 Merge_PicksLastBaseTypeChunkFromChunkTree()
        {
            // Arrange
            var merger = new SetBaseTypeChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                 new SetBaseTypeChunk { TypeName = "MyBase2" },
                 new LiteralChunk(),
                 new SetBaseTypeChunk { TypeName = "MyBase1" },
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk);
            Assert.Equal("MyBase1", setBaseTypeChunk.TypeName);
        }
Пример #19
0
        public void Merge_MatchesNamespacesInCaseSensitiveManner()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNet.mvc" }
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            Assert.Equal(2, chunkTree.Children.Count);
            var chunk = Assert.IsType<UsingChunk>(chunkTree.Children[0]);
            Assert.Equal("Microsoft.AspNet.Mvc", chunk.Namespace);
            chunk = Assert.IsType<UsingChunk>(chunkTree.Children[1]);
            Assert.Equal("Microsoft.AspNet.mvc", chunk.Namespace);
        }
Пример #20
0
        /// <inheritdoc />
        public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            if (inheritedChunks == null)
            {
                throw new ArgumentNullException(nameof(inheritedChunks));
            }

            var namespaceChunks = inheritedChunks.OfType<UsingChunk>();
            foreach (var namespaceChunk in namespaceChunks)
            {
                if (_currentUsings.Add(namespaceChunk.Namespace))
                {
                    chunkTree.Children.Add(namespaceChunk);
                }
            }
        }
Пример #21
0
 /// <summary>
 /// Instantiates a new <see cref="GeneratorResults"/> instance.
 /// </summary>
 /// <param name="parserResults">The results of parsing a document.</param>
 /// <param name="codeGeneratorResult">The results of generating code for the document.</param>
 /// <param name="chunkTree">A <see cref="ChunkTree"/> for the document.</param>
 public GeneratorResults(ParserResults parserResults,
                         CodeGeneratorResult codeGeneratorResult,
                         ChunkTree chunkTree)
     : this(parserResults.Document,
            parserResults.TagHelperDescriptors,
            parserResults.ErrorSink,
            codeGeneratorResult,
            chunkTree)
 {
     if (parserResults == null)
     {
         throw new ArgumentNullException(nameof(parserResults));
     }
     if (codeGeneratorResult == null)
     {
         throw new ArgumentNullException(nameof(codeGeneratorResult));
     }
     if (chunkTree == null)
     {
         throw new ArgumentNullException(nameof(chunkTree));
     }
 }
Пример #22
0
        /// <inheritdoc />
        public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            if (inheritedChunks == null)
            {
                throw new ArgumentNullException(nameof(inheritedChunks));
            }

            for (var i = inheritedChunks.Count - 1; i >= 0; i--)
            {
                var injectChunk = inheritedChunks[i] as InjectChunk;
                if (injectChunk != null &&
                    _addedMemberNames.Add(injectChunk.MemberName))
                {
                    chunkTree.Chunks.Add(TransformChunk(injectChunk));
                }
            }
        }
Пример #23
0
        public void Merge_DoesNotAddMoreThanOneInstanceOfTheSameInheritedNamespace()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new LiteralChunk(),
                new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNet.Mvc.Razor" }
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            Assert.Equal(2, chunkTree.Children.Count);
            var chunk = Assert.IsType<UsingChunk>(chunkTree.Children[0]);
            Assert.Equal("Microsoft.AspNet.Mvc", chunk.Namespace);
            chunk = Assert.IsType<UsingChunk>(chunkTree.Children[1]);
            Assert.Equal("Microsoft.AspNet.Mvc.Razor", chunk.Namespace);
        }
Пример #24
0
        /// <summary>
        /// Instantiates a new <see cref="GeneratorResults"/> instance.
        /// </summary>
        /// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
        /// <param name="tagHelperDescriptors">
        /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document.
        /// </param>
        /// <param name="errorSink">
        /// The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the
        /// current Razor document.
        /// </param>
        /// <param name="codeGeneratorResult">The results of generating code for the document.</param>
        /// <param name="chunkTree">A <see cref="ChunkTree"/> for the document.</param>
        public GeneratorResults(Block document,
                                IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
                                ErrorSink errorSink,
                                CodeGeneratorResult codeGeneratorResult,
                                ChunkTree chunkTree)
            : base(document, tagHelperDescriptors, errorSink)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (tagHelperDescriptors == null)
            {
                throw new ArgumentNullException(nameof(tagHelperDescriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (codeGeneratorResult == null)
            {
                throw new ArgumentNullException(nameof(codeGeneratorResult));
            }

            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            GeneratedCode = codeGeneratorResult.Code;
            DesignTimeLineMappings = codeGeneratorResult.DesignTimeLineMappings;
            ChunkTree = chunkTree;
        }
        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);
            }
        }
 private static Dictionary<Type, IChunkMerger> GetMergerMappings(ChunkTree chunkTree, string defaultModel)
 {
     var modelType = ChunkHelper.GetModelTypeName(chunkTree, defaultModel);
     return new Dictionary<Type, IChunkMerger>
     {
         { typeof(UsingChunk), new UsingChunkMerger() },
         { typeof(InjectChunk), new InjectChunkMerger(modelType) },
         { typeof(SetBaseTypeChunk), new SetBaseTypeChunkMerger(modelType) }
     };
 }
Пример #27
0
        public void Merge_ResolvesModelNameInTypesWithTModelToken()
        {
            // Arrange
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new InjectChunk("MyHelper<TModel>", "MyProperty")
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var injectChunk = Assert.IsType<InjectChunk>(chunk);
            Assert.Equal("MyHelper<dynamic>", injectChunk.TypeName);
            Assert.Equal("MyProperty", injectChunk.MemberName);
        }
        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);
            }
        }
Пример #29
0
        public void Merge_UsesTheLastInjectChunkOfAPropertyName()
        {
            // Arrange
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new LiteralChunk(),
                new InjectChunk("SomeOtherType", "Property"),
                new InjectChunk("DifferentPropertyType", "DifferentProperty"),
                new InjectChunk("SomeType", "Property"),
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            Assert.Collection(chunkTree.Children,
                chunk =>
                {
                    var injectChunk = Assert.IsType<InjectChunk>(chunk);
                    Assert.Equal("SomeType", injectChunk.TypeName);
                    Assert.Equal("Property", injectChunk.MemberName);
                },
                chunk =>
                {
                    var injectChunk = Assert.IsType<InjectChunk>(chunk);
                    Assert.Equal("DifferentPropertyType", injectChunk.TypeName);
                    Assert.Equal("DifferentProperty", injectChunk.MemberName);
                });
        }
Пример #30
0
 public ChunkTreeBuilder()
 {
     ChunkTree    = new ChunkTree();
     _parentStack = new Stack <ParentChunk>();
 }
Пример #31
0
        public void Merge_ReplacesTModelTokensWithModel()
        {
            // Arrange
            var merger = new InjectChunkMerger("MyTestModel2");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new InjectChunk("MyHelper<TModel>", "MyProperty")
            };

            // Act
            merger.MergeInheritedChunks(chunkTree, inheritedChunks);

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var injectChunk = Assert.IsType<InjectChunk>(chunk);
            Assert.Equal("MyHelper<MyTestModel2>", injectChunk.TypeName);
            Assert.Equal("MyProperty", injectChunk.MemberName);
        }