Skip to content

Commit 49b6dbd

Browse files
mmalerbajelbourn
authored andcommitted
feat(material/list): add test harnesses for list components (#17859)
1 parent 73dc106 commit 49b6dbd

24 files changed

+1477
-1
lines changed

src/cdk/testing/component-harness.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ export class HarnessPredicate<T extends ComponentHarness> {
412412
* @param pattern The pattern the value is expected to match. If `pattern` is a string,
413413
* `value` is expected to match exactly. If `pattern` is a regex, a partial match is
414414
* allowed. If `pattern` is `null`, the value is expected to be `null`.
415-
* @return A Promise that resolves to whether the value matches the pattern.
415+
* @return Whether the value matches the pattern.
416416
*/
417417
static async stringMatches(value: string | null | Promise<string | null>,
418418
pattern: string | RegExp | null): Promise<boolean> {

src/material/config.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ entryPoints = [
1717
"dialog",
1818
"dialog/testing",
1919
"divider",
20+
"divider/testing",
2021
"expansion",
2122
"expansion/testing",
2223
"form-field",
2324
"grid-list",
2425
"icon",
2526
"input",
2627
"list",
28+
"list/testing",
2729
"menu",
2830
"menu/testing",
2931
"paginator",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package(default_visibility = ["//visibility:public"])
2+
3+
load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library")
4+
5+
ts_library(
6+
name = "testing",
7+
srcs = glob(
8+
["**/*.ts"],
9+
exclude = ["**/*.spec.ts"],
10+
),
11+
module_name = "@angular/material/divider/testing",
12+
deps = [
13+
"//src/cdk/testing",
14+
],
15+
)
16+
17+
filegroup(
18+
name = "source-files",
19+
srcs = glob(["**/*.ts"]),
20+
)
21+
22+
ng_test_library(
23+
name = "harness_tests_lib",
24+
srcs = ["shared.spec.ts"],
25+
deps = [
26+
":testing",
27+
"//src/cdk/testing",
28+
"//src/cdk/testing/testbed",
29+
"//src/material/divider",
30+
"@npm//@angular/platform-browser",
31+
],
32+
)
33+
34+
ng_test_library(
35+
name = "unit_tests_lib",
36+
srcs = glob(
37+
["**/*.spec.ts"],
38+
exclude = ["shared.spec.ts"],
39+
),
40+
deps = [
41+
":harness_tests_lib",
42+
":testing",
43+
"//src/material/divider",
44+
],
45+
)
46+
47+
ng_web_test_suite(
48+
name = "unit_tests",
49+
deps = [":unit_tests_lib"],
50+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {BaseHarnessFilters} from '@angular/cdk/testing';
10+
11+
export interface DividerHarnessFilters extends BaseHarnessFilters {
12+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {MatDividerModule} from '@angular/material/divider';
2+
import {MatDividerHarness} from './divider-harness';
3+
import {runHarnessTests} from './shared.spec';
4+
5+
describe('Non-MDC-based MatButtonHarness', () => {
6+
runHarnessTests(MatDividerModule, MatDividerHarness);
7+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing';
10+
import {DividerHarnessFilters} from './divider-harness-filters';
11+
12+
/**
13+
* Harness for interacting with a `mat-divider`.
14+
* @dynamic
15+
*/
16+
export class MatDividerHarness extends ComponentHarness {
17+
static hostSelector = 'mat-divider';
18+
19+
static with(options: DividerHarnessFilters = {}) {
20+
return new HarnessPredicate(MatDividerHarness, options);
21+
}
22+
23+
async getOrientation(): Promise<'horizontal' | 'vertical'> {
24+
return (await this.host()).getAttribute('aria-orientation') as
25+
Promise<'horizontal' | 'vertical'>;
26+
}
27+
28+
async isInset(): Promise<boolean> {
29+
return (await this.host()).hasClass('mat-divider-inset');
30+
}
31+
}

src/material/divider/testing/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export * from './public-api';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export * from './divider-harness';
10+
export * from './divider-harness-filters';
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {HarnessLoader} from '@angular/cdk/testing';
2+
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
3+
import {Component} from '@angular/core';
4+
import {ComponentFixture, TestBed} from '@angular/core/testing';
5+
import {MatDividerModule} from '@angular/material/divider';
6+
import {MatDividerHarness} from './divider-harness';
7+
8+
/** Shared tests to run on both the original and MDC-based dividers. */
9+
export function runHarnessTests(
10+
dividerModule: typeof MatDividerModule, dividerHarness: typeof MatDividerHarness) {
11+
let fixture: ComponentFixture<DividerHarnessTest>;
12+
let loader: HarnessLoader;
13+
14+
beforeEach(async () => {
15+
await TestBed.configureTestingModule({
16+
imports: [dividerModule],
17+
declarations: [DividerHarnessTest],
18+
}).compileComponents();
19+
20+
fixture = TestBed.createComponent(DividerHarnessTest);
21+
fixture.detectChanges();
22+
loader = TestbedHarnessEnvironment.loader(fixture);
23+
});
24+
25+
it('should load all divider harnesses', async () => {
26+
const dividers = await loader.getAllHarnesses(dividerHarness);
27+
expect(dividers.length).toBe(2);
28+
});
29+
30+
it('should check if divider is inset', async () => {
31+
const dividers = await loader.getAllHarnesses(dividerHarness);
32+
expect(await dividers[0].isInset()).toBe(false);
33+
expect(await dividers[1].isInset()).toBe(true);
34+
});
35+
36+
it('should get divider orientation', async () => {
37+
const dividers = await loader.getAllHarnesses(dividerHarness);
38+
expect(await dividers[0].getOrientation()).toBe('horizontal');
39+
expect(await dividers[1].getOrientation()).toBe('vertical');
40+
});
41+
}
42+
43+
@Component({
44+
template: `
45+
<mat-divider></mat-divider>
46+
<mat-divider inset vertical></mat-divider>
47+
`
48+
})
49+
class DividerHarnessTest {}

src/material/list/testing/BUILD.bazel

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package(default_visibility = ["//visibility:public"])
2+
3+
load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library")
4+
5+
ts_library(
6+
name = "testing",
7+
srcs = glob(
8+
["**/*.ts"],
9+
exclude = ["**/*.spec.ts"],
10+
),
11+
module_name = "@angular/material/list/testing",
12+
deps = [
13+
"//src/cdk/coercion",
14+
"//src/cdk/testing",
15+
"//src/material/divider/testing",
16+
],
17+
)
18+
19+
filegroup(
20+
name = "source-files",
21+
srcs = glob(["**/*.ts"]),
22+
)
23+
24+
ng_test_library(
25+
name = "harness_tests_lib",
26+
srcs = ["shared.spec.ts"],
27+
deps = [
28+
":testing",
29+
"//src/cdk/testing",
30+
"//src/cdk/testing/testbed",
31+
"//src/material/divider/testing",
32+
"//src/material/list",
33+
"@npm//@angular/platform-browser",
34+
],
35+
)
36+
37+
ng_test_library(
38+
name = "unit_tests_lib",
39+
srcs = glob(
40+
["**/*.spec.ts"],
41+
exclude = ["shared.spec.ts"],
42+
),
43+
deps = [
44+
":harness_tests_lib",
45+
":testing",
46+
"//src/material/divider/testing",
47+
"//src/material/list",
48+
],
49+
)
50+
51+
ng_web_test_suite(
52+
name = "unit_tests",
53+
deps = [":unit_tests_lib"],
54+
)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {HarnessPredicate} from '@angular/cdk/testing';
10+
import {MatListHarnessBase} from './list-harness-base';
11+
import {ActionListHarnessFilters, ActionListItemHarnessFilters} from './list-harness-filters';
12+
import {getListItemPredicate, MatListItemHarnessBase} from './list-item-harness-base';
13+
14+
/** Harness for interacting with a standard mat-action-list in tests. */
15+
export class MatActionListHarness extends MatListHarnessBase<
16+
typeof MatActionListItemHarness, MatActionListItemHarness, ActionListItemHarnessFilters> {
17+
/** The selector for the host element of a `MatActionList` instance. */
18+
static hostSelector = 'mat-action-list';
19+
20+
/**
21+
* Gets a `HarnessPredicate` that can be used to search for a `MatActionListHarness` that meets
22+
* certain criteria.
23+
* @param options Options for filtering which action list instances are considered a match.
24+
* @return a `HarnessPredicate` configured with the given options.
25+
*/
26+
static with(options: ActionListHarnessFilters = {}): HarnessPredicate<MatActionListHarness> {
27+
return new HarnessPredicate(MatActionListHarness, options);
28+
}
29+
30+
_itemHarness = MatActionListItemHarness;
31+
}
32+
33+
/** Harness for interacting with an action list item. */
34+
export class MatActionListItemHarness extends MatListItemHarnessBase {
35+
/** The selector for the host element of a `MatListItem` instance. */
36+
static hostSelector = ['mat-list-item', 'a[mat-list-item]', 'button[mat-list-item]']
37+
.map(selector => `${MatActionListHarness.hostSelector} ${selector}`)
38+
.join(',');
39+
40+
/**
41+
* Gets a `HarnessPredicate` that can be used to search for a `MatActionListItemHarness` that
42+
* meets certain criteria.
43+
* @param options Options for filtering which action list item instances are considered a match.
44+
* @return a `HarnessPredicate` configured with the given options.
45+
*/
46+
static with(options: ActionListItemHarnessFilters = {}):
47+
HarnessPredicate<MatActionListItemHarness> {
48+
return getListItemPredicate(MatActionListItemHarness, options);
49+
}
50+
51+
/** Clicks on the action list item. */
52+
async click(): Promise<void> {
53+
return (await this.host()).click();
54+
}
55+
56+
/** Focuses the action list item. */
57+
async focus(): Promise<void> {
58+
return (await this.host()).focus();
59+
}
60+
61+
/** Blurs the action list item. */
62+
async blur(): Promise<void> {
63+
return (await this.host()).blur();
64+
}
65+
}

src/material/list/testing/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export * from './public-api';

0 commit comments

Comments
 (0)