75 lines
3.0 KiB
TypeScript
75 lines
3.0 KiB
TypeScript
|
/**
|
||
|
* @license
|
||
|
* Copyright Google Inc. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by an MIT-style license that can be
|
||
|
* found in the LICENSE file at https://angular.io/license
|
||
|
*/
|
||
|
|
||
|
import {ASTWithSource, AbsoluteSourceSpan, NullAstVisitor} from '@angular/compiler';
|
||
|
import * as t from '../../src/render3/r3_ast';
|
||
|
import {parseR3 as parse} from './view/util';
|
||
|
|
||
|
class ExpressionLocationHumanizer extends NullAstVisitor implements t.Visitor {
|
||
|
result: any[] = [];
|
||
|
|
||
|
visitASTWithSource(ast: ASTWithSource) { this.result.push([ast.source, ast.sourceSpan]); }
|
||
|
|
||
|
visitTemplate(ast: t.Template) { t.visitAll(this, ast.children); }
|
||
|
visitElement(ast: t.Element) {
|
||
|
t.visitAll(this, ast.children);
|
||
|
t.visitAll(this, ast.inputs);
|
||
|
t.visitAll(this, ast.outputs);
|
||
|
}
|
||
|
visitReference(ast: t.Reference) {}
|
||
|
visitVariable(ast: t.Variable) {}
|
||
|
visitEvent(ast: t.BoundEvent) { ast.handler.visit(this); }
|
||
|
visitTextAttribute(ast: t.TextAttribute) {}
|
||
|
visitBoundAttribute(ast: t.BoundAttribute) { ast.value.visit(this); }
|
||
|
visitBoundEvent(ast: t.BoundEvent) { ast.handler.visit(this); }
|
||
|
visitBoundText(ast: t.BoundText) { ast.value.visit(this); }
|
||
|
visitContent(ast: t.Content) {}
|
||
|
visitText(ast: t.Text) {}
|
||
|
visitIcu(ast: t.Icu) {}
|
||
|
}
|
||
|
|
||
|
function humanizeExpressionLocation(templateAsts: t.Node[]): any[] {
|
||
|
const humanizer = new ExpressionLocationHumanizer();
|
||
|
t.visitAll(humanizer, templateAsts);
|
||
|
return humanizer.result;
|
||
|
}
|
||
|
|
||
|
describe('expression AST absolute source spans', () => {
|
||
|
// TODO(ayazhafiz): duplicate this test without `preserveWhitespaces` once whitespace rewriting is
|
||
|
// moved to post-R3AST generation.
|
||
|
it('should provide absolute offsets with arbitrary whitespace', () => {
|
||
|
expect(humanizeExpressionLocation(
|
||
|
parse('<div>\n \n{{foo}}</div>', {preserveWhitespaces: true}).nodes))
|
||
|
.toContain(['\n \n{{foo}}', new AbsoluteSourceSpan(5, 16)]);
|
||
|
});
|
||
|
|
||
|
it('should provide absolute offsets of an expression in a bound text', () => {
|
||
|
expect(humanizeExpressionLocation(parse('<div>{{foo}}</div>').nodes)).toContain([
|
||
|
'{{foo}}', new AbsoluteSourceSpan(5, 12)
|
||
|
]);
|
||
|
});
|
||
|
|
||
|
it('should provide absolute offsets of an expression in a bound event', () => {
|
||
|
expect(humanizeExpressionLocation(parse('<div (click)="foo();bar();"></div>').nodes))
|
||
|
.toContain(['foo();bar();', new AbsoluteSourceSpan(14, 26)]);
|
||
|
|
||
|
expect(humanizeExpressionLocation(parse('<div on-click="foo();bar();"></div>').nodes))
|
||
|
.toContain(['foo();bar();', new AbsoluteSourceSpan(15, 27)]);
|
||
|
});
|
||
|
|
||
|
it('should provide absolute offsets of an expression in a bound attribute', () => {
|
||
|
expect(
|
||
|
humanizeExpressionLocation(parse('<input [disabled]="condition ? true : false" />').nodes))
|
||
|
.toContain(['condition ? true : false', new AbsoluteSourceSpan(19, 43)]);
|
||
|
|
||
|
expect(humanizeExpressionLocation(
|
||
|
parse('<input bind-disabled="condition ? true : false" />').nodes))
|
||
|
.toContain(['condition ? true : false', new AbsoluteSourceSpan(22, 46)]);
|
||
|
});
|
||
|
});
|