@motiadev/test 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export { createMotiaTester } from './src/tester';
2
+ export { CapturedEvent } from './src/types';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMotiaTester = void 0;
4
+ var tester_1 = require("./src/tester");
5
+ Object.defineProperty(exports, "createMotiaTester", { enumerable: true, get: function () { return tester_1.createMotiaTester; } });
@@ -0,0 +1,6 @@
1
+ import { EventManager } from '@motiadev/core';
2
+ interface TestEventManager extends EventManager {
3
+ waitEvents(): Promise<void>;
4
+ }
5
+ export declare const createEventManager: () => TestEventManager;
6
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createEventManager = void 0;
4
+ const createEventManager = () => {
5
+ const handlers = {};
6
+ const events = [];
7
+ const waitEvents = async () => {
8
+ let eventsToAwait = [...events];
9
+ // We need to wait for all events to be resolved because the event manager is async
10
+ // and we need to ensure that all events have been processed before we can continue
11
+ while (eventsToAwait.length > 0) {
12
+ events.splice(0, eventsToAwait.length);
13
+ await Promise.allSettled(eventsToAwait);
14
+ eventsToAwait = [...events];
15
+ }
16
+ };
17
+ const emit = async (event) => {
18
+ const eventHandlers = handlers[event.type] ?? [];
19
+ events.push(...eventHandlers.map((handler) => handler(event)));
20
+ };
21
+ const subscribe = (event, _, handler) => {
22
+ if (!handlers[event]) {
23
+ handlers[event] = [];
24
+ }
25
+ handlers[event].push(handler);
26
+ };
27
+ return { emit, subscribe, waitEvents };
28
+ };
29
+ exports.createEventManager = createEventManager;
@@ -0,0 +1,19 @@
1
+ import { Response } from 'supertest';
2
+ import { Event } from '@motiadev/core';
3
+ import { CapturedEvent, RequestOptions } from './types';
4
+ type Watcher<TData = unknown> = {
5
+ getCapturedEvents(): CapturedEvent<TData>[];
6
+ getLastCapturedEvent(): CapturedEvent<TData> | undefined;
7
+ getCapturedEvent(index: number): CapturedEvent<TData> | undefined;
8
+ };
9
+ interface MotiaTester {
10
+ post(path: string, options: RequestOptions): Promise<Response>;
11
+ get(path: string, options: RequestOptions): Promise<Response>;
12
+ emit(event: Event<any>): Promise<void>;
13
+ watch<TData>(event: string): Promise<Watcher<TData>>;
14
+ sleep(ms: number): Promise<void>;
15
+ close(): Promise<void>;
16
+ waitEvents(): Promise<void>;
17
+ }
18
+ export declare const createMotiaTester: () => MotiaTester;
19
+ export {};
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createMotiaTester = void 0;
7
+ const supertest_1 = __importDefault(require("supertest"));
8
+ const core_1 = require("@motiadev/core");
9
+ const generate_locked_data_1 = require("@motiadev/snap/src/generate-locked-data");
10
+ const event_manager_1 = require("./event-manager");
11
+ const path_1 = __importDefault(require("path"));
12
+ const createMotiaTester = () => {
13
+ const eventManager = (0, event_manager_1.createEventManager)();
14
+ const promise = (async () => {
15
+ const lockedData = await (0, generate_locked_data_1.generateLockedData)(path_1.default.join(process.cwd()));
16
+ const steps = [...lockedData.steps.active, ...lockedData.steps.dev];
17
+ const state = (0, core_1.createStateAdapter)({
18
+ adapter: 'default',
19
+ filePath: path_1.default.join(process.cwd(), '.motia'),
20
+ });
21
+ const { server, socketServer } = await (0, core_1.createServer)({
22
+ steps,
23
+ flows: lockedData.flows,
24
+ state,
25
+ eventManager,
26
+ });
27
+ (0, core_1.createStepHandlers)(steps, eventManager, state);
28
+ return { server, socketServer, eventManager, state };
29
+ })();
30
+ return {
31
+ waitEvents: async () => {
32
+ const { eventManager } = await promise;
33
+ await eventManager.waitEvents();
34
+ },
35
+ post: async (path, options) => {
36
+ const { server } = await promise;
37
+ return (0, supertest_1.default)(server).post(path).send(options.body);
38
+ },
39
+ get: async (path, options) => {
40
+ const { server } = await promise;
41
+ return (0, supertest_1.default)(server).get(path).send(options.body);
42
+ },
43
+ emit: async (event) => {
44
+ return eventManager.emit(event);
45
+ },
46
+ watch: async (event) => {
47
+ const events = [];
48
+ eventManager.subscribe(event, '$watcher', async (event) => {
49
+ const { logger, ...rest } = event;
50
+ events.push(rest);
51
+ });
52
+ return {
53
+ getCapturedEvents: () => events,
54
+ getLastCapturedEvent: () => events[events.length - 1],
55
+ getCapturedEvent: (index) => events[index],
56
+ };
57
+ },
58
+ sleep: async (ms) => {
59
+ return new Promise((resolve) => setTimeout(resolve, ms));
60
+ },
61
+ close: async () => {
62
+ const { server, socketServer, state } = await promise;
63
+ await state.cleanup();
64
+ await socketServer.close();
65
+ server.close();
66
+ },
67
+ };
68
+ };
69
+ exports.createMotiaTester = createMotiaTester;
@@ -0,0 +1,5 @@
1
+ import type { Event } from '@motiadev/core';
2
+ export type RequestOptions = {
3
+ body?: Record<string, unknown>;
4
+ };
5
+ export type CapturedEvent<TData = unknown> = Omit<Event<TData>, 'logger'>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@motiadev/test",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "peerDependencies": {
7
+ "@motiadev/core": "0.0.1",
8
+ "@motiadev/snap": "0.0.1"
9
+ },
10
+ "dependencies": {
11
+ "supertest": "^7.0.0"
12
+ },
13
+ "devDependencies": {
14
+ "@types/jest": "^29.5.14",
15
+ "@types/supertest": "^6.0.2",
16
+ "jest": "^29.7.0",
17
+ "ts-jest": "^29.2.5",
18
+ "typescript": "^5.7.2"
19
+ },
20
+ "scripts": {
21
+ "build": "rm -rf dist && tsc"
22
+ }
23
+ }