Skip to content

Commit c661a14

Browse files
committed
docs(material/tree): add harness example for tree
1 parent 4a60005 commit c661a14

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed

src/components-examples/material/tree/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ ng_module(
1111
]),
1212
module_name = "@angular/components-examples/material/tree",
1313
deps = [
14+
"//src/cdk/testing",
15+
"//src/cdk/testing/testbed",
1416
"//src/material/button",
1517
"//src/material/checkbox",
1618
"//src/material/icon",
1719
"//src/material/input",
1820
"//src/material/progress-bar",
1921
"//src/material/tree",
22+
"//src/material/tree/testing",
23+
"@npm//@angular/platform-browser",
24+
"@npm//@angular/platform-browser-dynamic",
25+
"@npm//@types/jasmine",
2026
],
2127
)
2228

src/components-examples/material/tree/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import {MatTreeModule} from '@angular/material/tree';
99
import {TreeChecklistExample} from './tree-checklist/tree-checklist-example';
1010
import {TreeDynamicExample} from './tree-dynamic/tree-dynamic-example';
1111
import {TreeFlatOverviewExample} from './tree-flat-overview/tree-flat-overview-example';
12+
import {TreeHarnessExample} from './tree-harness/tree-harness-example';
1213
import {TreeLoadmoreExample} from './tree-loadmore/tree-loadmore-example';
1314
import {TreeNestedOverviewExample} from './tree-nested-overview/tree-nested-overview-example';
1415

1516
export {
1617
TreeChecklistExample,
1718
TreeDynamicExample,
1819
TreeFlatOverviewExample,
20+
TreeHarnessExample,
1921
TreeLoadmoreExample,
2022
TreeNestedOverviewExample,
2123
};
@@ -24,6 +26,7 @@ const EXAMPLES = [
2426
TreeChecklistExample,
2527
TreeDynamicExample,
2628
TreeFlatOverviewExample,
29+
TreeHarnessExample,
2730
TreeLoadmoreExample,
2831
TreeNestedOverviewExample,
2932
];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
2+
<!-- This is the tree node template for leaf nodes -->
3+
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
4+
<!-- use a disabled button to provide padding for tree leaf -->
5+
<button mat-icon-button disabled></button>
6+
{{node.name}}
7+
</mat-tree-node>
8+
<!-- This is the tree node template for expandable nodes -->
9+
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
10+
<button mat-icon-button matTreeNodeToggle
11+
[attr.aria-label]="'Toggle ' + node.name">
12+
<mat-icon class="mat-icon-rtl-mirror">
13+
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
14+
</mat-icon>
15+
</button>
16+
{{node.name}}
17+
</mat-tree-node>
18+
</mat-tree>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {TestBed, ComponentFixture, waitForAsync} from '@angular/core/testing';
2+
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
3+
import {MatTreeHarness} from '@angular/material/tree/testing';
4+
import {HarnessLoader} from '@angular/cdk/testing';
5+
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting}
6+
from '@angular/platform-browser-dynamic/testing';
7+
import {MatTreeModule} from '@angular/material/tree';
8+
import {TreeHarnessExample} from './tree-harness-example';
9+
import {MatIconModule} from '@angular/material/icon';
10+
11+
describe('TreeHarnessExample', () => {
12+
let fixture: ComponentFixture<TreeHarnessExample>;
13+
let loader: HarnessLoader;
14+
15+
beforeAll(() => {
16+
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
17+
});
18+
19+
beforeEach(
20+
waitForAsync(() => {
21+
TestBed.configureTestingModule({
22+
imports: [MatTreeModule, MatIconModule],
23+
declarations: [TreeHarnessExample]
24+
}).compileComponents();
25+
fixture = TestBed.createComponent(TreeHarnessExample);
26+
fixture.detectChanges();
27+
loader = TestbedHarnessEnvironment.loader(fixture);
28+
})
29+
);
30+
31+
it('should get correct number of children and descendants', async () => {
32+
const tree = await loader.getHarness(MatTreeHarness);
33+
const treeDescendants = await tree.getNodes();
34+
35+
// flat nodes are not rendered until expanded
36+
expect(treeDescendants.length).toBe(2);
37+
38+
await treeDescendants[0].expand();
39+
40+
expect((await tree.getNodes()).length).toBe(5);
41+
});
42+
43+
it('should correctly get correct node with text', async () => {
44+
const tree = await loader.getHarness(MatTreeHarness);
45+
const treeNodes = await tree.getNodes({text: /Flat Group/});
46+
expect(treeNodes.length).toBe(2);
47+
const secondGroup = treeNodes[0];
48+
49+
expect(await secondGroup.getText()).toBe('Flat Group 1');
50+
expect(await secondGroup.getLevel()).toBe(1);
51+
expect(await secondGroup.isDisabled()).toBe(false);
52+
expect(await secondGroup.isExpanded()).toBe(false);
53+
});
54+
55+
it ('should correctly get tree structure', async () => {
56+
const tree = await loader.getHarness(MatTreeHarness);
57+
58+
expect(await tree.getTreeStructure()).toEqual({
59+
children: [
60+
{text: 'Flat Group 1'},
61+
{text: 'Flat Group 2'}
62+
]
63+
});
64+
65+
const firstGroup = (await tree.getNodes({text: /Flat Group 1/}))[0];
66+
await firstGroup.expand();
67+
68+
expect(await tree.getTreeStructure()).toEqual({
69+
children: [
70+
{
71+
text: 'Flat Group 1',
72+
children: [
73+
{text: 'Flat Leaf 1.1'},
74+
{text: 'Flat Leaf 1.2'},
75+
{text: 'Flat Leaf 1.3'}
76+
]
77+
},
78+
{text: 'Flat Group 2'}
79+
]
80+
});
81+
});
82+
});
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {FlatTreeControl} from '@angular/cdk/tree';
2+
import {Component} from '@angular/core';
3+
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
4+
5+
interface Node {
6+
name: string;
7+
children?: Node[];
8+
}
9+
10+
const FLAT_TREE_DATA: Node[] = [
11+
{
12+
name: 'Flat Group 1',
13+
children: [
14+
{name: 'Flat Leaf 1.1'},
15+
{name: 'Flat Leaf 1.2'},
16+
{name: 'Flat Leaf 1.3'},
17+
]
18+
}, {
19+
name: 'Flat Group 2',
20+
children: [
21+
{
22+
name: 'Flat Group 2.1',
23+
children: [
24+
{name: 'Flat Leaf 2.1.1'},
25+
{name: 'Flat Leaf 2.1.2'},
26+
{name: 'Flat Leaf 2.1.3'},
27+
]
28+
}
29+
]
30+
},
31+
];
32+
33+
interface ExampleFlatNode {
34+
expandable: boolean;
35+
name: string;
36+
level: number;
37+
}
38+
39+
/**
40+
* @title Testing with MatTreeHarness
41+
*/
42+
@Component({
43+
selector: 'tree-harness-example',
44+
templateUrl: 'tree-harness-example.html',
45+
})
46+
export class TreeHarnessExample {
47+
private _transformer = (node: Node, level: number) => {
48+
return {
49+
expandable: !!node.children && node.children.length > 0,
50+
name: node.name,
51+
level: level,
52+
};
53+
}
54+
55+
treeControl = new FlatTreeControl<ExampleFlatNode>(
56+
node => node.level, node => node.expandable);
57+
58+
treeFlattener = new MatTreeFlattener(
59+
this._transformer, node => node.level, node => node.expandable, node => node.children);
60+
61+
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
62+
63+
constructor() {
64+
this.dataSource.data = FLAT_TREE_DATA;
65+
}
66+
67+
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
68+
}

0 commit comments

Comments
 (0)