test(ivy): refactor Esm5Renderer tests to make them less fragile (#25534)
PR Close #25534
This commit is contained in:
parent
73047483a1
commit
e73e864f87
@ -27,74 +27,85 @@ function analyze(parser: Esm5FileParser, analyzer: Analyzer, file: ts.SourceFile
|
|||||||
return parsedFiles.map(file => analyzer.analyzeFile(file))[0];
|
return parsedFiles.map(file => analyzer.analyzeFile(file))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PROGRAM = {
|
||||||
|
name: 'some/file.js',
|
||||||
|
contents: `
|
||||||
|
/* A copyright notice */
|
||||||
|
import {Directive} from '@angular/core';
|
||||||
|
var A = (function() {
|
||||||
|
function A() {}
|
||||||
|
A.decorators = [
|
||||||
|
{ type: Directive, args: [{ selector: '[a]' }] },
|
||||||
|
{ type: OtherA }
|
||||||
|
];
|
||||||
|
return A;
|
||||||
|
}());
|
||||||
|
|
||||||
|
var B = (function() {
|
||||||
|
function B() {}
|
||||||
|
B.decorators = [
|
||||||
|
{ type: OtherB },
|
||||||
|
{ type: Directive, args: [{ selector: '[b]' }] }
|
||||||
|
];
|
||||||
|
return B;
|
||||||
|
}());
|
||||||
|
|
||||||
|
var C = (function() {
|
||||||
|
function C() {}
|
||||||
|
C.decorators = [
|
||||||
|
{ type: Directive, args: [{ selector: '[c]' }] },
|
||||||
|
];
|
||||||
|
return C;
|
||||||
|
}());
|
||||||
|
|
||||||
|
// Some other content
|
||||||
|
export {A, B, C};`
|
||||||
|
};
|
||||||
|
|
||||||
describe('Esm5Renderer', () => {
|
describe('Esm5Renderer', () => {
|
||||||
|
|
||||||
describe('addImports', () => {
|
describe('addImports', () => {
|
||||||
it('should insert the given imports at the start of the source file', () => {
|
it('should insert the given imports at the start of the source file', () => {
|
||||||
const PROGRAM = {
|
|
||||||
name: 'some/file.js',
|
|
||||||
contents: `
|
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
|
||||||
A.decorators = [
|
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] },
|
|
||||||
{ type: Other }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`
|
|
||||||
};
|
|
||||||
const {renderer} = setup(PROGRAM);
|
const {renderer} = setup(PROGRAM);
|
||||||
const output = new MagicString(PROGRAM.contents);
|
const output = new MagicString(PROGRAM.contents);
|
||||||
renderer.addImports(
|
renderer.addImports(
|
||||||
output, [{name: '@angular/core', as: 'i0'}, {name: '@angular/common', as: 'i1'}]);
|
output, [{name: '@angular/core', as: 'i0'}, {name: '@angular/common', as: 'i1'}]);
|
||||||
expect(output.toString())
|
expect(output.toString()).toContain(`import * as i0 from '@angular/core';
|
||||||
.toEqual(
|
import * as i1 from '@angular/common';
|
||||||
`import * as i0 from '@angular/core';\n` +
|
|
||||||
`import * as i1 from '@angular/common';\n` + PROGRAM.contents);
|
/* A copyright notice */`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('addConstants', () => {
|
||||||
|
it('should insert the given constants after imports in the source file', () => {
|
||||||
|
const {renderer, program} = setup(PROGRAM);
|
||||||
|
const file = program.getSourceFile('some/file.js');
|
||||||
|
if (file === undefined) {
|
||||||
|
throw new Error(`Could not find source file`);
|
||||||
|
}
|
||||||
|
const output = new MagicString(PROGRAM.contents);
|
||||||
|
renderer.addConstants(output, 'const x = 3;', file);
|
||||||
|
expect(output.toString()).toContain(`
|
||||||
|
import {Directive} from '@angular/core';
|
||||||
|
const x = 3;
|
||||||
|
|
||||||
|
var A = (function() {`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('addDefinitions', () => {
|
describe('addDefinitions', () => {
|
||||||
it('should insert the definitions directly after the class declaration', () => {
|
it('should insert the definitions directly after the class declaration', () => {
|
||||||
const PROGRAM = {
|
|
||||||
name: 'some/file.js',
|
|
||||||
contents: `
|
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
|
||||||
A.decorators = [
|
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] },
|
|
||||||
{ type: Other }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`
|
|
||||||
};
|
|
||||||
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
||||||
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
||||||
const output = new MagicString(PROGRAM.contents);
|
const output = new MagicString(PROGRAM.contents);
|
||||||
renderer.addDefinitions(output, analyzedFile.analyzedClasses[0], 'SOME DEFINITION TEXT');
|
renderer.addDefinitions(output, analyzedFile.analyzedClasses[0], 'SOME DEFINITION TEXT');
|
||||||
expect(output.toString()).toEqual(`
|
expect(output.toString()).toContain(`
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
function A() {}
|
||||||
SOME DEFINITION TEXT
|
SOME DEFINITION TEXT
|
||||||
A.decorators = [
|
A.decorators = [
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] },
|
`);
|
||||||
{ type: Other }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -103,120 +114,58 @@ export {A};`);
|
|||||||
describe('removeDecorators', () => {
|
describe('removeDecorators', () => {
|
||||||
|
|
||||||
it('should delete the decorator (and following comma) that was matched in the analysis', () => {
|
it('should delete the decorator (and following comma) that was matched in the analysis', () => {
|
||||||
const PROGRAM = {
|
|
||||||
name: 'some/file.js',
|
|
||||||
contents: `
|
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
|
||||||
A.decorators = [
|
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] },
|
|
||||||
{ type: Other }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`
|
|
||||||
};
|
|
||||||
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
||||||
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
||||||
const output = new MagicString(PROGRAM.contents);
|
const output = new MagicString(PROGRAM.contents);
|
||||||
const analyzedClass = analyzedFile.analyzedClasses[0];
|
const analyzedClass = analyzedFile.analyzedClasses[0];
|
||||||
|
const decorator = analyzedClass.decorators[0];
|
||||||
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
||||||
decoratorsToRemove.set(
|
decoratorsToRemove.set(decorator.node.parent !, [decorator.node]);
|
||||||
analyzedClass.decorators[0].node.parent !, [analyzedClass.decorators[0].node]);
|
|
||||||
renderer.removeDecorators(output, decoratorsToRemove);
|
renderer.removeDecorators(output, decoratorsToRemove);
|
||||||
expect(output.toString()).toEqual(`
|
expect(output.toString()).not.toContain(`{ type: Directive, args: [{ selector: '[a]' }] },`);
|
||||||
/* A copyright notice */
|
expect(output.toString()).toContain(`{ type: OtherA }`);
|
||||||
import {Directive} from '@angular/core';
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[b]' }] }`);
|
||||||
var A = (function() {
|
expect(output.toString()).toContain(`{ type: OtherB }`);
|
||||||
function A() {}
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[c]' }] }`);
|
||||||
A.decorators = [
|
|
||||||
{ type: Other }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should delete the decorator (but cope with no trailing comma) that was matched in the analysis',
|
it('should delete the decorator (but cope with no trailing comma) that was matched in the analysis',
|
||||||
() => {
|
() => {
|
||||||
const PROGRAM = {
|
|
||||||
name: 'some/file.js',
|
|
||||||
contents: `
|
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
|
||||||
A.decorators = [
|
|
||||||
{ type: Other },
|
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`
|
|
||||||
};
|
|
||||||
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
||||||
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
||||||
const output = new MagicString(PROGRAM.contents);
|
const output = new MagicString(PROGRAM.contents);
|
||||||
const analyzedClass = analyzedFile.analyzedClasses[0];
|
const analyzedClass = analyzedFile.analyzedClasses[1];
|
||||||
|
const decorator = analyzedClass.decorators[1];
|
||||||
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
||||||
decoratorsToRemove.set(
|
decoratorsToRemove.set(decorator.node.parent !, [decorator.node]);
|
||||||
analyzedClass.decorators[0].node.parent !, [analyzedClass.decorators[1].node]);
|
|
||||||
renderer.removeDecorators(output, decoratorsToRemove);
|
renderer.removeDecorators(output, decoratorsToRemove);
|
||||||
expect(output.toString()).toEqual(`
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[a]' }] },`);
|
||||||
/* A copyright notice */
|
expect(output.toString()).toContain(`{ type: OtherA }`);
|
||||||
import {Directive} from '@angular/core';
|
expect(output.toString())
|
||||||
var A = (function() {
|
.not.toContain(`{ type: Directive, args: [{ selector: '[b]' }] }`);
|
||||||
function A() {}
|
expect(output.toString()).toContain(`{ type: OtherB }`);
|
||||||
A.decorators = [
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[c]' }] }`);
|
||||||
{ type: Other },
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should delete the decorator (and its container if there are not other decorators left) that was matched in the analysis',
|
it('should delete the decorator (and its container if there are not other decorators left) that was matched in the analysis',
|
||||||
() => {
|
() => {
|
||||||
const PROGRAM = {
|
|
||||||
name: 'some/file.js',
|
|
||||||
contents: `
|
|
||||||
/* A copyright notice */
|
|
||||||
import {Directive} from '@angular/core';
|
|
||||||
var A = (function() {
|
|
||||||
function A() {}
|
|
||||||
A.decorators = [
|
|
||||||
{ type: Directive, args: [{ selector: '[a]' }] }
|
|
||||||
];
|
|
||||||
return A;
|
|
||||||
}());
|
|
||||||
// Some other content
|
|
||||||
export {A};`
|
|
||||||
};
|
|
||||||
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
const {analyzer, parser, program, renderer} = setup(PROGRAM);
|
||||||
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
const analyzedFile = analyze(parser, analyzer, program.getSourceFile(PROGRAM.name) !);
|
||||||
const output = new MagicString(PROGRAM.contents);
|
const output = new MagicString(PROGRAM.contents);
|
||||||
const analyzedClass = analyzedFile.analyzedClasses[0];
|
const analyzedClass = analyzedFile.analyzedClasses[2];
|
||||||
|
const decorator = analyzedClass.decorators[0];
|
||||||
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
||||||
decoratorsToRemove.set(
|
decoratorsToRemove.set(decorator.node.parent !, [decorator.node]);
|
||||||
analyzedClass.decorators[0].node.parent !, [analyzedClass.decorators[0].node]);
|
|
||||||
renderer.removeDecorators(output, decoratorsToRemove);
|
renderer.removeDecorators(output, decoratorsToRemove);
|
||||||
expect(output.toString()).toEqual(`
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[a]' }] },`);
|
||||||
/* A copyright notice */
|
expect(output.toString()).toContain(`{ type: OtherA }`);
|
||||||
import {Directive} from '@angular/core';
|
expect(output.toString()).toContain(`{ type: Directive, args: [{ selector: '[b]' }] }`);
|
||||||
var A = (function() {
|
expect(output.toString()).toContain(`{ type: OtherB }`);
|
||||||
function A() {}
|
expect(output.toString()).not.toContain(`C.decorators = [
|
||||||
return A;
|
{ type: Directive, args: [{ selector: '[c]' }] },
|
||||||
}());
|
];`);
|
||||||
// Some other content
|
|
||||||
export {A};`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user