-
-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: find ng-container via ngMocks.reveal and revealAll
closes #289
- Loading branch information
Showing
36 changed files
with
1,241 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-attribute-value.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
import crawlByAttributeValue from './crawl-by-attribute-value'; | ||
|
||
describe('crawl-by-attribute-value:ivy', () => { | ||
const attribute = 'attribute'; | ||
const value = 'value'; | ||
|
||
let callback: (node: MockedDebugNode) => boolean; | ||
beforeEach( | ||
() => (callback = crawlByAttributeValue(attribute, value)), | ||
); | ||
|
||
it('ignores empty nodes', () => { | ||
const node: any = { | ||
injector: {}, | ||
}; | ||
expect(callback(node)).toEqual(false); | ||
}); | ||
|
||
it('scans attrs with empty inputs', () => { | ||
const node: any = { | ||
injector: { | ||
_tNode: { | ||
attrs: [attribute, value], | ||
}, | ||
}, | ||
}; | ||
expect(callback(node)).toEqual(false); | ||
}); | ||
|
||
it('scans attrs with proper step switch on inputs', () => { | ||
const node: any = { | ||
injector: { | ||
_lView: { | ||
5: { | ||
prop: value, | ||
}, | ||
}, | ||
_tNode: { | ||
attrs: ['1', '2', 3, attribute], | ||
inputs: { | ||
[attribute]: [5, 'prop'], | ||
}, | ||
}, | ||
}, | ||
}; | ||
expect(callback(node)).toEqual(true); | ||
}); | ||
|
||
it('scans attrs with inputs but w/o values', () => { | ||
const node: any = { | ||
injector: { | ||
_tNode: { | ||
attrs: [attribute, value], | ||
inputs: {}, | ||
}, | ||
}, | ||
}; | ||
expect(callback(node)).toEqual(false); | ||
}); | ||
|
||
it('scans attrs with inputs but w/ values w/o lView', () => { | ||
const node: any = { | ||
injector: { | ||
_tNode: { | ||
attrs: [attribute, value], | ||
inputs: { | ||
[attribute]: [5, 'prop'], | ||
}, | ||
}, | ||
}, | ||
}; | ||
expect(callback(node)).toEqual(false); | ||
}); | ||
|
||
it('scans attrs with inputs but w/ values w/ lView', () => { | ||
const node: any = { | ||
injector: { | ||
_lView: { | ||
5: { | ||
prop: value, | ||
}, | ||
}, | ||
_tNode: { | ||
attrs: [attribute, value], | ||
inputs: { | ||
[attribute]: [5, 'prop'], | ||
}, | ||
}, | ||
}, | ||
}; | ||
expect(callback(node)).toEqual(true); | ||
}); | ||
}); |
52 changes: 52 additions & 0 deletions
52
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-attribute-value.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
import funcGetPublicProviderKeys from './func.get-public-provider-keys'; | ||
import funcParseInputsAndRequiresAttributes from './func.parse-inputs-and-requires-attributes'; | ||
|
||
const detectInClassic = (node: MockedDebugNode, attribute: string, value: any): boolean => { | ||
for (const key of funcGetPublicProviderKeys(node)) { | ||
const [inputs, expectedAttributes, nodeIndex] = funcParseInputsAndRequiresAttributes(node, key); | ||
for (const input of inputs) { | ||
const [prop, alias] = input.split(': '); | ||
if (attribute !== (alias || prop) || expectedAttributes.indexOf(prop) === -1) { | ||
continue; | ||
} | ||
if (value === (node.injector as any).view.nodes[nodeIndex].instance[prop]) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
const detectInIvy = (node: MockedDebugNode, attribute: string, value: any): boolean => { | ||
const attrs = (node.injector as any)._tNode?.attrs || []; | ||
let step = 2; | ||
for (let index = 0; index < attrs.length; index += step) { | ||
// 3 is a divider between static and dynamic bindings | ||
if (typeof attrs[index] === 'number') { | ||
step = 1; | ||
continue; | ||
} | ||
const attr = attrs[index]; | ||
if (attr !== attribute || !(node.injector as any)._tNode.inputs?.[attr]) { | ||
continue; | ||
} | ||
const [attrIndex, attrProp] = (node.injector as any)._tNode.inputs[attr]; | ||
|
||
if (value === (node.injector as any)._lView?.[attrIndex][attrProp]) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
export default (attribute: string, value: any): ((node: MockedDebugNode) => boolean) => node => { | ||
if (detectInClassic(node, attribute, value)) { | ||
return true; | ||
} | ||
|
||
return detectInIvy(node, attribute, value); | ||
}; |
18 changes: 18 additions & 0 deletions
18
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-attribute.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
import detectAttributeInSelectors from './detect-attribute-in-selectors'; | ||
import detectSelectorsFromNode from './detect-selectors-from-node'; | ||
|
||
export default (attribute: string): ((node: MockedDebugNode) => boolean) => node => { | ||
const [selectors, attributes] = detectSelectorsFromNode(node); | ||
|
||
if (attributes.indexOf(attribute) !== -1) { | ||
return true; | ||
} | ||
|
||
if (detectAttributeInSelectors(selectors, attribute)) { | ||
return true; | ||
} | ||
|
||
return false; | ||
}; |
18 changes: 18 additions & 0 deletions
18
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-declaration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import crawlByDeclaration from './crawl-by-declaration'; | ||
|
||
describe('crawl-by-declaration', () => { | ||
it('returns false on exceptions', () => { | ||
const declaration: any = {}; | ||
const callback = crawlByDeclaration(declaration); | ||
|
||
const node: any = { | ||
injector: { | ||
get: () => { | ||
throw new Error(); | ||
}, | ||
}, | ||
providerTokens: [declaration], | ||
}; | ||
expect(callback(node)).toEqual(false); | ||
}); | ||
}); |
22 changes: 22 additions & 0 deletions
22
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-declaration.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { AnyType } from '../../common/core.types'; | ||
import { getSourceOfMock } from '../../common/func.get-source-of-mock'; | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
export default (declaration: AnyType<any>): ((node: MockedDebugNode) => boolean) => { | ||
const source = getSourceOfMock(declaration); | ||
|
||
return node => { | ||
try { | ||
if (node.providerTokens.indexOf(source) === -1) { | ||
return false; | ||
} | ||
node.injector.get(source); | ||
|
||
return true; | ||
} catch (e) { | ||
// nothing to do. | ||
} | ||
|
||
return false; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
export default (id: string): ((node: MockedDebugNode) => boolean) => node => { | ||
return !!node.references[id]; | ||
}; |
10 changes: 10 additions & 0 deletions
10
libs/ng-mocks/src/lib/mock-helper/crawl/crawl-by-tag-name.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
import detectSelectorsFromNode from './detect-selectors-from-node'; | ||
import detectTagNameInSelectors from './detect-tag-name-in-selectors'; | ||
|
||
export default (attribute: string): ((node: MockedDebugNode) => boolean) => node => { | ||
const [selectors] = detectSelectorsFromNode(node); | ||
|
||
return detectTagNameInSelectors(selectors, attribute); | ||
}; |
16 changes: 16 additions & 0 deletions
16
libs/ng-mocks/src/lib/mock-helper/crawl/detect-attribute-in-selectors.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export default (selectors: string[], query: string): boolean => { | ||
for (const selector of selectors) { | ||
const attributes = selector.match(/\[([^\]=]+)/g); | ||
if (!attributes) { | ||
continue; | ||
} | ||
|
||
for (const attribute of attributes) { | ||
if (attribute === `[${query}`) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { AnyType } from '../../common/core.types'; | ||
import { MockedDebugNode } from '../../mock-render/types'; | ||
|
||
import crawlByAttribute from './crawl-by-attribute'; | ||
import crawlByAttributeValue from './crawl-by-attribute-value'; | ||
import crawlByDeclaration from './crawl-by-declaration'; | ||
import crawlById from './crawl-by-id'; | ||
import crawlByTagName from './crawl-by-tag-name'; | ||
|
||
type SELECTOR = string | AnyType<any> | [any] | [any, any]; | ||
|
||
const isCrawlByAttribute = (selector: SELECTOR): selector is [string] => { | ||
return Array.isArray(selector) && selector.length === 1 && typeof selector[0] === 'string'; | ||
}; | ||
|
||
const isCrawlByAttributeValue = (selector: SELECTOR): selector is [string, any] => { | ||
return Array.isArray(selector) && selector.length === 2 && typeof selector[0] === 'string'; | ||
}; | ||
|
||
const isCrawlById = (selector: SELECTOR): selector is string => { | ||
return typeof selector === 'string' && selector.indexOf('#') === 0 && selector.length > 1; | ||
}; | ||
|
||
const isCrawlByTagName = (selector: SELECTOR): selector is string => { | ||
return typeof selector === 'string' && selector.indexOf('#') !== 0 && selector.length > 0; | ||
}; | ||
|
||
const isCrawlByDeclaration = (selector: SELECTOR): selector is AnyType<any> => { | ||
return typeof selector === 'function'; | ||
}; | ||
|
||
export default (selector: SELECTOR): ((node: MockedDebugNode) => boolean) => { | ||
if (isCrawlByAttribute(selector)) { | ||
return crawlByAttribute(selector[0]); | ||
} | ||
if (isCrawlByAttributeValue(selector)) { | ||
return crawlByAttributeValue(selector[0], selector[1]); | ||
} | ||
if (isCrawlById(selector)) { | ||
return crawlById(selector.substr(1)); | ||
} | ||
if (isCrawlByTagName(selector)) { | ||
return crawlByTagName(selector); | ||
} | ||
if (isCrawlByDeclaration(selector)) { | ||
return crawlByDeclaration(selector); | ||
} | ||
|
||
throw new Error(`Unknown selector`); | ||
}; |
44 changes: 44 additions & 0 deletions
44
libs/ng-mocks/src/lib/mock-helper/crawl/detect-selectors-from-node.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import detectSelectorsFromNode from './detect-selectors-from-node'; | ||
|
||
describe('detect-selectors-from-node:ivy', () => { | ||
it('handles empty node', () => { | ||
const node: any = { | ||
injector: {}, | ||
providerTokens: [], | ||
}; | ||
expect(detectSelectorsFromNode(node)).toEqual([[], []]); | ||
}); | ||
|
||
it('scans attributes', () => { | ||
const node: any = { | ||
injector: { | ||
_tNode: { | ||
attrs: ['1', '2', '3', '4', 3, '5', '6'], | ||
}, | ||
}, | ||
providerTokens: [], | ||
}; | ||
expect(detectSelectorsFromNode(node)).toEqual([[], []]); | ||
}); | ||
|
||
it('scans attributes and inputs', () => { | ||
const node: any = { | ||
injector: { | ||
_tNode: { | ||
attrs: ['1', '2', '3', '4', 3, '5', '6'], | ||
inputs: { | ||
1: true, | ||
3: true, | ||
5: true, | ||
6: true, | ||
}, | ||
}, | ||
}, | ||
providerTokens: [], | ||
}; | ||
expect(detectSelectorsFromNode(node)).toEqual([ | ||
[], | ||
['1', '3', '5', '6'], | ||
]); | ||
}); | ||
}); |
Oops, something went wrong.