Compare commits

..

No commits in common. "54f10b33216ad516507c4d6eac45f435866a06ad" and "c81e5b79743714ed91f6ca4b2b0f73e62bb29df6" have entirely different histories.

10 changed files with 190 additions and 5 deletions

View file

@ -1,5 +1,5 @@
{ {
"_v": "2.0.1", "_v": "2.0.0",
"type": "module", "type": "module",
"main": "./built/index.js", "main": "./built/index.js",
"scripts": { "scripts": {
@ -38,6 +38,38 @@
"ws": "8.16.0" "ws": "8.16.0"
}, },
"devDependencies": { "devDependencies": {
"@koa/router": "9.4.0",
"@types/jest": "26.0.23",
"@types/koa": "2.13.1",
"@types/koa__router": "8.0.4",
"@types/websocket": "1.0.10",
"jest": "26.6.3",
"koa": "2.13.1",
"koa-json-body": "5.3.0",
"ts-jest": "26.5.6",
"websocket": "1.0.34"
},
"_moduleAliases": {
"@": "built"
},
"jest": {
"testRegex": "/test/.*",
"moduleFileExtensions": [
"ts",
"js"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsConfig": "test/tsconfig.json"
}
},
"moduleNameMapper": {
"^@/(.+)": "<rootDir>/src/$1",
"^#/(.+)": "<rootDir>/test/$1"
}
}, },
"nodemonConfig": { "nodemonConfig": {
"ignore": ["memory.json"] "ignore": ["memory.json"]

View file

@ -105,7 +105,7 @@ export default class 藍 {
@bindThis @bindThis
public log(msg: string) { public log(msg: string) {
log(`[${chalk.magenta('AiOS')}]: ${msg}`); log(chalk`[{magenta AiOS}]: ${msg}`);
} }
@bindThis @bindThis

View file

@ -89,10 +89,10 @@ export default class extends Module {
@bindThis @bindThis
private onReversiGameStart(game: any) { private onReversiGameStart(game: any) {
let strength = 5; let strength = 4;
const friend = this.ai.lookupFriend(game.user1Id !== this.ai.account.id ? game.user1Id : game.user2Id)!; const friend = this.ai.lookupFriend(game.user1Id !== this.ai.account.id ? game.user1Id : game.user2Id)!;
if (friend != null) { if (friend != null) {
strength = friend.doc.reversiStrength ?? 5; strength = friend.doc.reversiStrength ?? 4;
friend.updateReversiStrength(null); friend.updateReversiStrength(null);
} }

View file

@ -0,0 +1,7 @@
export const account = {
id: '0',
name: '藍',
username: 'ai',
host: null,
isBot: true,
};

67
test/__mocks__/misskey.ts Normal file
View file

@ -0,0 +1,67 @@
import * as http from 'http';
import * as Koa from 'koa';
import * as websocket from 'websocket';
export class Misskey {
private server: http.Server;
private streaming: websocket.connection;
constructor() {
const app = new Koa();
this.server = http.createServer(app.callback());
const ws = new websocket.server({
httpServer: this.server
});
ws.on('request', async (request) => {
const q = request.resourceURL.query as ParsedUrlQuery;
this.streaming = request.accept();
});
this.server.listen(3000);
}
public waitForStreamingMessage(handler) {
return new Promise((resolve, reject) => {
const onMessage = (data: websocket.IMessage) => {
if (data.utf8Data == null) return;
const message = JSON.parse(data.utf8Data);
const result = handler(message);
if (result) {
this.streaming.off('message', onMessage);
resolve();
}
};
this.streaming.on('message', onMessage);
});
}
public async waitForMainChannelConnected() {
await this.waitForStreamingMessage(message => {
const { type, body } = message;
if (type === 'connect') {
const { channel, id, params, pong } = body;
if (channel !== 'main') return;
if (pong) {
this.sendStreamingMessage('connected', {
id: id
});
}
return true;
}
});
}
public sendStreamingMessage(type: string, payload: any) {
this.streaming.send(JSON.stringify({
type: type,
body: payload
}));
}
}

17
test/__mocks__/ws.ts Normal file
View file

@ -0,0 +1,17 @@
import * as websocket from 'websocket';
export class StreamingApi {
private ws: WS;
constructor() {
this.ws = new WS('ws://localhost/streaming');
}
public async waitForMainChannelConnected() {
await expect(this.ws).toReceiveMessage("hello");
}
public send(message) {
this.ws.send(JSON.stringify(message));
}
}

26
test/__modules__/test.ts Normal file
View file

@ -0,0 +1,26 @@
import { bindThis } from '@/decorators.js';
import Module from '@/module.js';
import Message from '@/message';
export default class extends Module {
public readonly name = 'test';
@bindThis
public install() {
return {
mentionHook: this.mentionHook
};
}
@bindThis
private async mentionHook(msg: Message) {
if (msg.text && msg.text.includes('ping')) {
msg.reply('PONG!', {
immediate: true
});
return true;
} else {
return false;
}
}
}

20
test/core.ts Normal file
View file

@ -0,0 +1,20 @@
import from '@/ai';
import { account } from '#/__mocks__/account';
import TestModule from '#/__modules__/test';
import { StreamingApi } from '#/__mocks__/ws';
process.env.NODE_ENV = 'test';
let ai: ;
beforeEach(() => {
ai = new (account, [
new TestModule(),
]);
});
test('mention hook', async () => {
const streaming = new StreamingApi();
});

15
test/tsconfig.json Normal file
View file

@ -0,0 +1,15 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "../",
"paths": {
"@/*": ["../src/*"],
"#/*": ["./*"]
},
},
"compileOnSave": false,
"include": [
"**/*.ts"
]
}

View file

@ -40,6 +40,7 @@
"src/**/*" "src/**/*"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules",
"test/**/*"
], ],
} }