Previously, it was necessary to attach on of the three "stability" jsdoc tags (`@stable`, `@deprecated` or `@experimental`) to each public API export. To ensure that the public API was correctly tagged, the `ts-api-guardian` would check that one of these tags appeared on every public export. Now the doc-gen is able to compute that a code item is stable if it does not contain the `@experimental` nor `@deprecated` tags. Therefore there is no need to provide the `@stable` tag any more; and this tag has now been marked as deprecated - i.e. it should not be used. The ts-api-guardian has been modified in this commit so that it no longer warns/fails if the `@stable` is missing. PR Close #23176
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.9 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 chai = require('chai');
 | |
| import * as child_process from 'child_process';
 | |
| import * as fs from 'fs';
 | |
| import * as path from 'path';
 | |
| import {assertFileEqual, unlinkRecursively} from './helpers';
 | |
| 
 | |
| const BINARY = 'ts-api-guardian/bin/ts-api-guardian';
 | |
| 
 | |
| describe('cli: e2e test', () => {
 | |
|   const outDir = path.join(process.env['TEST_TMPDIR'], 'tmp');
 | |
| 
 | |
|   beforeEach(() => {
 | |
|     if (!fs.existsSync(outDir)) {
 | |
|       fs.mkdirSync(outDir);
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   afterEach(() => { unlinkRecursively(outDir); });
 | |
| 
 | |
|   it('should print usage without any argument', () => {
 | |
|     const {stderr} = execute([]);
 | |
|     chai.assert.match(stderr, /Usage/);
 | |
|   });
 | |
| 
 | |
|   it('should show help message with --help', () => {
 | |
|     const {stdout} = execute(['--help']);
 | |
|     chai.assert.match(stdout, /Usage/);
 | |
|   });
 | |
| 
 | |
|   it('should generate golden file with --out', () => {
 | |
|     const simpleFile = path.join(outDir, 'simple.d.ts');
 | |
|     const {status, stderr} = execute(['--out', simpleFile, 'test/fixtures/simple.d.ts']);
 | |
|     chai.assert.equal(status, 0, stderr);
 | |
|     assertFileEqual(simpleFile, 'test/fixtures/simple_expected.d.ts');
 | |
|   });
 | |
| 
 | |
|   it('should verify golden file with --verify and exit cleanly on no difference', () => {
 | |
|     const {stdout, status} =
 | |
|         execute(['--verify', 'test/fixtures/simple_expected.d.ts', 'test/fixtures/simple.d.ts']);
 | |
|     chai.assert.equal(stdout, '');
 | |
|     chai.assert.equal(status, 0);
 | |
|   });
 | |
| 
 | |
|   it('should verify golden file with --verify and exit with error on difference', () => {
 | |
|     const {stdout, status} = execute(
 | |
|         ['--verify', 'test/fixtures/verify_expected.d.ts', 'test/fixtures/verify_entrypoint.d.ts']);
 | |
|     chai.assert.equal(stdout, fs.readFileSync('test/fixtures/verify.patch').toString());
 | |
|     chai.assert.equal(status, 1);
 | |
|   });
 | |
| 
 | |
|   it('should generate multiple golden files with --outDir and --rootDir', () => {
 | |
|     const {status} = execute([
 | |
|       '--outDir', outDir, '--rootDir', 'test/fixtures', 'test/fixtures/simple.d.ts',
 | |
|       'test/fixtures/sorting.d.ts'
 | |
|     ]);
 | |
|     chai.assert.equal(status, 0);
 | |
|     assertFileEqual(path.join(outDir, 'simple.d.ts'), 'test/fixtures/simple_expected.d.ts');
 | |
|     assertFileEqual(path.join(outDir, 'sorting.d.ts'), 'test/fixtures/sorting_expected.d.ts');
 | |
|   });
 | |
| 
 | |
|   it('should verify multiple golden files with --verifyDir and --rootDir', () => {
 | |
|     copyFile('test/fixtures/simple_expected.d.ts', path.join(outDir, 'simple.d.ts'));
 | |
|     copyFile('test/fixtures/sorting_expected.d.ts', path.join(outDir, 'sorting.d.ts'));
 | |
|     const {stdout, status} = execute([
 | |
|       '--verifyDir', outDir, '--rootDir', 'test/fixtures', 'test/fixtures/simple.d.ts',
 | |
|       'test/fixtures/sorting.d.ts'
 | |
|     ]);
 | |
|     chai.assert.equal(stdout, '');
 | |
|     chai.assert.equal(status, 0);
 | |
|   });
 | |
| 
 | |
|   it('should generate respecting --stripExportPattern', () => {
 | |
|     const {stdout, status} = execute([
 | |
|       '--out', path.join(outDir, 'underscored.d.ts'), '--stripExportPattern', '^__.*',
 | |
|       'test/fixtures/underscored.d.ts'
 | |
|     ]);
 | |
|     chai.assert.equal(status, 0);
 | |
|     assertFileEqual(
 | |
|         path.join(outDir, 'underscored.d.ts'), 'test/fixtures/underscored_expected.d.ts');
 | |
|   });
 | |
| 
 | |
|   it('should not throw for aliased stripped exports', () => {
 | |
|     const {stdout, status} = execute([
 | |
|       '--out', path.join(outDir, 'stripped_alias.d.ts'), '--stripExportPattern', '^__.*',
 | |
|       'test/fixtures/stripped_alias.d.ts'
 | |
|     ]);
 | |
|     chai.assert.equal(status, 0);
 | |
|     assertFileEqual(
 | |
|         path.join(outDir, 'stripped_alias.d.ts'), 'test/fixtures/stripped_alias_expected.d.ts');
 | |
|   });
 | |
| 
 | |
|   it('should verify respecting --stripExportPattern', () => {
 | |
|     const {stdout, status} = execute([
 | |
|       '--verify', 'test/fixtures/underscored_expected.d.ts', 'test/fixtures/underscored.d.ts',
 | |
|       '--stripExportPattern', '^__.*'
 | |
|     ]);
 | |
|     chai.assert.equal(stdout, '');
 | |
|     chai.assert.equal(status, 0);
 | |
|   });
 | |
| 
 | |
|   it('should respect --allowModuleIdentifiers', () => {
 | |
|     const {stdout, status} = execute([
 | |
|       '--verify', 'test/fixtures/module_identifier_expected.d.ts', '--allowModuleIdentifiers',
 | |
|       'foo', 'test/fixtures/module_identifier.d.ts'
 | |
|     ]);
 | |
|     chai.assert.equal(stdout, '');
 | |
|     chai.assert.equal(status, 0);
 | |
|   });
 | |
| });
 | |
| 
 | |
| function copyFile(sourceFile: string, targetFile: string) {
 | |
|   fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));
 | |
| }
 | |
| 
 | |
| function execute(args: string[]): {stdout: string, stderr: string, status: number} {
 | |
|   const output = child_process.spawnSync(process.execPath, [path.resolve(BINARY), ...args], {
 | |
|     env: {
 | |
|       'NODE_PATH': process.cwd(),
 | |
|     }
 | |
|   });
 | |
|   chai.assert(!output.error, 'Child process failed or timed out: ' + output.error);
 | |
|   chai.assert(!output.signal, `Child process killed by signal ${output.signal}`);
 | |
| 
 | |
|   return {
 | |
|     stdout: output.stdout.toString(),
 | |
|     stderr: output.stderr.toString(),
 | |
|     status: output.status
 | |
|   };
 | |
| }
 |