test(compiler-cli): convert di compliance tests (#39863)

This commit converts the DI compliance tests taken from
`r3_view_compiler_di_spec.ts` to the new test runner.

PR Close #39863
This commit is contained in:
JoostK 2020-11-26 23:41:01 +01:00 committed by Jessica Janiuk
parent 157d690704
commit c622b17b0d
25 changed files with 772 additions and 0 deletions

View File

@ -0,0 +1,373 @@
/****************************************************************************************************
* PARTIAL FILE: component_factory.js
****************************************************************************************************/
import { Attribute, Component, Host, Injectable, NgModule, Optional, Self, SkipSelf } from '@angular/core';
import * as i0 from "@angular/core";
export class MyService {
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: MyService.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable
}], null, null); })();
export class MyComponent {
constructor(name, s1, s2, s4, s3, s5, s6) { }
}
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(i0.ɵɵinjectAttribute('name'), i0.ɵɵdirectiveInject(MyService), i0.ɵɵdirectiveInject(MyService, 1), i0.ɵɵdirectiveInject(MyService, 2), i0.ɵɵdirectiveInject(MyService, 4), i0.ɵɵdirectiveInject(MyService, 8), i0.ɵɵdirectiveInject(MyService, 10)); };
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ``, isInline: true } });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
type: Component,
args: [{ selector: 'my-component', template: `` }]
}], function () { return [{ type: undefined, decorators: [{
type: Attribute,
args: ['name']
}] }, { type: MyService }, { type: MyService, decorators: [{
type: Host
}] }, { type: MyService, decorators: [{
type: Self
}] }, { type: MyService, decorators: [{
type: SkipSelf
}] }, { type: MyService, decorators: [{
type: Optional
}] }, { type: MyService, decorators: [{
type: Self
}, {
type: Optional
}] }]; }, null); })();
export class MyModule {
}
MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); }, providers: [MyService] });
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
type: NgModule,
args: [{ declarations: [MyComponent], providers: [MyService] }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: component_factory.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyService {
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
export declare class MyComponent {
constructor(name: string, s1: MyService, s2: MyService, s4: MyService, s3: MyService, s5: MyService, s6: MyService);
static ɵfac: i0.ɵɵFactoryDef<MyComponent, [{ attribute: "name"; }, null, { host: true; }, { self: true; }, { skipSelf: true; }, { optional: true; }, { optional: true; self: true; }]>;
static ɵcmp: i0.ɵɵComponentDefWithMeta<MyComponent, "my-component", never, {}, {}, never, never>;
}
export declare class MyModule {
static ɵmod: i0.ɵɵNgModuleDefWithMeta<MyModule, [typeof MyComponent], never, never>;
static ɵinj: i0.ɵɵInjectorDef<MyModule>;
}
/****************************************************************************************************
* PARTIAL FILE: injectable_factory.js
****************************************************************************************************/
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class MyDependency {
}
export class MyService {
constructor(dep) { }
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(i0.ɵɵinject(MyDependency)); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: MyService.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable
}], function () { return [{ type: MyDependency }]; }, null); })();
/****************************************************************************************************
* PARTIAL FILE: injectable_factory.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
declare class MyDependency {
}
export declare class MyService {
constructor(dep: MyDependency);
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
export {};
/****************************************************************************************************
* PARTIAL FILE: ctor_overload.js
****************************************************************************************************/
import { Injectable, Optional } from '@angular/core';
import * as i0 from "@angular/core";
class MyDependency {
}
class MyOptionalDependency {
}
export class MyService {
constructor(dep, optionalDep) { }
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(i0.ɵɵinject(MyDependency), i0.ɵɵinject(MyOptionalDependency, 8)); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: MyService.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable
}], function () { return [{ type: MyDependency }, { type: MyOptionalDependency, decorators: [{
type: Optional
}] }]; }, null); })();
/****************************************************************************************************
* PARTIAL FILE: ctor_overload.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
declare class MyDependency {
}
export declare class MyService {
constructor(dep: MyDependency);
static ɵfac: i0.ɵɵFactoryDef<MyService, [null, { optional: true; }]>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
export {};
/****************************************************************************************************
* PARTIAL FILE: usefactory_without_deps.js
****************************************************************************************************/
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class MyAlternateService {
}
function alternateFactory() {
return new MyAlternateService();
}
export class MyService {
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: function () { return alternateFactory(); }, providedIn: 'root' });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable,
args: [{ providedIn: 'root', useFactory: alternateFactory }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: usefactory_without_deps.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyService {
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
/****************************************************************************************************
* PARTIAL FILE: usefactory_with_deps.js
****************************************************************************************************/
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class SomeDep {
}
class MyAlternateService {
}
export class MyService {
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: function MyService_Factory(t) { let r = null; if (t) {
r = new t();
}
else {
r = (() => new MyAlternateService())(i0.ɵɵinject(SomeDep));
} return r; }, providedIn: 'root' });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable,
args: [{ providedIn: 'root', useFactory: () => new MyAlternateService(), deps: [SomeDep] }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: usefactory_with_deps.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyService {
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
/****************************************************************************************************
* PARTIAL FILE: useclass_without_deps.js
****************************************************************************************************/
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class MyAlternateService {
}
MyAlternateService.ɵfac = function MyAlternateService_Factory(t) { return new (t || MyAlternateService)(); };
MyAlternateService.ɵprov = i0.ɵɵdefineInjectable({ token: MyAlternateService, factory: MyAlternateService.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyAlternateService, [{
type: Injectable
}], null, null); })();
export class MyService {
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: function (t) { return MyAlternateService.ɵfac(t); }, providedIn: 'root' });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable,
args: [{ providedIn: 'root', useClass: MyAlternateService }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: useclass_without_deps.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyService {
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
/****************************************************************************************************
* PARTIAL FILE: useclass_with_deps.js
****************************************************************************************************/
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class SomeDep {
}
class MyAlternateService {
}
MyAlternateService.ɵfac = function MyAlternateService_Factory(t) { return new (t || MyAlternateService)(); };
MyAlternateService.ɵprov = i0.ɵɵdefineInjectable({ token: MyAlternateService, factory: MyAlternateService.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyAlternateService, [{
type: Injectable
}], null, null); })();
export class MyService {
}
MyService.ɵfac = function MyService_Factory(t) { return new (t || MyService)(); };
MyService.ɵprov = i0.ɵɵdefineInjectable({ token: MyService, factory: function MyService_Factory(t) { let r = null; if (t) {
r = new t();
}
else {
r = new MyAlternateService(i0.ɵɵinject(SomeDep));
} return r; }, providedIn: 'root' });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyService, [{
type: Injectable,
args: [{ providedIn: 'root', useClass: MyAlternateService, deps: [SomeDep] }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: useclass_with_deps.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyService {
static ɵfac: i0.ɵɵFactoryDef<MyService, never>;
static ɵprov: i0.ɵɵInjectableDef<MyService>;
}
/****************************************************************************************************
* PARTIAL FILE: useclass_forwardref.js
****************************************************************************************************/
import { forwardRef, Injectable } from '@angular/core';
import * as i0 from "@angular/core";
class SomeProvider {
}
SomeProvider.ɵfac = function SomeProvider_Factory(t) { return new (t || SomeProvider)(); };
SomeProvider.ɵprov = i0.ɵɵdefineInjectable({ token: SomeProvider, factory: function (t) { return SomeProviderImpl.ɵfac(t); }, providedIn: 'root' });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(SomeProvider, [{
type: Injectable,
args: [{ providedIn: 'root', useClass: forwardRef(() => SomeProviderImpl) }]
}], null, null); })();
class SomeProviderImpl extends SomeProvider {
}
SomeProviderImpl.ɵfac = function SomeProviderImpl_Factory(t) { return ɵSomeProviderImpl_BaseFactory(t || SomeProviderImpl); };
SomeProviderImpl.ɵprov = i0.ɵɵdefineInjectable({ token: SomeProviderImpl, factory: SomeProviderImpl.ɵfac });
const ɵSomeProviderImpl_BaseFactory = /*@__PURE__*/ i0.ɵɵgetInheritedFactory(SomeProviderImpl);
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(SomeProviderImpl, [{
type: Injectable
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: useclass_forwardref.d.ts
****************************************************************************************************/
export {};
/****************************************************************************************************
* PARTIAL FILE: pipe_and_injectable.js
****************************************************************************************************/
import { Component, Injectable, NgModule, Pipe } from '@angular/core';
import * as i0 from "@angular/core";
class Service {
}
Service.ɵfac = function Service_Factory(t) { return new (t || Service)(); };
Service.ɵprov = i0.ɵɵdefineInjectable({ token: Service, factory: Service.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(Service, [{
type: Injectable
}], null, null); })();
export class MyPipe {
constructor(service) { }
transform(value, ...args) {
return value;
}
}
MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service)); };
MyPipe.ɵpipe = i0.ɵɵdefinePipe({ name: "myPipe", type: MyPipe, pure: true });
MyPipe.ɵprov = i0.ɵɵdefineInjectable({ token: MyPipe, factory: MyPipe.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyPipe, [{
type: Injectable
}, {
type: Pipe,
args: [{ name: 'myPipe' }]
}], function () { return [{ type: Service }]; }, null); })();
export class MyOtherPipe {
constructor(service) { }
transform(value, ...args) {
return value;
}
}
MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)(i0.ɵɵdirectiveInject(Service)); };
MyOtherPipe.ɵpipe = i0.ɵɵdefinePipe({ name: "myOtherPipe", type: MyOtherPipe, pure: true });
MyOtherPipe.ɵprov = i0.ɵɵdefineInjectable({ token: MyOtherPipe, factory: MyOtherPipe.ɵfac });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyOtherPipe, [{
type: Pipe,
args: [{ name: 'myOtherPipe' }]
}, {
type: Injectable
}], function () { return [{ type: Service }]; }, null); })();
export class MyApp {
}
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyApp, selector: "my-app", ngImport: i0, template: { source: '{{0 | myPipe | myOtherPipe}}', isInline: true }, pipes: { "myOtherPipe": MyOtherPipe, "myPipe": MyPipe } });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyApp, [{
type: Component,
args: [{ selector: 'my-app', template: '{{0 | myPipe | myOtherPipe}}' }]
}], null, null); })();
export class MyModule {
}
MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); }, providers: [Service] });
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyPipe, MyOtherPipe, MyApp] }); })();
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
type: NgModule,
args: [{ declarations: [MyPipe, MyOtherPipe, MyApp], providers: [Service] }]
}], null, null); })();
/****************************************************************************************************
* PARTIAL FILE: pipe_and_injectable.d.ts
****************************************************************************************************/
import { PipeTransform } from '@angular/core';
import * as i0 from "@angular/core";
declare class Service {
static ɵfac: i0.ɵɵFactoryDef<Service, never>;
static ɵprov: i0.ɵɵInjectableDef<Service>;
}
export declare class MyPipe implements PipeTransform {
constructor(service: Service);
transform(value: any, ...args: any[]): any;
static ɵfac: i0.ɵɵFactoryDef<MyPipe, never>;
static ɵpipe: i0.ɵɵPipeDefWithMeta<MyPipe, "myPipe">;
static ɵprov: i0.ɵɵInjectableDef<MyPipe>;
}
export declare class MyOtherPipe implements PipeTransform {
constructor(service: Service);
transform(value: any, ...args: any[]): any;
static ɵfac: i0.ɵɵFactoryDef<MyOtherPipe, never>;
static ɵpipe: i0.ɵɵPipeDefWithMeta<MyOtherPipe, "myOtherPipe">;
static ɵprov: i0.ɵɵInjectableDef<MyOtherPipe>;
}
export declare class MyApp {
static ɵfac: i0.ɵɵFactoryDef<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDefWithMeta<MyApp, "my-app", never, {}, {}, never, never>;
}
export declare class MyModule {
static ɵmod: i0.ɵɵNgModuleDefWithMeta<MyModule, [typeof MyPipe, typeof MyOtherPipe, typeof MyApp], never, never>;
static ɵinj: i0.ɵɵInjectorDef<MyModule>;
}
export {};

View File

@ -0,0 +1,179 @@
{
"$schema": "../../test_case_schema.json",
"cases": [
{
"description": "should create factory methods",
"inputFiles": [
"component_factory.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory",
"files": [
"component_factory.js"
]
}
]
},
{
"description": "should create a factory definition for an injectable",
"inputFiles": [
"injectable_factory.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory definition",
"files": [
{
"expected": "injectable_factory_fac.js",
"generated": "injectable_factory.js"
}
]
},
{
"failureMessage": "Incorrect injectable definition",
"files": [
{
"expected": "injectable_factory_prov.js",
"generated": "injectable_factory.js"
}
]
}
]
},
{
"description": "should create a factory definition for an injectable with an overloaded constructor",
"inputFiles": [
"ctor_overload.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory definition",
"files": [
{
"expected": "ctor_overload_fac.js",
"generated": "ctor_overload.js"
}
]
},
{
"failureMessage": "Incorrect injectable definition",
"files": [
{
"expected": "ctor_overload_prov.js",
"generated": "ctor_overload.js"
}
]
}
]
},
{
"description": "should delegate directly to the alternate factory when setting `useFactory` without `deps`",
"inputFiles": [
"usefactory_without_deps.ts"
],
"expectations": [
{
"failureMessage": "Incorrect injectable definition",
"files": [
"usefactory_without_deps.js"
]
}
]
},
{
"description": "should not delegate directly to the alternate factory when setting `useFactory` with `deps`",
"inputFiles": [
"usefactory_with_deps.ts"
],
"expectations": [
{
"failureMessage": "Incorrect injectable definition",
"files": [
"usefactory_with_deps.js"
]
}
]
},
{
"description": "should delegate directly to the alternate class factory when setting `useClass` without `deps`",
"inputFiles": [
"useclass_without_deps.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory definition",
"files": [
"useclass_without_deps.js"
]
}
]
},
{
"description": "should not delegate directly to the alternate class when setting `useClass` with `deps`",
"inputFiles": [
"useclass_with_deps.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory definition",
"files": [
"useclass_with_deps.js"
]
}
]
},
{
"description": "should unwrap forward refs when delegating to a different class",
"inputFiles": [
"useclass_forwardref.ts"
],
"expectations": [
{
"failureMessage": "Incorrect factory definition",
"files": [
"useclass_forwardref.js"
]
}
]
},
{
"description": "should have the pipe factory take precedence over the injectable factory, if a class has multiple decorators",
"inputFiles": [
"pipe_and_injectable.ts"
],
"expectations": [
{
"failureMessage": "Invalid pipe factory function",
"files": [
{
"expected": "pipe_and_injectable_pipe_last.js",
"generated": "pipe_and_injectable.js"
}
],
"extraChecks": [
[
"verifyUniqueFactory",
"MyPipe"
]
]
},
{
"failureMessage": "Invalid pipe factory function",
"files": [
{
"expected": "pipe_and_injectable_pipe_first.js",
"generated": "pipe_and_injectable.js"
}
],
"extraChecks": [
[
"verifyUniqueFactory",
"MyOtherPipe"
]
]
}
]
}
]
}

View File

@ -0,0 +1,12 @@
MyComponent.ɵfac = function MyComponent_Factory(t) {
return new (t || MyComponent)(
$r3$.ɵɵinjectAttribute('name'),
$r3$.ɵɵdirectiveInject(MyService),
$r3$.ɵɵdirectiveInject(MyService, 1),
$r3$.ɵɵdirectiveInject(MyService, 2),
$r3$.ɵɵdirectiveInject(MyService, 4),
$r3$.ɵɵdirectiveInject(MyService, 8),
$r3$.ɵɵdirectiveInject(MyService, 10)
);
}

View File

@ -0,0 +1,22 @@
import {Attribute, Component, Host, Injectable, NgModule, Optional, Self, SkipSelf} from '@angular/core';
@Injectable()
export class MyService {
}
@Component({selector: 'my-component', template: ``})
export class MyComponent {
constructor(
@Attribute('name') name: string,
s1: MyService,
@Host() s2: MyService,
@Self() s4: MyService,
@SkipSelf() s3: MyService,
@Optional() s5: MyService,
@Self() @Optional() s6: MyService,
) {}
}
@NgModule({declarations: [MyComponent], providers: [MyService]})
export class MyModule {
}

View File

@ -0,0 +1,10 @@
import {Injectable, Optional} from '@angular/core';
class MyDependency {}
class MyOptionalDependency {}
@Injectable()
export class MyService {
constructor(dep: MyDependency);
constructor(dep: MyDependency, @Optional() optionalDep?: MyOptionalDependency) {}
}

View File

@ -0,0 +1,3 @@
MyService.ɵfac = function MyService_Factory(t) {
return new (t || MyService)($r3$.ɵɵinject(MyDependency), $r3$.ɵɵinject(MyOptionalDependency, 8));
}

View File

@ -0,0 +1,4 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: MyService.ɵfac
});

View File

@ -0,0 +1,8 @@
import {Injectable} from '@angular/core';
class MyDependency {}
@Injectable()
export class MyService {
constructor(dep: MyDependency) {}
}

View File

@ -0,0 +1,3 @@
MyService.ɵfac = function MyService_Factory(t) {
return new (t || MyService)($r3$.ɵɵinject(MyDependency));
}

View File

@ -0,0 +1,4 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: MyService.ɵfac
});

View File

@ -0,0 +1,31 @@
import {Component, Injectable, NgModule, Pipe, PipeTransform} from '@angular/core';
@Injectable()
class Service {
}
@Injectable()
@Pipe({name: 'myPipe'})
export class MyPipe implements PipeTransform {
constructor(service: Service) {}
transform(value: any, ...args: any[]) {
return value;
}
}
@Pipe({name: 'myOtherPipe'})
@Injectable()
export class MyOtherPipe implements PipeTransform {
constructor(service: Service) {}
transform(value: any, ...args: any[]) {
return value;
}
}
@Component({selector: 'my-app', template: '{{0 | myPipe | myOtherPipe}}'})
export class MyApp {
}
@NgModule({declarations: [MyPipe, MyOtherPipe, MyApp], providers: [Service]})
export class MyModule {
}

View File

@ -0,0 +1,4 @@
// NOTE The prov definition must be last so MyOtherPipe.fac is defined
MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵdirectiveInject(Service)); };
MyOtherPipe.ɵpipe = i0.ɵɵdefinePipe({ name: "myOtherPipe", type: MyOtherPipe, pure: true });
MyOtherPipe.ɵprov = i0.ɵɵdefineInjectable({ token: MyOtherPipe, factory: MyOtherPipe.ɵfac });

View File

@ -0,0 +1,4 @@
// NOTE The prov definition must be last so MyPipe.fac is defined
MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service)); };
MyPipe.ɵpipe = i0.ɵɵdefinePipe({ name: "myPipe", type: MyPipe, pure: true });
MyPipe.ɵprov = i0.ɵɵdefineInjectable({ token: MyPipe, factory: MyPipe.ɵfac });

View File

@ -0,0 +1,7 @@
SomeProvider.ɵprov = $r3$.ɵɵdefineInjectable({
token: SomeProvider,
factory: function(t) {
return SomeProviderImpl.ɵfac(t);
},
providedIn: 'root'
});

View File

@ -0,0 +1,9 @@
import {forwardRef, Injectable} from '@angular/core';
@Injectable({providedIn: 'root', useClass: forwardRef(() => SomeProviderImpl)})
abstract class SomeProvider {
}
@Injectable()
class SomeProviderImpl extends SomeProvider {
}

View File

@ -0,0 +1,13 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: function MyService_Factory(t) {
let r = null;
if (t) {
r = new t();
} else {
r = new MyAlternateService($r3$.ɵɵinject(SomeDep));
}
return r;
},
providedIn: 'root'
});

View File

@ -0,0 +1,11 @@
import {Injectable} from '@angular/core';
class SomeDep {}
@Injectable()
class MyAlternateService {
}
@Injectable({providedIn: 'root', useClass: MyAlternateService, deps: [SomeDep]})
export class MyService {
}

View File

@ -0,0 +1,7 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: function(t) {
return MyAlternateService.ɵfac(t);
},
providedIn: 'root'
});

View File

@ -0,0 +1,9 @@
import {Injectable} from '@angular/core';
@Injectable()
class MyAlternateService {
}
@Injectable({providedIn: 'root', useClass: MyAlternateService})
export class MyService {
}

View File

@ -0,0 +1,13 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: function MyService_Factory(t) {
let r = null;
if (t) {
r = new t();
} else {
r = (() => new MyAlternateService())($r3$.ɵɵinject(SomeDep));
}
return r;
},
providedIn: 'root'
});

View File

@ -0,0 +1,8 @@
import {Injectable} from '@angular/core';
class SomeDep {}
class MyAlternateService {}
@Injectable({providedIn: 'root', useFactory: () => new MyAlternateService(), deps: [SomeDep]})
export class MyService {
}

View File

@ -0,0 +1,7 @@
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService,
factory: function() {
return alternateFactory();
},
providedIn: 'root'
});

View File

@ -0,0 +1,11 @@
import {Injectable} from '@angular/core';
class MyAlternateService {}
function alternateFactory() {
return new MyAlternateService();
}
@Injectable({providedIn: 'root', useFactory: alternateFactory})
export class MyService {
}

View File

@ -8,6 +8,7 @@
import {FileSystem} from '../../../src/ngtsc/file_system';
import {getBuildOutputDirectory, getRootDirectory} from './compile_test';
import {verifyUniqueFactory} from './di_checks';
import {expectEmit} from './expect_emit';
import {replaceMacros} from './expected_file_macros';
import {ExpectedFile, ExtraCheck} from './get_compliance_tests';
@ -17,6 +18,7 @@ type ExtraCheckFunction = (generated: string, ...extraArgs: any[]) => boolean;
const EXTRA_CHECK_FUNCTIONS: Record<string, ExtraCheckFunction> = {
verifyPlaceholdersIntegrity,
verifyUniqueConsts,
verifyUniqueFactory,
};
/**

View File

@ -0,0 +1,18 @@
/**
* @license
* Copyright Google LLC 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
*/
/**
* Verifies that there is exactly one factory definition for the provided type.
*/
export function verifyUniqueFactory(output: string, type: string): boolean {
const matches = output.match(new RegExp(type + '\.ɵfac =', 'g'));
if (matches === null) {
return false;
}
return matches.length === 1;
}