| 
									
										
										
										
											2019-04-28 20:47:57 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-04-28 20:47:57 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												fix(ngcc): correctly detect emitted TS helpers in ES5 (#35191)
In ES5 code, TypeScript requires certain helpers (such as
`__spreadArrays()`) to be able to support ES2015+ features. These
helpers can be either imported from `tslib` (by setting the
`importHelpers` TS compiler option to `true`) or emitted inline (by
setting the `importHelpers` and `noEmitHelpers` TS compiler options to
`false`, which is the default value for both).
Ngtsc's `StaticInterpreter` (which is also used during ngcc processing)
is able to statically evaluate some of these helpers (currently
`__assign()`, `__spread()` and `__spreadArrays()`), as long as
`ReflectionHost#getDefinitionOfFunction()` correctly detects the
declaration of the helper. For this to happen, the left-hand side of the
corresponding call expression (i.e. `__spread(...)` or
`tslib.__spread(...)`) must be evaluated as a function declaration for
`getDefinitionOfFunction()` to be called with.
In the case of imported helpers, the `tslib.__someHelper` expression was
resolved to a function declaration of the form
`export declare function __someHelper(...args: any[][]): any[];`, which
allows `getDefinitionOfFunction()` to correctly map it to a TS helper.
In contrast, in the case of emitted helpers (and regardless of the
module format: `CommonJS`, `ESNext`, `UMD`, etc.)), the `__someHelper`
identifier was resolved to a variable declaration of the form
`var __someHelper = (this && this.__someHelper) || function () { ... }`,
which upon further evaluation was categorized as a `DynamicValue`
(prohibiting further evaluation by the `getDefinitionOfFunction()`).
As a result of the above, emitted TypeScript helpers were not evaluated
in ES5 code.
---
This commit changes the detection of TS helpers to leverage the existing
`KnownFn` feature (previously only used for built-in functions).
`Esm5ReflectionHost` is changed to always return `KnownDeclaration`s for
TS helpers, both imported (`getExportsOfModule()`) as well as emitted
(`getDeclarationOfIdentifier()`).
Similar changes are made to `CommonJsReflectionHost` and
`UmdReflectionHost`.
The `KnownDeclaration`s are then mapped to `KnownFn`s in
`StaticInterpreter`, allowing it to statically evaluate call expressions
involving any kind of TS helpers.
Jira issue: https://angular-team.atlassian.net/browse/FW-1689
PR Close #35191
											
										 
											2020-02-06 18:44:49 +02:00
										 |  |  | import * as ts from 'typescript'; | 
					
						
							| 
									
										
										
										
											2020-04-01 17:31:04 +03:00
										 |  |  | import {absoluteFrom as _abs} from '../../src/ngtsc/file_system'; | 
					
						
							|  |  |  | import {runInEachFileSystem} from '../../src/ngtsc/file_system/testing'; | 
					
						
							| 
									
										
											  
											
												fix(ngcc): correctly detect emitted TS helpers in ES5 (#35191)
In ES5 code, TypeScript requires certain helpers (such as
`__spreadArrays()`) to be able to support ES2015+ features. These
helpers can be either imported from `tslib` (by setting the
`importHelpers` TS compiler option to `true`) or emitted inline (by
setting the `importHelpers` and `noEmitHelpers` TS compiler options to
`false`, which is the default value for both).
Ngtsc's `StaticInterpreter` (which is also used during ngcc processing)
is able to statically evaluate some of these helpers (currently
`__assign()`, `__spread()` and `__spreadArrays()`), as long as
`ReflectionHost#getDefinitionOfFunction()` correctly detects the
declaration of the helper. For this to happen, the left-hand side of the
corresponding call expression (i.e. `__spread(...)` or
`tslib.__spread(...)`) must be evaluated as a function declaration for
`getDefinitionOfFunction()` to be called with.
In the case of imported helpers, the `tslib.__someHelper` expression was
resolved to a function declaration of the form
`export declare function __someHelper(...args: any[][]): any[];`, which
allows `getDefinitionOfFunction()` to correctly map it to a TS helper.
In contrast, in the case of emitted helpers (and regardless of the
module format: `CommonJS`, `ESNext`, `UMD`, etc.)), the `__someHelper`
identifier was resolved to a variable declaration of the form
`var __someHelper = (this && this.__someHelper) || function () { ... }`,
which upon further evaluation was categorized as a `DynamicValue`
(prohibiting further evaluation by the `getDefinitionOfFunction()`).
As a result of the above, emitted TypeScript helpers were not evaluated
in ES5 code.
---
This commit changes the detection of TS helpers to leverage the existing
`KnownFn` feature (previously only used for built-in functions).
`Esm5ReflectionHost` is changed to always return `KnownDeclaration`s for
TS helpers, both imported (`getExportsOfModule()`) as well as emitted
(`getDeclarationOfIdentifier()`).
Similar changes are made to `CommonJsReflectionHost` and
`UmdReflectionHost`.
The `KnownDeclaration`s are then mapped to `KnownFn`s in
`StaticInterpreter`, allowing it to statically evaluate call expressions
involving any kind of TS helpers.
Jira issue: https://angular-team.atlassian.net/browse/FW-1689
PR Close #35191
											
										 
											2020-02-06 18:44:49 +02:00
										 |  |  | import {KnownDeclaration} from '../../src/ngtsc/reflection'; | 
					
						
							|  |  |  | import {FactoryMap, getTsHelperFnFromDeclaration, getTsHelperFnFromIdentifier, isRelativePath, stripExtension} from '../src/utils'; | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  | describe('FactoryMap', () => { | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  |   it('should return an existing value', () => { | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     const factoryFnSpy = jasmine.createSpy('factory'); | 
					
						
							|  |  |  |     const factoryMap = new FactoryMap<string, string>(factoryFnSpy, [['k1', 'v1'], ['k2', 'v2']]); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     expect(factoryMap.get('k1')).toBe('v1'); | 
					
						
							|  |  |  |     expect(factoryMap.get('k2')).toBe('v2'); | 
					
						
							|  |  |  |     expect(factoryFnSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not treat falsy values as missing', () => { | 
					
						
							|  |  |  |     const factoryFnSpy = jasmine.createSpy('factory').and.returnValue('never gonna happen'); | 
					
						
							|  |  |  |     const factoryMap = new FactoryMap<string, any>(factoryFnSpy, [ | 
					
						
							|  |  |  |       ['k1', ''], | 
					
						
							|  |  |  |       ['k2', 0], | 
					
						
							|  |  |  |       ['k3', false], | 
					
						
							|  |  |  |       ['k4', null], | 
					
						
							|  |  |  |       ['k5', undefined], | 
					
						
							|  |  |  |     ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(factoryMap.get('k1')).toBe(''); | 
					
						
							|  |  |  |     expect(factoryMap.get('k2')).toBe(0); | 
					
						
							|  |  |  |     expect(factoryMap.get('k3')).toBe(false); | 
					
						
							|  |  |  |     expect(factoryMap.get('k4')).toBe(null); | 
					
						
							|  |  |  |     expect(factoryMap.get('k5')).toBe(undefined); | 
					
						
							|  |  |  |     expect(factoryFnSpy).not.toHaveBeenCalled(); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should create, store and return the value if it does not exist', () => { | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     const factoryFnSpy = jasmine.createSpy('factory').and.returnValues('v3', 'never gonna happen'); | 
					
						
							|  |  |  |     const factoryMap = new FactoryMap(factoryFnSpy, [['k1', 'v1'], ['k2', 'v2']]); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     expect(factoryMap.get('k3')).toBe('v3'); | 
					
						
							|  |  |  |     expect(factoryFnSpy).toHaveBeenCalledTimes(1); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     factoryFnSpy.calls.reset(); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 02:10:01 +02:00
										 |  |  |     expect(factoryMap.get('k3')).toBe('v3'); | 
					
						
							|  |  |  |     expect(factoryFnSpy).not.toHaveBeenCalled(); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2019-04-28 20:47:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												fix(ngcc): correctly detect emitted TS helpers in ES5 (#35191)
In ES5 code, TypeScript requires certain helpers (such as
`__spreadArrays()`) to be able to support ES2015+ features. These
helpers can be either imported from `tslib` (by setting the
`importHelpers` TS compiler option to `true`) or emitted inline (by
setting the `importHelpers` and `noEmitHelpers` TS compiler options to
`false`, which is the default value for both).
Ngtsc's `StaticInterpreter` (which is also used during ngcc processing)
is able to statically evaluate some of these helpers (currently
`__assign()`, `__spread()` and `__spreadArrays()`), as long as
`ReflectionHost#getDefinitionOfFunction()` correctly detects the
declaration of the helper. For this to happen, the left-hand side of the
corresponding call expression (i.e. `__spread(...)` or
`tslib.__spread(...)`) must be evaluated as a function declaration for
`getDefinitionOfFunction()` to be called with.
In the case of imported helpers, the `tslib.__someHelper` expression was
resolved to a function declaration of the form
`export declare function __someHelper(...args: any[][]): any[];`, which
allows `getDefinitionOfFunction()` to correctly map it to a TS helper.
In contrast, in the case of emitted helpers (and regardless of the
module format: `CommonJS`, `ESNext`, `UMD`, etc.)), the `__someHelper`
identifier was resolved to a variable declaration of the form
`var __someHelper = (this && this.__someHelper) || function () { ... }`,
which upon further evaluation was categorized as a `DynamicValue`
(prohibiting further evaluation by the `getDefinitionOfFunction()`).
As a result of the above, emitted TypeScript helpers were not evaluated
in ES5 code.
---
This commit changes the detection of TS helpers to leverage the existing
`KnownFn` feature (previously only used for built-in functions).
`Esm5ReflectionHost` is changed to always return `KnownDeclaration`s for
TS helpers, both imported (`getExportsOfModule()`) as well as emitted
(`getDeclarationOfIdentifier()`).
Similar changes are made to `CommonJsReflectionHost` and
`UmdReflectionHost`.
The `KnownDeclaration`s are then mapped to `KnownFn`s in
`StaticInterpreter`, allowing it to statically evaluate call expressions
involving any kind of TS helpers.
Jira issue: https://angular-team.atlassian.net/browse/FW-1689
PR Close #35191
											
										 
											2020-02-06 18:44:49 +02:00
										 |  |  | describe('getTsHelperFnFromDeclaration()', () => { | 
					
						
							|  |  |  |   const createFunctionDeclaration = (fnName?: string) => ts.createFunctionDeclaration( | 
					
						
							|  |  |  |       undefined, undefined, undefined, fnName, undefined, [], undefined, undefined); | 
					
						
							|  |  |  |   const createVariableDeclaration = (varName: string) => | 
					
						
							|  |  |  |       ts.createVariableDeclaration(varName, undefined, undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__assign` helper as function declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createFunctionDeclaration('__assign'); | 
					
						
							|  |  |  |     const decl2 = createFunctionDeclaration('__assign$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__assign` helper as variable declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createVariableDeclaration('__assign'); | 
					
						
							|  |  |  |     const decl2 = createVariableDeclaration('__assign$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spread` helper as function declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createFunctionDeclaration('__spread'); | 
					
						
							|  |  |  |     const decl2 = createFunctionDeclaration('__spread$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spread` helper as variable declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createVariableDeclaration('__spread'); | 
					
						
							|  |  |  |     const decl2 = createVariableDeclaration('__spread$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spreadArrays` helper as function declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createFunctionDeclaration('__spreadArrays'); | 
					
						
							|  |  |  |     const decl2 = createFunctionDeclaration('__spreadArrays$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spreadArrays` helper as variable declaration', () => { | 
					
						
							|  |  |  |     const decl1 = createVariableDeclaration('__spreadArrays'); | 
					
						
							|  |  |  |     const decl2 = createVariableDeclaration('__spreadArrays$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should return null for unrecognized helpers', () => { | 
					
						
							|  |  |  |     const decl1 = createFunctionDeclaration('__foo'); | 
					
						
							|  |  |  |     const decl2 = createVariableDeclaration('spread'); | 
					
						
							|  |  |  |     const decl3 = createFunctionDeclaration('spread$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl1)).toBe(null); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl2)).toBe(null); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(decl3)).toBe(null); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should return null for unnamed declarations', () => { | 
					
						
							|  |  |  |     const unnamledDecl = createFunctionDeclaration(undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromDeclaration(unnamledDecl)).toBe(null); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should return null for non-function/variable declarations', () => { | 
					
						
							|  |  |  |     const classDecl = | 
					
						
							|  |  |  |         ts.createClassDeclaration(undefined, undefined, '__assign', undefined, undefined, []); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-06 08:30:08 +01:00
										 |  |  |     expect(classDecl.name!.text).toBe('__assign'); | 
					
						
							| 
									
										
											  
											
												fix(ngcc): correctly detect emitted TS helpers in ES5 (#35191)
In ES5 code, TypeScript requires certain helpers (such as
`__spreadArrays()`) to be able to support ES2015+ features. These
helpers can be either imported from `tslib` (by setting the
`importHelpers` TS compiler option to `true`) or emitted inline (by
setting the `importHelpers` and `noEmitHelpers` TS compiler options to
`false`, which is the default value for both).
Ngtsc's `StaticInterpreter` (which is also used during ngcc processing)
is able to statically evaluate some of these helpers (currently
`__assign()`, `__spread()` and `__spreadArrays()`), as long as
`ReflectionHost#getDefinitionOfFunction()` correctly detects the
declaration of the helper. For this to happen, the left-hand side of the
corresponding call expression (i.e. `__spread(...)` or
`tslib.__spread(...)`) must be evaluated as a function declaration for
`getDefinitionOfFunction()` to be called with.
In the case of imported helpers, the `tslib.__someHelper` expression was
resolved to a function declaration of the form
`export declare function __someHelper(...args: any[][]): any[];`, which
allows `getDefinitionOfFunction()` to correctly map it to a TS helper.
In contrast, in the case of emitted helpers (and regardless of the
module format: `CommonJS`, `ESNext`, `UMD`, etc.)), the `__someHelper`
identifier was resolved to a variable declaration of the form
`var __someHelper = (this && this.__someHelper) || function () { ... }`,
which upon further evaluation was categorized as a `DynamicValue`
(prohibiting further evaluation by the `getDefinitionOfFunction()`).
As a result of the above, emitted TypeScript helpers were not evaluated
in ES5 code.
---
This commit changes the detection of TS helpers to leverage the existing
`KnownFn` feature (previously only used for built-in functions).
`Esm5ReflectionHost` is changed to always return `KnownDeclaration`s for
TS helpers, both imported (`getExportsOfModule()`) as well as emitted
(`getDeclarationOfIdentifier()`).
Similar changes are made to `CommonJsReflectionHost` and
`UmdReflectionHost`.
The `KnownDeclaration`s are then mapped to `KnownFn`s in
`StaticInterpreter`, allowing it to statically evaluate call expressions
involving any kind of TS helpers.
Jira issue: https://angular-team.atlassian.net/browse/FW-1689
PR Close #35191
											
										 
											2020-02-06 18:44:49 +02:00
										 |  |  |     expect(getTsHelperFnFromDeclaration(classDecl)).toBe(null); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('getTsHelperFnFromIdentifier()', () => { | 
					
						
							|  |  |  |   it('should recognize the `__assign` helper', () => { | 
					
						
							|  |  |  |     const id1 = ts.createIdentifier('__assign'); | 
					
						
							|  |  |  |     const id2 = ts.createIdentifier('__assign$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id1)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id2)).toBe(KnownDeclaration.TsHelperAssign); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spread` helper', () => { | 
					
						
							|  |  |  |     const id1 = ts.createIdentifier('__spread'); | 
					
						
							|  |  |  |     const id2 = ts.createIdentifier('__spread$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id1)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id2)).toBe(KnownDeclaration.TsHelperSpread); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should recognize the `__spreadArrays` helper', () => { | 
					
						
							|  |  |  |     const id1 = ts.createIdentifier('__spreadArrays'); | 
					
						
							|  |  |  |     const id2 = ts.createIdentifier('__spreadArrays$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id1)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id2)).toBe(KnownDeclaration.TsHelperSpreadArrays); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should return null for unrecognized helpers', () => { | 
					
						
							|  |  |  |     const id1 = ts.createIdentifier('__foo'); | 
					
						
							|  |  |  |     const id2 = ts.createIdentifier('spread'); | 
					
						
							|  |  |  |     const id3 = ts.createIdentifier('spread$42'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id1)).toBe(null); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id2)).toBe(null); | 
					
						
							|  |  |  |     expect(getTsHelperFnFromIdentifier(id3)).toBe(null); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 17:31:04 +03:00
										 |  |  | runInEachFileSystem(() => { | 
					
						
							|  |  |  |   describe('isRelativePath()', () => { | 
					
						
							|  |  |  |     it('should return true for relative paths', () => { | 
					
						
							|  |  |  |       expect(isRelativePath('.')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('..')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('./')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('.\\')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('../')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('..\\')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('./abc/xyz')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('.\\abc\\xyz')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('../abc/xyz')).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath('..\\abc\\xyz')).toBe(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return true for absolute paths', () => { | 
					
						
							|  |  |  |       expect(isRelativePath(_abs('/'))).toBe(true); | 
					
						
							|  |  |  |       expect(isRelativePath(_abs('/abc/xyz'))).toBe(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return false for other paths', () => { | 
					
						
							|  |  |  |       expect(isRelativePath('abc')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('abc/xyz')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('.abc')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('..abc')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('@abc')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('.abc/xyz')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('..abc/xyz')).toBe(false); | 
					
						
							|  |  |  |       expect(isRelativePath('@abc/xyz')).toBe(false); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-04-28 20:47:57 +01:00
										 |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2019-12-20 15:38:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('stripExtension()', () => { | 
					
						
							|  |  |  |   it('should strip the extension from a file name', () => { | 
					
						
							|  |  |  |     expect(stripExtension('foo.ts')).toBe('foo'); | 
					
						
							|  |  |  |     expect(stripExtension('/foo/bar.ts')).toBe('/foo/bar'); | 
					
						
							|  |  |  |     expect(stripExtension('/foo/bar.d.ts')).toBe('/foo/bar'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should do nothing if there is no extension in a file name', () => { | 
					
						
							|  |  |  |     expect(stripExtension('foo')).toBe('foo'); | 
					
						
							|  |  |  |     expect(stripExtension('/foo/bar')).toBe('/foo/bar'); | 
					
						
							|  |  |  |     expect(stripExtension('/fo-o/b_ar')).toBe('/fo-o/b_ar'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |