Skip to content

Commit 5aa0d9a

Browse files
committed
fix: looking in vcr.createComponent on root node #1596
1 parent 4a27fc5 commit 5aa0d9a

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

libs/ng-mocks/src/lib/mock-helper/crawl/nested-check-children.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,23 @@ export default (node: MockedDebugNode): MockedDebugNode[] => {
2626
children.push(childNode);
2727
}
2828

29+
if ((node as any).parent?.name === 'BODY') {
30+
const childNodes: any[] = (node as any).parent.childNodes;
31+
let start = childNodes.length;
32+
let end = 0;
33+
for (let i = childNodes.length - 1; i >= 0; i -= 1) {
34+
const childNode = childNodes[i];
35+
if (childNode.nativeNode.nodeName === '#comment') {
36+
end = i;
37+
} else if (childNode.nativeNode === node.nativeNode) {
38+
start = i + 1;
39+
break;
40+
}
41+
}
42+
for (let i = start; i < end; i += 1) {
43+
children.push(childNodes[i]);
44+
}
45+
}
46+
2947
return children;
3048
};

tests/issue-1596/test.spec.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
Component,
3+
ComponentFactoryResolver,
4+
NgModule,
5+
Optional,
6+
ViewContainerRef,
7+
} from '@angular/core';
8+
import { TestBed } from '@angular/core/testing';
9+
import { By } from '@angular/platform-browser';
10+
import { MockBuilder, ngMocks } from 'ng-mocks';
11+
12+
@Component({
13+
selector: 'parent',
14+
template: '<div #parent>parent</div>',
15+
})
16+
class ParentComponent {
17+
public constructor(
18+
viewContainerRef: ViewContainerRef,
19+
@Optional() componentFactoryResolver: ComponentFactoryResolver,
20+
) {
21+
const vcr: any = viewContainerRef;
22+
23+
try {
24+
vcr.createComponent(ChildComponent);
25+
} catch (e) {
26+
const factory =
27+
componentFactoryResolver.resolveComponentFactory(
28+
ChildComponent,
29+
);
30+
vcr.createComponent(factory);
31+
}
32+
}
33+
}
34+
35+
@Component({
36+
selector: 'child',
37+
template: '<span #child>child</span>',
38+
})
39+
class ChildComponent {}
40+
41+
@NgModule({
42+
declarations: [ParentComponent, ChildComponent],
43+
entryComponents: [ChildComponent],
44+
})
45+
class TargetModule {}
46+
47+
// It's a tricky thing, because it behaves like that in Ivy only.
48+
// But even in Ivy, it doesn't render the child component properly.
49+
describe('issue-1596', () => {
50+
beforeEach(() => MockBuilder(ParentComponent, TargetModule));
51+
52+
it('finds child component', () => {
53+
const fixture1 = TestBed.createComponent(ParentComponent);
54+
fixture1.detectChanges();
55+
const expectedEl1 = fixture1.debugElement.query(
56+
By.directive(ChildComponent),
57+
);
58+
const expectedInstance1 = expectedEl1
59+
? expectedEl1.componentInstance
60+
: null;
61+
62+
expect(ngMocks.findInstance(fixture1, ChildComponent, null)).toBe(
63+
expectedInstance1,
64+
);
65+
66+
const fixture2 = TestBed.createComponent(ParentComponent);
67+
fixture2.detectChanges();
68+
const expectedEl2 = fixture2.debugElement.query(
69+
By.directive(ChildComponent),
70+
);
71+
const expectedInstance2 = expectedEl2
72+
? expectedEl2.componentInstance
73+
: null;
74+
75+
expect(ngMocks.findInstance(fixture2, ChildComponent, null)).toBe(
76+
expectedInstance2,
77+
);
78+
});
79+
});

0 commit comments

Comments
 (0)