Skip to content

Commit

Permalink
feat(ngMocks.findInstance): looks for instances in all matched DebugE…
Browse files Browse the repository at this point in the history
…lements #2105
  • Loading branch information
satanTime committed Mar 27, 2022
1 parent b99b535 commit bb39517
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 11 deletions.
7 changes: 4 additions & 3 deletions docs/articles/api/ngMocks/findInstances.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: ngMocks.findInstances
description: Documentation about ngMocks.findInstances from ng-mocks library
---

Returns an array of all found components, directives, pipes or services which belong to the current element and all its children.
Returns an array of all found components, directives, pipes or services which belong to matched elements and all its children.
If the element is not specified, then the current fixture is used.

- `ngMocks.findInstances( fixture?, directive )`
Expand All @@ -29,6 +29,7 @@ const pipes = ngMocks.findInstances('div span.text', MyPipe);
```

:::important
A css selector helps to find the first matched element.
It will be used to look up the desired declaration.
A css selector helps to find instances in all matched `DebugElements`.
Therefore, the same instance can be found several times via nested `DebugElements` with the same selector.
In this case, the instance will be added to the returning array only once.
:::
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getSourceOfMock } from '../../common/func.get-source-of-mock';
import mockHelperCrawl from '../crawl/mock-helper.crawl';
import mockHelperFind from '../find/mock-helper.find';
import mockHelperFindAll from '../find/mock-helper.find-all';
import funcGetFromNode from '../func.get-from-node';
import funcGetLastFixture from '../func.get-last-fixture';
import funcParseFindArgs from '../func.parse-find-args';
Expand All @@ -15,13 +15,16 @@ export default <T>(...args: any[]): T[] => {

const declaration = getSourceOfMock(sel);
const result: T[] = [];
mockHelperCrawl(
mockHelperFind(funcGetLastFixture(), el, undefined),
node => {
funcGetFromNode(result, node, declaration);
},
true,
);
const elements = mockHelperFindAll(funcGetLastFixture(), el, undefined);
for (const element of elements) {
mockHelperCrawl(
element,
node => {
funcGetFromNode(result, node, declaration);
},
true,
);
}

return result;
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { DebugElement } from '@angular/core';

import isDebugNode from '../format/is-debug-node';

import funcParseFindArgs from './func.parse-find-args';
import funcParseFindTerm from './func.parse-find-term';

export default (...args: any[]): DebugElement[] => {
const [el, sel] = funcParseFindArgs(args);
if (isDebugNode(sel)) {
return [sel as any];
}

return el?.queryAll(funcParseFindTerm(sel)) || [];
};
59 changes: 59 additions & 0 deletions tests/issue-2105/test.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Component, Input, NgModule } from '@angular/core';
import { MockBuilder, MockRender, ngMocks } from 'ng-mocks';

@Component({
selector: 'target',
template: ' {{ value }} ',
})
class TargetComponent {
@Input() public readonly value: string | null = null;
}

@NgModule({
declarations: [TargetComponent],
})
class TargetModule {}

// @see https://github.com/ike18t/ng-mocks/issues/2105
describe('issue-2105', () => {
beforeEach(() => MockBuilder(TargetComponent, TargetModule));

it('finds all instances', () => {
const fixture = MockRender(`
<div class="root">
<target value="1"></target>
<target value="2"></target>
<div class="child child1">
<target value="3"></target>
<target value="4"></target>
</div>
<div class="child child2">
<target value="5"></target>
<target value="6"></target>
<div class="child child3">
<target value="7"></target>
<target value="8"></target>
</div>
</div>
</div>
`);

expect(ngMocks.formatText(fixture)).toEqual('1 2 3 4 5 6 7 8');

// looking for all
{
const instances = ngMocks.findInstances('div', TargetComponent);
expect(instances.length).toEqual(8);
}

// looking for children only
// it should collect data from child1, child2 and child3.
{
const instances = ngMocks.findInstances(
'div.child',
TargetComponent,
);
expect(instances.length).toEqual(6);
}
});
});

0 comments on commit bb39517

Please sign in to comment.