CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-istanbul-lib-report

Base reporting library for istanbul providing core utilities for generating coverage reports across different formats

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

tree-traversal.mddocs/

Tree Traversal

Tree traversal system in Istanbul Lib Report implements the visitor pattern for walking coverage trees and generating reports with different organizational strategies. The system provides flexible navigation through coverage data with support for custom processing at each node.

Capabilities

Visitor Pattern

The core visitor implementation allows custom processing during tree traversal with specific callbacks for different node types and traversal phases.

/**
 * Visitor for traversing coverage trees with custom callbacks
 */
class Visitor {
  /**
   * Create a visitor with delegate methods
   * @param {Object} delegate - Partial visitor implementing methods of interest
   */
  constructor(delegate);

  /**
   * Called before traversal begins
   * @param {Object} root - Root node of the tree
   * @param {Object} state - Optional state passed around during traversal
   */
  onStart(root, state);

  /**
   * Called for every summary node during traversal
   * @param {Object} node - Current summary node
   * @param {Object} state - Optional state passed around during traversal
   */
  onSummary(node, state);

  /**
   * Called for every detail node during traversal
   * @param {Object} node - Current detail node
   * @param {Object} state - Optional state passed around during traversal
   */
  onDetail(node, state);

  /**
   * Called after all children have been visited for a summary node
   * @param {Object} node - Current summary node
   * @param {Object} state - Optional state passed around during traversal
   */
  onSummaryEnd(node, state);

  /**
   * Called after traversal ends
   * @param {Object} root - Root node of the tree
   * @param {Object} state - Optional state passed around during traversal
   */
  onEnd(root, state);
}

Usage Example:

const visitor = new Visitor({
  onStart(root, state) {
    console.log('Starting traversal');
    state.fileCount = 0;
  },
  
  onDetail(node, state) {
    state.fileCount++;
    const summary = node.getCoverageSummary();
    console.log(`File: ${node.getQualifiedName()}`);
    console.log(`  Statements: ${summary.statements.pct}%`);
  },
  
  onEnd(root, state) {
    console.log(`Processed ${state.fileCount} files`);
  }
});

// Use with tree
tree.visit(visitor, {});

Composite Visitor

Allows combining multiple visitors to process a tree with multiple different operations in a single traversal.

/**
 * Composite visitor that delegates to multiple visitors
 */
class CompositeVisitor extends Visitor {
  /**
   * Create a composite visitor
   * @param {Array|Object} visitors - Array of visitors or single visitor
   */
  constructor(visitors);
}

Usage Example:

const summaryVisitor = {
  onSummary(node) {
    console.log(`Summary: ${node.getQualifiedName()}`);
  }
};

const detailVisitor = {
  onDetail(node) {
    console.log(`Detail: ${node.getQualifiedName()}`);
  }
};

const composite = new CompositeVisitor([summaryVisitor, detailVisitor]);
tree.visit(composite);

Base Node

Abstract base class for tree nodes providing common navigation and traversal methods.

/**
 * Base class for tree nodes
 */
class BaseNode {
  /**
   * Check if this node is the root of the tree
   * @returns {boolean} True if this is the root node
   */
  isRoot();

  /**
   * Visit all nodes depth-first from this node down
   * @param {Visitor} visitor - Visitor called during tree traversal
   * @param {Object} [state] - Optional state passed around during traversal
   */
  visit(visitor, state);

  /**
   * Check if this is a summary node (abstract)
   * @returns {boolean} True if this is a summary node
   */
  isSummary();

  /**
   * Get the parent node (abstract)
   * @returns {BaseNode|null} Parent node or null if root
   */
  getParent();

  /**
   * Get child nodes (abstract)
   * @returns {Array<BaseNode>} Array of child nodes
   */
  getChildren();
}

Base Tree

Abstract base class for coverage trees providing tree-wide traversal operations.

/**
 * Abstract base class for a coverage tree
 */
class BaseTree {
  /**
   * Create a tree with the specified root node
   * @param {BaseNode} root - Root node of the tree
   */
  constructor(root);

  /**
   * Returns the root node of the tree
   * @returns {BaseNode} Root node
   */
  getRoot();

  /**
   * Visits the tree depth-first with the supplied partial visitor
   * @param {Visitor|Object} visitor - Visitor or partial visitor object
   * @param {Object} [state] - State to be passed around during traversal
   */
  visit(visitor, state);
}

Usage Example:

// Get tree from context
const tree = context.getTree('nested');

// Visit with partial visitor
tree.visit({
  onStart(root) {
    console.log('=== Coverage Report ===');
  },
  
  onSummary(node) {
    const summary = node.getCoverageSummary();
    const name = node.getQualifiedName() || 'All files';
    console.log(`\\n${name}:`);
    console.log(`  Statements: ${summary.statements.covered}/${summary.statements.total} (${summary.statements.pct}%)`);
    console.log(`  Branches: ${summary.branches.covered}/${summary.branches.total} (${summary.branches.pct}%)`);
    console.log(`  Functions: ${summary.functions.covered}/${summary.functions.total} (${summary.functions.pct}%)`);
    console.log(`  Lines: ${summary.lines.covered}/${summary.lines.total} (${summary.lines.pct}%)`);
  },
  
  onDetail(node) {
    const summary = node.getCoverageSummary();
    console.log(`    ${node.getRelativeName()}: ${summary.statements.pct}%`);
  }
});

Path Utility

Path management utility for normalized file path operations across platforms.

/**
 * Path utility for normalized file path operations
 */
class Path {
  /**
   * Create a path from string or array
   * @param {string|Array} strOrArray - Path string or array of path elements
   */
  constructor(strOrArray);

  /**
   * Convert path to string with '/' separators
   * @returns {string} Path as string
   */
  toString();

  /**
   * Check if path has parent elements
   * @returns {boolean} True if path has parent
   */
  hasParent();

  /**
   * Get parent path
   * @returns {Path} Parent path instance
   * @throws {Error} If path has no parent
   */
  parent();

  /**
   * Get copy of path elements array
   * @returns {Array} Array of path elements
   */
  elements();

  /**
   * Get the last element of the path
   * @returns {string} Last path element
   */
  name();

  /**
   * Check if this path contains another path
   * @param {Path} other - Other path to compare
   * @returns {boolean} True if this path contains the other
   */
  contains(other);

  /**
   * Check if this path is an ancestor of another path
   * @param {Path} other - Other path to compare
   * @returns {boolean} True if this is ancestor of other
   */
  ancestorOf(other);

  /**
   * Check if this path is a descendant of another path
   * @param {Path} other - Other path to compare
   * @returns {boolean} True if this is descendant of other
   */
  descendantOf(other);

  /**
   * Get common prefix path with another path
   * @param {Path} other - Other path to compare
   * @returns {Path} Common prefix path
   */
  commonPrefixPath(other);

  /**
   * Compare two paths for sorting
   * @param {Path} a - First path
   * @param {Path} b - Second path
   * @returns {number} -1, 0, or 1 for sorting
   */
  static compare(a, b);

  /**
   * Array-like operations - Path implements array manipulation methods
   */
  
  /**
   * Add elements to the end of the path
   * @param {...string} elements - Elements to add
   * @returns {number} New length of the path
   */
  push(...elements);

  /**
   * Remove and return the last element of the path
   * @returns {string} Last element, or undefined if empty
   */
  pop();

  /**
   * Remove and return the first element of the path
   * @returns {string} First element, or undefined if empty
   */
  shift();

  /**
   * Add elements to the beginning of the path
   * @param {...string} elements - Elements to add
   * @returns {number} New length of the path
   */
  unshift(...elements);

  /**
   * Change path contents by removing/inserting elements
   * @param {number} start - Index to start changes
   * @param {number} [deleteCount] - Number of elements to remove
   * @param {...string} items - Elements to insert
   * @returns {Array} Array of removed elements
   */
  splice(start, deleteCount, ...items);

  /**
   * Length of the path (number of elements)
   * @type {number}
   */
  length;
}

Usage Examples:

const { Path } = require('istanbul-lib-report/lib/path');

// Create paths
const path1 = new Path('/src/components/Button.js');
const path2 = new Path(['src', 'components', 'Button.js']);

// Path operations
console.log(path1.toString()); // "src/components/Button.js"
console.log(path1.name()); // "Button.js"
console.log(path1.hasParent()); // true

const parentPath = path1.parent(); // Path for "src/components"
console.log(parentPath.toString()); // "src/components"

// Path relationships
const rootPath = new Path(['src']);
console.log(rootPath.ancestorOf(path1)); // true
console.log(path1.descendantOf(rootPath)); // true

// Common prefix
const path3 = new Path(['src', 'utils', 'helpers.js']);
const common = path1.commonPrefixPath(path3); // Path for "src"

// Array-like operations
const workingPath = new Path(['src', 'components']);
console.log(workingPath.length); // 2

// Add elements
workingPath.push('Button.js'); // ['src', 'components', 'Button.js']
workingPath.unshift('project'); // ['project', 'src', 'components', 'Button.js']

// Remove elements
const filename = workingPath.pop(); // 'Button.js', path is now ['project', 'src', 'components']
const project = workingPath.shift(); // 'project', path is now ['src', 'components']

// Splice operations
const removed = workingPath.splice(1, 0, 'ui'); // [], path is now ['src', 'ui', 'components']
workingPath.splice(1, 1, 'shared'); // ['ui'], path is now ['src', 'shared', 'components']

Types

interface VisitorDelegate {
  onStart?(root: Object, state: Object): void;
  onSummary?(node: Object, state: Object): void;
  onDetail?(node: Object, state: Object): void;
  onSummaryEnd?(node: Object, state: Object): void;
  onEnd?(root: Object, state: Object): void;
}

interface TreeNode {
  isRoot(): boolean;
  isSummary(): boolean;
  getParent(): TreeNode | null;
  getChildren(): TreeNode[];
  getQualifiedName(): string;
  getRelativeName(): string;
  getCoverageSummary(): Object;
  visit(visitor: Visitor, state?: Object): void;
}

interface Tree {
  getRoot(): TreeNode;
  visit(visitor: Visitor | VisitorDelegate, state?: Object): void;
}

docs

context.md

file-writing.md

index.md

tree-traversal.md

xml-generation.md

tile.json