зеркало из https://github.com/dotnet/razor.git
Update TagHelper completion to understand dictionary attributes.
- Since dictionaries fill `TagHelperDescriptor`s with two ways to bind to a `TagHelper` (prefix or full match) we need to take into account their indexer name prefix when providing attribute completions. - Added tests to ensure that bound and unbound scenarios work as expected. #7759
This commit is contained in:
Родитель
4c8e63e610
Коммит
e3d89c262e
|
@ -88,11 +88,25 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
foreach (var attributeDescriptor in descriptor.BoundAttributes)
|
||||
{
|
||||
UpdateCompletions(attributeDescriptor.Name, attributeDescriptor);
|
||||
|
||||
if (!string.IsNullOrEmpty(attributeDescriptor.IndexerNamePrefix))
|
||||
{
|
||||
UpdateCompletions(attributeDescriptor.IndexerNamePrefix + "...", attributeDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var htmlNameToBoundAttribute = descriptor.BoundAttributes.ToDictionary(attribute => attribute.Name, StringComparer.OrdinalIgnoreCase);
|
||||
var htmlNameToBoundAttribute = new Dictionary<string, BoundAttributeDescriptor>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var attributeDescriptor in descriptor.BoundAttributes)
|
||||
{
|
||||
htmlNameToBoundAttribute[attributeDescriptor.Name] = attributeDescriptor;
|
||||
|
||||
if (!string.IsNullOrEmpty(attributeDescriptor.IndexerNamePrefix))
|
||||
{
|
||||
htmlNameToBoundAttribute[attributeDescriptor.IndexerNamePrefix] = attributeDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var rule in descriptor.TagMatchingRules)
|
||||
{
|
||||
|
@ -100,11 +114,11 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
{
|
||||
if (htmlNameToBoundAttribute.TryGetValue(requiredAttribute.Name, out var attributeDescriptor))
|
||||
{
|
||||
UpdateCompletions(requiredAttribute.Name, attributeDescriptor);
|
||||
UpdateCompletions(requiredAttribute.DisplayName, attributeDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCompletions(requiredAttribute.Name, possibleDescriptor: null);
|
||||
UpdateCompletions(requiredAttribute.DisplayName, possibleDescriptor: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
@ -11,6 +12,96 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
{
|
||||
public class DefaultTagHelperCompletionServiceTest
|
||||
{
|
||||
[Fact]
|
||||
public void GetAttributeCompletions_BoundDictionaryAttribute_ReturnsPrefixIndexerAndFullSetter()
|
||||
{
|
||||
// Arrange
|
||||
var documentDescriptors = new[]
|
||||
{
|
||||
TagHelperDescriptorBuilder.Create("FormTagHelper", "TestAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule
|
||||
.RequireTagName("form"))
|
||||
.BoundAttributeDescriptor(attribute => attribute
|
||||
.Name("asp-all-route-data")
|
||||
.TypeName("System.Collections.Generic.IDictionary<System.String, System.String>")
|
||||
.PropertyName("RouteValues").AsDictionary("asp-route-", typeof(string).FullName))
|
||||
.Build(),
|
||||
};
|
||||
var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
|
||||
{
|
||||
["asp-all-route-data"] = new HashSet<BoundAttributeDescriptor>()
|
||||
{
|
||||
documentDescriptors[0].BoundAttributes.Last(),
|
||||
},
|
||||
["asp-route-..."] = new HashSet<BoundAttributeDescriptor>()
|
||||
{
|
||||
documentDescriptors[0].BoundAttributes.Last(),
|
||||
}
|
||||
});
|
||||
|
||||
var completionContext = BuildAttributeCompletionContext(
|
||||
documentDescriptors,
|
||||
Array.Empty<string>(),
|
||||
attributes: new Dictionary<string, string>(),
|
||||
currentTagName: "form");
|
||||
var service = CreateTagHelperCompletionFactsService();
|
||||
|
||||
// Act
|
||||
var completions = service.GetAttributeCompletions(completionContext);
|
||||
|
||||
// Assert
|
||||
AssertCompletionsAreEquivalent(expectedCompletions, completions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetAttributeCompletions_RequiredBoundDictionaryAttribute_ReturnsPrefixIndexerAndFullSetter()
|
||||
{
|
||||
// Arrange
|
||||
var documentDescriptors = new[]
|
||||
{
|
||||
TagHelperDescriptorBuilder.Create("FormTagHelper", "TestAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule
|
||||
.RequireTagName("form")
|
||||
.RequireAttributeDescriptor(builder =>
|
||||
{
|
||||
builder.Name = "asp-route-";
|
||||
builder.NameComparisonMode = RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch;
|
||||
}))
|
||||
.TagMatchingRuleDescriptor(rule => rule
|
||||
.RequireTagName("form")
|
||||
.RequireAttributeDescriptor(builder => builder.Name = "asp-all-route-data"))
|
||||
.BoundAttributeDescriptor(attribute => attribute
|
||||
.Name("asp-all-route-data")
|
||||
.TypeName("System.Collections.Generic.IDictionary<System.String, System.String>")
|
||||
.PropertyName("RouteValues").AsDictionary("asp-route-", typeof(string).FullName))
|
||||
.Build(),
|
||||
};
|
||||
var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
|
||||
{
|
||||
["asp-all-route-data"] = new HashSet<BoundAttributeDescriptor>()
|
||||
{
|
||||
documentDescriptors[0].BoundAttributes.Last(),
|
||||
},
|
||||
["asp-route-..."] = new HashSet<BoundAttributeDescriptor>()
|
||||
{
|
||||
documentDescriptors[0].BoundAttributes.Last(),
|
||||
}
|
||||
});
|
||||
|
||||
var completionContext = BuildAttributeCompletionContext(
|
||||
documentDescriptors,
|
||||
Array.Empty<string>(),
|
||||
attributes: new Dictionary<string, string>(),
|
||||
currentTagName: "form");
|
||||
var service = CreateTagHelperCompletionFactsService();
|
||||
|
||||
// Act
|
||||
var completions = service.GetAttributeCompletions(completionContext);
|
||||
|
||||
// Assert
|
||||
AssertCompletionsAreEquivalent(expectedCompletions, completions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetAttributeCompletions_DoesNotReturnCompletionsForAlreadySuppliedAttributes()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче