From 70b25a3d4f6a7013a5c2292086076e80e5aed585 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 29 Apr 2020 11:25:02 +0100 Subject: [PATCH] fix(localize): ensure `getLocation()` works (#36853) The `getLocation()` method was not working as there were typos in the properties it was reading. This was not picked up because there were neither typings for these properties nor unit tests to check it worked. PR Close #36853 --- .../src/tools/src/source_file_utils.ts | 2 +- .../src/tools/test/source_file_utils_spec.ts | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/localize/src/tools/src/source_file_utils.ts b/packages/localize/src/tools/src/source_file_utils.ts index 62cb32f9ee..34c186f89e 100644 --- a/packages/localize/src/tools/src/source_file_utils.ts +++ b/packages/localize/src/tools/src/source_file_utils.ts @@ -349,7 +349,7 @@ export function buildCodeFrameError(path: NodePath, e: BabelParseError): string export function getLocation(path: NodePath): ɵSourceLocation|undefined { const location = path.node.loc; - const file = path.hub.file.ops.fileName; + const file = path.hub.file.opts.filename; if (!location || !file) { return undefined; diff --git a/packages/localize/src/tools/test/source_file_utils_spec.ts b/packages/localize/src/tools/test/source_file_utils_spec.ts index d5fea629f1..f13a566629 100644 --- a/packages/localize/src/tools/test/source_file_utils_spec.ts +++ b/packages/localize/src/tools/test/source_file_utils_spec.ts @@ -6,11 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ import {ɵmakeTemplateObject} from '@angular/localize'; -import {NodePath, transformSync} from '@babel/core'; +import {NodePath, TransformOptions, transformSync} from '@babel/core'; import generate from '@babel/generator'; + import template from '@babel/template'; import {Expression, Identifier, TaggedTemplateExpression, ExpressionStatement, FunctionDeclaration, CallExpression, isParenthesizedExpression, numericLiteral, binaryExpression, NumericLiteral} from '@babel/types'; -import {isGlobalIdentifier, isNamedIdentifier, isStringLiteralArray, isArrayOfExpressions, unwrapStringLiteralArray, unwrapMessagePartsFromLocalizeCall, wrapInParensIfNecessary, buildLocalizeReplacement, unwrapSubstitutionsFromLocalizeCall, unwrapMessagePartsFromTemplateLiteral} from '../src/source_file_utils'; +import {isGlobalIdentifier, isNamedIdentifier, isStringLiteralArray, isArrayOfExpressions, unwrapStringLiteralArray, unwrapMessagePartsFromLocalizeCall, wrapInParensIfNecessary, buildLocalizeReplacement, unwrapSubstitutionsFromLocalizeCall, unwrapMessagePartsFromTemplateLiteral, getLocation} from '../src/source_file_utils'; describe('utils', () => { describe('isNamedIdentifier()', () => { @@ -193,11 +194,32 @@ describe('utils', () => { expect(isArrayOfExpressions(ast.params)).toBe(false); }); }); + + describe('getLocation()', () => { + it('should return a plain object containing the start, end and file of a NodePath', () => { + const taggedTemplate = + getTaggedTemplate('const x = $localize ``;', {filename: 'src/test.js'}); + const location = getLocation(taggedTemplate)!; + expect(location).toBeDefined(); + expect(location.start).toEqual({line: 1, column: 10}); + expect(location.start.constructor.name).toEqual('Object'); + expect(location.end).toEqual({line: 1, column: 22}); + expect(location.end.constructor.name).toEqual('Object'); + expect(location.file).toContain('src/test.js'); + }); + + it('should return undefined if the NodePath has no filename', () => { + const taggedTemplate = getTaggedTemplate('const x = $localize ``;'); + const location = getLocation(taggedTemplate)!; + expect(location).toBeUndefined(); + }); + }); }); -function getTaggedTemplate(code: string): NodePath { +function getTaggedTemplate( + code: string, options?: TransformOptions): NodePath { const {expressions, plugin} = collectExpressionsPlugin(); - transformSync(code, {plugins: [plugin]}); + transformSync(code, {...options, plugins: [plugin]}); return expressions.find(e => e.isTaggedTemplateExpression()) as any; }