fix(language-service): HTML path should include last node before cursor (#34440)
Given the following HTML and cursor position: ``` <div c|></div> ^ cursor is here ``` Note that the cursor is **after** the attribute `c`. Under the current implementation, only `Element` is included in the path. Instead, it should be `Element -> Attribute`. This bug occurs only for cases where the cursor is right after the Node, and it is because the `end` position of the span is excluded from the search. Instead, the `end` position should be included. PR Close #34440
This commit is contained in:

committed by
Kara Erickson

parent
11257b85fa
commit
76e4870a3f
@ -6,8 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as ng from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
import {getDirectiveClassLike} from '../src/utils';
|
||||
|
||||
import {getDirectiveClassLike, getPathToNodeAtPosition} from '../src/utils';
|
||||
|
||||
describe('getDirectiveClassLike()', () => {
|
||||
it('should return a directive class', () => {
|
||||
@ -32,3 +34,49 @@ describe('getDirectiveClassLike()', () => {
|
||||
expect(classDecl.name !.text).toBe('AppModule');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPathToNodeAtPosition', () => {
|
||||
const html = '<div c></div>';
|
||||
const nodes: ng.Node[] = [];
|
||||
|
||||
beforeAll(() => {
|
||||
const parser = new ng.HtmlParser();
|
||||
const {rootNodes, errors} = parser.parse(html, 'url');
|
||||
expect(errors.length).toBe(0);
|
||||
nodes.push(...rootNodes);
|
||||
});
|
||||
|
||||
it('must capture element', () => {
|
||||
// First, try to get a Path to the Element
|
||||
// <|div c></div>
|
||||
// ^ cursor is here
|
||||
const position = html.indexOf('div');
|
||||
const path = getPathToNodeAtPosition(nodes, position);
|
||||
// There should be just 1 node in the path, the Element node
|
||||
expect(path.empty).toBe(false);
|
||||
expect(path.head instanceof ng.Element).toBe(true);
|
||||
expect(path.head).toBe(path.tail);
|
||||
});
|
||||
|
||||
it('must capture attribute', () => {
|
||||
// Then, try to get a Path to the Attribute
|
||||
// <div |c></div>
|
||||
// ^ cusor is here, before the attribute
|
||||
const position = html.indexOf('c');
|
||||
const path = getPathToNodeAtPosition(nodes, position);
|
||||
expect(path.empty).toBe(false);
|
||||
expect(path.head instanceof ng.Element).toBe(true);
|
||||
expect(path.tail instanceof ng.Attribute).toBe(true);
|
||||
});
|
||||
|
||||
it('must capture attribute before cursor', () => {
|
||||
// Finally, try to get a Path to the attribute after the 'c' text
|
||||
// <div c|></div>
|
||||
// ^ cursor is here, after the attribute
|
||||
const position = html.indexOf('c') + 1;
|
||||
const path = getPathToNodeAtPosition(nodes, position);
|
||||
expect(path.empty).toBe(false);
|
||||
expect(path.head instanceof ng.Element).toBe(true);
|
||||
expect(path.tail instanceof ng.Attribute).toBe(true);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user