sass-references/angular-material/material/tree/testing/tree-harness.spec.ts

288 lines
8.9 KiB
TypeScript
Raw Normal View History

2024-12-06 10:42:08 +08:00
import {Component} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FlatTreeControl, NestedTreeControl} from '@angular/cdk/tree';
import {
MatTreeFlatDataSource,
MatTreeFlattener,
MatTreeModule,
MatTreeNestedDataSource,
} from '@angular/material/tree';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {MatTreeHarness} from './tree-harness';
describe('MatTreeHarness', () => {
let fixture: ComponentFixture<TreeHarnessTest>;
let loader: HarnessLoader;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatTreeModule, TreeHarnessTest],
});
fixture = TestBed.createComponent(TreeHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should load harness with 2 tress', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
expect(trees.length).toBe(2);
});
it('should get correct number of children and descendants', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const flatTree = trees[0];
const nestedTree = trees[1];
const flatTreeDescendants = await flatTree.getNodes();
const nestedDescendants = await nestedTree.getNodes();
// flat nodes are not rendered until expanded
expect(flatTreeDescendants.length).toBe(2);
await flatTreeDescendants[0].expand();
expect((await flatTree.getNodes()).length).toBe(5);
expect(nestedDescendants.length).toBe(8);
});
it('should correctly get correct node with text (flat tree)', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const flatTree = trees[0];
const flatTreeNodes = await flatTree.getNodes({text: /Flat Group/});
expect(flatTreeNodes.length).toBe(2);
const secondGroup = flatTreeNodes[0];
expect(await secondGroup.getText()).toBe('Flat Group 1');
expect(await secondGroup.getLevel()).toBe(1);
expect(await secondGroup.isDisabled()).toBe(false);
expect(await secondGroup.isExpanded()).toBe(false);
});
it('should correctly get correct node with text (nested tree)', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const nestedTree = trees[1];
const nestedTreeNodes = await nestedTree.getNodes({text: /2./});
expect(nestedTreeNodes.length).toBe(3);
const thirdGroup = nestedTreeNodes[1];
expect(await thirdGroup.getText()).toBe('Nested Leaf 2.1.1');
expect(await thirdGroup.getLevel()).toBe(3);
expect(await thirdGroup.isDisabled()).toBe(false);
expect(await thirdGroup.isExpanded()).toBe(false);
});
it('should toggle expansion', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const nestedTree = trees[1];
const nestedTreeNodes = await nestedTree.getNodes();
const firstGroup = nestedTreeNodes[0];
expect(await firstGroup.isExpanded()).toBe(false);
await firstGroup.expand();
expect(await firstGroup.isExpanded()).toBe(true);
await firstGroup.expand();
// no-op if already expanded
expect(await firstGroup.isExpanded()).toBe(true);
await firstGroup.collapse();
expect(await firstGroup.isExpanded()).toBe(false);
await firstGroup.collapse();
// no-op if already collapsed
expect(await firstGroup.isExpanded()).toBe(false);
});
it('should correctly get tree structure', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const flatTree = trees[0];
expect(await flatTree.getTreeStructure()).toEqual({
children: [{text: 'Flat Group 1'}, {text: 'Flat Group 2'}],
});
const firstGroup = (await flatTree.getNodes({text: /Flat Group 1/}))[0];
await firstGroup.expand();
expect(await flatTree.getTreeStructure()).toEqual({
children: [
{
text: 'Flat Group 1',
children: [{text: 'Flat Leaf 1.1'}, {text: 'Flat Leaf 1.2'}, {text: 'Flat Leaf 1.3'}],
},
{text: 'Flat Group 2'},
],
});
const secondGroup = (await flatTree.getNodes({text: /Flat Group 2/}))[0];
await secondGroup.expand();
expect(await flatTree.getTreeStructure()).toEqual({
children: [
{
text: 'Flat Group 1',
children: [{text: 'Flat Leaf 1.1'}, {text: 'Flat Leaf 1.2'}, {text: 'Flat Leaf 1.3'}],
},
{
text: 'Flat Group 2',
children: [{text: 'Flat Group 2.1'}],
},
],
});
});
it('should correctly get tree structure', async () => {
const trees = await loader.getAllHarnesses(MatTreeHarness);
const nestedTree = trees[1];
expect(await nestedTree.getTreeStructure()).toEqual({
children: [{text: 'Nested Group 1'}, {text: 'Nested Group 2'}],
});
const firstGroup = (await nestedTree.getNodes({text: /Nested Group 1/}))[0];
await firstGroup.expand();
expect(await nestedTree.getTreeStructure()).toEqual({
children: [
{
text: 'Nested Group 1',
children: [
{text: 'Nested Leaf 1.1'},
{text: 'Nested Leaf 1.2'},
{text: 'Nested Leaf 1.3'},
],
},
{text: 'Nested Group 2'},
],
});
const secondGroup = (await nestedTree.getNodes({text: /Nested Group 2/}))[0];
await secondGroup.expand();
expect(await nestedTree.getTreeStructure()).toEqual({
children: [
{
text: 'Nested Group 1',
children: [
{text: 'Nested Leaf 1.1'},
{text: 'Nested Leaf 1.2'},
{text: 'Nested Leaf 1.3'},
],
},
{
text: 'Nested Group 2',
children: [{text: 'Nested Group 2.1'}],
},
],
});
});
});
interface Node {
name: string;
children?: Node[];
}
const FLAT_TREE_DATA: Node[] = [
{
name: 'Flat Group 1',
children: [{name: 'Flat Leaf 1.1'}, {name: 'Flat Leaf 1.2'}, {name: 'Flat Leaf 1.3'}],
},
{
name: 'Flat Group 2',
children: [
{
name: 'Flat Group 2.1',
children: [{name: 'Flat Leaf 2.1.1'}, {name: 'Flat Leaf 2.1.2'}, {name: 'Flat Leaf 2.1.3'}],
},
],
},
];
const NESTED_TREE_DATA: Node[] = [
{
name: 'Nested Group 1',
children: [{name: 'Nested Leaf 1.1'}, {name: 'Nested Leaf 1.2'}, {name: 'Nested Leaf 1.3'}],
},
{
name: 'Nested Group 2',
children: [
{
name: 'Nested Group 2.1',
children: [{name: 'Nested Leaf 2.1.1'}, {name: 'Nested Leaf 2.1.2'}],
},
],
},
];
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
@Component({
template: `
<mat-tree [dataSource]="flatTreeDataSource" [treeControl]="flatTreeControl">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: flatTreeHasChild" matTreeNodePadding isExpandable>
<button matTreeNodeToggle>
Toggle
</button>
{{node.name}}
</mat-tree-node>
</mat-tree>
<mat-tree [dataSource]="nestedTreeDataSource" [treeControl]="nestedTreeControl">
<!-- This is the tree node template for leaf nodes -->
<mat-nested-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
{{node.name}}
</mat-nested-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-nested-tree-node *matTreeNodeDef="let node; when: nestedTreeHasChild" isExpandable>
<button matTreeNodeToggle>
Toggle
</button>
{{node.name}}
<ul [class.example-tree-invisible]="!nestedTreeControl.isExpanded(node)">
<ng-container matTreeNodeOutlet></ng-container>
</ul>
</mat-nested-tree-node>
</mat-tree>
`,
standalone: true,
imports: [MatTreeModule],
})
class TreeHarnessTest {
private _transformer = (node: Node, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
};
};
treeFlattener = new MatTreeFlattener(
this._transformer,
node => node.level,
node => node.expandable,
node => node.children,
);
flatTreeControl = new FlatTreeControl<ExampleFlatNode>(
node => node.level,
node => node.expandable,
);
flatTreeDataSource = new MatTreeFlatDataSource(this.flatTreeControl, this.treeFlattener);
nestedTreeControl = new NestedTreeControl<Node>(node => node.children);
nestedTreeDataSource = new MatTreeNestedDataSource<Node>();
constructor() {
this.flatTreeDataSource.data = FLAT_TREE_DATA;
this.nestedTreeDataSource.data = NESTED_TREE_DATA;
}
flatTreeHasChild = (_: number, node: ExampleFlatNode) => node.expandable;
nestedTreeHasChild = (_: number, node: Node) => !!node.children && node.children.length > 0;
}