public void TagHelpers_CanReplaceAttributeChunkGeneratorLogic() { // Arrange var inputTypePropertyInfo = typeof(TestType).GetProperty("Type"); var checkedPropertyInfo = typeof(TestType).GetProperty("Checked"); var tagHelperDescriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly" }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", Attributes = new TagHelperAttributeDescriptor[] { new TagHelperAttributeDescriptor("type", inputTypePropertyInfo) }, TagStructure = TagStructure.WithoutEndTag }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", Attributes = new TagHelperAttributeDescriptor[] { new TagHelperAttributeDescriptor("type", inputTypePropertyInfo), new TagHelperAttributeDescriptor("checked", checkedPropertyInfo) } } }; // Act & Assert RunTagHelperTest(testName: "BasicTagHelpers", baseLineName: "BasicTagHelpers.CustomAttributeCodeGenerator", tagHelperDescriptors: tagHelperDescriptors, hostConfig: (host) => { return new CodeGeneratorReplacingHost(host); }); }
public void TagHelperDescriptor_CanBeSerialized() { // Arrange var descriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", RequiredAttributes = new[] { "required attribute one", "required attribute two" }, AllowedChildren = new[] { "allowed child one" }, RequiredParent = "parent name", DesignTimeDescriptor = new TagHelperDesignTimeDescriptor { Summary = "usage summary", Remarks = "usage remarks", OutputElementHint = "some-tag" }, }; var expectedSerializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":" + "[\"required attribute one\",\"required attribute two\"]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\"]," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{"+ $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); // Assert Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal); }
public void CreateDescriptor_OnlyAcceptsPropertiesWithGetAndSet() { // Arrange var validProperty = typeof(MissingAccessorTagHelper).GetProperty( nameof(MissingAccessorTagHelper.ValidAttribute)); var expectedDescriptor = new TagHelperDescriptor( "missing-accessor", typeof(MissingAccessorTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("valid-attribute", validProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(MissingAccessorTagHelper)); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public void GetDescriptors_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool() { // Arrange var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div")) .Build(); var descriptors = new TagHelperDescriptor[] { divDescriptor, divDescriptor }; var tagHelperBinder = new TagHelperBinder(null, descriptors); // Act var bindingResult = tagHelperBinder.GetBinding( tagName: "div", attributes: Array.Empty <KeyValuePair <string, string> >(), parentTagName: "p", parentIsTagHelper: false); // Assert var descriptor = Assert.Single(bindingResult.Descriptors); Assert.Same(divDescriptor, descriptor); }
public void CreateDescriptor_DoesntResolveInheritedTagNames() { // Arrange var validProp = typeof(InheritedMultiTagTagHelper).GetProperty(nameof(InheritedMultiTagTagHelper.ValidAttribute)); var expectedDescriptor = new TagHelperDescriptor( "InheritedMultiTag", typeof(InheritedMultiTagTagHelper).FullName, AssemblyName, ContentBehavior.None, new[] { new TagHelperAttributeDescriptor(nameof(InheritedMultiTagTagHelper.ValidAttribute), validProp) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(InheritedMultiTagTagHelper)); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public void CreateDescriptor_BuildsDescriptorsWithInheritedProperties() { // Arrange var intProperty = typeof(InheritedSingleAttributeTagHelper).GetProperty( nameof(InheritedSingleAttributeTagHelper.IntAttribute)); var expectedDescriptor = new TagHelperDescriptor( "inherited-single-attribute", typeof(InheritedSingleAttributeTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("int-attribute", intProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(InheritedSingleAttributeTagHelper)); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public void CreateDescriptor_BuildsDescriptorsWithConventionNames() { // Arrange var intProperty = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute)); var expectedDescriptor = new TagHelperDescriptor( "SingleAttribute", typeof(SingleAttributeTagHelper).FullName, AssemblyName, ContentBehavior.None, new[] { new TagHelperAttributeDescriptor(nameof(SingleAttributeTagHelper.IntAttribute), intProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(SingleAttributeTagHelper)); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public async Task EnqueuePublish_OnProjectBeforeTagHelperProcessed_DoesNotPublish() { // Arrange var serializationSuccessful = false; var firstSnapshot = CreateProjectSnapshot("/path/to/project.csproj"); var tagHelpers = new TagHelperDescriptor[] { new DefaultTagHelperDescriptor(FileKinds.Component, "Namespace.FileNameOther", "Assembly", "FileName", "FileName document", "FileName hint", caseSensitive: false, tagMatchingRules: null, attributeDescriptors: null, allowedChildTags: null, metadata: null, diagnostics: null) }; var secondSnapshot = CreateProjectSnapshot("/path/to/project.csproj", new ProjectWorkspaceState(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp8), new string[] { "FileName.razor" }); var expectedConfigurationFilePath = "/path/to/obj/bin/Debug/project.razor.json"; var publisher = new TestDefaultRazorProjectChangePublisher( ProjectConfigurationFilePathStore, _razorLogger, onSerializeToFile: (snapshot, configurationFilePath) => { Assert.Same(secondSnapshot, snapshot); Assert.Equal(expectedConfigurationFilePath, configurationFilePath); serializationSuccessful = true; }, useRealShouldSerialize: true) { EnqueueDelay = 10, _active = true, }; publisher.Initialize(ProjectSnapshotManager); ProjectConfigurationFilePathStore.Set(firstSnapshot.FilePath, expectedConfigurationFilePath); // Act publisher.EnqueuePublish(secondSnapshot); // Assert var kvp = Assert.Single(publisher.DeferredPublishTasks); await kvp.Value.ConfigureAwait(false); Assert.False(serializationSuccessful); }
public async Task ProjectManager_Changed_Remove_Change_NoopsOnDelayedPublish() { // Arrange var serializationSuccessful = false; var tagHelpers = new TagHelperDescriptor[] { new DefaultTagHelperDescriptor(FileKinds.Component, "Namespace.FileNameOther", "Assembly", "FileName", "FileName document", "FileName hint", caseSensitive: false, tagMatchingRules: null, attributeDescriptors: null, allowedChildTags: null, metadata: null, diagnostics: null) }; var initialProjectSnapshot = CreateProjectSnapshot("/path/to/project.csproj", new ProjectWorkspaceState(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.Preview)); var expectedProjectSnapshot = CreateProjectSnapshot("/path/to/project.csproj", new ProjectWorkspaceState(ImmutableArray <TagHelperDescriptor> .Empty, CodeAnalysis.CSharp.LanguageVersion.Preview)); var expectedConfigurationFilePath = "/path/to/obj/bin/Debug/project.razor.json"; var publisher = new TestDefaultRazorProjectChangePublisher( ProjectConfigurationFilePathStore, _razorLogger, onSerializeToFile: (snapshot, configurationFilePath) => { Assert.Same(expectedProjectSnapshot, snapshot); Assert.Equal(expectedConfigurationFilePath, configurationFilePath); serializationSuccessful = true; }) { EnqueueDelay = 10, _active = true, }; publisher.Initialize(ProjectSnapshotManager); ProjectConfigurationFilePathStore.Set(expectedProjectSnapshot.FilePath, expectedConfigurationFilePath); var documentRemovedArgs = ProjectChangeEventArgs.CreateTestInstance(initialProjectSnapshot, initialProjectSnapshot, documentFilePath: "/path/to/file.razor", ProjectChangeKind.DocumentRemoved); var projectChangedArgs = ProjectChangeEventArgs.CreateTestInstance(initialProjectSnapshot, expectedProjectSnapshot, documentFilePath: null, ProjectChangeKind.ProjectChanged); // Act publisher.ProjectSnapshotManager_Changed(null, documentRemovedArgs); publisher.ProjectSnapshotManager_Changed(null, projectChangedArgs); // Assert var stalePublishTask = Assert.Single(publisher.DeferredPublishTasks); await stalePublishTask.Value.ConfigureAwait(false); Assert.True(serializationSuccessful); }
public void DescriptorResolver_ResolvesMultipleTypes() { // Arrange var resolver = new TestTagHelperDescriptorResolver( new LookupBasedTagHelperTypeResolver( new Dictionary <string, IEnumerable <Type> >(StringComparer.OrdinalIgnoreCase) { { AssemblyName, new Type[] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } }, })); var expectedDescriptors = new TagHelperDescriptor[] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor }; // Act var descriptors = resolver.Resolve(AssemblyName).ToArray(); // Assert Assert.Equal(descriptors.Length, 2); Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default); }
public void GetDescriptors_ReturnsNothingForUnregisteredTags() { // Arrange var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div")) .Build(); var spanDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName("span")) .Build(); var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor }; var tagHelperBinder = new TagHelperBinder(null, descriptors); // Act var tagHelperBinding = tagHelperBinder.GetBinding( tagName: "foo", attributes: Array.Empty <KeyValuePair <string, string> >(), parentTagName: "p", parentIsTagHelper: false); // Assert Assert.Null(tagHelperBinding); }
private void Register(TagHelperDescriptor descriptor) { var count = descriptor.TagMatchingRules.Count; for (var i = 0; i < count; i++) { var rule = descriptor.TagMatchingRules[i]; var registrationKey = string.Equals(rule.TagName, TagHelperMatchingConventions.ElementCatchAllName, StringComparison.Ordinal) ? TagHelperMatchingConventions.ElementCatchAllName : _tagHelperPrefix + rule.TagName; // Ensure there's a HashSet to add the descriptor to. if (!_registrations.TryGetValue(registrationKey, out HashSet <TagHelperDescriptor> descriptorSet)) { descriptorSet = new HashSet <TagHelperDescriptor>(TagHelperDescriptorComparer.Default); _registrations[registrationKey] = descriptorSet; } descriptorSet.Add(descriptor); } }
public void CreateDescriptor_OnlyAcceptsPropertiesWithPublicGetAndSet() { // Arrange var validProperty = typeof(PrivateAccessorTagHelper).GetProperty( nameof(PrivateAccessorTagHelper.ValidAttribute)); var expectedDescriptor = new TagHelperDescriptor( "PrivateAccessor", typeof(PrivateAccessorTagHelper).FullName, ContentBehavior.None, new[] { new TagHelperAttributeDescriptor( nameof(PrivateAccessorTagHelper.ValidAttribute), validProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(PrivateAccessorTagHelper)); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public override int GetHashCode(TagHelperDescriptor descriptor) { var hashCodeCombiner = HashCodeCombiner.Start(); hashCodeCombiner.Add(base.GetHashCode(descriptor)); hashCodeCombiner.Add(descriptor.TagName, StringComparer.Ordinal); hashCodeCombiner.Add(descriptor.Prefix, StringComparer.Ordinal); if (descriptor.DesignTimeDescriptor != null) { hashCodeCombiner.Add( TagHelperDesignTimeDescriptorComparer.Default.GetHashCode(descriptor.DesignTimeDescriptor)); } foreach (var requiredAttribute in descriptor.RequiredAttributes.OrderBy(attribute => attribute.Name)) { hashCodeCombiner.Add( CaseSensitiveTagHelperRequiredAttributeDescriptorComparer.Default.GetHashCode(requiredAttribute)); } if (descriptor.AllowedChildren != null) { foreach (var child in descriptor.AllowedChildren.OrderBy(child => child)) { hashCodeCombiner.Add(child, StringComparer.Ordinal); } } var orderedAttributeHashCodes = descriptor.Attributes .Select(attribute => TagHelperAttributeDescriptorComparer.Default.GetHashCode(attribute)) .OrderBy(hashcode => hashcode); foreach (var attributeHashCode in orderedAttributeHashCodes) { hashCodeCombiner.Add(attributeHashCode); } return(hashCodeCombiner.CombinedHash); }
private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo) { if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal)) { return(false); } if (lookupInfo.TypePattern.EndsWith("*", StringComparison.Ordinal)) { if (lookupInfo.TypePattern.Length == 1) { // TypePattern is "*". return(true); } var lookupTypeName = lookupInfo.TypePattern.Substring(0, lookupInfo.TypePattern.Length - 1); return(descriptor.TypeName.StartsWith(lookupTypeName, StringComparison.Ordinal)); } return(string.Equals(descriptor.TypeName, lookupInfo.TypePattern, StringComparison.Ordinal)); }
public void DescriptorResolver_ResolvesOnlyTypeResolverProvidedTypes() { // Arrange var resolver = new TagHelperDescriptorResolver( new LookupBasedTagHelperTypeResolver( new Dictionary <string, IEnumerable <Type> >(StringComparer.OrdinalIgnoreCase) { { "lookupText1", ValidTestableTagHelpers }, { "lookupText2", new Type[] { typeof(Valid_PlainTagHelper) } } })); var expectedDescriptor = new TagHelperDescriptor("Valid_Plain", typeof(Valid_PlainTagHelper).FullName, ContentBehavior.None); // Act var descriptors = resolver.Resolve("lookupText2"); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default); }
public void GetDescriptors_ReturnsCatchAllsWithEveryTagName() { // Arrange var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div")) .Build(); var spanDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName("span")) .Build(); var catchAllDescriptor = TagHelperDescriptorBuilder.Create("foo3", "SomeAssembly") .TagMatchingRuleDescriptor(rule => rule.RequireTagName(TagHelperMatchingConventions.ElementCatchAllName)) .Build(); var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor }; var tagHelperBinder = new TagHelperBinder(null, descriptors); // Act var divBinding = tagHelperBinder.GetBinding( tagName: "div", attributes: Array.Empty <KeyValuePair <string, string> >(), parentTagName: "p", parentIsTagHelper: false); var spanBinding = tagHelperBinder.GetBinding( tagName: "span", attributes: Array.Empty <KeyValuePair <string, string> >(), parentTagName: "p", parentIsTagHelper: false); // Assert // For divs Assert.Equal(2, divBinding.Descriptors.Count()); Assert.Contains(divDescriptor, divBinding.Descriptors); Assert.Contains(catchAllDescriptor, divBinding.Descriptors); // For spans Assert.Equal(2, spanBinding.Descriptors.Count()); Assert.Contains(spanDescriptor, spanBinding.Descriptors); Assert.Contains(catchAllDescriptor, spanBinding.Descriptors); }
public TagHelperDescriptor GetTagHelperDescriptorOne() { var descriptor = new TagHelperDescriptor { TagName = "vc:one", TypeName = "__Generated__OneViewComponentTagHelper", AssemblyName = "Microsoft.AspNetCore.Mvc.Razor", Attributes = new List <TagHelperAttributeDescriptor> { new TagHelperAttributeDescriptor { Name = "foo", PropertyName = "foo", TypeName = typeof(string).FullName }, new TagHelperAttributeDescriptor { Name = "bar", PropertyName = "bar", TypeName = typeof(string).FullName } }, RequiredAttributes = new List <TagHelperRequiredAttributeDescriptor> { new TagHelperRequiredAttributeDescriptor { Name = "foo" }, new TagHelperRequiredAttributeDescriptor { Name = "bar" } } }; descriptor.PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "One"); return(descriptor); }
public void DescriptorResolver_IgnoresSpaces(string lookupText) { // Arrange var tagHelperTypeResolver = new TestTagHelperTypeResolver(TestableTagHelpers) { OnGetLibraryDefinedTypes = (assemblyName) => { Assert.Equal("MyAssembly", assemblyName.Name); } }; var tagHelperDescriptorResolver = new TagHelperDescriptorResolver(tagHelperTypeResolver); var expectedDescriptor = new TagHelperDescriptor("Valid_Plain", typeof(Valid_PlainTagHelper).FullName, ContentBehavior.None); // Act var descriptors = tagHelperDescriptorResolver.Resolve(lookupText); // Assert var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default); }
public override bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY) { if (descriptorX == descriptorY) { return(true); } return(base.Equals(descriptorX, descriptorY) && // Normal comparer doesn't care about the case, required attribute order, attributes or prefixes. // In tests we do. string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.Ordinal) && string.Equals(descriptorX.Prefix, descriptorY.Prefix, StringComparison.Ordinal) && Enumerable.SequenceEqual( descriptorX.RequiredAttributes, descriptorY.RequiredAttributes, StringComparer.Ordinal) && descriptorX.Attributes.SequenceEqual( descriptorY.Attributes, TagHelperAttributeDescriptorComparer.Default) && TagHelperDesignTimeDescriptorComparer.Default.Equals( descriptorX.DesignTimeDescriptor, descriptorY.DesignTimeDescriptor)); }
private static void ValidateBinding( TagHelperBinding bindingResult, string tagName, Block tagBlock, ErrorSink errorSink) { // Ensure that all descriptors associated with this tag have appropriate TagStructures. Cannot have // multiple descriptors that expect different TagStructures (other than TagStructure.Unspecified). TagHelperDescriptor baseDescriptor = null; TagStructure? baseStructure = null; foreach (var descriptor in bindingResult.Descriptors) { var boundRules = bindingResult.GetBoundRules(descriptor); foreach (var rule in boundRules) { if (rule.TagStructure != TagStructure.Unspecified) { // Can't have a set of TagHelpers that expect different structures. if (baseStructure.HasValue && baseStructure != rule.TagStructure) { errorSink.OnError( tagBlock.Start, LegacyResources.FormatTagHelperParseTreeRewriter_InconsistentTagStructure( baseDescriptor.DisplayName, descriptor.DisplayName, tagName, nameof(TagMatchingRuleDescriptor.TagStructure)), tagBlock.Length); } baseDescriptor = descriptor; baseStructure = rule.TagStructure; } } } }
private void RewriteUsage(TagHelperIntermediateNode node, TagHelperDescriptor tagHelper) { // We need to surround the contents of the node with open and close nodes to ensure the component // is scoped correctly. node.Children.Insert(0, new ComponentOpenExtensionNode() { TypeName = tagHelper.GetTypeName(), }); for (var i = node.Children.Count - 1; i >= 0; i--) { if (node.Children[i] is TagHelperBodyIntermediateNode bodyNode) { // Replace with a node that we recognize so that it we can do proper scope tracking. // // Note that we force the body node to be last, this is done to push it after the // attribute nodes. This gives us the ordering we want for the render tree. node.Children.RemoveAt(i); node.Children.Add(new ComponentBodyExtensionNode(bodyNode) { TagMode = node.TagMode, TagName = node.TagName, }); } } node.Children.Add(new ComponentCloseExtensionNode()); // Now we need to rewrite any set property or HTML nodes to call the appropriate AddAttribute api. for (var i = node.Children.Count - 1; i >= 0; i--) { if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode && propertyNode.TagHelper == tagHelper) { node.Children[i] = new ComponentAttributeExtensionNode(propertyNode); }
public void TagHelperDescriptorProvider_GetTagHelpersReturnsCatchAllsWithEveryTagName() { // Arrange var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly", ContentBehavior.None); var spanDescriptor = new TagHelperDescriptor("span", "foo2", "SomeAssembly", ContentBehavior.None); var catchAllDescriptor = new TagHelperDescriptor("*", "foo3", "SomeAssembly", ContentBehavior.None); var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act var divDescriptors = provider.GetTagHelpers("div"); var spanDescriptors = provider.GetTagHelpers("span"); // Assert // For divs Assert.Equal(2, divDescriptors.Count()); Assert.Contains(divDescriptor, divDescriptors); Assert.Contains(catchAllDescriptor, divDescriptors); // For spans Assert.Equal(2, spanDescriptors.Count()); Assert.Contains(spanDescriptor, spanDescriptors); Assert.Contains(catchAllDescriptor, spanDescriptors); }
public void Rewrite_AllowsCompatibleTagStructures( string documentContent, TagStructure structure1, TagStructure structure2, MarkupBlock expectedOutput) { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", TagStructure = structure1 }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", TagStructure = structure2 } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void Rewrite_CreatesErrorForWithoutEndTagTagStructureForEndTags() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var expectedError = new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag( "input", "InputTagHelper", TagStructure.WithoutEndTag), absoluteIndex: 2, lineIndex: 0, columnIndex: 2, length: 5); var documentContent = "</input>"; var expectedOutput = new MarkupBlock(blockFactory.MarkupTagBlock("</input>")); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError }); }
public void Rewrite_CanHandleStartTagOnlyTagTagMode() { // Arrange var documentContent = "<input>"; var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly)); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void DescriptorResolver_ResolvesMultipleTypes() { // Arrange var resolver = new TestTagHelperDescriptorResolver( new LookupBasedTagHelperTypeResolver( new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase) { { AssemblyName, new Type[]{ Valid_PlainTagHelperType, Valid_InheritedTagHelperType } }, })); var expectedDescriptors = new TagHelperDescriptor[] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor }; // Act var descriptors = resolver.Resolve("*, " + AssemblyName).ToArray(); // Assert Assert.Equal(descriptors.Length, 2); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }
public void GetDescriptors_ReturnsNothingForUnregisteredTags() { // Arrange var divDescriptor = new TagHelperDescriptor { TagName = "div", TypeName = "foo1", AssemblyName = "SomeAssembly", }; var spanDescriptor = new TagHelperDescriptor { TagName = "span", TypeName = "foo2", AssemblyName = "SomeAssembly", }; var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act var retrievedDescriptors = provider.GetDescriptors( tagName: "foo", attributeNames: Enumerable.Empty<string>(), parentTagName: "p"); // Assert Assert.Empty(retrievedDescriptors); }
public void GetDescriptors_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool() { // Arrange var divDescriptor = new TagHelperDescriptor { TagName = "div", TypeName = "foo1", AssemblyName = "SomeAssembly", }; var descriptors = new TagHelperDescriptor[] { divDescriptor, divDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act var retrievedDescriptors = provider.GetDescriptors( tagName: "div", attributeNames: Enumerable.Empty<string>(), parentTagName: "p"); // Assert var descriptor = Assert.Single(retrievedDescriptors); Assert.Same(divDescriptor, descriptor); }
public void TagHelperDescriptor_WithAttributes_CanBeDeserialized() { // Arrange var serializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":0," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name" }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsStringProperty = true }, }, AllowedChildren = new[] { "allowed child one", "allowed child two" } }; // Act var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor); // Assert Assert.NotNull(descriptor); Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.FullTagName, descriptor.FullTagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.Attributes, descriptor.Attributes, TagHelperAttributeDescriptorComparer.Default); Assert.Empty(descriptor.RequiredAttributes); }
public void Rewrite_UnderstandsNullTagNameWithAllowedChildrenForCatchAllWithPrefix() { // Arrange var documentContent = "<th:p></</th:p>"; var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "custom" }, Prefix = "th:", }, new TagHelperDescriptor { TagName = "*", TypeName = "CatchAllTagHelper", AssemblyName = "SomeAssembly", Prefix = "th:", } }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("th:p", BlockFactory.MarkupTagBlock("</"))); var descriptorProvider = new TagHelperDescriptorProvider(descriptors); var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_CannotHaveNonTagContent("th:p", "custom"), absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 2) }; // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public static bool IsAttributeDescriptor(this TagHelperDescriptor d) { return(d.Metadata.TryGetValue(TagHelperMetadata.Common.ClassifyAttributesOnly, out var value) || string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase)); }
internal static bool TryGetDescriptor(int hashCode, out TagHelperDescriptor descriptor) => CachedTagHelperDescriptors.TryGetValue(hashCode, out descriptor);
public string GetFieldName(TagHelperDescriptor taghelper) { return(_tagHelpers[taghelper].fieldName); }
public void Rewrite_CanHandleMultipleTagHelpersWithAllowedChildren() { // Arrange var factory = CreateDefaultSpanFactory(); var documentContent = "<p><strong>Hello World</strong><br></p>"; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("p", new MarkupTagHelperBlock("strong", factory.Markup("Hello World")), new MarkupTagHelperBlock("br", TagMode.StartTagOnly))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper1", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "strong" } }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper2", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "br" } }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly" }, new TagHelperDescriptor { TagName = "br", TypeName = "BRTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
internal static string GetVariableName(TagHelperDescriptor descriptor) { return "__" + descriptor.TypeName.Replace('.', '_'); }
public void ProcessMessage_ResolveTagHelperDescriptors_ResolvesDesignTimeTagHelperDescriptors() { // Arrange var expectedSourceLocation = new SourceLocation(absoluteIndex: 1, lineIndex: 2, characterIndex: 3); var sourceLocationJson = JsonConvert.SerializeObject(expectedSourceLocation); var messageData = new JObject { { "AssemblyName", CustomTagHelperAssembly }, { "SourceLocation", JObject.Parse(sourceLocationJson) } }; var message = new JObject { { "MessageType", RazorPluginMessageTypes.ResolveTagHelperDescriptors }, { "Data", messageData }, }; ResolveTagHelperDescriptorsMessage responseMessage = null; var messageBroker = new TestPluginMessageBroker( data => responseMessage = (ResolveTagHelperDescriptorsMessage)data); var assembly = new TestAssembly(typeof(DesignTimeTagHelper)); var assemblyNameLookups = new Dictionary<string, Assembly> { { CustomTagHelperAssembly, assembly } }; var assemblyLoadContext = new TestAssemblyLoadContext(assemblyNameLookups); var plugin = new RazorPlugin(messageBroker); var expectedDescriptor = new TagHelperDescriptor { Prefix = DefaultPrefix, TagName = "design-time", TypeName = typeof(DesignTimeTagHelper).FullName, AssemblyName = typeof(DesignTimeTagHelper).Assembly.GetName().Name, AllowedChildren = new[] { "br" }, TagStructure = TagStructure.NormalOrSelfClosing, DesignTimeDescriptor = new TagHelperDesignTimeDescriptor { OutputElementHint = "strong" } }; // Act var handled = plugin.ProcessMessage(message, assemblyLoadContext); // Assert Assert.NotNull(responseMessage); Assert.Equal( RazorPluginMessageTypes.ResolveTagHelperDescriptors, responseMessage.MessageType, StringComparer.Ordinal); var responseData = responseMessage.Data; Assert.Equal(CustomTagHelperAssembly, responseData.AssemblyName, StringComparer.Ordinal); var actualDescriptor = Assert.Single(responseData.Descriptors); Assert.Equal(expectedDescriptor, actualDescriptor, CaseSensitiveTagHelperDescriptorComparer.Default); Assert.Empty(responseData.Errors); Assert.True(handled); }
public void Rewrite_UnderstandsMinimizedAttributes( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true } }, RequiredAttributes = new[] { "unbound-required" } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true } }, RequiredAttributes = new[] { "bound-required-string" } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-int", PropertyName = "BoundRequiredInt", TypeName = typeof(int).FullName } }, RequiredAttributes = new[] { "bound-required-int" } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper3", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "int-dictionary", PropertyName ="DictionaryOfIntProperty", TypeName = typeof(IDictionary<string, int>).FullName }, new TagHelperAttributeDescriptor { Name = "string-dictionary", PropertyName = "DictionaryOfStringProperty", TypeName = typeof(IDictionary<string, string>).FullName }, new TagHelperAttributeDescriptor { Name = "int-prefix-", PropertyName = "DictionaryOfIntProperty", TypeName = typeof(int).FullName, IsIndexer = true }, new TagHelperAttributeDescriptor { Name = "string-prefix-", PropertyName = "DictionaryOfStringProperty", TypeName = typeof(string).FullName, IsIndexer = true, IsStringProperty = true } } }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true }, new TagHelperAttributeDescriptor { Name = "bound-int", PropertyName = "BoundRequiredString", TypeName = typeof(int).FullName } } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_UnderstandsAllowedChildren( string documentContent, IEnumerable<string> allowedChildren, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = allowedChildren }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = allowedChildren }, new TagHelperDescriptor { TagName = "br", TypeName = "BRTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public string GetClassName(TagHelperDescriptor taghelper) { return(_tagHelpers[taghelper].className); }
public void TagHelperDescriptor_WithAttributes_CanBeSerialized() { // Arrange var descriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name" }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsStringProperty = true }, }, TagStructure = TagStructure.NormalOrSelfClosing }; var expectedSerializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":1," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); // Assert Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal); }
public void Rewrite_UnderstandsNestedRequiredParent(string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredParent = "p", }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredParent = "div", }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly" } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void GetDescriptors_ReturnsCatchAllsWithEveryTagName() { // Arrange var divDescriptor = new TagHelperDescriptor { TagName = "div", TypeName = "foo1", AssemblyName = "SomeAssembly", }; var spanDescriptor = new TagHelperDescriptor { TagName = "span", TypeName = "foo2", AssemblyName = "SomeAssembly", }; var catchAllDescriptor = new TagHelperDescriptor { TagName = TagHelperDescriptorProvider.ElementCatchAllTarget, TypeName = "foo3", AssemblyName = "SomeAssembly", }; var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act var divDescriptors = provider.GetDescriptors( tagName: "div", attributeNames: Enumerable.Empty<string>(), parentTagName: "p"); var spanDescriptors = provider.GetDescriptors( tagName: "span", attributeNames: Enumerable.Empty<string>(), parentTagName: "p"); // Assert // For divs Assert.Equal(2, divDescriptors.Count()); Assert.Contains(divDescriptor, divDescriptors); Assert.Contains(catchAllDescriptor, divDescriptors); // For spans Assert.Equal(2, spanDescriptors.Count()); Assert.Contains(spanDescriptor, spanDescriptors); Assert.Contains(catchAllDescriptor, spanDescriptors); }
public void TagHelpers_WithinHelpersAndSections_GeneratesExpectedOutput() { // Arrange var propertyInfo = typeof(TestType).GetProperty("BoundProperty"); var tagHelperDescriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "MyTagHelper", TypeName = "MyTagHelper", AssemblyName = "SomeAssembly", Attributes = new [] { new TagHelperAttributeDescriptor("BoundProperty", propertyInfo) } }, new TagHelperDescriptor { TagName = "NestedTagHelper", TypeName = "NestedTagHelper", AssemblyName = "SomeAssembly" } }; // Act & Assert RunTagHelperTest("TagHelpersInSection", tagHelperDescriptors: tagHelperDescriptors); }
public void Rewrite_RecoversWhenRequiredAttributeMismatchAndRestrictedChildren() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var documentContent = "<strong required><strong></strong></strong>"; var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InvalidNestedTag("strong", "strong", "br"), absoluteIndex: 18, lineIndex: 0, columnIndex: 18, length: 6) }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("strong", new List<KeyValuePair<string, SyntaxTreeNode>> { new KeyValuePair<string, SyntaxTreeNode>("required", null) }, blockFactory.MarkupTagBlock("<strong>"), blockFactory.MarkupTagBlock("</strong>"))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredAttributes = new[] { "required" }, AllowedChildren = new[] { "br" } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_UnderstandsTagHelperPrefixAndAllowedChildren() { // Arrange var documentContent = "<th:p><th:strong></th:strong></th:p>"; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("th:p", new MarkupTagHelperBlock("th:strong"))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "strong" }, Prefix = "th:" }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", Prefix = "th:" } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData( descriptorProvider, documentContent, expectedOutput, expectedErrors: Enumerable.Empty<RazorError>()); }
public void TagHelperParseTreeRewriter_CreatesMarkupCodeSpansForNonStringTagHelperAttributes( string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "person", TypeName = "PersonTagHelper", AssemblyName = "personAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "age", PropertyName = "Age", TypeName = typeof(int).FullName }, new TagHelperAttributeDescriptor { Name = "birthday", PropertyName = "BirthDay", TypeName = typeof(DateTime).FullName }, new TagHelperAttributeDescriptor { Name = "name", PropertyName = "Name", TypeName = typeof(string).FullName, IsStringProperty = true } } } }; var providerContext = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(providerContext, documentContent, expectedOutput, expectedErrors: Enumerable.Empty<RazorError>()); }
public void Rewrite_CreatesErrorForInconsistentTagStructures() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var expectedError = new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InconsistentTagStructure( "InputTagHelper1", "InputTagHelper2", "input", nameof(TagHelperDescriptor.TagStructure)), absoluteIndex: 0, lineIndex: 0, columnIndex: 0, length: 7); var documentContent = "<input>"; var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly)); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", TagStructure = TagStructure.NormalOrSelfClosing } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError }); }
public void Rewrite_CanHandleInvalidChildrenWithWhitespace() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var documentContent = $"<p>{Environment.NewLine} <strong>{Environment.NewLine} Hello" + $"{Environment.NewLine} </strong>{Environment.NewLine}</p>"; var newLineLength = Environment.NewLine.Length; var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InvalidNestedTag("strong", "p", "br"), absoluteIndex: 8 + newLineLength, lineIndex: 1, columnIndex: 5, length: 6), }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("p", factory.Markup(Environment.NewLine + " "), blockFactory.MarkupTagBlock("<strong>"), factory.Markup(Environment.NewLine + " Hello" + Environment.NewLine + " "), blockFactory.MarkupTagBlock("</strong>"), factory.Markup(Environment.NewLine))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "br" }, } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_CanHandleWithoutEndTagTagStructure(string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag, } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
internal static string GetVariableName(TagHelperDescriptor descriptor) { return("__" + descriptor.TypeName.Replace('.', '_')); }
public void Rewrite_CreatesErrorForEmptyTagHelperBoundAttributes( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "myth", TypeName = "mythTagHelper", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound", PropertyName = "Bound", TypeName = typeof(bool).FullName }, new TagHelperAttributeDescriptor { Name = "name", PropertyName = "Name", TypeName = typeof(string).FullName, IsStringProperty = true } } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public string GetFullyQualifiedName(TagHelperDescriptor taghelper) { return(_tagHelpers[taghelper].fullyQualifiedName); }
public void Rewrite_RequiredAttributeDescriptorsCreateMalformedTagHelperBlocksCorrectly( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "pTagHelper", AssemblyName = "SomeAssembly", RequiredAttributes = new[] { "class" } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
private static string GenerateFieldName(TagHelperDescriptor tagHelper) { return($"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper"); }
public void TagHelperDescrictorsAreCompatibleWithPinnedVisualStudioVersion() { // Arrange var runtimeDescriptor = new TagHelperDescriptor { AllowedChildren = new[] { "tr", "td" }, AssemblyName = "CustomAssembly", Prefix = "th:", RequiredAttributes = new[] { "runat" }, RequiredParent = "body", TagName = "custom-table", TagStructure = TagStructure.NormalOrSelfClosing, TypeName = "Custom.Type.TableTagHelper", DesignTimeDescriptor = new TagHelperDesignTimeDescriptor { OutputElementHint = "table", Remarks = "Some tag level remarks.", Summary = "Some tag level summary." }, Attributes = new[] { new TagHelperAttributeDescriptor { IsIndexer = false, IsStringProperty = true, Name = "bind", PropertyName = "Bind", TypeName = "System.String", DesignTimeDescriptor = new TagHelperAttributeDesignTimeDescriptor { Remarks = "Some attribute level remarks.", Summary = "Some attribute level summary." } } } }; var expectedVSDescriptor = new VisualStudioTagHelperDescriptor { AllowedChildren = new[] { "tr", "td" }, AssemblyName = "CustomAssembly", Prefix = "th:", RequiredAttributes = new[] { "runat" }, RequiredParent = "body", TagName = "custom-table", TagStructure = VisualStudioTagStructure.NormalOrSelfClosing, TypeName = "Custom.Type.TableTagHelper", DesignTimeDescriptor = new VisualStudioTagHelperDesignTimeDescriptor { OutputElementHint = "table", Remarks = "Some tag level remarks.", Summary = "Some tag level summary." }, Attributes = new[] { new VisualStudioTagHelperAttributeDescriptor { IsIndexer = false, IsStringProperty = true, Name = "bind", PropertyName = "Bind", TypeName = "System.String", DesignTimeDescriptor = new VisualStudioTagHelperAttributeDesignTimeDescriptor { Remarks = "Some attribute level remarks.", Summary = "Some attribute level summary." } } } }; var serializedRuntimeDescriptor = JsonConvert.SerializeObject(runtimeDescriptor); // Act var vsDescriptor = JsonConvert.DeserializeObject<VisualStudioTagHelperDescriptor>(serializedRuntimeDescriptor); // Assert Assert.Equal(expectedVSDescriptor.AllowedChildren, vsDescriptor.AllowedChildren, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.AssemblyName, vsDescriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.Prefix, vsDescriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.RequiredAttributes, vsDescriptor.RequiredAttributes, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.RequiredParent, vsDescriptor.RequiredParent, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.TagName, vsDescriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedVSDescriptor.TagStructure, vsDescriptor.TagStructure); Assert.Equal(expectedVSDescriptor.TypeName, vsDescriptor.TypeName, StringComparer.Ordinal); var dtDescriptor = vsDescriptor.DesignTimeDescriptor; var expectedDTDescriptor = expectedVSDescriptor.DesignTimeDescriptor; Assert.Equal(expectedDTDescriptor.OutputElementHint, dtDescriptor.OutputElementHint, StringComparer.Ordinal); Assert.Equal(expectedDTDescriptor.Remarks, dtDescriptor.Remarks, StringComparer.Ordinal); Assert.Equal(expectedDTDescriptor.Summary, dtDescriptor.Summary, StringComparer.Ordinal); var attribute = Assert.Single(vsDescriptor.Attributes); var expectedAttribute = Assert.Single(expectedVSDescriptor.Attributes); Assert.Equal(attribute.IsIndexer, expectedAttribute.IsIndexer); Assert.Equal(attribute.IsStringProperty, expectedAttribute.IsStringProperty); Assert.Equal(attribute.Name, expectedAttribute.Name, StringComparer.Ordinal); Assert.Equal(attribute.PropertyName, expectedAttribute.PropertyName, StringComparer.Ordinal); Assert.Equal(attribute.TypeName, expectedAttribute.TypeName, StringComparer.Ordinal); var dtAttribute = attribute.DesignTimeDescriptor; var expectedDTAttribute = expectedAttribute.DesignTimeDescriptor; Assert.Equal(dtAttribute.Remarks, expectedDTAttribute.Remarks, StringComparer.Ordinal); Assert.Equal(dtAttribute.Summary, expectedDTAttribute.Summary, StringComparer.Ordinal); }
internal static void Set(int hashCode, TagHelperDescriptor descriptor) => CachedTagHelperDescriptors.Set(hashCode, descriptor);
public void CreateDescriptors_UnderstandsEditorBrowsableAttribute( Type tagHelperType, bool designTime, TagHelperDescriptor[] expectedDescriptors) { // Arrange var errorSink = new ErrorSink(); var factory = new TagHelperDescriptorFactory(designTime); // Act var descriptors = factory.CreateDescriptors( AssemblyName, GetTypeInfo(tagHelperType), errorSink); // Assert Assert.Empty(errorSink.Errors); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }
internal static bool TrySplitNamespaceAndType(TagHelperDescriptor tagHelperDescriptor, out StringSegment @namespace) => TrySplitNamespaceAndType(tagHelperDescriptor, out @namespace, out _);
public void CreateDescriptors_IsEnumIsSetCorrectly( Type tagHelperType, TagHelperDescriptor[] expectedDescriptors) { // Arrange var errorSink = new ErrorSink(); var factory = new TagHelperDescriptorFactory(designTime: false); // Act var descriptors = factory.CreateDescriptors( AssemblyName, GetTypeInfo(tagHelperType), errorSink: errorSink); // Assert Assert.Empty(errorSink.Errors); // We don't care about order. Mono returns reflected attributes differently so we need to ensure order // doesn't matter by sorting. descriptors = descriptors.OrderBy(descriptor => descriptor.TagName); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }