Example #1
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);
            }
        }
Example #2
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);
            });
        }
Example #3
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.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);
        }
Example #4
0
        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.Chunks);
            var setBaseTypeChunk = Assert.IsType <SetBaseTypeChunk>(chunk);

            Assert.Equal("MyBase1", setBaseTypeChunk.TypeName);
        }
Example #5
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.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", chunk.Namespace);
        }
Example #6
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.Chunks.Count);
            var injectChunk = Assert.IsType <InjectChunk>(chunkTree.Chunks[0]);

            Assert.Equal("MyType", injectChunk.TypeName);
            Assert.Equal("myproperty", injectChunk.MemberName);

            injectChunk = Assert.IsType <InjectChunk>(chunkTree.Chunks[1]);
            Assert.Equal("MyTypeB", injectChunk.TypeName);
            Assert.Equal("different-property", injectChunk.MemberName);
        }
        /// <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;
                    }
                }
            }
        }
Example #8
0
        /// <summary>
        /// Merges <see cref="Chunk"/> inherited by default and <see cref="ChunkTree"/> instances produced by parsing
        /// <c>_ViewImports</c> files into the specified <paramref name="chunkTree"/>.
        /// </summary>
        /// <param name="chunkTree">The <see cref="ChunkTree"/> to merge in to.</param>
        /// <param name="inheritedChunkTrees"><see cref="IReadOnlyList{ChunkTree}"/> inherited from <c>_ViewImports</c>
        /// files.</param>
        /// <param name="defaultModel">The list of chunks to merge.</param>
        public void MergeInheritedChunkTrees(
            [NotNull] ChunkTree chunkTree,
            [NotNull] IReadOnlyList <ChunkTree> inheritedChunkTrees,
            string defaultModel)
        {
            var          mergerMappings = GetMergerMappings(chunkTree, defaultModel);
            IChunkMerger merger;

            // We merge chunks into the ChunkTree in two passes. In the first pass, we traverse the ChunkTree visiting
            // a mapped IChunkMerger for types that are registered.
            foreach (var chunk in chunkTree.Chunks)
            {
                if (mergerMappings.TryGetValue(chunk.GetType(), out merger))
                {
                    merger.VisitChunk(chunk);
                }
            }

            // In the second phase we invoke IChunkMerger.Merge for each chunk that has a mapped merger.
            // During this phase, the merger can either add to the ChunkTree or ignore the chunk based on the merging
            // rules.
            // Read the chunks outside in - that is chunks from the _ViewImports closest to the page get merged in first
            // and the furthest one last. This allows the merger to ignore a directive like @model that was previously
            // seen.
            var chunksToMerge = inheritedChunkTrees.SelectMany(tree => tree.Chunks)
                                .Concat(_defaultInheritedChunks);

            foreach (var chunk in chunksToMerge)
            {
                if (mergerMappings.TryGetValue(chunk.GetType(), out merger))
                {
                    merger.Merge(chunkTree, chunk);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Merges <see cref="Chunk"/> inherited by default and <see cref="ChunkTree"/> instances produced by parsing
        /// <c>_ViewImports</c> files into the specified <paramref name="chunkTree"/>.
        /// </summary>
        /// <param name="chunkTree">The <see cref="ChunkTree"/> to merge in to.</param>
        /// <param name="inheritedChunkTrees"><see cref="IReadOnlyList{ChunkTree}"/> inherited from <c>_ViewImports</c>
        /// files.</param>
        /// <param name="defaultModel">The default model <see cref="Type"/> name.</param>
        public void MergeInheritedChunkTrees(
            ChunkTree chunkTree,
            IReadOnlyList <ChunkTree> inheritedChunkTrees,
            string defaultModel)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

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

            var chunkMergers = GetChunkMergers(chunkTree, defaultModel);

            // We merge chunks into the ChunkTree in two passes. In the first pass, we traverse the ChunkTree visiting
            // a mapped IChunkMerger for types that are registered.
            foreach (var chunk in chunkTree.Chunks)
            {
                foreach (var merger in chunkMergers)
                {
                    merger.VisitChunk(chunk);
                }
            }

            var inheritedChunks = _defaultInheritedChunks.Concat(
                inheritedChunkTrees.SelectMany(tree => tree.Chunks)).ToArray();

            foreach (var merger in chunkMergers)
            {
                merger.MergeInheritedChunks(chunkTree, inheritedChunks);
            }
        }
Example #10
0
        private void AddImports(ChunkTree chunkTree, CSharpCodeWriter writer, IEnumerable <string> defaultImports)
        {
            // Write out using directives
            var usingVisitor = new CSharpUsingVisitor(writer, Context);

            foreach (var chunk in Tree.Children)
            {
                usingVisitor.Accept(chunk);
            }

            _pageUsings = new HashSet <string>(usingVisitor.ImportedUsings);
            foreach (var ns in defaultImports)
            {
                _pageUsings.Add(ns);
            }

            defaultImports = defaultImports.Except(usingVisitor.ImportedUsings);

            foreach (string import in defaultImports)
            {
                writer.WriteUsing(import);
            }

            var taskNamespace = typeof(Task).Namespace;

            // We need to add the task namespace but ONLY if it hasn't been added by the default imports or using imports yet.
            if (!defaultImports.Contains(taskNamespace) && !usingVisitor.ImportedUsings.Contains(taskNamespace))
            {
                writer.WriteUsing(taskNamespace);
            }
        }
Example #11
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);
        }
Example #12
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);
        }
Example #13
0
        public void Merge_AddsNamespacesThatHaveNotBeenVisitedInChunkTree()
        {
            // Arrange
            var expected        = "MyApp.Models";
            var merger          = new UsingChunkMerger();
            var chunkTree       = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new UsingChunk {
                    Namespace = expected
                },
            };

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

            // Assert
            var chunk      = Assert.Single(chunkTree.Chunks);
            var usingChunk = Assert.IsType <UsingChunk>(chunk);

            Assert.Equal(expected, usingChunk.Namespace);
        }
Example #14
0
        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);
            }
        }
Example #15
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(
            [NotNull] ChunkTree chunkTree,
            [NotNull] string defaultModelName)
        {
            var modelChunk = GetModelChunk(chunkTree);

            return(modelChunk != null ? modelChunk.ModelType : defaultModelName);
        }
Example #16
0
        protected override void AcceptTreeCore(ChunkTree tree)
        {
            base.AcceptTreeCore(tree);

            if (_modelChunk != null)
            {
                WriteModelChunkLineMapping();
            }
        }
Example #17
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([NotNull] ChunkTree 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
            .Chunks
            .OfType <ModelChunk>()
            .LastOrDefault());
 }
        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));
            }
        }
Example #19
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([NotNull] ParserResults parserResults,
                         [NotNull] CodeGeneratorResult codeGeneratorResult,
                         [NotNull] ChunkTree chunkTree)
     : this(parserResults.Document,
            parserResults.TagHelperDescriptors,
            parserResults.ErrorSink,
            codeGeneratorResult,
            chunkTree)
 {
 }
Example #20
0
        private static IChunkMerger[] GetChunkMergers(ChunkTree chunkTree, string defaultModel)
        {
            var modelType = ChunkHelper.GetModelTypeName(chunkTree, defaultModel);

            return(new IChunkMerger[]
            {
                new UsingChunkMerger(),
                new SetBaseTypeChunkMerger(modelType)
            });
        }
Example #21
0
        /// <inheritdoc />
        public void Merge([NotNull] ChunkTree chunkTree, [NotNull] Chunk chunk)
        {
            var namespaceChunk = ChunkHelper.EnsureChunk <UsingChunk>(chunk);

            if (!_currentUsings.Contains(namespaceChunk.Namespace))
            {
                _currentUsings.Add(namespaceChunk.Namespace);
                chunkTree.Chunks.Add(namespaceChunk);
            }
        }
        /// <inheritdoc />
        public void Merge([NotNull] ChunkTree chunkTree, [NotNull] Chunk chunk)
        {
            var injectChunk = ChunkHelper.EnsureChunk <InjectChunk>(chunk);

            if (!_addedMemberNames.Contains(injectChunk.MemberName))
            {
                _addedMemberNames.Add(injectChunk.MemberName);
                chunkTree.Chunks.Add(TransformChunk(injectChunk));
            }
        }
Example #23
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]);
        }
Example #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([NotNull] Block document,
                         [NotNull] IEnumerable <TagHelperDescriptor> tagHelperDescriptors,
                         [NotNull] ErrorSink errorSink,
                         [NotNull] CodeGeneratorResult codeGeneratorResult,
                         [NotNull] ChunkTree chunkTree)
     : base(document, tagHelperDescriptors, errorSink)
 {
     GeneratedCode          = codeGeneratorResult.Code;
     DesignTimeLineMappings = codeGeneratorResult.DesignTimeLineMappings;
     ChunkTree = chunkTree;
 }
Example #25
0
        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) }
            });
        }
Example #26
0
        /// <inheritdoc />
        public void Merge([NotNull] ChunkTree chunkTree, [NotNull] Chunk chunk)
        {
            if (!_isBaseTypeSet)
            {
                var baseTypeChunk = ChunkHelper.EnsureChunk <SetBaseTypeChunk>(chunk);

                // The base type can set exactly once and the first one we encounter wins.
                _isBaseTypeSet = true;

                chunkTree.Chunks.Add(TransformChunk(baseTypeChunk));
            }
        }
 public void AcceptTree(ChunkTree tree)
 {
     if (Context.Host.DesignTimeMode)
     {
         using (Writer.BuildMethodDeclaration("private", "void", "@" + DesignTimeHelperMethodName))
         {
             using (Writer.BuildDisableWarningScope(DisableVariableNamingWarnings))
             {
                 AcceptTreeCore(tree);
             }
         }
     }
 }
        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);
        }
Example #29
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());
        }
Example #30
0
        /// <summary>
        /// Initializes a new instance of <see cref="ChunkTreeResult"/>.
        /// </summary>
        /// <param name="chunkTree">The <see cref="AspNetCore.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;
        }
        public void Merge_ReplacesTModelTokensWithModel()
        {
            // Arrange
            var merger    = new InjectChunkMerger("MyTestModel2");
            var chunkTree = new ChunkTree();

            // Act
            merger.Merge(chunkTree, new InjectChunk("MyHelper<TModel>", "MyProperty"));

            // Assert
            var chunk       = Assert.Single(chunkTree.Chunks);
            var injectChunk = Assert.IsType <InjectChunk>(chunk);

            Assert.Equal("MyHelper<MyTestModel2>", injectChunk.TypeName);
            Assert.Equal("MyProperty", injectChunk.MemberName);
        }
Example #32
0
        public void Merge_IgnoresChunkIfChunkWithMatchingPropertyNameWasVisitedInChunkTree()
        {
            // Arrange
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new InjectChunk("MyTypeB", "MyProperty")
            };

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

            // Assert
            Assert.Empty(chunkTree.Children);
        }
Example #33
0
        public void Merge_IgnoresSetBaseTypeChunksIfChunkTreeContainsOne()
        {
            // Arrange
            var merger = new SetBaseTypeChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                 new SetBaseTypeChunk { TypeName = "MyBaseType2" }
            };

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

            // Assert
            Assert.Empty(chunkTree.Children);
        }
Example #34
0
        public void Merge_IgnoresNamespacesThatHaveBeenVisitedInChunkTree()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new UsingChunk { Namespace = "Microsoft.AspNetCore.Mvc" },
                new InjectChunk("Foo", "Bar")
            };

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

            // Assert
            Assert.Empty(chunkTree.Children);
        }
Example #35
0
        public void Merge_SetsBaseTypeIfItHasNotBeenSetInChunkTree()
        {
            // Arrange
            var expected = "MyApp.Razor.MyBaseType";
            var merger = new SetBaseTypeChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new SetBaseTypeChunk { TypeName = expected }
            };

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

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk);
            Assert.Equal(expected, setBaseTypeChunk.TypeName);
        }
Example #36
0
        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);
        }
Example #37
0
        public void Merge_AddsNamespacesThatHaveNotBeenVisitedInChunkTree()
        {
            // Arrange
            var expected = "MyApp.Models";
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new UsingChunk { Namespace = expected },
            };

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

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var usingChunk = Assert.IsType<UsingChunk>(chunk);
            Assert.Equal(expected, usingChunk.Namespace);
        }
Example #38
0
        public void Merge_AddsChunkIfChunkWithMatchingPropertyNameWasNotVisitedInChunkTree()
        {
            // Arrange
            var expectedType = "MyApp.MyHelperType";
            var expectedProperty = "MyHelper";
            var merger = new InjectChunkMerger("dynamic");
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new InjectChunk(expectedType, expectedProperty)
            };

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

            // Assert
            var chunk = Assert.Single(chunkTree.Children);
            var injectChunk = Assert.IsType<InjectChunk>(chunk);
            Assert.Equal(expectedType, injectChunk.TypeName);
            Assert.Equal(expectedProperty, injectChunk.MemberName);
        }
Example #39
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());
            }
        }
Example #40
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);
                }
            }
        }
Example #41
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));
     }
 }
Example #42
0
        public void Merge_DoesNotAddMoreThanOneInstanceOfTheSameInheritedNamespace()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new Chunk[]
            {
                new LiteralChunk(),
                new UsingChunk { Namespace = "Microsoft.AspNetCore.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNetCore.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNetCore.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.AspNetCore.Mvc", chunk.Namespace);
            chunk = Assert.IsType<UsingChunk>(chunkTree.Children[1]);
            Assert.Equal("Microsoft.AspNetCore.Mvc.Razor", chunk.Namespace);
        }
Example #43
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);
            }
        }
Example #44
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;
        }
Example #45
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);
            }
        }
Example #46
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);
            }
        }
Example #47
0
        public void GetTagHelperDescriptors_ReturnsExpectedDirectiveDescriptors(
            ChunkTree[] chunkTrees,
            TagHelperDirectiveDescriptor[] expectedDirectiveDescriptors)
        {
            // Arrange
            var builder = new BlockBuilder { Type = BlockType.Comment };
            var block = new Block(builder);

            IList<TagHelperDirectiveDescriptor> descriptors = null;
            var resolver = new Mock<ITagHelperDescriptorResolver>();
            resolver.Setup(r => r.Resolve(It.IsAny<TagHelperDescriptorResolutionContext>()))
                    .Callback((TagHelperDescriptorResolutionContext context) =>
                    {
                        descriptors = context.DirectiveDescriptors;
                    })
                    .Returns(Enumerable.Empty<TagHelperDescriptor>())
                    .Verifiable();

            var baseParser = new RazorParser(
                new CSharpCodeParser(),
                new HtmlMarkupParser(),
                tagHelperDescriptorResolver: resolver.Object);
            var parser = new TestableMvcRazorParser(baseParser, chunkTrees, defaultInheritedChunks: new Chunk[0]);

            // Act
            parser.GetTagHelperDescriptorsPublic(block, errorSink: new ErrorSink()).ToArray();

            // Assert
            Assert.NotNull(descriptors);
            Assert.Equal(expectedDirectiveDescriptors.Length, descriptors.Count);

            for (var i = 0; i < expectedDirectiveDescriptors.Length; i++)
            {
                var expected = expectedDirectiveDescriptors[i];
                var actual = descriptors[i];

                Assert.Equal(expected.DirectiveText, actual.DirectiveText, StringComparer.Ordinal);
                Assert.Equal(SourceLocation.Zero, actual.Location);
                Assert.Equal(expected.DirectiveType, actual.DirectiveType);
            }
        }
Example #48
0
        public void Merge_MatchesNamespacesInCaseSensitiveManner()
        {
            // Arrange
            var merger = new UsingChunkMerger();
            var chunkTree = new ChunkTree();
            var inheritedChunks = new[]
            {
                new UsingChunk { Namespace = "Microsoft.AspNetCore.Mvc" },
                new UsingChunk { Namespace = "Microsoft.AspNetCore.mvc" }
            };

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

            // Assert
            Assert.Equal(2, chunkTree.Children.Count);
            var chunk = Assert.IsType<UsingChunk>(chunkTree.Children[0]);
            Assert.Equal("Microsoft.AspNetCore.Mvc", chunk.Namespace);
            chunk = Assert.IsType<UsingChunk>(chunkTree.Children[1]);
            Assert.Equal("Microsoft.AspNetCore.mvc", chunk.Namespace);
        }
Example #49
0
 private static IChunkMerger[] GetChunkMergers(ChunkTree chunkTree, string defaultModel)
 {
     var modelType = ChunkHelper.GetModelTypeName(chunkTree, defaultModel);
     return new IChunkMerger[]
     {
         new UsingChunkMerger(),
         new InjectChunkMerger(modelType),
         new SetBaseTypeChunkMerger(modelType)
     };
 }
Example #50
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);
        }
Example #51
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);
                });
        }
Example #52
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());
            }
        }
Example #53
0
        /// <summary>
        /// Merges <see cref="Chunk"/> inherited by default and <see cref="ChunkTree"/> instances produced by parsing
        /// <c>_ViewImports</c> files into the specified <paramref name="chunkTree"/>.
        /// </summary>
        /// <param name="chunkTree">The <see cref="ChunkTree"/> to merge in to.</param>
        /// <param name="inheritedChunkTrees"><see cref="IReadOnlyList{ChunkTree}"/> inherited from <c>_ViewImports</c>
        /// files.</param>
        /// <param name="defaultModel">The default model <see cref="Type"/> name.</param>
        public void MergeInheritedChunkTrees(
            ChunkTree chunkTree,
            IReadOnlyList<ChunkTree> inheritedChunkTrees,
            string defaultModel)
        {
            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

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

            var chunkMergers = GetChunkMergers(chunkTree, defaultModel);
            // We merge chunks into the ChunkTree in two passes. In the first pass, we traverse the ChunkTree visiting
            // a mapped IChunkMerger for types that are registered.
            foreach (var chunk in chunkTree.Children)
            {
                foreach (var merger in chunkMergers)
                {
                    merger.VisitChunk(chunk);
                }
            }

            var inheritedChunks = _defaultInheritedChunks.Concat(
                inheritedChunkTrees.SelectMany(tree => tree.Children)).ToArray();

            foreach (var merger in chunkMergers)
            {
                merger.MergeInheritedChunks(chunkTree, inheritedChunks);
            }
        }
        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));
            }
        }
Example #55
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);
        }