{"version":3,"file":"testing.mjs","sources":["../../../../../../../src/material/tree/testing/node-harness.ts","../../../../../../../src/material/tree/testing/tree-harness.ts","../../../../../../../src/material/tree/testing/tree-harness-filters.ts","../../../../../../../src/material/tree/testing/public-api.ts","../../../../../../../src/material/tree/testing/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {\n  ComponentHarnessConstructor,\n  ContentContainerComponentHarness,\n  HarnessPredicate,\n} from '@angular/cdk/testing';\nimport {TreeNodeHarnessFilters} from './tree-harness-filters';\nimport {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion';\n\n/** Harness for interacting with a standard Angular Material tree node. */\nexport class MatTreeNodeHarness extends ContentContainerComponentHarness<string> {\n  /** The selector of the host element of a `MatTreeNode` instance. */\n  static hostSelector = '.mat-tree-node, .mat-nested-tree-node';\n\n  _toggle = this.locatorForOptional('[matTreeNodeToggle]');\n\n  /**\n   * Gets a `HarnessPredicate` that can be used to search for a tree node with specific attributes.\n   * @param options Options for narrowing the search\n   * @return a `HarnessPredicate` configured with the given options.\n   */\n  static with(options: TreeNodeHarnessFilters = {}): HarnessPredicate<MatTreeNodeHarness> {\n    return getNodePredicate(MatTreeNodeHarness, options);\n  }\n\n  /** Whether the tree node is expanded. */\n  async isExpanded(): Promise<boolean> {\n    return coerceBooleanProperty(await (await this.host()).getAttribute('aria-expanded'));\n  }\n\n  /** Whether the tree node is disabled. */\n  async isDisabled(): Promise<boolean> {\n    return coerceBooleanProperty(await (await this.host()).getProperty('aria-disabled'));\n  }\n\n  /** Gets the level of the tree node. Note that this gets the aria-level and is 1 indexed. */\n  async getLevel(): Promise<number> {\n    return coerceNumberProperty(await (await this.host()).getAttribute('aria-level'));\n  }\n\n  /** Gets the tree node's text. */\n  async getText(): Promise<string> {\n    return (await this.host()).text({exclude: '.mat-tree-node, .mat-nested-tree-node, button'});\n  }\n\n  /** Toggles node between expanded/collapsed. Only works when node is not disabled. */\n  async toggle(): Promise<void> {\n    const toggle = await this._toggle();\n    if (toggle) {\n      return toggle.click();\n    }\n  }\n\n  /** Expands the node if it is collapsed. Only works when node is not disabled. */\n  async expand(): Promise<void> {\n    if (!(await this.isExpanded())) {\n      await this.toggle();\n    }\n  }\n\n  /** Collapses the node if it is expanded. Only works when node is not disabled. */\n  async collapse(): Promise<void> {\n    if (await this.isExpanded()) {\n      await this.toggle();\n    }\n  }\n}\n\nfunction getNodePredicate<T extends MatTreeNodeHarness>(\n  type: ComponentHarnessConstructor<T>,\n  options: TreeNodeHarnessFilters): HarnessPredicate<T> {\n  return new HarnessPredicate(type, options)\n    .addOption('text', options.text,\n      (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n    .addOption(\n      'disabled', options.disabled,\n      async (harness, disabled) => (await harness.isDisabled()) === disabled)\n    .addOption(\n      'expanded', options.expanded,\n      async (harness, expanded) => (await harness.isExpanded()) === expanded)\n    .addOption(\n      'level', options.level,\n      async (harness, level) => (await harness.getLevel()) === level);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ComponentHarness, HarnessPredicate, parallel} from '@angular/cdk/testing';\nimport {MatTreeNodeHarness} from './node-harness';\nimport {TreeHarnessFilters, TreeNodeHarnessFilters} from './tree-harness-filters';\n\nexport type TextTree = {\n  text?: string;\n  children?: TextTree[];\n};\n\n/** Harness for interacting with a standard mat-tree in tests. */\nexport class MatTreeHarness extends ComponentHarness {\n  /** The selector for the host element of a `MatTableHarness` instance. */\n  static hostSelector = '.mat-tree';\n\n  /**\n   * Gets a `HarnessPredicate` that can be used to search for a tree with specific attributes.\n   * @param options Options for narrowing the search\n   * @return a `HarnessPredicate` configured with the given options.\n   */\n  static with(options: TreeHarnessFilters = {}): HarnessPredicate<MatTreeHarness> {\n    return new HarnessPredicate(MatTreeHarness, options);\n  }\n\n  /** Gets all of the nodes in the tree. */\n  async getNodes(filter: TreeNodeHarnessFilters = {}): Promise<MatTreeNodeHarness[]> {\n    return this.locatorForAll(MatTreeNodeHarness.with(filter))();\n  }\n\n  /**\n   * Gets an object representation for the visible tree structure\n   * If a node is under an unexpanded node it will not be included.\n   * Eg.\n   * Tree (all nodes expanded):\n   * `\n   * <mat-tree>\n   *   <mat-tree-node>Node 1<mat-tree-node>\n   *   <mat-nested-tree-node>\n   *     Node 2\n   *     <mat-nested-tree-node>\n   *       Node 2.1\n   *       <mat-tree-node>\n   *         Node 2.1.1\n   *       <mat-tree-node>\n   *     <mat-nested-tree-node>\n   *     <mat-tree-node>\n   *       Node 2.2\n   *     <mat-tree-node>\n   *   <mat-nested-tree-node>\n   * </mat-tree>`\n   *\n   * Tree structure:\n   * {\n   *  children: [\n   *    {\n   *      text: 'Node 1',\n   *      children: [\n   *        {\n   *          text: 'Node 2',\n   *          children: [\n   *            {\n   *              text: 'Node 2.1',\n   *              children: [{text: 'Node 2.1.1'}]\n   *            },\n   *            {text: 'Node 2.2'}\n   *          ]\n   *        }\n   *      ]\n   *    }\n   *  ]\n   * };\n   */\n  async getTreeStructure(): Promise<TextTree> {\n    const nodes = await this.getNodes();\n    const nodeInformation = await parallel(() => nodes.map(node => {\n      return parallel(() => [node.getLevel(), node.getText(), node.isExpanded()]);\n    }));\n    return this._getTreeStructure(nodeInformation, 1, true);\n  }\n\n  /**\n   * Recursively collect the structured text of the tree nodes.\n   * @param nodes A list of tree nodes\n   * @param level The level of nodes that are being accounted for during this iteration\n   * @param parentExpanded Whether the parent of the first node in param nodes is expanded\n   */\n  private _getTreeStructure(nodes: [number, string, boolean][], level: number,\n                                     parentExpanded: boolean): TextTree {\n    const result: TextTree = {};\n    for (let i = 0; i < nodes.length; i++) {\n      const [nodeLevel, text, expanded] = nodes[i];\n      const nextNodeLevel = nodes[i + 1]?.[0] ?? -1;\n\n      // Return the accumulated value for the current level once we reach a shallower level node\n      if (nodeLevel < level) {\n        return result;\n      }\n      // Skip deeper level nodes during this iteration, they will be picked up in a later iteration\n      if (nodeLevel > level) {\n        continue;\n      }\n      // Only add to representation if it is visible (parent is expanded)\n      if (parentExpanded) {\n        // Collect the data under this node according to the following rules:\n        // 1. If the next node in the list is a sibling of the current node add it to the child list\n        // 2. If the next node is a child of the current node, get the sub-tree structure for the\n        //    child and add it under this node\n        // 3. If the next node has a shallower level, we've reached the end of the child nodes for\n        //    the current parent.\n        if (nextNodeLevel === level) {\n          this._addChildToNode(result, {text});\n        } else if (nextNodeLevel > level) {\n          let children = this._getTreeStructure(nodes.slice(i + 1),\n            nextNodeLevel,\n            expanded)?.children;\n          let child = children ? {text, children} : {text};\n          this._addChildToNode(result, child);\n        } else {\n          this._addChildToNode(result, {text});\n          return result;\n        }\n      }\n    }\n    return result;\n  }\n\n  private _addChildToNode(result: TextTree, child: TextTree) {\n    result.children ? result.children.push(child) : result.children = [child];\n  }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {BaseHarnessFilters} from '@angular/cdk/testing';\n\n/** A set of criteria that can be used to filter a list of tree harness instances */\nexport interface TreeHarnessFilters extends BaseHarnessFilters {\n}\n\n/** A set of criteria that can be used to filter a list of node harness instances. */\nexport interface TreeNodeHarnessFilters extends BaseHarnessFilters {\n  /** Only find instances whose text matches the given value. */\n  text?: string | RegExp;\n\n  /** Only find instances whose disabled state matches the given value. */\n  disabled?: boolean;\n\n  /** Only find instances whose expansion state matches the given value. */\n  expanded?: boolean;\n\n  /** Only find instances whose level matches the given value. */\n  level?: number;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport * from './node-harness';\nexport * from './tree-harness';\nexport * from './tree-harness-filters';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}