UNPKG

koishi-test-utils

Version:
807 lines (797 loc) 31.3 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; // packages/koishi-test-utils/src/index.ts __export(exports, { App: () => MockedApp, BASE_SELF_ID: () => BASE_SELF_ID, MockedApp: () => MockedApp, TestSession: () => TestSession, Tests: () => Tests, createArray: () => createArray, default: () => src_default }); // packages/koishi-test-utils/src/memory.ts var memory_exports = {}; __export(memory_exports, { MemoryDatabase: () => MemoryDatabase, apply: () => apply }); var import_koishi_core = __toModule(require("koishi-core")); var import_koishi_utils = __toModule(require("koishi-utils")); var MemoryDatabase = class { constructor(app, config) { this.app = app; this.config = config; this.$store = {}; this.memory = this; } $table(table) { var _a; return (_a = this.$store)[table] || (_a[table] = []); } $count(table, field = "id") { return new Set(this.$table(table).map((data) => data[field])).size; } }; MemoryDatabase.tables = {}; var queryOperators = { $eq: (query, data) => data.valueOf() === query.valueOf(), $ne: (query, data) => data.valueOf() !== query.valueOf(), $gt: (query, data) => data.valueOf() > query.valueOf(), $gte: (query, data) => data.valueOf() >= query.valueOf(), $lt: (query, data) => data.valueOf() < query.valueOf(), $lte: (query, data) => data.valueOf() <= query.valueOf(), $in: (query, data) => query.includes(data), $nin: (query, data) => !query.includes(data), $regex: (query, data) => query.test(data), $regexFor: (query, data) => new RegExp(data, "i").test(query), $bitsAllSet: (query, data) => (query & data) === query, $bitsAllClear: (query, data) => (query & data) === 0, $bitsAnySet: (query, data) => (query & data) !== 0, $bitsAnyClear: (query, data) => (query & data) !== query, $el: (query, data) => data.some((item) => executeFieldQuery(query, item)), $size: (query, data) => data.length === query }; var evalOperators = { $add: (args, data) => args.reduce((prev, curr) => prev + executeEval(curr, data), 0), $multiply: (args, data) => args.reduce((prev, curr) => prev * executeEval(curr, data), 1), $subtract: ([left, right], data) => executeEval(left, data) - executeEval(right, data), $divide: ([left, right], data) => executeEval(left, data) - executeEval(right, data), $eq: ([left, right], data) => executeEval(left, data).valueOf() === executeEval(right, data).valueOf(), $ne: ([left, right], data) => executeEval(left, data).valueOf() !== executeEval(right, data).valueOf(), $gt: ([left, right], data) => executeEval(left, data).valueOf() > executeEval(right, data).valueOf(), $gte: ([left, right], data) => executeEval(left, data).valueOf() >= executeEval(right, data).valueOf(), $lt: ([left, right], data) => executeEval(left, data).valueOf() < executeEval(right, data).valueOf(), $lte: ([left, right], data) => executeEval(left, data).valueOf() <= executeEval(right, data).valueOf(), $sum: (expr, table) => table.reduce((prev, curr) => prev + executeEval(expr, curr), 0), $avg: (expr, table) => table.reduce((prev, curr) => prev + executeEval(expr, curr), 0) / table.length, $min: (expr, table) => Math.min(...table.map((data) => executeEval(expr, data))), $max: (expr, table) => Math.max(...table.map((data) => executeEval(expr, data))), $count: (expr, table) => new Set(table.map((data) => executeEval(expr, data))).size }; function executeFieldQuery(query, data) { if (Array.isArray(query)) { return query.includes(data); } else if (query instanceof RegExp) { return query.test(data); } else if (typeof query === "string" || typeof query === "number" || query instanceof Date) { return data.valueOf() === query.valueOf(); } for (const key in queryOperators) { const value = query[key]; if (value === void 0) continue; if (!queryOperators[key](value, data)) return false; } return true; } function executeQuery(query, data) { const entries = Object.entries(query); return entries.every(([key, value]) => { if (key === "$and") { return value.reduce((prev, query2) => prev && executeQuery(query2, data), true); } else if (key === "$or") { return value.reduce((prev, query2) => prev || executeQuery(query2, data), false); } else if (key === "$not") { return !executeQuery(value, data); } else if (key === "$expr") { return executeEval(value, data); } try { if (!(key in data)) return false; return executeFieldQuery(value, data[key]); } catch { return false; } }); } function executeEval(expr, data) { if (typeof expr === "string") { return data[expr]; } else if (typeof expr === "number" || typeof expr === "boolean") { return expr; } for (const key in expr) { if (key in evalOperators) { return evalOperators[key](expr[key], data); } } } import_koishi_core.Database.extend(MemoryDatabase, { async drop(name) { if (name) { delete this.$store[name]; } else { this.$store = {}; } }, async get(name, query, modifier) { const expr = import_koishi_core.Query.resolve(name, query); const { fields, limit = Infinity, offset = 0 } = import_koishi_core.Query.resolveModifier(modifier); return this.$table(name).filter((row) => executeQuery(expr, row)).map((row) => (0, import_koishi_utils.clone)((0, import_koishi_utils.pick)(row, fields))).slice(offset, offset + limit); }, async remove(name, query) { const entries = Object.entries(import_koishi_core.Query.resolve(name, query)); this.$store[name] = this.$table(name).filter((row) => !entries.every(([key, value]) => value.includes(row[key]))); }, async create(table, data) { const store = this.$table(table); const { primary = "id" } = MemoryDatabase.tables[table] || {}; if (!data[primary]) { const max = store.length ? Math.max(...store.map((row) => +row[primary])) : 0; data[primary] = max + 1; } store.push(data); return data; }, async update(table, data, key) { if (key) key = (MemoryDatabase.tables[table] || {}).primary || "id"; for (const item of data) { const row = this.$table(table).find((row2) => row2[key] === item[key]); Object.assign(row, (0, import_koishi_utils.clone)(item)); } }, async aggregate(name, fields, query) { const expr = import_koishi_core.Query.resolve(name, query); const table = this.$table(name).filter((row) => executeQuery(expr, row)); return Object.fromEntries(Object.entries(fields).map(([key, expr2]) => [key, executeEval(expr2, table)])); }, async getUser(type, id, fields) { if (Array.isArray(id)) { return this.get("user", { [type]: id }, fields); } else { return (await this.get("user", { [type]: [id] }, fields))[0]; } }, async setUser(type, id, data) { const table = this.$table("user"); const index = table.findIndex((row) => row[type] === id); if (index < 0) return; Object.assign(table[index], (0, import_koishi_utils.clone)(data)); }, async createUser(type, id, data) { const table = this.$table("user"); const index = table.findIndex((row) => row[type] === id); if (index >= 0) return; const user = await this.create("user", __spreadValues(__spreadValues({}, import_koishi_core.User.create(type, id)), (0, import_koishi_utils.clone)(data))); user.id = "" + user.id; }, async getChannel(type, id, fields) { if (Array.isArray(id)) { return this.get("channel", id.map((id2) => `${type}:${id2}`), fields); } else { return (await this.get("channel", [`${type}:${id}`], fields))[0]; } }, async getAssignedChannels(fields, assignMap = this.app.getSelfIds()) { return this.$table("channel").filter((row) => { var _a; const [type] = row.id.split(":"); return (_a = assignMap[type]) == null ? void 0 : _a.includes(row.assignee); }).map((row) => (0, import_koishi_utils.clone)((0, import_koishi_utils.pick)(row, fields))); }, async setChannel(type, id, data) { const table = this.$table("channel"); const index = table.findIndex((row) => row.id === `${type}:${id}`); if (index < 0) return; Object.assign(table[index], (0, import_koishi_utils.clone)(data)); }, async createChannel(type, id, data) { const table = this.$table("channel"); const index = table.findIndex((row) => row.id === `${type}:${id}`); if (index >= 0) return; table.push(__spreadValues(__spreadValues({}, import_koishi_core.Channel.create(type, id)), (0, import_koishi_utils.clone)(data))); } }); function apply(app, config = {}) { app.database = new MemoryDatabase(app, config); } // packages/koishi-test-utils/src/app.ts var import_koishi_core2 = __toModule(require("koishi-core")); var import_chai = __toModule(require("chai")); var import_net = __toModule(require("net")); var import_util = __toModule(require("util")); var http = __toModule(require("http")); var import_koishi_utils2 = __toModule(require("koishi-utils")); var BASE_SELF_ID = "514"; var MockedBot = class extends import_koishi_core2.Bot { constructor() { super(...arguments); this.status = import_koishi_core2.Bot.Status.GOOD; } async getMessage(channelId, messageId) { return { messageId, channelId, content: "", time: 0, subtype: null, messageType: null, author: { userId: this.selfId } }; } }; var MockedServer = class extends import_koishi_core2.Adapter { constructor(app) { super(app, MockedBot); } stop() { } async start() { } get(path, headers) { return this.receive("GET", path, headers, ""); } post(path, body, headers) { return this.receive("POST", path, __spreadProps(__spreadValues({}, headers), { "content-type": "application/json" }), JSON.stringify(body)); } receive(method, path, headers, content) { const socket = new import_net.Socket(); const req = new http.IncomingMessage(socket); req.url = path; req.method = method; Object.assign(req.headers, headers); req.headers["content-length"] = "" + content.length; return new Promise((resolve) => { const res = new http.ServerResponse(req); let body = ""; res.write = (chunk) => { body += chunk; return true; }; res.end = (chunk) => { res.write(chunk); const code = res.statusCode; const headers2 = res.getHeaders(); resolve({ code, body, headers: headers2 }); }; this.app._httpServer.emit("request", req, res); req.emit("data", content); req.emit("end"); }); } }; import_koishi_core2.Adapter.types.mock = MockedServer; var MockedApp = class extends import_koishi_core2.App { constructor(options = {}) { super(__spreadValues({ type: "mock", selfId: BASE_SELF_ID, channelCacheAge: Number.EPSILON, userCacheAge: Number.EPSILON }, options)); this.server = this.adapters.mock; if (options.mockStart !== false) this.status = import_koishi_core2.App.Status.open; if (options.mockDatabase) this.plugin(memory_exports); } get selfId() { return this.bots[0].selfId; } receive(meta) { const session = new import_koishi_core2.Session(this, meta); this.adapters.mock.dispatch(session); return session.id; } session(userId, channelId) { return new TestSession(this, userId, channelId); } async initUser(id, authority = 1) { await this.database.createUser("mock", id, { authority }); } async initChannel(id, assignee = this.selfId) { await this.database.createChannel("mock", id, { assignee }); } }; var TestSession = class { constructor(app, userId, channelId) { this.app = app; this.userId = userId; this.channelId = channelId; this.replies = []; this.meta = { platform: "mock", type: "message", selfId: app.selfId, userId, author: { userId, username: "" + userId } }; if (channelId) { this.meta.groupId = channelId; this.meta.channelId = channelId; this.meta.subtype = "group"; } else { this.meta.channelId = "private:" + userId; this.meta.subtype = "private"; } } async receive(content, count) { return new Promise((resolve) => { let resolved = false; const _resolve = () => { if (resolved) return; resolved = true; dispose(); resolve(this.replies); this.replies = []; }; const send = async (content2) => { if (!content2) return; const session = this.app.bots[0].createSession((0, import_koishi_utils2.pick)(this.meta, ["userId", "channelId", "groupId"])); session.content = content2; this.app.emit(session, "before-send", session); const length = this.replies.push(content2); if (length >= count) _resolve(); }; const dispose = this.app.on("middleware", (session) => { if (session.id === uuid) process.nextTick(_resolve); }); const uuid = this.app.receive(__spreadProps(__spreadValues({}, this.meta), { send, content })); }); } async shouldReply(message, reply) { if (!reply) { const result2 = await this.receive(message); return import_chai.assert.ok(result2.length, (0, import_util.format)(RECEIVED_NOTHING, message)); } if (!Array.isArray(reply)) reply = [reply]; const result = await this.receive(message, reply.length); for (const index in reply) { const expected = reply[index]; const actual = result[index]; import_chai.assert.ok(actual, (0, import_util.format)(RECEIVED_NOTHING, message)); if (typeof expected === "string") { import_chai.assert.strictEqual(actual, expected, (0, import_util.format)(RECEIVED_OTHERWISE, message, `"${expected}"`, actual)); } else { import_chai.assert.match(actual, expected, (0, import_util.format)(RECEIVED_OTHERWISE, message, expected.toString(), actual)); } } } async shouldNotReply(message) { const result = await this.receive(message); import_chai.assert.ok(!result.length, `expected "${message}" to have no reply but received "${result[0]}"`); } }; var RECEIVED_NOTHING = 'expected "%s" to be replied but received nothing'; var RECEIVED_OTHERWISE = 'expected "%s" to be replied with %s but received "%s"'; // packages/koishi-test-utils/src/tests/builtin.ts var import_koishi_core3 = __toModule(require("koishi-core")); var import_chai3 = __toModule(require("chai")); // packages/koishi-test-utils/chai/src/index.ts var import_chai2 = __toModule(require("chai")); var import_util2 = __toModule(require("util")); (0, import_chai2.use)(({ Assertion }) => { function checkShape(expect3, actual, path) { if (actual === expect3 || Number.isNaN(expect3) && Number.isNaN(actual)) return; function formatError(expect4, actual2) { return `expected to have ${expect4} but got ${actual2} at path ${path}`; } if (!expect3 || ["string", "number", "boolean", "bigint"].includes(typeof expect3)) { return formatError((0, import_util2.inspect)(expect3), (0, import_util2.inspect)(actual)); } if (expect3 instanceof Date) { if (!(actual instanceof Date) || +expect3 !== +actual) { return formatError((0, import_util2.inspect)(expect3), (0, import_util2.inspect)(actual)); } return; } if (actual === null) { const type = Object.prototype.toString.call(expect3).slice(8, -1).toLowerCase(); return formatError(`a ${type}`, "null"); } for (const prop in expect3) { if (typeof actual[prop] === "undefined" && typeof expect3[prop] !== "undefined") { return `expected "${prop}" field to be defined at path ${path}`; } const message = checkShape(expect3[prop], actual[prop], `${path}${prop}/`); if (message) return message; } } Assertion.addMethod("shape", function(expect3) { const message = checkShape(expect3, this._obj, "/"); if (message) this.assert(false, message, void 0, expect3, this._obj); }); }); (0, import_chai2.use)(require("chai-as-promised")); // packages/koishi-test-utils/src/tests/builtin.ts function BuiltinMethods(app) { const { database: db } = app; it("user operations", async () => { await db.setUser("mock", "A", import_koishi_core3.User.create("mock", "A")); await (0, import_chai3.expect)(db.getUser("mock", "A")).eventually.not.to.be.ok; await db.createUser("mock", "A", { authority: 1 }); await (0, import_chai3.expect)(db.getUser("mock", "A")).eventually.to.have.shape({ authority: 1 }); await db.setUser("mock", "A", { authority: 2 }); await (0, import_chai3.expect)(db.getUser("mock", "A")).eventually.to.have.shape({ authority: 2 }); await db.remove("user", { mock: ["A"] }); await (0, import_chai3.expect)(db.getUser("mock", ["A"])).eventually.to.deep.equal([]); }); it("channel operations", async () => { await db.setChannel("mock", "A", import_koishi_core3.Channel.create("mock", "A")); await (0, import_chai3.expect)(db.getChannel("mock", "A")).eventually.not.to.be.ok; await db.createChannel("mock", "A", { assignee: "123" }); await (0, import_chai3.expect)(db.getChannel("mock", "A")).eventually.to.have.shape({ assignee: "123" }); await db.setChannel("mock", "A", { assignee: "321" }); await (0, import_chai3.expect)(db.getChannel("mock", "A")).eventually.to.have.shape({ assignee: "321" }); await db.createChannel("mock", "B", { assignee: app.bots[0].selfId }); await db.createChannel("mock", "C", { assignee: app.bots[0].selfId }); await (0, import_chai3.expect)(db.getAssignedChannels(null)).eventually.to.have.length(2); await (0, import_chai3.expect)(db.getAssignedChannels(null, { mock: ["321"] })).eventually.to.have.length(1); await db.remove("channel", { id: ["mock:A"] }); await (0, import_chai3.expect)(db.getChannel("mock", ["A"])).eventually.to.deep.equal([]); }); } // packages/koishi-test-utils/src/tests/query.ts var import_koishi_core4 = __toModule(require("koishi-core")); var import_chai5 = __toModule(require("chai")); import_koishi_core4.Tables.extend("foo", { type: "incremental", fields: { id: "unsigned", text: "string", value: "integer", list: "list", date: "timestamp" } }); var QueryOperators; (function(QueryOperators2) { QueryOperators2.name = "QueryOperators"; QueryOperators2.comparison = function Comparison(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { text: "awesome foo", date: new Date("2000-01-01") }); await db.create("foo", { text: "awesome bar" }); await db.create("foo", { text: "awesome baz" }); }); it("compile expr query", async () => { await (0, import_chai5.expect)(db.get("foo", { id: { $eq: 2 } })).eventually.to.have.length(1).with.nested.property("0.text").equal("awesome bar"); await (0, import_chai5.expect)(db.get("foo", { id: { $ne: 3 } })).eventually.to.have.length(2).with.nested.property("0.text").equal("awesome foo"); await (0, import_chai5.expect)(db.get("foo", { id: { $gt: 1 } })).eventually.to.have.length(2).with.nested.property("1.text").equal("awesome baz"); await (0, import_chai5.expect)(db.get("foo", { id: { $gte: 3 } })).eventually.to.have.length(1).with.nested.property("0.text").equal("awesome baz"); await (0, import_chai5.expect)(db.get("foo", { id: { $lt: 1 } })).eventually.to.have.length(0); await (0, import_chai5.expect)(db.get("foo", { id: { $lte: 2 } })).eventually.to.have.length(2).with.nested.property("0.text").equal("awesome foo"); }); it("date comparisons", async () => { await (0, import_chai5.expect)(db.get("foo", { date: { $gt: new Date("1999-01-01") } })).eventually.to.have.length(1).with.nested.property("0.text").equal("awesome foo"); await (0, import_chai5.expect)(db.get("foo", { date: { $lte: new Date("1999-01-01") } })).eventually.to.have.length(0); }); it("shorthand syntax", async () => { await (0, import_chai5.expect)(db.get("foo", { id: 2 })).eventually.to.have.length(1).with.nested.property("0.text").equal("awesome bar"); await (0, import_chai5.expect)(db.get("foo", { date: new Date("2000-01-01") })).eventually.to.have.length(1).with.nested.property("0.text").equal("awesome foo"); }); }; QueryOperators2.membership = function Membership(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { value: 3 }); await db.create("foo", { value: 4 }); await db.create("foo", { value: 7 }); }); it("should verify empty array", async () => { await (0, import_chai5.expect)(db.get("foo", { value: { $in: [] } })).eventually.to.have.length(0); await (0, import_chai5.expect)(db.get("foo", { value: { $nin: [] } })).eventually.to.have.length(3); }); it("filter data by include", async () => { await (0, import_chai5.expect)(db.get("foo", { value: { $in: [3, 4] } })).eventually.to.have.length(2); await (0, import_chai5.expect)(db.get("foo", { value: { $nin: [4] } })).eventually.to.have.length(2); }); }; QueryOperators2.regexp = function RegularExpression(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { text: "awesome foo" }); await db.create("foo", { text: "awesome bar" }); await db.create("foo", { text: "awesome foo bar" }); }); it("filter data by regex", async () => { await (0, import_chai5.expect)(db.get("foo", { text: /^.*foo$/ })).eventually.to.have.nested.property("[0].text").equal("awesome foo"); await (0, import_chai5.expect)(db.get("foo", { text: { $regex: /^.*foo$/ } })).eventually.to.have.nested.property("[0].text").equal("awesome foo"); await (0, import_chai5.expect)(db.get("foo", { text: /^.*foo.*$/ })).eventually.to.have.length(2); }); }; QueryOperators2.bitwise = function Bitwise(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { value: 3 }); await db.create("foo", { value: 4 }); await db.create("foo", { value: 7 }); }); it("filter data by bits", async () => { await (0, import_chai5.expect)(db.get("foo", { value: { $bitsAllSet: 3 } })).eventually.to.have.shape([{ value: 3 }, { value: 7 }]); await (0, import_chai5.expect)(db.get("foo", { value: { $bitsAllClear: 9 } })).eventually.to.have.shape([{ value: 4 }]); await (0, import_chai5.expect)(db.get("foo", { value: { $bitsAnySet: 4 } })).eventually.to.have.shape([{ value: 4 }, { value: 7 }]); await (0, import_chai5.expect)(db.get("foo", { value: { $bitsAnyClear: 6 } })).eventually.to.have.shape([{ value: 3 }, { value: 4 }]); }); }; QueryOperators2.list = function List(app, options = {}) { const db = app.database; const { size = true, element = true, elementQuery = element } = options; before(async () => { await db.remove("foo", {}); await db.create("foo", { id: 1, list: [] }); await db.create("foo", { id: 2, list: [23] }); await db.create("foo", { id: 3, list: [233] }); await db.create("foo", { id: 4, list: [233, 332] }); }); size && it("$size", async () => { await (0, import_chai5.expect)(db.get("foo", { list: { $size: 1 } })).eventually.to.have.length(2).with.shape([{ id: 2 }, { id: 3 }]); }); element && it("$el shorthand", async () => { await (0, import_chai5.expect)(db.get("foo", { list: { $el: 233 } })).eventually.to.have.length(2).with.shape([{ id: 3 }, { id: 4 }]); }); elementQuery && it("$el with field query", async () => { await (0, import_chai5.expect)(db.get("foo", { list: { $el: { $lt: 50 } } })).eventually.to.have.shape([{ id: 2 }]); }); }; QueryOperators2.evaluation = function Evaluation(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { id: 1, value: 8 }); await db.create("foo", { id: 2, value: 7 }); await db.create("foo", { id: 3, value: 9 }); }); it("arithmetic operators", async () => { await (0, import_chai5.expect)(db.get("foo", { $expr: { $eq: [9, { $add: ["id", "value"] }] } })).eventually.to.have.length(2).with.shape([{ id: 1 }, { id: 2 }]); }); }; QueryOperators2.logical = function Logical(app) { const db = app.database; before(async () => { await db.remove("foo", {}); await db.create("foo", { id: 1, text: "awesome foo", value: 3, list: [], date: new Date("2000-01-01") }); await db.create("foo", { id: 2, text: "awesome bar", value: 4, list: [1] }); await db.create("foo", { id: 3, text: "awesome foo bar", value: 7, list: [100] }); }); it("edge cases", async () => { await (0, import_chai5.expect)(db.get("foo", {})).eventually.to.have.length(3); await (0, import_chai5.expect)(db.get("foo", { $and: [] })).eventually.to.have.length(3); await (0, import_chai5.expect)(db.get("foo", { $or: [] })).eventually.to.have.length(0); await (0, import_chai5.expect)(db.get("foo", { $not: {} })).eventually.to.have.length(0); await (0, import_chai5.expect)(db.get("foo", { $not: { $and: [] } })).eventually.to.have.length(0); await (0, import_chai5.expect)(db.get("foo", { $not: { $or: [] } })).eventually.to.have.length(3); }); it("should verify `$or`, `$and` and `$not`", async () => { await (0, import_chai5.expect)(db.get("foo", { $or: [{ id: [1, 2] }, { id: [1, 3] }] })).eventually.to.have.length(3); await (0, import_chai5.expect)(db.get("foo", { $or: [{ id: [2] }, { text: /.*foo.*/ }] })).eventually.to.have.length(3); await (0, import_chai5.expect)(db.get("foo", { $or: [{ id: { $gt: 1 } }, { text: /.*foo$/ }] })).eventually.to.have.length(3); await (0, import_chai5.expect)(db.get("foo", { $or: [{ text: /.*foo/ }, { text: /foo.*/ }] })).eventually.to.have.length(2); await (0, import_chai5.expect)(db.get("foo", { $and: [{ text: /.*foo$/ }, { text: /foo.*/ }] })).eventually.to.have.length(1); await (0, import_chai5.expect)(db.get("foo", { $not: { $and: [{ text: /.*foo$/ }, { text: /foo.*/ }] } })).eventually.to.have.length(2); await (0, import_chai5.expect)(db.get("foo", { $not: { $or: [{ text: /.*foo/ }, { text: /foo.*/ }] } })).eventually.to.have.length(1); }); it("should verify `$or` and other key", async () => { await (0, import_chai5.expect)(db.get("foo", { text: /.*foo.*/, $or: [{ text: /.*foo/ }] })).eventually.to.have.length(2); await (0, import_chai5.expect)(db.get("foo", { text: /.*foo.*/, $or: [{ text: /foo.+/ }] })).eventually.to.have.length(1); }); }; })(QueryOperators || (QueryOperators = {})); var query_default = QueryOperators; // packages/koishi-test-utils/src/tests/index.ts var Tests; (function(Tests2) { const Keywords = ["name"]; function createUnit(target, root = false) { const test = (app, options = {}) => { function callback() { if (typeof target === "function") { target(app, options); } for (const key in target) { if (options[key] === false || Keywords.includes(key)) continue; test[key](app, options[key]); } } const title = target["name"]; if (!root && title) { describe(title.replace(/(?=[A-Z])/g, " ").trimStart(), callback); } else { callback(); } }; for (const key in target) { if (Keywords.includes(key)) continue; test[key] = createUnit(target[key]); } return test; } function DatabaseTests(app) { before(() => app.start()); after(async () => { await app.database.drop(); await app.stop(); }); } (function(DatabaseTests2) { DatabaseTests2.builtin = BuiltinMethods; DatabaseTests2.query = query_default; })(DatabaseTests || (DatabaseTests = {})); Tests2.database = createUnit(DatabaseTests, true); })(Tests || (Tests = {})); // packages/koishi-test-utils/src/index.ts var src_default = MemoryDatabase; function createArray(length, create) { return [...new Array(length).keys()].map(create); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { App, BASE_SELF_ID, MockedApp, TestSession, Tests, createArray }); //# sourceMappingURL=index.js.map