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)]);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 |