From c2cf500da9fc81935e0cb1347253b4477bdaa7d1 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Sun, 28 Apr 2019 20:47:56 +0100 Subject: [PATCH] test(ivy): ngcc - check private dependency in integration test (#29643) The test now attempts to compile an entry-point (@angular/common/http/testing) that has a transient "private" dependency. A private dependency is one that is only visible by looking at the compiled JS code, rather than the generated TS typings files. This proves that we can't rely on typings files alone for computing the dependencies between entry-points. PR Close #29643 --- .../ngcc/test/integration/ngcc_spec.ts | 88 +++++-------------- 1 file changed, 22 insertions(+), 66 deletions(-) diff --git a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts index 6b72e3a47d..6500dc9fc9 100644 --- a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts +++ b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts @@ -10,7 +10,6 @@ import {AbsoluteFsPath} from '@angular/compiler-cli/src/ngtsc/path'; import {existsSync, readFileSync, readdirSync, statSync, writeFileSync} from 'fs'; import * as mockFs from 'mock-fs'; import {join} from 'path'; -const Module = require('module'); import {getAngularPackagesFromRunfiles, resolveNpmTreeArtifact} from '../../../test/runfile_helpers'; import {mainNgcc} from '../../src/main'; @@ -40,39 +39,27 @@ describe('ngcc main()', () => { describe('with targetEntryPointPath', () => { it('should only compile the given package entry-point (and its dependencies).', () => { - mainNgcc({basePath: '/node_modules', targetEntryPointPath: '@angular/common/http'}); + const STANDARD_MARKERS = { + module: '0.0.0-PLACEHOLDER', + es2015: '0.0.0-PLACEHOLDER', + esm5: '0.0.0-PLACEHOLDER', + esm2015: '0.0.0-PLACEHOLDER', + fesm5: '0.0.0-PLACEHOLDER', + fesm2015: '0.0.0-PLACEHOLDER', + typings: '0.0.0-PLACEHOLDER', + }; - expect(loadPackage('@angular/common/http').__processed_by_ivy_ngcc__).toEqual({ - module: '0.0.0-PLACEHOLDER', - es2015: '0.0.0-PLACEHOLDER', - esm5: '0.0.0-PLACEHOLDER', - esm2015: '0.0.0-PLACEHOLDER', - fesm5: '0.0.0-PLACEHOLDER', - fesm2015: '0.0.0-PLACEHOLDER', - typings: '0.0.0-PLACEHOLDER', - }); - // * `common` is a dependency of `common/http`, so is compiled. - expect(loadPackage('@angular/common').__processed_by_ivy_ngcc__).toEqual({ - module: '0.0.0-PLACEHOLDER', - es2015: '0.0.0-PLACEHOLDER', - esm5: '0.0.0-PLACEHOLDER', - esm2015: '0.0.0-PLACEHOLDER', - fesm5: '0.0.0-PLACEHOLDER', - fesm2015: '0.0.0-PLACEHOLDER', - typings: '0.0.0-PLACEHOLDER', - }); - // * `core` is a dependency of `common`, so is compiled. - expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({ - module: '0.0.0-PLACEHOLDER', - es2015: '0.0.0-PLACEHOLDER', - esm5: '0.0.0-PLACEHOLDER', - esm2015: '0.0.0-PLACEHOLDER', - fesm5: '0.0.0-PLACEHOLDER', - fesm2015: '0.0.0-PLACEHOLDER', - typings: '0.0.0-PLACEHOLDER', - }); - - // * `common/testing` is not a dependency of `common/http` so is not compiled. + mainNgcc({basePath: '/node_modules', targetEntryPointPath: '@angular/common/http/testing'}); + expect(loadPackage('@angular/common/http/testing').__processed_by_ivy_ngcc__) + .toEqual(STANDARD_MARKERS); + // * `common/http` is a dependency of `common/http/testing`, so is compiled. + expect(loadPackage('@angular/common/http').__processed_by_ivy_ngcc__) + .toEqual(STANDARD_MARKERS); + // * `core` is a dependency of `common/http`, so is compiled. + expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual(STANDARD_MARKERS); + // * `common` is a private (only in .js not .d.ts) dependency so is compiled. + expect(loadPackage('@angular/common').__processed_by_ivy_ngcc__).toEqual(STANDARD_MARKERS); + // * `common/testing` is not a dependency so is not compiled. expect(loadPackage('@angular/common/testing').__processed_by_ivy_ngcc__).toBeUndefined(); }); @@ -332,13 +319,13 @@ function createMockFileSystem() { '/node_modules/tslib': loadDirectory(resolveNpmTreeArtifact('tslib', 'tslib.js')), '/node_modules/test-package': { 'package.json': '{"name": "test-package", "es2015": "./index.js", "typings": "./index.d.ts"}', + // no metadata.json file so not compiled by Angular. 'index.js': 'import {AppModule} from "@angular/common"; export class MyApp extends AppModule;', - 'index.d.s': + 'index.d.ts': 'import {AppModule} from "@angular/common"; export declare class MyApp extends AppModule;', } }); - spyOn(Module, '_resolveFilename').and.callFake(mockResolve); } function restoreRealFileSystem() { @@ -380,37 +367,6 @@ interface Directory { [pathSegment: string]: string|Directory; } -/** - * A mock implementation of the node.js Module._resolveFilename function, - * which we are spying on to support mocking out the file-system in these tests. - * - * @param request the path to a module that needs resolving. - */ -function mockResolve(request: string): string|null { - if (existsSync(request)) { - const stat = statSync(request); - if (stat.isFile()) { - return request; - } else if (stat.isDirectory()) { - const pIndex = mockResolve(request + '/index'); - if (pIndex && existsSync(pIndex)) { - return pIndex; - } - } - } - for (const ext of ['.js', '.d.ts']) { - if (existsSync(request + ext)) { - return request + ext; - } - } - if (request.indexOf('/node_modules') === 0) { - // We already tried adding node_modules so give up. - return null; - } else { - return mockResolve(join('/node_modules', request)); - } -} - function loadPackage(packageName: string): EntryPointPackageJson { return JSON.parse(readFileSync(`/node_modules/${packageName}/package.json`, 'utf8')); }