From df627e65dfbaaae0e026ee9b3cfbdd8b6adbc1be Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Sun, 17 Feb 2019 16:25:45 -0800 Subject: [PATCH] fix(ivy): correct absolute path processing for templateUrl and styleUrls (#28789) Prior to this change absolute file paths (like `/a/b/c/style.css`) were calculated taking current component file location into account. As a result, absolute file paths were calculated using current file as a root. This change updates this logic to ignore current file path in case of absolute paths. PR Close #28789 --- .../compiler-cli/src/ngtsc/resource_loader.ts | 3 + .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 69 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/packages/compiler-cli/src/ngtsc/resource_loader.ts b/packages/compiler-cli/src/ngtsc/resource_loader.ts index e676a1683d..0ca239dc15 100644 --- a/packages/compiler-cli/src/ngtsc/resource_loader.ts +++ b/packages/compiler-cli/src/ngtsc/resource_loader.ts @@ -115,6 +115,9 @@ export class HostResourceLoader implements ResourceLoader { // Strip a leading '/' if one is present. if (url.startsWith('/')) { url = url.substr(1); + + // Do not take current file location into account if we process absolute path. + fromFile = ''; } // Turn absolute paths into relative paths. if (!url.startsWith('.')) { diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 05d84cae96..8776565186 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -826,6 +826,75 @@ describe('ngtsc behavioral tests', () => { }); }); + describe('templateUrl and styleUrls processing', () => { + const testsForResource = (resource: string) => [ + // [component location, resource location, resource reference] + + // component and resource are in the same folder + [`a/app.ts`, `a/${resource}`, `./${resource}`], // + [`a/app.ts`, `a/${resource}`, resource], // + [`a/app.ts`, `a/${resource}`, `/a/${resource}`], + + // resource is one level up + [`a/app.ts`, resource, `../${resource}`], // + [`a/app.ts`, resource, `/${resource}`], + + // component and resource are in different folders + [`a/app.ts`, `b/${resource}`, `../b/${resource}`], // + [`a/app.ts`, `b/${resource}`, `/b/${resource}`], + + // resource is in subfolder of component directory + [`a/app.ts`, `a/b/c/${resource}`, `./b/c/${resource}`], // + [`a/app.ts`, `a/b/c/${resource}`, `b/c/${resource}`], // + [`a/app.ts`, `a/b/c/${resource}`, `/a/b/c/${resource}`], + ]; + + testsForResource('style.css').forEach((test) => { + const [compLoc, styleLoc, styleRef] = test; + it(`should handle ${styleRef}`, () => { + env.tsconfig(); + env.write(styleLoc, ':host { background-color: blue; }'); + env.write(compLoc, ` + import {Component} from '@angular/core'; + + @Component({ + selector: 'test-cmp', + styleUrls: ['${styleRef}'], + template: '...', + }) + export class TestCmp {} + `); + + env.driveMain(); + + const jsContents = env.getContents(compLoc.replace('.ts', '.js')); + expect(jsContents).toContain('background-color: blue'); + }); + }); + + testsForResource('template.html').forEach((test) => { + const [compLoc, templateLoc, templateRef] = test; + it(`should handle ${templateRef}`, () => { + env.tsconfig(); + env.write(templateLoc, 'Template Content'); + env.write(compLoc, ` + import {Component} from '@angular/core'; + + @Component({ + selector: 'test-cmp', + templateUrl: '${templateRef}' + }) + export class TestCmp {} + `); + + env.driveMain(); + + const jsContents = env.getContents(compLoc.replace('.ts', '.js')); + expect(jsContents).toContain('Template Content'); + }); + }); + }); + describe('former View Engine AST transform bugs', () => { it('should compile array literals behind conditionals', () => { env.tsconfig();