Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions .agents/skills/dali-orm-test-patterns/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
name: dali-orm-test-patterns
description: Test patterns for DaliORM — SurrealDB mocking, record comparison, migration assertions, and NodeDriver test setup
license: MIT
---

# DaliORM Test Patterns

Test patterns and conventions for the DaliORM mono-repo test suite.

## Record Comparison

**Always sort before deep-equality** when tests query unordered result sets:

```typescript
// CORRECT — sort before compare
const expected = [
{ id: '1', name: 'alpha' },
{ id: '2', name: 'beta' },
];
const actual = [...results].sort((a, b) => a.id.localeCompare(b.id));
expect(actual).toEqual(expected);

// WRONG — ordering is non-deterministic
expect(results).toEqual(expected);
```

Use a stable field (`id`, `name`) for sorting. Avoid relying on insertion
order.

## SurrealWebSocket Mock Setup

When testing NodeDriver directly, mock `SurrealWebSocket` before import:

```typescript
vi.mock('surrealdb.js', async () => {
const actual = await vi.importActual('surrealdb.js');
const MockSocket = vi.fn(() => ({
readyState: WebSocket.OPEN,
close: vi.fn(),
send: vi.fn(),
}));
return { ...actual, SurrealWebSocket: MockSocket as any };
});
```

Always restore mocks in `afterEach()`:

```typescript
afterEach(() => {
vi.restoreAllMocks();
vi.clearAllMocks();
});
```

## Migration Assertions

Use snapshot-based matching for generated DDL:

```typescript
const sql = generateMigration(prevSchema, nextSchema);
expect(stripDynamicIds(sql)).toMatchSnapshot();
```

For programmatic migration API tests:

```typescript
const status = await getMigrationStatus(driver);
expect(status.pending).toHaveLength(1);
expect(status.applied).toHaveLength(0);
```

## Test File Placement

| Package | Test Directory |
| ------------------- | ------------------------------------- |
| `@woss/dali-orm` | `packages/dali-orm/src/**/__tests__/` |
| `@woss/dali-memory` | `packages/dali-memory/tests/` |

Run tests:

```bash
# Root (all packages)
pnpm test

# Single package
pnpm --filter @woss/dali-orm test

# Watch mode
pnpm --filter @woss/dali-orm test:watch

# With coverage
pnpm test:coverage
```

## Cross-Skill References

- **Vitest setup** → Use `vitest` skill for test configuration patterns
- **DaliORM driver API** → Use `dali-orm` skill for driver config details
22 changes: 22 additions & 0 deletions .agents/skills/dali-orm/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ const [newUser] = await insert(driver, usersTable)
await orm.query('SELECT * FROM users WHERE email = $email', { email: 'a@b.com' });
```

## ConnectOptions Auth Pattern

System-level auth (root / namespace / database) MUST flow through `ConnectOptions.authentication` in SurrealDB SDK v2. Do **not** use standalone `db.signin()` for system auth.

**Why**: SDK v2 opens a new WebSocket on auto-reconnect. Session-level `db.signin()` tokens bind to the old connection and are lost. Credentials in `ConnectOptions.authentication` persist across reconnects.

**System auth** — auth config maps to `buildSystemAuth()` which strips the `type` discriminator and produces `RootAuth | NamespaceAuth | DatabaseAuth`:

```typescript
const orm = await DaliORM.connect({
nodeDriver: {
url: 'ws://localhost:10101',
namespace: 'test',
database: 'test',
auth: { type: 'root', username: 'root', password: 'root' },
},
});
```

**Record / scope auth** still uses `db.use()` + `db.signin()` — it requires matching the selected namespace/database to the access scope.

## Reference Files

| Task | File |
Expand Down Expand Up @@ -144,3 +165,4 @@ await orm.query('SELECT * FROM users WHERE email = $email', { email: 'a@b.com' }

- **TypeScript generics** → Use `typescript-pro` skill for advanced type patterns
- **Testing query builders** → Use `vitest` skill for writing tests
- **Test patterns (mocking, record comparison)** → Use `dali-orm-test-patterns` skill
Loading
Loading