/// <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; } } } }
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(); } }
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); }
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); }
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); }
/// <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(); }
/// <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; }
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); }
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); }
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); }
/// <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; }
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); }
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 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); }
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); }
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); }
/// <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); } } }
/// <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)); } }
/// <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)); } } }
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); }
/// <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) } }; }
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); } }
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); }); }
public ChunkTreeBuilder() { ChunkTree = new ChunkTree(); _parentStack = new Stack <ParentChunk>(); }
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); }