{"id":11972,"library":"rxjs-marbles","title":"RxJS Marble Testing","description":"rxjs-marbles is a flexible and framework-agnostic library designed for conducting marble tests in RxJS applications. It provides a consistent interface for testing observable streams across various JavaScript testing frameworks, including AVA, Jasmine, Jest, Mocha, and Tape, in both browser and Node.js environments. The library currently targets RxJS version 7.x, as indicated by its peer dependency on `rxjs: ^7.0.0`. Its key differentiator lies in abstracting away framework-specific boilerplate like global setups or `beforeEach`/`afterEach` hooks, allowing developers to focus solely on the marble diagrams. It wraps RxJS's internal `TestScheduler` and exposes similar helper methods, simplifying the process of defining hot/cold observables, subscriptions, and expected outputs using the familiar marble syntax. While no explicit release cadence is stated, the package is actively maintained, with version 7.0.1 being the current stable release. The library ships with TypeScript types, facilitating its use in TypeScript projects.","status":"active","version":"7.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/cartant/rxjs-marbles","tags":["javascript","ava","jasmine","jest","marble","marbles","mocha","rxjs","tape","typescript"],"install":[{"cmd":"npm install rxjs-marbles","lang":"bash","label":"npm"},{"cmd":"yarn add rxjs-marbles","lang":"bash","label":"yarn"},{"cmd":"pnpm add rxjs-marbles","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime peer dependency for RxJS observable stream manipulation and `TestScheduler` functionality.","package":"rxjs","optional":false}],"imports":[{"note":"Always use framework-specific import paths (e.g., `/jest`, `/ava`) for optimal integration and clearer error reporting. The generic path might work but is not recommended.","wrong":"import { marbles } from 'rxjs-marbles';","symbol":"marbles","correct":"import { marbles } from 'rxjs-marbles/mocha';"},{"note":"RxJS operators like `map` are imported from `rxjs/operators` for tree-shaking and consistency with modern RxJS practices.","wrong":"import { map } from 'rxjs';","symbol":"map","correct":"import { map } from 'rxjs/operators';"},{"note":"Direct import of `TestScheduler` is rarely needed as `rxjs-marbles` abstracts it. This is primarily for type-checking or advanced direct interaction with RxJS's testing utilities.","symbol":"TestScheduler","correct":"import { TestScheduler } from 'rxjs/testing';"}],"quickstart":{"code":"import { marbles } from \"rxjs-marbles/mocha\";\nimport { map } from \"rxjs/operators\";\nimport { Observable } from 'rxjs';\n\ndescribe(\"rxjs-marbles basic test\", () => {\n\n    it(\"should map values from a hot observable\", marbles(m => {\n        // Define a hot observable source using marble syntax\n        const source =  m.hot(\"--^-a-b-c-|');\n        // Define the subscription timeframe\n        const subs =            \"^-------!\";\n        // Define the expected output after mapping\n        const expected =        \"--b-c-d-|';\n\n        // Apply the map operator to the source observable\n        const destination: Observable<string> = source.pipe(\n            map(value => String.fromCharCode(value.charCodeAt(0) + 1))\n        );\n\n        // Assert that the destination observable matches the expected marble diagram\n        m.expect(destination).toBeObservable(expected);\n        // Assert that the source was subscribed to during the defined 'subs' timeframe\n        m.expect(source).toHaveSubscriptions(subs);\n    }));\n});","lang":"typescript","description":"Demonstrates a basic marble test using `rxjs-marbles` with Mocha. It defines a hot observable, applies a transformation, and asserts the output against a marble diagram."},"warnings":[{"fix":"Install a compatible `rxjs` version (e.g., `npm install rxjs@^7.0.0 --save-dev`) or use an `rxjs-marbles` version that targets your existing `rxjs` installation.","message":"Ensure your `rxjs` version is compatible with the `rxjs-marbles` peer dependency. `rxjs-marbles@7.x` requires `rxjs@^7.0.0`. Mismatched versions can lead to `TestScheduler` API incompatibilities and runtime errors.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Always import `marbles` from the path specific to your test framework, such as `import { marbles } from 'rxjs-marbles/mocha';` or `import { marbles } from 'rxjs-marbles/jest';`.","message":"Failing to use framework-specific import paths (e.g., `rxjs-marbles/jest` instead of `rxjs-marbles`) results in less optimal test integration, potentially poorer error reporting, and missing framework-specific matchers.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Thoroughly review the official RxJS documentation on 'marble syntax' and 'synchronous assertion' to grasp the intricacies of marble diagram interpretation and test execution.","message":"A common pitfall is misunderstanding the core RxJS marble testing syntax, especially synchronous assertion rules and frame timing. `rxjs-marbles` acts as a wrapper for RxJS's `TestScheduler`, so its behavior is dictated by RxJS's underlying marble test mechanics.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure your test callback is passed to `marbles`, like `it('should work', marbles(m => { ... }));`.","cause":"The test function was not correctly wrapped by the `marbles` helper function, meaning no `TestScheduler` instance ('m' argument) was provided.","error":"TypeError: Cannot read properties of undefined (reading 'run')"},{"fix":"Carefully re-examine your source, subscription, and expected marble diagrams. Use `m.log('label', observable)` to debug and inspect the actual emissions of your observables during the test run.","cause":"A common assertion error indicating that the expected marble diagram does not match the actual observable output.","error":"Expected true to be false"},{"fix":"Verify that RxJS operators are imported from `rxjs/operators` (e.g., `import { map } from 'rxjs/operators';`). If using CommonJS, ensure your build setup correctly transpires ESM imports, or use `const { map } = require('rxjs/operators');` if targeting CJS directly (though ESM imports are preferred for modern RxJS).","cause":"This error typically occurs when RxJS operators are imported incorrectly, often in CommonJS environments or when using incompatible RxJS versions with your module resolution settings.","error":"TypeError: (0 , rxjs_operators_1.map) is not a function"}],"ecosystem":"npm"}