feat(core): missing-injectable migration should migrate empty object literal providers (#33709)

In View Engine, providers which neither used `useValue`, `useClass`,
`useFactory` or `useExisting`, were interpreted differently.

e.g.

```
{provide: X} -> {provide: X, useValue: undefined}, // this is how it works in View Engine
{provide: X} -> {provide: X, useClass: X}, // this is how it works in Ivy
```

The missing-injectable migration should migrate such providers to the
explicit `useValue` provider. This ensures that there is no unexpected
behavioral change when updating to v9.

PR Close #33709
This commit is contained in:
Paul Gschwendtner
2019-11-14 10:16:07 +01:00
committed by Alex Rickabaugh
parent 1b7aa05699
commit b7c012f91b
10 changed files with 229 additions and 48 deletions

View File

@ -121,6 +121,7 @@ describe('Google3 missing injectable tslint rule', () => {
export class MyServiceE {}
export class MyServiceF {}
export class MyServiceG {}
export class MyServiceH {}
@${type}({${propName}: [
WithPipe,
@ -135,6 +136,7 @@ describe('Google3 missing injectable tslint rule', () => {
{provide: null, useExisting: MyServiceE},
{provide: MyServiceF, useFactory: () => null},
{provide: MyServiceG, useValue: null},
{provide: MyServiceH, deps: []},
]})
export class TestClass {}
`);
@ -149,11 +151,13 @@ describe('Google3 missing injectable tslint rule', () => {
.toMatch(/WithDirective {}\s+@Component\(\)\s+export class WithComponent/);
expect(getFile('/index.ts')).toMatch(/@Injectable\(\)\s+export class MyServiceA/);
expect(getFile('/index.ts')).toMatch(/@Injectable\(\)\s+export class MyServiceB/);
expect(getFile('/index.ts')).toMatch(/@Injectable\(\)\s+export class MyServiceC/);
expect(getFile('/index.ts')).toMatch(/MyServiceB {}\s+export class MyServiceC/);
expect(getFile('/index.ts')).toMatch(/@Injectable\(\)\s+export class MyServiceD/);
expect(getFile('/index.ts')).toMatch(/MyServiceD {}\s+export class MyServiceE/);
expect(getFile('/index.ts')).toMatch(/MyServiceE {}\s+export class MyServiceF/);
expect(getFile('/index.ts')).toMatch(/MyServiceF {}\s+export class MyServiceG/);
expect(getFile('/index.ts')).toMatch(/MyServiceG {}\s+export class MyServiceH/);
expect(getFile('/index.ts')).toContain(`{ provide: MyServiceC, useValue: undefined },`);
});
it(`should migrate provider once if referenced in multiple ${type} definitions`, () => {