npm package: @lark-apaas/action-plugin-testing
Description: Testing utilities for action plugins
Latest version: 0.1.1

# @lark-apaas/action-plugin-testing

Testing utilities for `@lark-apaas/action-plugin-core` — provides mock context, test runner, stream helpers, and schema validation tools.

## Install

```bash
npm install -D @lark-apaas/action-plugin-testing
```

## Quick Start

```typescript
import { createTestContext, createTestRunner } from '@lark-apaas/action-plugin-testing';
import plugin from './my-plugin';

const runner = createTestRunner(plugin);
const context = createTestContext();

// Run an action
const result = await runner.run('sayHello', context, { name: 'World' });
console.log(result); // { greeting: 'Hello, World!' }
```

## API

### Test Context

#### `createTestContext(options?)`

Creates a mock `ActionContext` for testing.

```typescript
import { createTestContext } from '@lark-apaas/action-plugin-testing';

// Default context
const ctx = createTestContext();

// Custom context
const ctx = createTestContext({
  userId: 'user-123',
  tenantId: 'tenant-456',
  appId: 'app-789',
});
```

### Test Runner

#### `createTestRunner(plugin, options?)`

Wraps a plugin instance with convenience methods for testing.

```typescript
import { createTestRunner } from '@lark-apaas/action-plugin-testing';

const runner = createTestRunner(plugin);

// Unary action
const result = await runner.run('actionName', context, input);

// Stream action
const stream = runner.runStream('actionName', context, input);

// Schema access
const inputSchema = runner.getInputSchema('actionName');
const outputSchema = runner.getOutputSchema('actionName');
```

### Mock Logger

#### `createMockLogger()`

Creates a logger that records all log entries for assertions.

```typescript
import { createMockLogger } from '@lark-apaas/action-plugin-testing';

const logger = createMockLogger();
const ctx = createTestContext({ logger });

await runner.run('action', ctx, input);

// Query logs
logger.getLogs();                    // all entries
logger.getLogs('error');             // filter by level
logger.hasLog('error');              // check existence
logger.getLastLog('info');           // last entry of level
```

### Stream Helpers

Utilities for testing async iterable streams.

```typescript
import {
  collectStream,
  collectStreamData,
  collectStreamText,
  firstChunk,
  lastChunk,
  countChunks,
  assertStreamChunks,
  assertEveryChunk,
} from '@lark-apaas/action-plugin-testing';

const stream = runner.runStream('chat', context, input);

// Collect all chunks
const chunks = await collectStream(stream);

// Extract data fields from StreamChunk items
const data = await collectStreamData(stream);

// Concatenate text content
const text = await collectStreamText(stream);

// Access specific chunks
const first = await firstChunk(stream);
const last = await lastChunk(stream);

// Count without storing
const count = await countChunks(stream);

// Assertions
await assertStreamChunks(stream, [expected1, expected2]);
await assertEveryChunk(stream, (chunk) => chunk.data.content.length > 0);
```

### StreamEvent Helpers

Utilities for testing `StreamEvent` streams.

```typescript
import {
  collectStreamEvents,
  collectEventData,
  waitForDone,
  waitForError,
  expectStreamCompletes,
  expectStreamErrors,
  expectAggregatedResult,
} from '@lark-apaas/action-plugin-testing';

// Collect and categorize events
const { dataEvents, doneEvent, errorEvent } = await collectStreamEvents(stream);

// Collect only data payloads
const data = await collectEventData(stream);

// Wait for completion / error
const meta = await waitForDone(stream);
const error = await waitForError(stream);

// Assertions
await expectStreamCompletes(stream);
await expectStreamErrors(stream, 'ERROR_CODE');
await expectAggregatedResult(stream, expectedResult);
```

### Schema Validation

```typescript
import { parseInput, expectInputRejected } from '@lark-apaas/action-plugin-testing';

// Validate input against action schema
const parsed = parseInput(runner, 'actionName', { name: 'test' });

// Assert invalid input is rejected
expectInputRejected(runner, 'actionName', { name: 123 });
```

## Types

```typescript
import type {
  TestContextOptions,
  TestRunner,
  TestRunnerOptions,
  MockLogger,
  LogEntry,
  StreamEventResult,
} from '@lark-apaas/action-plugin-testing';
```

## License

MIT