diff --git a/libs/ng-mocks/src/lib/common/mock.ts b/libs/ng-mocks/src/lib/common/mock.ts index 49a4e6bf2a..c52e0c8952 100644 --- a/libs/ng-mocks/src/lib/common/mock.ts +++ b/libs/ng-mocks/src/lib/common/mock.ts @@ -1,4 +1,4 @@ -import { EventEmitter, Injector, Optional, Self } from '@angular/core'; +import { EventEmitter, Injector, Optional, PipeTransform, Self } from '@angular/core'; import { IMockBuilderConfig } from '../mock-builder/types'; import mockHelperStub from '../mock-helper/mock-helper.stub'; @@ -116,6 +116,7 @@ export type ngMocksMockConfig = { outputs?: string[]; queryScanKeys?: string[]; setControlValueAccessor?: boolean; + transform?: PipeTransform['transform']; }; const applyOverrides = (instance: any, mockOf: any, injector?: Injector): void => { diff --git a/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts b/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts index 0c69ebd022..b2aeba2f14 100644 --- a/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts +++ b/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts @@ -192,7 +192,7 @@ const configureTestingModule = // 0b10 - mock exist // 0b01 - real exist let hasMocks = 0; - const mockBuilder: Array<[any, boolean]> = []; + const mockBuilder: Array<[any, any, boolean]> = []; for (const key of useMockBuilder ? ['imports', 'declarations'] : []) { for (const declaration of flatten(moduleDef[key as never]) as any[]) { if (!declaration) { @@ -205,10 +205,11 @@ const configureTestingModule = providers: declaration.providers, } : getSourceOfMock(declaration), + isNgModuleDefWithProviders(declaration) ? declaration.ngModule : declaration, isMockNgDef(funcGetType(declaration)), ]); if (key === 'imports') { - hasMocks |= mockBuilder[mockBuilder.length - 1][1] ? 0b10 : 0b01; + hasMocks |= mockBuilder[mockBuilder.length - 1][2] ? 0b10 : 0b01; } } } @@ -216,8 +217,10 @@ const configureTestingModule = let finalModuleDef = hasMocks === 0b11 ? undefined : moduleDef; if (!finalModuleDef) { let builder = MockBuilder(NG_MOCKS_ROOT_PROVIDERS); - for (const [def, isMock] of mockBuilder) { - builder = isMock ? builder.mock(def) : builder.keep(def); + for (const [source, def, isMock] of mockBuilder) { + const transform = def.prototype.__ngMocksConfig?.transform; + builder = + isMock && transform ? builder.mock(source, transform) : isMock ? builder.mock(source) : builder.keep(source); } finalModuleDef = builder.build(); finalModuleDef = { diff --git a/libs/ng-mocks/src/lib/mock-pipe/mock-pipe.ts b/libs/ng-mocks/src/lib/mock-pipe/mock-pipe.ts index 806765a3f0..500a40a909 100644 --- a/libs/ng-mocks/src/lib/mock-pipe/mock-pipe.ts +++ b/libs/ng-mocks/src/lib/mock-pipe/mock-pipe.ts @@ -44,6 +44,7 @@ const getMockClass = (pipe: Type, transform?: PipeTransform['transform']): helperMockService.mock(instance, 'transform', `${funcGetName(instance)}.transform`); } }, + transform, }); return mock; diff --git a/tests/issue-4564/test.spec.ts b/tests/issue-4564/test.spec.ts new file mode 100644 index 0000000000..6786e8b33e --- /dev/null +++ b/tests/issue-4564/test.spec.ts @@ -0,0 +1,65 @@ +import { + Component, + NgModule, + Pipe, + PipeTransform, +} from '@angular/core'; +import { TestBed } from '@angular/core/testing'; + +import { MockModule, MockPipe, MockRender, ngMocks } from 'ng-mocks'; + +@Pipe({ + name: 'target', +}) +class TargetPipe implements PipeTransform { + transform() { + return 'real'; + } +} + +@Pipe({ + name: 'standard', +}) +class StandardPipe implements PipeTransform { + transform() { + return 'standard'; + } +} + +@NgModule({ + declarations: [TargetPipe, StandardPipe], + exports: [TargetPipe, StandardPipe], +}) +class PipeModule {} + +@Component({ + selector: 'target', + template: ' {{ null | target }}', +}) +class TargetComponent {} + +@NgModule({ + imports: [PipeModule], + declarations: [TargetComponent], + exports: [TargetComponent], +}) +class ComponentModule {} + +// @see https://github.com/help-me-mom/ng-mocks/issues/4564 +// mixed imports forget pipe customizations. +describe('issue-4564', () => { + beforeEach(() => + TestBed.configureTestingModule({ + imports: [ComponentModule, MockModule(PipeModule)], + declarations: [ + MockPipe(TargetPipe, () => 'mock'), + MockPipe(StandardPipe), + ], + }).compileComponents(), + ); + + it('customizes pipe', () => { + const fixture = MockRender(TargetComponent); + expect(ngMocks.formatText(fixture)).toEqual('mock'); + }); +});