public void GetCompletionAt_AtAttributeEdge_BoolAttribute_ReturnsCompletionsWithout()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<test2 />", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(36 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Collection(
                completions,
                completion =>
            {
                Assert.Equal("bool-val", completion.InsertText);
                Assert.Equal(TagHelperCompletionProvider.MinimizedAttributeCommitCharacters, completion.CommitCharacters);
                Assert.Equal(CompletionSortTextHelper.HighSortPriority, completion.SortText);
            },
                completion =>
            {
                Assert.Equal("int-val", completion.InsertText);
                Assert.Equal(TagHelperCompletionProvider.AttributeCommitCharacters, completion.CommitCharacters);
                Assert.Equal(CompletionSortTextHelper.HighSortPriority, completion.SortText);
            });
        }
Beispiel #2
0
        private CompletionList GenerateCompletionList(string documentContent, int queryIndex, TagHelperCompletionProvider componentCompletionProvider)
        {
            var sourceDocument           = RazorSourceDocument.Create(documentContent, RazorSourceDocumentProperties.Default);
            var syntaxTree               = RazorSyntaxTree.Parse(sourceDocument);
            var tagHelperDocumentContext = TagHelperDocumentContext.Create(prefix: string.Empty, DefaultTagHelpers);

            var completionQueryLocation = new SourceSpan(queryIndex, length: 0);
            var context = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            var razorCompletionItems = componentCompletionProvider.GetCompletionItems(context, completionQueryLocation);
            var completionList       = RazorCompletionEndpoint.CreateLSPCompletionList(
                razorCompletionItems,
                new CompletionListCache(),
                new[] { ExtendedCompletionItemKinds.TagHelper },
                new PlatformAgnosticCompletionCapability()
            {
                VSCompletionList = new VSCompletionListCapability()
                {
                    CommitCharacters = true,
                    Data             = true,
                }
            });

            return(completionList);
        }
        private CompletionList GenerateCompletionList(string documentContent, int queryIndex, TagHelperCompletionProvider componentCompletionProvider)
        {
            var sourceDocument           = RazorSourceDocument.Create(documentContent, RazorSourceDocumentProperties.Default);
            var syntaxTree               = RazorSyntaxTree.Parse(sourceDocument);
            var tagHelperDocumentContext = TagHelperDocumentContext.Create(prefix: string.Empty, DefaultTagHelpers);

            var completionQueryLocation = new SourceSpan(queryIndex, length: 0);
            var context = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            var razorCompletionItems = componentCompletionProvider.GetCompletionItems(context, completionQueryLocation);
            var completionList       = RazorCompletionEndpoint.CreateLSPCompletionList(
                razorCompletionItems,
                new CompletionListCache(),
                new VSInternalClientCapabilities()
            {
                TextDocument = new TextDocumentClientCapabilities()
                {
                    Completion = new VSInternalCompletionSetting()
                    {
                        CompletionItemKind = new CompletionItemKindSetting()
                        {
                            ValueSet = new[] { CompletionItemKind.TagHelper }
                        },
                        CompletionList = new VSInternalCompletionListSetting()
                        {
                            CommitCharacters = true,
                            Data             = true,
                        }
                    }
                }
            });

            return(completionList);
        }
        public void GetCompletionAt_InBody_ParentRequiring_ReturnsCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<test1><</test1>", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(37 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Collection(
                completions,
                completion =>
            {
                Assert.Equal("test1", completion.InsertText);
            },
                completion =>
            {
                Assert.Equal("SomeChild", completion.InsertText);
            },
                completion =>
            {
                Assert.Equal("test2", completion.InsertText);
            });
        }
Beispiel #5
0
        public override IReadOnlyList <RazorCompletionItem> GetCompletionItems(RazorCompletionContext context, SourceSpan location)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.TagHelperDocumentContext is null)
            {
                throw new ArgumentNullException(nameof(context.TagHelperDocumentContext));
            }

            if (!FileKinds.IsComponent(context.SyntaxTree.Options.FileKind))
            {
                // Directive attributes are only supported in components
                return(s_noDirectiveAttributeCompletionItems);
            }

            var change = new SourceChange(location, string.Empty);
            var owner  = context.SyntaxTree.Root.LocateOwner(change);

            if (owner == null)
            {
                return(s_noDirectiveAttributeCompletionItems);
            }

            if (!TryGetAttributeInfo(owner, out _, out var attributeName, out var attributeNameLocation, out _, out _))
            {
                // Either we're not in an attribute or the attribute is so malformed that we can't provide proper completions.
                return(s_noDirectiveAttributeCompletionItems);
            }

            if (!attributeNameLocation.IntersectsWith(location.AbsoluteIndex))
            {
                // We're trying to retrieve completions on a portion of the name that is not supported (such as a parameter).
                return(s_noDirectiveAttributeCompletionItems);
            }

            if (!TryGetElementInfo(owner.Parent.Parent, out var containingTagName, out var attributes))
            {
                // This should never be the case, it means that we're operating on an attribute that doesn't have a tag.
                return(s_noDirectiveAttributeCompletionItems);
            }

            // At this point we've determined that completions have been requested for the name portion of the selected attribute.

            var completionItems = GetAttributeCompletions(attributeName, containingTagName, attributes, context.TagHelperDocumentContext);

            // We don't provide Directive Attribute completions when we're in the middle of
            // another unrelated (doesn't start with @) partially completed attribute.
            // <svg xml:| ></svg> (attributeName = "xml:") should not get any directive attribute completions.
            if (string.IsNullOrWhiteSpace(attributeName) || attributeName.StartsWith("@", StringComparison.Ordinal))
            {
                return(completionItems);
            }

            return(s_noDirectiveAttributeCompletionItems);
        }
        public async Task <CompletionContext> GetCompletionContextAsync(
            IAsyncCompletionSession session,
            CompletionTrigger trigger,
            SnapshotPoint triggerLocation,
            SnapshotSpan applicableSpan,
            CancellationToken token)
        {
            try
            {
                var codeDocument = await Parser.GetLatestCodeDocumentAsync(triggerLocation.Snapshot, token);

                if (codeDocument is null)
                {
                    return(CompletionContext.Empty);
                }

                var location   = new SourceSpan(triggerLocation.Position, 0);
                var syntaxTree = codeDocument.GetSyntaxTree();
                var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
                var razorCompletionContext   = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);
                var razorCompletionItems     = _completionFactsService.GetCompletionItems(razorCompletionContext, location);

                var completionItems = new List <CompletionItem>();
                foreach (var razorCompletionItem in razorCompletionItems)
                {
                    if (razorCompletionItem.Kind != RazorCompletionItemKind.Directive)
                    {
                        // Don't support any other types of completion kinds other than directives.
                        continue;
                    }

                    var completionItem = new CompletionItem(
                        displayText: razorCompletionItem.DisplayText,
                        filterText: razorCompletionItem.DisplayText,
                        insertText: razorCompletionItem.InsertText,
                        source: this,
                        icon: DirectiveImageGlyph,
                        filters: DirectiveCompletionFilters,
                        suffix: string.Empty,
                        sortText: razorCompletionItem.DisplayText,
                        attributeIcons: ImmutableArray <ImageElement> .Empty);
                    var completionDescription = razorCompletionItem.GetDirectiveCompletionDescription();
                    completionItem.Properties.AddProperty(DescriptionKey, completionDescription);
                    completionItems.Add(completionItem);
                }

                var context = new CompletionContext(completionItems.ToImmutableArray());
                return(context);
            }
            catch (OperationCanceledException)
            {
                return(CompletionContext.Empty);
            }
        }
        public void GetCompletionItems_AttributeAreaInNonComponentFile_ReturnsEmptyList()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<input  />", FileKinds.Legacy);
            var location   = new SourceSpan(7, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            Assert.Empty(result);
        }
        public void GetCompletionItems_OutsideOfFile_ReturnsEmptyList()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<input  />");
            var location   = new SourceSpan(50, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            Assert.Empty(result);
        }
        public void GetCompletionItems_ExistingAttribute_TrailingEdge_ReturnsEmptyList()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<input src=\"xyz\" />");
            var location   = new SourceSpan(16, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            Assert.Empty(result);
        }
        public void GetCompletionItems_ExistingAttribute_Partial_ReturnsEmptyList()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<svg xml: ></svg>");
            var location   = new SourceSpan(9, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            Assert.Empty(result);
        }
        public void GetCompletionAt_AtHtmlElementNameEdge_ReturnsNoCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<br />", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(32 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionAt_HtmlAttributeValue_DoesNotReturnCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<test2 class='' />", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(43 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionAt_InTagHelperAttribute_ReturnsCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<test2 int-val='123' />", DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(38 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionItems_InbetweenSelfClosingEnd_ReturnsEmptyList()
        {
            // Arrange

            var syntaxTree = GetSyntaxTree("<input /" + Environment.NewLine);
            var location   = new SourceSpan(8, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            Assert.Empty(result);
        }
        public void GetCompletionsAt_MalformedAttributeNamePrefix_ReturnsCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<test2 int->", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(36 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            AssertBoolIntCompletions(completions);
        }
        public void GetCompletionItems_ExistingAttribute_Partial_ReturnsEmptyCollection()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<svg xml: ></svg>");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span = new SourceSpan(9, 0);
            var razorCompletionContext = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(razorCompletionContext, span);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionItems_ExistingAttribute_TrailingEdge_ReturnsEmptyCollection()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input src=\"xyz\" />");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span = new SourceSpan(16, 0);
            var razorCompletionContext = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(razorCompletionContext, span);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionItems_AttributeAreaEndOfOpeningTag_ReturnsEmptyCollection()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input @bind:fo   ></input>");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span = new SourceSpan(16, 0);
            var razorCompletionContext = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(razorCompletionContext, span);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionItems_OnDirectiveAttributeName_attributes_ReturnsCompletions()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input @  />");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span = new SourceSpan(8, 0);
            var razorCompletionContext = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(razorCompletionContext, span);

            // Assert
            AssertContains(completions, "attributes", "@attributes", new[] { "=" });
        }
Beispiel #20
0
        public void GetCompletionItems_LocationHasNoOwner_ReturnsEmptyCollection()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input @  />");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span    = new SourceSpan(30, 0);
            var context = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(context, span);

            // Assert
            Assert.Empty(completions);
        }
        public void GetCompletionItems_AttributeAreaInIncompleteComponent_ReturnsTransitionCompletionItem()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<svg  xml:base=\"d\"></svg>");
            var location   = new SourceSpan(5, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            var item = Assert.Single(result);

            Assert.Same(item, TransitionCompletionItem);
        }
        public void GetCompletionItems_AttributeAreaEndOfOpeningTag_ReturnsTransitionCompletionItem()
        {
            // Arrange
            var syntaxTree = GetSyntaxTree("<input ></input>");
            var location   = new SourceSpan(7, 0);
            var context    = new RazorCompletionContext(syntaxTree, TagHelperDocumentContext);

            // Act
            var result = Provider.GetCompletionItems(context, location);

            // Assert
            var item = Assert.Single(result);

            Assert.Same(item, TransitionCompletionItem);
        }
Beispiel #23
0
        public void GetCompletionItems_OnDirectiveAttributeName_ReturnsEmptyCollection()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input @bind:fo  />");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span    = new SourceSpan(8, 0);
            var context = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(context, span);

            // Assert
            Assert.Empty(completions);
        }
Beispiel #24
0
        public override IReadOnlyList <RazorCompletionItem> GetCompletionItems(RazorCompletionContext context, SourceSpan location)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.TagHelperDocumentContext is null)
            {
                throw new ArgumentNullException(nameof(context.TagHelperDocumentContext));
            }

            if (!FileKinds.IsComponent(context.SyntaxTree.Options.FileKind))
            {
                // Directive attribute parameters are only supported in components
                return(Array.Empty <RazorCompletionItem>());
            }

            var change = new SourceChange(location, string.Empty);
            var owner  = context.SyntaxTree.Root.LocateOwner(change);

            if (owner == null)
            {
                return(Array.Empty <RazorCompletionItem>());
            }

            if (!TryGetAttributeInfo(owner, out _, out var attributeName, out _, out var parameterName, out var parameterNameLocation))
            {
                // Either we're not in an attribute or the attribute is so malformed that we can't provide proper completions.
                return(Array.Empty <RazorCompletionItem>());
            }

            if (!parameterNameLocation.IntersectsWith(location.AbsoluteIndex))
            {
                // We're trying to retrieve completions on a portion of the name that is not supported (such as the name, i.e., |@bind|:format).
                return(Array.Empty <RazorCompletionItem>());
            }

            if (!TryGetElementInfo(owner.Parent.Parent, out var containingTagName, out var attributes))
            {
                // This should never be the case, it means that we're operating on an attribute that doesn't have a tag.
                return(Array.Empty <RazorCompletionItem>());
            }

            var completions = GetAttributeParameterCompletions(attributeName, parameterName, containingTagName, attributes, context.TagHelperDocumentContext);

            return(completions);
        }
        public void GetCompletionAt_AtEmptyTagName_ReturnsCompletions()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<", DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(30 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Collection(
                completions,
                completion => Assert.Equal("test1", completion.InsertText),
                completion => Assert.Equal("test2", completion.InsertText));
        }
        public override IReadOnlyList <RazorCompletionItem> GetCompletionItems(RazorCompletionContext context, SourceSpan location)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var completions = new List <RazorCompletionItem>();

            if (ShouldProvideCompletions(context, location))
            {
                var directiveCompletions = GetDirectiveCompletionItems(context.SyntaxTree);
                completions.AddRange(directiveCompletions);
            }

            return(completions);
        }
        public void GetDirectiveCompletionItems_AllProvidersCompletionItems()
        {
            // Arrange
            var syntaxTree = RazorSyntaxTree.Parse(TestRazorSourceDocument.Create());
            var tagHelperDocumentContext = TagHelperDocumentContext.Create(prefix: null, Enumerable.Empty <TagHelperDescriptor>());
            var completionItem1          = new RazorCompletionItem("displayText1", "insertText1", RazorCompletionItemKind.Directive);
            var context                = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);
            var provider1              = Mock.Of <RazorCompletionItemProvider>(p => p.GetCompletionItems(context, default) == new[] { completionItem1 }, MockBehavior.Strict);
            var completionItem2        = new RazorCompletionItem("displayText2", "insertText2", RazorCompletionItemKind.Directive);
            var provider2              = Mock.Of <RazorCompletionItemProvider>(p => p.GetCompletionItems(context, default) == new[] { completionItem2 }, MockBehavior.Strict);
            var completionFactsService = new DefaultRazorCompletionFactsService(new[] { provider1, provider2 });

            // Act
            var completionItems = completionFactsService.GetCompletionItems(context, default);

            // Assert
            Assert.Equal(new[] { completionItem1, completionItem2 }, completionItems);
        }
Beispiel #28
0
        public void GetCompletionItems_OnDirectiveAttributeParameter_ReturnsCompletions()
        {
            // Arrange
            var codeDocument             = GetCodeDocument("<input @bind:fo  />");
            var syntaxTree               = codeDocument.GetSyntaxTree();
            var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
            var span    = new SourceSpan(14, 0);
            var context = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);

            // Act
            var completions = Provider.GetCompletionItems(context, span);

            // Assert
            Assert.Equal(3, completions.Count);
            AssertContains(completions, "culture");
            AssertContains(completions, "event");
            AssertContains(completions, "format");
        }
Beispiel #29
0
        public override IReadOnlyList <RazorCompletionItem> GetCompletionItems(RazorCompletionContext context, SourceSpan location)
        {
            if (!FileKinds.IsComponent(context.SyntaxTree.Options.FileKind))
            {
                // Directive attributes are only supported in components
                return(Array.Empty <RazorCompletionItem>());
            }

            var change = new SourceChange(location, string.Empty);
            var owner  = context.SyntaxTree.Root.LocateOwner(change);

            if (owner is null)
            {
                return(Array.Empty <RazorCompletionItem>());
            }

            var attribute = owner.Parent;

            if (attribute is MarkupMiscAttributeContentSyntax && attribute.ContainsOnlyWhitespace())
            {
                // This represents a tag when there's no attribute content <InputText | />.
                return(s_completions);
            }

            if (!TryGetAttributeInfo(owner, out var prefixLocation, out var attributeName, out var attributeNameLocation, out _, out _))
            {
                return(Array.Empty <RazorCompletionItem>());
            }

            if (attributeNameLocation.IntersectsWith(location.AbsoluteIndex) && attributeName.StartsWith("@", StringComparison.Ordinal))
            {
                // The transition is already provided for the attribute name
                return(Array.Empty <RazorCompletionItem>());
            }

            if (!IsValidCompletionPoint(location, prefixLocation, attributeNameLocation))
            {
                // Not operating in the attribute name area
                return(Array.Empty <RazorCompletionItem>());
            }

            // This represents a tag when there's no attribute content <InputText | />.
            return(s_completions);
        }
        public void GetCompletionAt_KnownHtmlElement_ReturnsCompletions_DefaultPriority()
        {
            // Arrange
            var service      = new TagHelperCompletionProvider(RazorTagHelperCompletionService, HtmlFactsService, TagHelperFactsService);
            var codeDocument = CreateCodeDocument($"@addTagHelper *, TestAssembly{Environment.NewLine}<title  mutator />", isRazorFile: false, DefaultTagHelpers);
            var sourceSpan   = new SourceSpan(36 + Environment.NewLine.Length, 0);
            var context      = new RazorCompletionContext(codeDocument.GetSyntaxTree(), codeDocument.GetTagHelperContext());

            // Act
            var completions = service.GetCompletionItems(context, sourceSpan);

            // Assert
            Assert.Collection(
                completions,
                completion =>
            {
                Assert.Equal("Extra", completion.InsertText);
                Assert.Equal(TagHelperCompletionProvider.MinimizedAttributeCommitCharacters, completion.CommitCharacters);
                Assert.Equal("Extra", completion.SortText);
            });
        }