Skip to content

Commit

Permalink
feat(material-experimenta/mdc-core): add test harnesses for MDC optio…
Browse files Browse the repository at this point in the history
…n and option group

Adds test harnesses for the MDC-based `MatOption` and `MatOptgroup`.
  • Loading branch information
crisbeto authored and wagnermaciel committed Aug 18, 2020
1 parent d7754e7 commit 2d4cab2
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/material-experimental/config.bzl
Expand Up @@ -10,6 +10,7 @@ entryPoints = [
"mdc-chips",
"mdc-chips/testing",
"mdc-core",
"mdc-core/testing",
"mdc-dialog",
"mdc-dialog/testing",
"mdc-form-field",
Expand Down
35 changes: 35 additions & 0 deletions src/material-experimental/mdc-core/testing/BUILD.bazel
@@ -0,0 +1,35 @@
load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library")

package(default_visibility = ["//visibility:public"])

ts_library(
name = "testing",
srcs = glob(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/material-experimental/mdc-core/testing",
deps = [
"//src/cdk/testing",
],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)

ng_test_library(
name = "unit_tests_lib",
srcs = glob(["**/*.spec.ts"]),
deps = [
":testing",
"//src/material-experimental/mdc-core",
"//src/material/core/testing:harness_tests_lib",
],
)

ng_web_test_suite(
name = "unit_tests",
deps = [":unit_tests_lib"],
)
9 changes: 9 additions & 0 deletions src/material-experimental/mdc-core/testing/index.ts
@@ -0,0 +1,9 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

export * from './public-api';
@@ -0,0 +1,13 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {BaseHarnessFilters} from '@angular/cdk/testing';

export interface OptgroupHarnessFilters extends BaseHarnessFilters {
labelText?: string | RegExp;
}
@@ -0,0 +1,7 @@
import {MatOptionModule} from '@angular/material-experimental/mdc-core';
import {runHarnessTests} from '@angular/material/core/testing/optgroup-shared.spec';
import {MatOptgroupHarness} from './optgroup-harness';

describe('MDC-based MatOptgroupHarness', () => {
runHarnessTests(MatOptionModule, MatOptgroupHarness as any);
});
51 changes: 51 additions & 0 deletions src/material-experimental/mdc-core/testing/optgroup-harness.ts
@@ -0,0 +1,51 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing';
import {OptgroupHarnessFilters} from './optgroup-harness-filters';
import {MatOptionHarness} from './option-harness';
import {OptionHarnessFilters} from './option-harness-filters';

/** Harness for interacting with an MDC-based `mat-optgroup` in tests. */
export class MatOptgroupHarness extends ComponentHarness {
/** Selector used to locate option group instances. */
static hostSelector = '.mat-mdc-optgroup';
private _label = this.locatorFor('.mat-mdc-optgroup-label');

/**
* Gets a `HarnessPredicate` that can be used to search for a `MatOptgroupHarness` that meets
* certain criteria.
* @param options Options for filtering which option instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with(options: OptgroupHarnessFilters = {}) {
return new HarnessPredicate(MatOptgroupHarness, options)
.addOption('labelText', options.labelText,
async (harness, title) =>
HarnessPredicate.stringMatches(await harness.getLabelText(), title));
}

/** Gets the option group's label text. */
async getLabelText(): Promise<string> {
return (await this._label()).text();
}

/** Gets whether the option group is disabled. */
async isDisabled(): Promise<boolean> {
return (await (await this.host()).getAttribute('aria-disabled')) === 'true';
}

/**
* Gets the options that are inside the group.
* @param filter Optionally filters which options are included.
*/
async getOptions(filter: OptionHarnessFilters = {}): Promise<MatOptionHarness[]> {
return this.locatorForAll(MatOptionHarness.with(filter))();
}
}

@@ -0,0 +1,14 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {BaseHarnessFilters} from '@angular/cdk/testing';

export interface OptionHarnessFilters extends BaseHarnessFilters {
text?: string | RegExp;
isSelected?: boolean;
}
@@ -0,0 +1,7 @@
import {MatOptionModule, MatOption} from '@angular/material-experimental/mdc-core';
import {runHarnessTests} from '@angular/material/core/testing/option-shared.spec';
import {MatOptionHarness} from './option-harness';

describe('MDC-based MatOptionHarness', () => {
runHarnessTests(MatOptionModule, MatOptionHarness as any, MatOption);
});
62 changes: 62 additions & 0 deletions src/material-experimental/mdc-core/testing/option-harness.ts
@@ -0,0 +1,62 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing';
import {OptionHarnessFilters} from './option-harness-filters';

/** Harness for interacting with an MDC-based `mat-option` in tests. */
export class MatOptionHarness extends ComponentHarness {
/** Selector used to locate option instances. */
static hostSelector = '.mat-mdc-option';

/**
* Gets a `HarnessPredicate` that can be used to search for a `MatOptionsHarness` that meets
* certain criteria.
* @param options Options for filtering which option instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with(options: OptionHarnessFilters = {}) {
return new HarnessPredicate(MatOptionHarness, options)
.addOption('text', options.text,
async (harness, title) =>
HarnessPredicate.stringMatches(await harness.getText(), title))
.addOption('isSelected', options.isSelected,
async (harness, isSelected) => await harness.isSelected() === isSelected);

}

/** Clicks the option. */
async click(): Promise<void> {
return (await this.host()).click();
}

/** Gets the option's label text. */
async getText(): Promise<string> {
return (await this.host()).text();
}

/** Gets whether the option is disabled. */
async isDisabled(): Promise<boolean> {
return (await this.host()).hasClass('mdc-list-item--disabled');
}

/** Gets whether the option is selected. */
async isSelected(): Promise<boolean> {
return (await this.host()).hasClass('mdc-list-item--selected');
}

/** Gets whether the option is active. */
async isActive(): Promise<boolean> {
return (await this.host()).hasClass('mat-mdc-option-active');
}

/** Gets whether the option is in multiple selection mode. */
async isMultiple(): Promise<boolean> {
return (await this.host()).hasClass('mat-mdc-option-multiple');
}
}
12 changes: 12 additions & 0 deletions src/material-experimental/mdc-core/testing/public-api.ts
@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

export * from './option-harness';
export * from './option-harness-filters';
export * from './optgroup-harness';
export * from './optgroup-harness-filters';
4 changes: 2 additions & 2 deletions src/material/core/testing/option-harness.spec.ts
@@ -1,7 +1,7 @@
import {MatOptionModule} from '@angular/material/core';
import {MatOptionModule, MatOption} from '@angular/material/core';
import {runHarnessTests} from './option-shared.spec';
import {MatOptionHarness} from './option-harness';

describe('Non-MDC-based MatOptionHarness', () => {
runHarnessTests(MatOptionModule, MatOptionHarness);
runHarnessTests(MatOptionModule, MatOptionHarness, MatOption);
});
34 changes: 17 additions & 17 deletions src/material/core/testing/option-shared.spec.ts
Expand Up @@ -12,7 +12,9 @@ import {MatOptionHarness} from './option-harness';

/** Shared tests to run on both the original and MDC-based options. */
export function runHarnessTests(
optionModule: typeof MatOptionModule, optionHarness: typeof MatOptionHarness) {
optionModule: typeof MatOptionModule,
optionHarness: typeof MatOptionHarness,
optionComponent: typeof MatOption) {
let fixture: ComponentFixture<OptionHarnessTest>;
let loader: HarnessLoader;

Expand Down Expand Up @@ -102,21 +104,19 @@ export function runHarnessTests(

expect(await option.isMultiple()).toBe(true);
});
}


@Component({
providers: [{
provide: MAT_OPTION_PARENT_COMPONENT,
useExisting: OptionHarnessTest
}],
template: `
<mat-option>Plain option</mat-option>
<mat-option disabled>Disabled option</mat-option>
`
})
class OptionHarnessTest implements MatOptionParentComponent {
@ViewChildren(MatOption) options: QueryList<MatOption>;
multiple = false;
@Component({
providers: [{
provide: MAT_OPTION_PARENT_COMPONENT,
useExisting: OptionHarnessTest
}],
template: `
<mat-option>Plain option</mat-option>
<mat-option disabled>Disabled option</mat-option>
`
})
class OptionHarnessTest implements MatOptionParentComponent {
@ViewChildren(optionComponent) options: QueryList<{setActiveStyles(): void}>;
multiple = false;
}
}

0 comments on commit 2d4cab2

Please sign in to comment.