15.1.0 • Published 9 months ago

@roughapp/replimock v15.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

Replimock

npm version License: MIT

A lightweight, intuitive testing utility for mocking Replicache clients in your unit and integration tests.

Why Use Replimock?

When building applications with Replicache, testing can be challenging because the real Replicache client requires IndexedDB and a full sync infrastructure. Replimock solves this problem by providing:

  • Simplified Testing: Test your Replicache mutators and queries without the need for a real database or sync infrastructure
  • Fast Tests: No network or indexedDB means your tests run lightning fast
  • Predictable Environment: Full control over the Replicache client state for deterministic testing
  • API Compatibility: Works with the standard Replicache client API, so your tests reflect real usage

Installation

# Using npm
npm install @roughapp/replimock --save-dev

# Using yarn
yarn add @roughapp/replimock --dev

# Using pnpm
pnpm add @roughapp/replimock --save-dev

Usage

Replimock provides a simple API to create a mock Replicache client that mimics the behavior of a real Replicache client.

Basic Example

import { mockReplicache } from '@roughapp/replimock';
import { expect, test } from 'vitest'; // or your testing framework of choice

test('should add a new todo', async () => {
  // Create a mock Replicache client
  const rep = mockReplicache({
    mutators: {
      addTodo: async (tx, todo) => {
        await tx.set(`todo/${todo.id}`, todo);
        return todo;
      },
    },
  });

  // Use the mock client just like you would use a real Replicache client
  const todo = await rep.mutate.addTodo({ id: '123', text: 'Buy milk', done: false });

  // Query the data to verify the mutation worked
  const storedTodo = await rep.query(tx => tx.get(`todo/${todo.id}`));

  expect(storedTodo).toEqual({ id: '123', text: 'Buy milk', done: false });
});

With Initial Data

You can initialize the mock client with data:

const rep = mockReplicache({
  initialData: {
    'todo/1': { id: '1', text: 'Existing todo', done: false },
    'todo/2': { id: '2', text: 'Another todo', done: true },
  },
  mutators: {
    // your mutators here
  },
});

// Query existing data
const todos = await rep.query(tx => tx.scan({ prefix: 'todo/' }).values().toArray());
console.log(todos); // will include the initial data

Testing Watchers

Replimock supports the experimentalWatch API for testing reactive code:

import { mockReplicache } from '@roughapp/replimock';
import { vi } from 'vitest';

test('should call watcher when data changes', async () => {
  const rep = mockReplicache({
    mutators: {
      addTodo: async (tx, todo) => {
        await tx.set(`todo/${todo.id}`, todo);
      },
    },
  });

  const watcher = vi.fn();
  rep.experimentalWatch(watcher, { prefix: 'todo/' });

  // Trigger a mutation that should notify the watcher
  await rep.mutate.addTodo({ id: '123', text: 'New todo', done: false });

  // Wait for the next tick to allow the callback to be called
  await new Promise(resolve => setTimeout(resolve, 0));

  expect(watcher).toHaveBeenCalledWith([
    {
      op: 'add',
      key: 'todo/123',
      newValue: { id: '123', text: 'New todo', done: false }
    }
  ]);
});

API

mockReplicache(options)

Creates a mock Replicache client.

Options:

  • mutators: Object containing mutator functions (required)
  • initialData: Object containing initial data to populate the store (optional)

The returned mock client implements the Replicache API, focusing on the most commonly used features:

  • query: Execute read-only operations
  • mutate: Execute mutations
  • experimentalWatch: Watch for changes to data

Limitations

Replimock aims to provide a testing environment that's faithful to the real Replicache API, but there are some limitations:

  • Indexes are not fully supported
  • Some advanced features like conflict resolution might behave differently
  • Network-related features (push/pull/sync) are stubbed out

License

MIT

Contributing

Contributions are welcome! Please feel free to open issues or PRs on GitHub.

15.0.2

1 year ago

15.0.3

1 year ago

15.1.0

9 months ago

15.0.4

1 year ago

15.0.5

1 year ago

15.0.1

2 years ago

15.0.0

2 years ago