Via subagent, verified against real behavior (all use jotai store + enableMapSet): - state/list (11): createListAtom PUT/DELETE/REPLACE (single + array, identity). - state/room/roomToParents (10): INITIALIZE/PUT/DELETE incl. cycle-skip and orphan-cleanup pruning of zero-parent children. - state/room/roomToUnread (22): unreadInfoToUnread, unreadEqual, and the roomToUnreadAtom reducer — leaf/overwrite/equal-guard, multi-level parent roll-up with `from` recording, RESET rebuild, DELETE subtract/prune. No bugs (noted a latent never-hit string-spread in deleteUnreadInfo's `from ?? roomId` fallback; left as-is). Suite growing toward full pure-logic coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
105 lines
4.0 KiB
TypeScript
105 lines
4.0 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createStore } from 'jotai';
|
|
import { createListAtom } from './list';
|
|
|
|
// `createListAtom` produces a write atom whose reducer handles PUT (append a
|
|
// single item or an array of items), DELETE (identity-based removal of a single
|
|
// item or array of items) and REPLACE (identity match -> replacement). We drive
|
|
// the pure reducer through a real jotai store. The exported `TListAtom` type is
|
|
// a type alias only, nothing to test at runtime.
|
|
|
|
test('starts as an empty array', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
assert.deepEqual(store.get(listAtom), []);
|
|
});
|
|
|
|
test('PUT appends a single item', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: 'a' });
|
|
store.set(listAtom, { type: 'PUT', item: 'b' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'b']);
|
|
});
|
|
|
|
test('PUT appends an array of items in order', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: 'a' });
|
|
store.set(listAtom, { type: 'PUT', item: ['b', 'c'] });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'b', 'c']);
|
|
});
|
|
|
|
test('PUT does not deduplicate', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: 'a' });
|
|
store.set(listAtom, { type: 'PUT', item: 'a' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'a']);
|
|
});
|
|
|
|
test('DELETE removes a single item by identity', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b', 'c'] });
|
|
store.set(listAtom, { type: 'DELETE', item: 'b' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'c']);
|
|
});
|
|
|
|
test('DELETE removes an array of items', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b', 'c', 'd'] });
|
|
store.set(listAtom, { type: 'DELETE', item: ['a', 'c'] });
|
|
assert.deepEqual(store.get(listAtom), ['b', 'd']);
|
|
});
|
|
|
|
test('DELETE of an absent item is a no-op', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b'] });
|
|
store.set(listAtom, { type: 'DELETE', item: 'z' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'b']);
|
|
});
|
|
|
|
test('DELETE uses reference identity for object items', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<{ id: number }>();
|
|
const a = { id: 1 };
|
|
const b = { id: 2 };
|
|
store.set(listAtom, { type: 'PUT', item: [a, b] });
|
|
|
|
// A structurally-equal but distinct object is not removed.
|
|
store.set(listAtom, { type: 'DELETE', item: { id: 1 } });
|
|
assert.deepEqual(store.get(listAtom), [a, b]);
|
|
|
|
// The same reference is removed.
|
|
store.set(listAtom, { type: 'DELETE', item: a });
|
|
assert.deepEqual(store.get(listAtom), [b]);
|
|
});
|
|
|
|
test('REPLACE swaps the matching item, preserving position', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b', 'c'] });
|
|
store.set(listAtom, { type: 'REPLACE', item: 'b', replacement: 'B' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'B', 'c']);
|
|
});
|
|
|
|
test('REPLACE matches by identity and replaces every match', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b', 'a'] });
|
|
store.set(listAtom, { type: 'REPLACE', item: 'a', replacement: 'X' });
|
|
assert.deepEqual(store.get(listAtom), ['X', 'b', 'X']);
|
|
});
|
|
|
|
test('REPLACE with no match leaves the list unchanged', () => {
|
|
const store = createStore();
|
|
const listAtom = createListAtom<string>();
|
|
store.set(listAtom, { type: 'PUT', item: ['a', 'b'] });
|
|
store.set(listAtom, { type: 'REPLACE', item: 'z', replacement: 'Z' });
|
|
assert.deepEqual(store.get(listAtom), ['a', 'b']);
|
|
});
|