# mocha-ui-esm

> A test interface for esmodules with Mocha

Latest version **1.0.0** (published 2026-03-22) · ISC license · 0 weekly downloads

## Install

```sh
npm install mocha-ui-esm
pnpm add mocha-ui-esm
yarn add mocha-ui-esm
bun add mocha-ui-esm
```

## Health

**Score 60/100 (C)** — status: active.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-03-22 |
| First published | 2017-05-23 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 295.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | pflannery |
| Maintainers | pflannery |
| Keywords | mocha, bdd, ui, es6, es2016, es2017, es2018, es2019, es2020, es2021, es2022, esmodules |

## Links

- npm: https://www.npmjs.com/package/mocha-ui-esm
- Repository: https://gitlab.com/esm-test-group/mocha-ui-esm
- Homepage: https://gitlab.com/esm-test-group/mocha-ui-esm#readme
- Issues: https://gitlab.com/esm-test-group/mocha-ui-esm/issues
- npm.io page: https://npm.io/package/mocha-ui-esm

## Dependencies (1)

- [esm-test-parser](https://npm.io/package/esm-test-parser.md) 1.0.0

## Alternatives

- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) — 3.7M weekly downloads
- [solid-js](https://npm.io/package/solid-js.md) — 2.7M weekly downloads
- [expo-glass-effect](https://npm.io/package/expo-glass-effect.md) — 2.5M weekly downloads
- [nanoassert](https://npm.io/package/nanoassert.md) — 780.8K weekly downloads
- [@ffmpeg/ffmpeg](https://npm.io/package/@ffmpeg/ffmpeg.md) — 529.5K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2026-03-22
- 1.0.0-beta.19 (next) — 2026-03-21
- 1.0.0-alpha.3 (alpha) — 2017-05-24
- 1.0.0-beta.18 — 2026-03-20
- 1.0.0-beta.17 — 2026-03-02
- 1.0.0-beta.16 — 2026-03-02
- 1.0.0-beta.15 — 2026-03-01
- 1.0.0-beta.14 — 2023-01-28
- 1.0.0-beta.13 — 2023-01-27
- 1.0.0-beta.12 — 2023-01-27
- 1.0.0-beta.11 — 2023-01-25
- 1.0.0-beta.10 — 2023-01-22
- 1.0.0-beta.9 — 2023-01-20
- 1.0.0-beta.8 — 2023-01-18
- 1.0.0-beta.7 — 2023-01-16
- … 10 more at https://npm.io/package/mocha-ui-esm/versions

## README

# mocha-ui-esm

[![Pipeline status](https://gitlab.com/pflannery/mocha-ui-esm/badges/master/pipeline.svg)](https://gitlab.com/pflannery/mocha-ui-esm/-/pipelines)
[![The ISC license](https://img.shields.io/badge/license-ISC-orange.png?color=blue&style=flat-square)](http://opensource.org/licenses/ISC)
[![NPM version](https://img.shields.io/npm/v/mocha-ui-esm.svg)](https://www.npmjs.org/package/mocha-ui-esm)
[![NPM downloads](https://img.shields.io/npm/dm/mocha-ui-esm.svg)](https://npmjs.org/package/mocha-ui-esm "View this project on NPM")

[![BuyMeACoffee](https://www.buymeacoffee.com/assets/img/custom_images/purple_img.png)](https://www.buymeacoffee.com/peterf)

A modern Mocha UI that allows you to define tests using ES Modules (ESM). It supports multiple test styles including Classes, Objects, and Functions, leveraging the powerful [esm-test-parser](https://gitlab.com/esm-test-group/esm-test-parser).

---

## Contents

- [Installation](#installation)
- [Usage](#usage)
  - [1. Register the UI](#1-register-the-ui)
  - [2. Configuration](#2-configuration)
    - [MochaUiEsmOptions](#mochauiesmoptions)
- [Test Styles with Examples](#test-styles-with-examples)
  - [1. Test Objects (Hierarchical & Declarative)](#1-test-objects-hierarchical--declarative)
  - [2. Test Classes (Stateful & Declarative)](#2-test-classes-stateful--declarative)
  - [3. Pure Test Functions (Functional & Simple)](#3-pure-test-functions-functional--simple)
- [License](#license)

---

## Installation

```bash
npm install mocha-ui-esm --save-dev
```

---

## Usage

### 1. Register the UI

In your test runner, register the UI before initializing Mocha.

```typescript
// runner.js
import Mocha from 'mocha';
import { registerMochaUiEsm } from 'mocha-ui-esm';
import * as MyTests from './tests.js';

// Register the 'esm' interface
registerMochaUiEsm(Mocha.interfaces);

// Create the runner
const mocha = new Mocha({
  ui: 'esm',
  reporter: 'spec'
});

// Emit your test modules to the suite
mocha.suite.emit('modules', MyTests);

mocha.run(failures => process.exit(failures ? 1 : 0));
```

### 2. Configuration

You can pass options to `registerMochaUiEsm` to customize the behavior.

```typescript
// runner.js
import Mocha from 'mocha';
import { SortByEnum, registerMochaUiEsm } from 'mocha-ui-esm';

registerMochaUiEsm(Mocha.interfaces, {
  classContextPropertyName: 'suiteContext', // Default
  sort: SortByEnum.byTitle,                 // Sort tests by title
  parserFlags: {
    allowLiteralTitle: true
  }
});
```

#### `MochaUiEsmOptions`

| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `classContextPropertyName` | `string` | `"suiteContext"` | The property name used to access the Mocha context in class instances. |
| `sort` | `SortByEnum` | `"none"` | Sorting strategy: `"none"`, `"byGroup"`, `"byTitle"`, `"byTitleAndGroup"`. |
| `testCaseTitleTemplate` | `Function` | `internal` | Custom function to generate titles for parameterized tests. |
| `parserFlags` | `Object` | `{...}` | Flags for the underlying `esm-test-parser`. |

---

## Test Styles with Examples

`mocha-ui-esm` supports three primary styles for defining your tests, each with its own advantages.

### 1. Test Objects (Hierarchical & Declarative)
Objects are ideal for hierarchical grouping where keys automatically define the structure and titles of the test suite.

*   **Hierarchical Grouping:** Organize tests into logical suites using nested structures.
*   **Implicit Titles:** Object keys serve as test and group titles.
*   **Sequential Filtering:** Use `only: true`, `only: number`, or `only: '*'` within the object to control execution.
*   **Parameterized Tests:** Use arrays of arguments to define multiple cases for a single key.

```typescript
// tests.js
import assert from 'assert';
import { test } from 'mocha-ui-esm';

export const MyMathTests = {
  [test.title]: "Math Suite",

  only: true, // Optional. runs the 'Basic Operations' suite in isolation
  'Basic Operations': {
    'Addition': {
      '1 + 1 = 2': () => { assert.strictEqual(1 + 1, 2); },
    },
  },

  // only: '*', // Optional. runs all remaining tests in the current suite in isolation

  // Parameterized test: Runs for each array entry
  'Calculate Square Root ($i)': [
    [9, 3],
    [16, 4],
    function(input, expected) {
      assert.strictEqual(Math.sqrt(input), expected);
    }
  ]
};
```

### 2. Test Classes (Stateful & Declarative)
Classes provide a declarative, stateful approach to testing, utilizing decorators for metadata.

*   **Declarative Testing:** Classes act as suites and methods act as tests.
*   **Decorators:** Use `@testCase`, `@testOnly`, and `@testTitle` for clean definitions.
*   **Instance Context:** Tests run within the class instance, allowing shared state via `this`.
*   **Context Injection:** Access the Mocha context via `this.suiteContext` (default name).

```typescript
// tests.js
import assert from 'assert';
import { testTitle, testCase, testOnly } from 'mocha-ui-esm';

@testTitle('Math Suite')
export class MathTests {
  suiteContext: any;

  @testCase(1, 1, 2)
  @testCase(2, 3, 5)
  'add $1 + $2 = $3'(a, b, expected) {
    assert.strictEqual(a + b, expected);
  }

  @testOnly()
  onlyThisTest() {
    assert.ok(true);
  }
}
```

### 3. Pure Test Functions (Functional & Simple)
Functional tests treat exported functions as individual tests, with metadata attached directly to the function objects.

*   **Automatic Discovery:** All exported functions (except reserved hooks) are treated as tests.
*   **Metadata via Properties:** Attach `[test.title]`, `[test.cases]`, and `[only]` directly to the function.
*   **Reserved Hooks:** Export functions named `beforeEach`, `afterEach`, etc., for setup/teardown.

```typescript
// tests.js
import assert from 'assert';
import { only, test } from 'mocha-ui-esm';

export function basicTest() { 
  assert.ok(true); 
}

// Attach metadata to the function object
customTest[only] = true;
customTest[test.title] = "This is a custom title";
export function customTest() { 
  assert.ok(true); 
}

// Parameterized functional test
parameterizedTest[test.cases] = [[1, 1], [2, 4]];
export function parameterizedTest(val, expected) { 
  assert.strictEqual(val * val, expected); 
}

export function beforeAll() {
  // Runs before all tests in this module
}
```

---

## License

[ISC](LICENSE)

---
_Source: https://npm.io/package/mocha-ui-esm · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
