npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bupkis/rxjs

v1.0.0

Published

RxJS Observable assertions for Bupkis

Readme

@bupkis/rxjs

RxJS Observable assertions for BUPKIS.

All assertions are asynchronous since Observable operations are inherently async.

Installation

npm install @bupkis/rxjs bupkis rxjs

Usage

import { use } from 'bupkis';
import rxjsAssertions from '@bupkis/rxjs';
import { EMPTY, of, throwError } from 'rxjs';

const { expectAsync } = use(rxjsAssertions);

// Completion assertions
await expectAsync(of(1, 2, 3), 'to complete');
await expectAsync(EMPTY, 'to be empty');

// Error assertions
await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
);
await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
  'oops',
);

// Value assertions
await expectAsync(of('foo', 'bar'), 'to emit values', ['foo', 'bar']);
await expectAsync(of(1, 2, 3), 'to emit times', 3);
await expectAsync(of(42), 'to emit once');

// Completion value assertions
await expectAsync(of(1, 2, 'final'), 'to complete with value', 'final');

Assertions

{Observable} to complete

Asserts that an Observable completes successfully (does not error).

Success:

await expectAsync(of(1, 2, 3), 'to complete');
await expectAsync(EMPTY, 'to complete');

Failure:

await expectAsync(
  throwError(() => new Error('oops')),
  'to complete',
);
// AssertionError: Expected Observable to complete, but it errored with Error: oops

Negation:

await expectAsync(
  throwError(() => new Error('oops')),
  'not to complete',
);

{Observable} to be empty

Aliases:

{Observable} to be empty
{Observable} to complete without emitting

Asserts that an Observable completes without emitting any values.

Success:

await expectAsync(EMPTY, 'to be empty');
await expectAsync(EMPTY, 'to complete without emitting');

Failure:

await expectAsync(of(1), 'to be empty');
// AssertionError: Expected Observable to emit 0 values, but it emitted 1

Negation:

await expectAsync(of(1), 'not to be empty');

{Observable} to emit error

Asserts that an Observable errors (calls the error callback).

Success:

await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
);

Failure:

await expectAsync(of(1, 2, 3), 'to emit error');
// AssertionError: Expected Observable to error, but it completed successfully

Negation:

await expectAsync(of(1, 2, 3), 'not to emit error');

{Observable} to emit error {string | RegExp}

Asserts that an Observable errors with a message matching the given string or regex.

Success:

await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
  'oops',
);
await expectAsync(
  throwError(() => new Error('something went wrong')),
  'to emit error',
  /went wrong/,
);

Failure:

await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
  'different',
);
// AssertionError: Expected error message to be "different", but got "oops"

await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error',
  /no match/,
);
// AssertionError: Expected error message to match /no match/, but got "oops"

Negation:

await expectAsync(
  throwError(() => new Error('oops')),
  'not to emit error',
  'different',
);

{Observable} to emit error satisfying {object}

Asserts that an Observable errors with an error object satisfying a partial specification.

Success:

await expectAsync(
  throwError(() => new TypeError('type error')),
  'to emit error satisfying',
  { name: 'TypeError' },
);

await expectAsync(
  throwError(() => new TypeError('type error')),
  'to emit error satisfying',
  { name: 'TypeError', message: 'type error' },
);

Failure:

await expectAsync(
  throwError(() => new Error('oops')),
  'to emit error satisfying',
  { name: 'TypeError' },
);
// AssertionError: Expected error to satisfy spec, but name did not match: expected Error, got TypeError

Negation:

await expectAsync(
  throwError(() => new Error('oops')),
  'not to emit error satisfying',
  { name: 'TypeError' },
);

{Observable} to emit values {array}

Asserts that an Observable emits exactly the specified values in order. Uses strict equality (===) for comparison.

Success:

await expectAsync(of('foo', 'bar'), 'to emit values', ['foo', 'bar']);
await expectAsync(of(1, 2, 3), 'to emit values', [1, 2, 3]);
await expectAsync(EMPTY, 'to emit values', []);

Failure:

await expectAsync(of(1, 2, 3), 'to emit values', [1, 2]);
// AssertionError: Expected Observable to emit 2 values, but it emitted 3

await expectAsync(of(1, 2), 'to emit values', [2, 1]);
// AssertionError: Expected value at index 0 to be 2, but got 1

Note: Uses strict equality, so objects must be the same reference:

const obj = { a: 1 };
await expectAsync(of(obj), 'to emit values', [obj]); // passes - same reference
await expectAsync(of({ a: 1 }), 'to emit values', [{ a: 1 }]); // fails - different references

Negation:

await expectAsync(of(1, 2, 3), 'not to emit values', [3, 2, 1]);

{Observable} to emit times {number}

Asserts that an Observable emits exactly the specified number of values.

Success:

await expectAsync(of(1, 2, 3), 'to emit times', 3);
await expectAsync(EMPTY, 'to emit times', 0);

Failure:

await expectAsync(of(1, 2, 3), 'to emit times', 2);
// AssertionError: Expected Observable to emit 2 values, but it emitted 3

Negation:

await expectAsync(of(1, 2, 3), 'not to emit times', 5);

{Observable} to emit once

Asserts that an Observable emits exactly one value.

Success:

await expectAsync(of(42), 'to emit once');

Failure:

await expectAsync(EMPTY, 'to emit once');
// AssertionError: Expected Observable to emit 1 value, but it emitted 0

await expectAsync(of(1, 2), 'to emit once');
// AssertionError: Expected Observable to emit 1 value, but it emitted 2

Negation:

await expectAsync(of(1, 2), 'not to emit once');

{Observable} to emit twice

Asserts that an Observable emits exactly two values.

Success:

await expectAsync(of(1, 2), 'to emit twice');

Failure:

await expectAsync(of(1), 'to emit twice');
// AssertionError: Expected Observable to emit 2 values, but it emitted 1

Negation:

await expectAsync(of(1), 'not to emit twice');

{Observable} to emit thrice

Asserts that an Observable emits exactly three values.

Success:

await expectAsync(of(1, 2, 3), 'to emit thrice');

Failure:

await expectAsync(of(1, 2), 'to emit thrice');
// AssertionError: Expected Observable to emit 3 values, but it emitted 2

Negation:

await expectAsync(of(1, 2), 'not to emit thrice');

{Observable} to complete with value {unknown}

Asserts that an Observable completes and its last emitted value equals the expected value (strict equality).

Success:

await expectAsync(of(1, 2, 'final'), 'to complete with value', 'final');
await expectAsync(of(42), 'to complete with value', 42);

Failure:

await expectAsync(of(1, 2, 3), 'to complete with value', 2);
// AssertionError: Expected Observable to complete with value 2, but got 3

await expectAsync(EMPTY, 'to complete with value', 'any');
// AssertionError: Expected Observable to emit at least one value, but it completed without emitting

Negation:

await expectAsync(of(1, 2, 3), 'not to complete with value', 5);

{Observable} to complete with values {array}

Asserts that an Observable completes and emits exactly the specified values in order. Essentially an alias for to emit values that emphasizes completion.

Success:

await expectAsync(of('foo', 'bar', 'baz'), 'to complete with values', [
  'foo',
  'bar',
  'baz',
]);
await expectAsync(EMPTY, 'to complete with values', []);

Failure:

await expectAsync(of(1, 2, 3), 'to complete with values', [1, 2]);
// AssertionError: Expected Observable to emit 2 values, but it emitted 3

Negation:

await expectAsync(of(1, 2, 3), 'not to complete with values', [3, 2, 1]);

{Observable} to complete with value satisfying {object}

Asserts that an Observable completes and its last emitted value satisfies a partial specification (all specified properties match).

Success:

await expectAsync(
  of({ status: 'pending' }, { status: 'done', result: 42 }),
  'to complete with value satisfying',
  { status: 'done' },
);

await expectAsync(
  of({ a: 1, b: 2, c: 3 }),
  'to complete with value satisfying',
  { a: 1, b: 2 },
);

Failure:

await expectAsync(
  of({ status: 'pending' }),
  'to complete with value satisfying',
  { status: 'done' },
);
// AssertionError: Expected last value to satisfy spec, but status did not match: expected done, got pending

await expectAsync(EMPTY, 'to complete with value satisfying', { any: 'spec' });
// AssertionError: Expected Observable to emit at least one value, but it completed without emitting

Negation:

await expectAsync(
  of({ status: 'pending' }),
  'not to complete with value satisfying',
  { status: 'done' },
);

License

Copyright © 2026 Christopher "boneskull" Hiller. Licensed under BlueOak-1.0.0.