chapterjs 0.2.3 → 0.3.0
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.
- package/README.md +65 -0
- package/dist/cli/cli.js +41 -6
- package/dist/cli/project.d.ts +19 -0
- package/dist/cli/project.js +18 -8
- package/dist/cli/test.d.ts +29 -0
- package/dist/cli/test.js +444 -0
- package/dist/commands/autocomplete.d.ts +1 -1
- package/dist/commands/autocomplete.js +37 -41
- package/dist/commands/router.d.ts +4 -1
- package/dist/commands/router.js +15 -17
- package/dist/components/router.d.ts +7 -2
- package/dist/components/router.js +16 -16
- package/dist/discord/types/channel.d.ts +9 -1
- package/dist/discord/types/guild.d.ts +5 -5
- package/dist/discord/types/permissions.d.ts +6 -0
- package/dist/discord/types/poll.d.ts +7 -1
- package/dist/events/router.d.ts +9 -4
- package/dist/events/router.js +24 -11
- package/dist/interactions/dispatch.d.ts +5 -1
- package/dist/interactions/dispatch.js +6 -2
- package/dist/loader/hot.js +22 -2
- package/dist/loader/loader.d.ts +7 -0
- package/dist/loader/loader.js +22 -12
- package/dist/store/memory-backend.d.ts +15 -0
- package/dist/store/memory-backend.js +56 -0
- package/dist/store/store.js +4 -1
- package/dist/tasks/scheduler.d.ts +6 -0
- package/dist/tasks/scheduler.js +9 -3
- package/dist/testing/failure.d.ts +9 -0
- package/dist/testing/failure.js +20 -0
- package/dist/testing/fake-discord.d.ts +59 -0
- package/dist/testing/fake-discord.js +120 -0
- package/dist/testing/fake-gateway.d.ts +59 -0
- package/dist/testing/fake-gateway.js +123 -0
- package/dist/testing/harness.d.ts +387 -0
- package/dist/testing/harness.js +1418 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/scenario.d.ts +39 -0
- package/dist/testing/scenario.js +58 -0
- package/dist/testing/smoke.d.ts +20 -0
- package/dist/testing/smoke.js +659 -0
- package/dist/testing/websocket.d.ts +34 -0
- package/dist/testing/websocket.js +167 -0
- package/dist/testing/world.d.ts +145 -0
- package/dist/testing/world.js +1479 -0
- package/package.json +20 -3
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import type { PermissionName } from '../discord/permissions.js';
|
|
2
|
+
import type { Locale } from '../discord/types/common.js';
|
|
3
|
+
import { type RawEmbed } from '../discord/types/message.js';
|
|
4
|
+
import type { CommandDeclaration, CommandOption, CommandOptions, CommandWhere } from '../commands/command.js';
|
|
5
|
+
import type { ButtonDeclaration } from '../components/button.js';
|
|
6
|
+
import { type ButtonComponent, type ModalComponent, type SelectComponent } from '../components/instance.js';
|
|
7
|
+
import type { CheckboxesField, CheckboxField, EntityField, FilesField, ModalDeclaration, ModalField, ModalFields, NoteField, RadioField, SelectField, TextField } from '../components/modal.js';
|
|
8
|
+
import type { OptionValue } from '../components/options.js';
|
|
9
|
+
import type { SelectDeclaration } from '../components/select.js';
|
|
10
|
+
import type { Bot } from '../core/bot.js';
|
|
11
|
+
import type { Project, ProjectObserver } from '../cli/project.js';
|
|
12
|
+
import type { Log } from '../cli/log.js';
|
|
13
|
+
import type { TaskDeclaration } from '../tasks/task.js';
|
|
14
|
+
import { type Camelize } from '../util/case.js';
|
|
15
|
+
import { World } from './world.js';
|
|
16
|
+
/** A person in the test server. */
|
|
17
|
+
export interface TestMember {
|
|
18
|
+
/** The id of the person. */
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** The username of the person: what `bot.member()` was given. */
|
|
21
|
+
readonly name: string;
|
|
22
|
+
/** The nickname in the server, or `null` without one. */
|
|
23
|
+
readonly nickname: string | null;
|
|
24
|
+
/** The names of the roles of the person. */
|
|
25
|
+
readonly roles: readonly string[];
|
|
26
|
+
/** The permissions of the person in the server. */
|
|
27
|
+
readonly permissions: readonly PermissionName[];
|
|
28
|
+
/** Whether the person is in the server right now. */
|
|
29
|
+
readonly inServer: boolean;
|
|
30
|
+
/** Whether the person is banned from the server. */
|
|
31
|
+
readonly banned: boolean;
|
|
32
|
+
/** Whether the person is timed out right now. */
|
|
33
|
+
readonly timedOut: boolean;
|
|
34
|
+
/** The messages the bot sent to the person in private, oldest first. */
|
|
35
|
+
readonly privateMessages: readonly TestMessage[];
|
|
36
|
+
/** Whether the person may do that in the server. */
|
|
37
|
+
can(permission: PermissionName): boolean;
|
|
38
|
+
/** Whether the person has that role. */
|
|
39
|
+
hasRole(role: string | TestRole): boolean;
|
|
40
|
+
}
|
|
41
|
+
/** A role of the test server. */
|
|
42
|
+
export interface TestRole {
|
|
43
|
+
readonly id: string;
|
|
44
|
+
readonly name: string;
|
|
45
|
+
/** What the role allows. */
|
|
46
|
+
readonly permissions: readonly PermissionName[];
|
|
47
|
+
/** Whether the role still exists. */
|
|
48
|
+
readonly exists: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** The kinds of channels a test can make. */
|
|
51
|
+
export type TestChannelType = 'text' | 'announcement' | 'voice' | 'category' | 'forum';
|
|
52
|
+
/** A channel of the test server, a thread, or a private conversation. */
|
|
53
|
+
export interface TestChannel {
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly name: string;
|
|
56
|
+
/** What kind of channel it is: `'text'`, `'voice'`, `'thread'`, `'dm'`... */
|
|
57
|
+
readonly type: string;
|
|
58
|
+
/** The topic, or `null`. */
|
|
59
|
+
readonly topic: string | null;
|
|
60
|
+
/** The seconds between two messages of one person (slowmode); `0` for none. */
|
|
61
|
+
readonly slowmode: number;
|
|
62
|
+
/** Whether the channel still exists. */
|
|
63
|
+
readonly exists: boolean;
|
|
64
|
+
/** Every message in it that everyone sees, oldest first (deleted and ephemeral ones left out). */
|
|
65
|
+
readonly messages: readonly TestMessage[];
|
|
66
|
+
/** The newest message, or `null`. */
|
|
67
|
+
readonly last: TestMessage | null;
|
|
68
|
+
/** The threads opened in it. */
|
|
69
|
+
readonly threads: readonly TestChannel[];
|
|
70
|
+
/** For a thread: who is in it. */
|
|
71
|
+
readonly members: readonly TestMember[];
|
|
72
|
+
/** For a thread: whether it is archived. */
|
|
73
|
+
readonly archived: boolean;
|
|
74
|
+
/** For a thread: whether it is locked. */
|
|
75
|
+
readonly locked: boolean;
|
|
76
|
+
/** Whether a member may do that in the channel (its overwrites counted). */
|
|
77
|
+
allows(member: TestMember | TestRole, permission: PermissionName): boolean;
|
|
78
|
+
}
|
|
79
|
+
/** A button on a message the bot sent. */
|
|
80
|
+
export interface TestButton {
|
|
81
|
+
/** The text on the button, or `null` for an emoji alone. */
|
|
82
|
+
readonly label: string | null;
|
|
83
|
+
/** `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'link'` or `'premium'`. */
|
|
84
|
+
readonly style: string;
|
|
85
|
+
readonly disabled: boolean;
|
|
86
|
+
/** The id the framework wrote in it. */
|
|
87
|
+
readonly customId: string | null;
|
|
88
|
+
}
|
|
89
|
+
/** A select menu on a message the bot sent. */
|
|
90
|
+
export interface TestMenu {
|
|
91
|
+
/** `'string'`, `'user'`, `'role'`, `'mentionable'` or `'channel'`. */
|
|
92
|
+
readonly type: string;
|
|
93
|
+
readonly placeholder: string | null;
|
|
94
|
+
readonly disabled: boolean;
|
|
95
|
+
/** For a menu of texts: its options. */
|
|
96
|
+
readonly options: readonly {
|
|
97
|
+
label: string;
|
|
98
|
+
value: string;
|
|
99
|
+
}[];
|
|
100
|
+
/** The id the framework wrote in it. */
|
|
101
|
+
readonly customId: string;
|
|
102
|
+
}
|
|
103
|
+
/** A form the bot opened. */
|
|
104
|
+
export interface TestForm {
|
|
105
|
+
readonly title: string;
|
|
106
|
+
/** The names of its fields, in order. */
|
|
107
|
+
readonly fields: readonly string[];
|
|
108
|
+
/** The id the framework wrote in it. */
|
|
109
|
+
readonly customId: string;
|
|
110
|
+
}
|
|
111
|
+
/** A suggestion the bot gave while someone typed in an option. */
|
|
112
|
+
export interface TestSuggestion {
|
|
113
|
+
readonly name: string;
|
|
114
|
+
readonly value: string | number;
|
|
115
|
+
}
|
|
116
|
+
/** A file someone attaches to a command or a form. */
|
|
117
|
+
export interface TestFile {
|
|
118
|
+
/** The name of the file, with its extension: `photo.png`. */
|
|
119
|
+
name: string;
|
|
120
|
+
/** Its content, as text. */
|
|
121
|
+
content?: string;
|
|
122
|
+
/** Its media type: guessed from the name by default. */
|
|
123
|
+
type?: string;
|
|
124
|
+
}
|
|
125
|
+
/** What is checked of a message or an answer. */
|
|
126
|
+
export interface TestAssertions<Self> {
|
|
127
|
+
/** Checks that the text contains `text` (or matches it). */
|
|
128
|
+
says(text: string | RegExp): Self;
|
|
129
|
+
/** Checks that the text is exactly `text`. */
|
|
130
|
+
saysExactly(text: string): Self;
|
|
131
|
+
/** Checks that only the person who asked sees it. */
|
|
132
|
+
isEphemeral(): Self;
|
|
133
|
+
/** Checks that everyone sees it. */
|
|
134
|
+
isPublic(): Self;
|
|
135
|
+
/** Checks that there is a button with this label. */
|
|
136
|
+
hasButton(label: string): Self;
|
|
137
|
+
/** Checks that there is an embed, with this title when given. */
|
|
138
|
+
hasEmbed(title?: string): Self;
|
|
139
|
+
/** Checks that there is no embed. */
|
|
140
|
+
hasNoEmbed(): Self;
|
|
141
|
+
/** Checks that there is no button and no menu. */
|
|
142
|
+
hasNoComponent(): Self;
|
|
143
|
+
}
|
|
144
|
+
/** A message in the test server. */
|
|
145
|
+
export interface TestMessage extends TestAssertions<TestMessage> {
|
|
146
|
+
readonly id: string;
|
|
147
|
+
/** The text of the message. */
|
|
148
|
+
readonly content: string;
|
|
149
|
+
/** Who wrote it; `null` for someone who is not in the world any more. */
|
|
150
|
+
readonly author: TestMember | null;
|
|
151
|
+
/** Whether the bot wrote it. */
|
|
152
|
+
readonly fromBot: boolean;
|
|
153
|
+
/** The embeds, as the bot sent them. */
|
|
154
|
+
readonly embeds: readonly Camelize<RawEmbed>[];
|
|
155
|
+
/** The buttons on it, in order. */
|
|
156
|
+
readonly buttons: readonly TestButton[];
|
|
157
|
+
/** The select menus on it, in order. */
|
|
158
|
+
readonly menus: readonly TestMenu[];
|
|
159
|
+
/** Whether only one person sees it. */
|
|
160
|
+
readonly ephemeral: boolean;
|
|
161
|
+
readonly pinned: boolean;
|
|
162
|
+
/** The channel it is in. */
|
|
163
|
+
readonly channel: TestChannel;
|
|
164
|
+
/** Whether the message was deleted since. */
|
|
165
|
+
readonly deleted: boolean;
|
|
166
|
+
/** The button with this label: to click it. Fails when there is none. */
|
|
167
|
+
button(label: string): TestButton;
|
|
168
|
+
/** The menu, or the one with this placeholder. Fails when there is none. */
|
|
169
|
+
menu(placeholder?: string): TestMenu;
|
|
170
|
+
}
|
|
171
|
+
/** What the bot answered to a command, a button, a menu or a form. */
|
|
172
|
+
export interface TestReply extends TestAssertions<TestReply> {
|
|
173
|
+
/** The message the bot answered with (or changed), or `null` without one. */
|
|
174
|
+
readonly message: TestMessage | null;
|
|
175
|
+
/** The text of the answer; `''` without a message. */
|
|
176
|
+
readonly content: string;
|
|
177
|
+
readonly embeds: readonly Camelize<RawEmbed>[];
|
|
178
|
+
readonly buttons: readonly TestButton[];
|
|
179
|
+
readonly menus: readonly TestMenu[];
|
|
180
|
+
/** The messages sent after the first answer, in order. */
|
|
181
|
+
readonly followUps: readonly TestMessage[];
|
|
182
|
+
/** The form the bot opened, or `null`. */
|
|
183
|
+
readonly form: TestForm | null;
|
|
184
|
+
/** Whether the bot said the answer was coming before answering. */
|
|
185
|
+
readonly deferred: boolean;
|
|
186
|
+
/** Whether the answer changed the message of the component. */
|
|
187
|
+
readonly updated: boolean;
|
|
188
|
+
readonly ephemeral: boolean;
|
|
189
|
+
/** Checks that the bot said the answer was coming ("thinking…"). */
|
|
190
|
+
isDeferred(): TestReply;
|
|
191
|
+
/** Checks that the bot changed the message of the button or menu. */
|
|
192
|
+
updatesMessage(): TestReply;
|
|
193
|
+
/** Checks that the bot opened a form, this one when given. */
|
|
194
|
+
opensForm(form?: ModalDeclaration<ModalFields, never> | TestForm): TestReply;
|
|
195
|
+
/** Checks that the bot answered with nothing visible (a deferred update). */
|
|
196
|
+
changesNothing(): TestReply;
|
|
197
|
+
/** The button with this label, to click it. Fails when there is none. */
|
|
198
|
+
button(label: string): TestButton;
|
|
199
|
+
/** The menu, or the one with this placeholder. Fails when there is none. */
|
|
200
|
+
menu(placeholder?: string): TestMenu;
|
|
201
|
+
}
|
|
202
|
+
/** How to make a person for a test. */
|
|
203
|
+
export interface TestMemberOptions {
|
|
204
|
+
/** The roles of the person, by name or as `bot.role()` gave them. */
|
|
205
|
+
roles?: readonly (string | TestRole)[];
|
|
206
|
+
/** Permissions given through a role of their own. */
|
|
207
|
+
permissions?: readonly PermissionName[];
|
|
208
|
+
nickname?: string;
|
|
209
|
+
/** Whether the person is a bot. */
|
|
210
|
+
bot?: boolean;
|
|
211
|
+
/** The language of the person: what `t` answers them in. Default: `'en-US'`. */
|
|
212
|
+
locale?: Locale;
|
|
213
|
+
}
|
|
214
|
+
export interface TestRoleOptions {
|
|
215
|
+
permissions?: readonly PermissionName[];
|
|
216
|
+
}
|
|
217
|
+
export interface TestChannelOptions {
|
|
218
|
+
/** Default: `'text'`. */
|
|
219
|
+
type?: TestChannelType;
|
|
220
|
+
/** The category it is in. */
|
|
221
|
+
parent?: TestChannel;
|
|
222
|
+
topic?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Who does something, and where. */
|
|
225
|
+
export interface TestWhere {
|
|
226
|
+
/** Who does it. Default: `bot.someone`. */
|
|
227
|
+
by?: TestMember;
|
|
228
|
+
/** Where: a channel, or `'dm'` for a private message with the bot. Default: `#general`. */
|
|
229
|
+
in?: TestChannel | 'dm';
|
|
230
|
+
/** For a button or a menu: the message it is on. Default: a message of the bot. */
|
|
231
|
+
on?: TestMessage | TestReply;
|
|
232
|
+
}
|
|
233
|
+
/** What a test gives for an option, by its kind. */
|
|
234
|
+
type OptionInput<Option extends CommandOption> = Option extends {
|
|
235
|
+
choices: readonly (infer Choice)[];
|
|
236
|
+
} ? Choice : Option extends {
|
|
237
|
+
choices: Readonly<Record<string, infer Choice>>;
|
|
238
|
+
} ? Choice : Option['type'] extends 'string' ? string : Option['type'] extends 'integer' | 'number' ? number : Option['type'] extends 'boolean' ? boolean : Option['type'] extends 'user' ? TestMember : Option['type'] extends 'role' ? TestRole : Option['type'] extends 'channel' ? TestChannel : Option['type'] extends 'mentionable' ? TestMember | TestRole : TestFile;
|
|
239
|
+
/** The options of a command as a test fills them in. */
|
|
240
|
+
export type OptionInputsOf<Options extends CommandOptions> = {
|
|
241
|
+
[Name in keyof Options as Options[Name] extends {
|
|
242
|
+
required: true;
|
|
243
|
+
} ? Name : never]: OptionInput<Options[Name]>;
|
|
244
|
+
} & {
|
|
245
|
+
[Name in keyof Options as Options[Name] extends {
|
|
246
|
+
required: true;
|
|
247
|
+
} ? never : Name]?: OptionInput<Options[Name]>;
|
|
248
|
+
};
|
|
249
|
+
/** What a test gives for a field of a form, by its kind. */
|
|
250
|
+
type FieldInput<Field extends ModalField> = Field extends TextField ? string : Field extends SelectField<infer Options> ? readonly OptionValue<Options>[] : Field extends EntityField ? Field['type'] extends 'user' ? readonly TestMember[] : Field['type'] extends 'role' ? readonly TestRole[] : Field['type'] extends 'channel' ? readonly TestChannel[] : readonly (TestMember | TestRole)[] : Field extends FilesField ? readonly TestFile[] : Field extends RadioField<infer Options> ? OptionValue<Options> : Field extends CheckboxesField<infer Options> ? readonly OptionValue<Options>[] : Field extends CheckboxField ? boolean : never;
|
|
251
|
+
/** The fields of a form as a test fills them in: a field left out stays empty. */
|
|
252
|
+
export type FieldInputsOf<Fields extends ModalFields> = {
|
|
253
|
+
[Name in keyof Fields as Fields[Name] extends NoteField ? never : Name]?: FieldInput<Fields[Name]>;
|
|
254
|
+
};
|
|
255
|
+
/** What a test picks in a menu: texts, or people, roles and channels. */
|
|
256
|
+
export type SelectInput = string | TestMember | TestRole | TestChannel;
|
|
257
|
+
/** A button, as a test names it: the declaration, an instance, or one found on a message. */
|
|
258
|
+
export type ButtonTarget = ButtonDeclaration<never> | ButtonComponent | TestButton;
|
|
259
|
+
export type SelectTarget = SelectDeclaration<never> | SelectComponent | TestMenu;
|
|
260
|
+
export type FormTarget<Fields extends ModalFields = ModalFields> = ModalDeclaration<Fields, never> | ModalComponent | TestForm;
|
|
261
|
+
/** The arguments of `bot.use()`: the options may be left out when none is required. */
|
|
262
|
+
type UseArgs<Options extends CommandOptions> = {} extends OptionInputsOf<Options> ? [options?: OptionInputsOf<Options>, where?: TestWhere] : [options: OptionInputsOf<Options>, where?: TestWhere];
|
|
263
|
+
/**
|
|
264
|
+
* The bot of the project, running in a Discord in memory: one server, a few
|
|
265
|
+
* people, and everything the bot does kept where the test can read it.
|
|
266
|
+
*/
|
|
267
|
+
export interface TestBot {
|
|
268
|
+
/** The test server. */
|
|
269
|
+
readonly guild: {
|
|
270
|
+
readonly id: string;
|
|
271
|
+
readonly name: string;
|
|
272
|
+
};
|
|
273
|
+
/** The bot itself, as a member of the server. */
|
|
274
|
+
readonly me: TestMember;
|
|
275
|
+
/** The owner of the server. */
|
|
276
|
+
readonly owner: TestMember;
|
|
277
|
+
/** A person with no special rights: who does things when nobody is named. */
|
|
278
|
+
readonly someone: TestMember;
|
|
279
|
+
/** Every request the bot sent to Discord so far. */
|
|
280
|
+
readonly requests: readonly {
|
|
281
|
+
method: string;
|
|
282
|
+
path: string;
|
|
283
|
+
body: unknown;
|
|
284
|
+
}[];
|
|
285
|
+
/**
|
|
286
|
+
* A person of the server, made the first time the name is given. The
|
|
287
|
+
* options only count the first time.
|
|
288
|
+
*/
|
|
289
|
+
member(name: string, options?: TestMemberOptions): TestMember;
|
|
290
|
+
/** A role of the server, made the first time the name is given. */
|
|
291
|
+
role(name: string, options?: TestRoleOptions): TestRole;
|
|
292
|
+
/** A channel of the server, made the first time the name is given. `#general` exists. */
|
|
293
|
+
channel(name: string, options?: TestChannelOptions): TestChannel;
|
|
294
|
+
/** Uses a slash command, as a person would. Resolves once the bot answered. */
|
|
295
|
+
use<Options extends CommandOptions, Where extends CommandWhere>(command: CommandDeclaration<Options, Where>, ...args: UseArgs<Options>): Promise<TestReply>;
|
|
296
|
+
/** Clicks a button. Resolves once the bot answered. */
|
|
297
|
+
click(button: ButtonTarget, where?: TestWhere): Promise<TestReply>;
|
|
298
|
+
/** Picks values in a select menu. Resolves once the bot answered. */
|
|
299
|
+
select(menu: SelectTarget, values: readonly SelectInput[], where?: TestWhere): Promise<TestReply>;
|
|
300
|
+
/** Fills in and sends a form. Resolves once the bot answered. */
|
|
301
|
+
submit<Fields extends ModalFields>(form: FormTarget<Fields>, fields?: FieldInputsOf<Fields>, where?: TestWhere): Promise<TestReply>;
|
|
302
|
+
/** Types in an option with suggestions, and gets what the bot suggests. */
|
|
303
|
+
suggest<Options extends CommandOptions, Where extends CommandWhere>(command: CommandDeclaration<Options, Where>, option: keyof Options & string, typed: string, where?: TestWhere): Promise<TestSuggestion[]>;
|
|
304
|
+
/** Sends a message as a person. Resolves once the bot handled it. */
|
|
305
|
+
say(content: string, where?: TestWhere): Promise<TestMessage>;
|
|
306
|
+
/** Reacts to a message as a person. Resolves once the bot handled it. */
|
|
307
|
+
react(message: TestMessage, emoji: string, where?: Pick<TestWhere, 'by'>): Promise<void>;
|
|
308
|
+
/** Makes a person join the server. Resolves once the bot handled it. */
|
|
309
|
+
join(member: string | TestMember, options?: TestMemberOptions): Promise<TestMember>;
|
|
310
|
+
/** Makes a person leave the server. Resolves once the bot handled it. */
|
|
311
|
+
leave(member: TestMember): Promise<void>;
|
|
312
|
+
/** Runs a task now, as if its time had come. Resolves once it is done. */
|
|
313
|
+
run(task: TaskDeclaration, at?: Date): Promise<void>;
|
|
314
|
+
/** Waits for everything the bot started to be done. */
|
|
315
|
+
settle(): Promise<void>;
|
|
316
|
+
}
|
|
317
|
+
/** What the test runner reads of what the bot said to the developer. */
|
|
318
|
+
export interface Captured {
|
|
319
|
+
errors: string[];
|
|
320
|
+
warnings: string[];
|
|
321
|
+
infos: string[];
|
|
322
|
+
}
|
|
323
|
+
/** A `Log` that keeps what is written, for the runner to show per check. */
|
|
324
|
+
export declare function captureLog(): {
|
|
325
|
+
log: Log;
|
|
326
|
+
take(): Captured;
|
|
327
|
+
};
|
|
328
|
+
/** Watches what the bot does with the files, to wait for it. */
|
|
329
|
+
export declare class Observer {
|
|
330
|
+
#private;
|
|
331
|
+
readonly observe: ProjectObserver;
|
|
332
|
+
/** Forgets the interactions seen so far: a new world starts. */
|
|
333
|
+
reset(): void;
|
|
334
|
+
/** Resolves once the files are done with the interaction `id`. */
|
|
335
|
+
interaction(id: string, timeout: number): Promise<void>;
|
|
336
|
+
/** Resolves once the files are done with the next event that matches. */
|
|
337
|
+
event(match: (event: string, data: unknown) => boolean, timeout: number): Promise<void>;
|
|
338
|
+
/** Resolves once nothing the files started is still running. */
|
|
339
|
+
settle(): Promise<void>;
|
|
340
|
+
}
|
|
341
|
+
/** The bot in its world, with the handles a test works with. */
|
|
342
|
+
export declare class Session implements TestBot {
|
|
343
|
+
#private;
|
|
344
|
+
readonly world: World;
|
|
345
|
+
readonly project: Project;
|
|
346
|
+
readonly bot: Bot;
|
|
347
|
+
constructor(world: World, project: Project, bot: Bot, observer: Observer, options?: {
|
|
348
|
+
timeout?: number;
|
|
349
|
+
});
|
|
350
|
+
get guild(): {
|
|
351
|
+
id: string;
|
|
352
|
+
name: string;
|
|
353
|
+
};
|
|
354
|
+
get me(): TestMember;
|
|
355
|
+
get owner(): TestMember;
|
|
356
|
+
get someone(): TestMember;
|
|
357
|
+
get requests(): {
|
|
358
|
+
method: string;
|
|
359
|
+
path: string;
|
|
360
|
+
body: unknown;
|
|
361
|
+
}[];
|
|
362
|
+
member(name: string, options?: TestMemberOptions): TestMember;
|
|
363
|
+
role(name: string, options?: TestRoleOptions): TestRole;
|
|
364
|
+
channel(name: string, options?: TestChannelOptions): TestChannel;
|
|
365
|
+
use<Options extends CommandOptions, Where extends CommandWhere>(command: CommandDeclaration<Options, Where>, ...args: UseArgs<Options>): Promise<TestReply>;
|
|
366
|
+
suggest<Options extends CommandOptions, Where extends CommandWhere>(command: CommandDeclaration<Options, Where>, option: keyof Options & string, typed: string, where?: TestWhere): Promise<TestSuggestion[]>;
|
|
367
|
+
click(button: ButtonTarget, where?: TestWhere): Promise<TestReply>;
|
|
368
|
+
select(menu: SelectTarget, values: readonly SelectInput[], where?: TestWhere): Promise<TestReply>;
|
|
369
|
+
submit<Fields extends ModalFields>(form: FormTarget<Fields>, fields?: FieldInputsOf<Fields>, where?: TestWhere): Promise<TestReply>;
|
|
370
|
+
say(content: string, where?: TestWhere): Promise<TestMessage>;
|
|
371
|
+
react(message: TestMessage, emoji: string, where?: Pick<TestWhere, 'by'>): Promise<void>;
|
|
372
|
+
join(member: string | TestMember, options?: TestMemberOptions): Promise<TestMember>;
|
|
373
|
+
leave(member: TestMember): Promise<void>;
|
|
374
|
+
run(task: TaskDeclaration, at?: Date): Promise<void>;
|
|
375
|
+
settle(): Promise<void>;
|
|
376
|
+
/**
|
|
377
|
+
* Sends a gateway event to the bot and waits for the files to be done
|
|
378
|
+
* with it. For the checks of `chapterjs test`, not for scenarios.
|
|
379
|
+
*/
|
|
380
|
+
emit(type: string, data: unknown): Promise<void>;
|
|
381
|
+
/**
|
|
382
|
+
* Runs `act`, which makes the world send the event `type`, and waits for
|
|
383
|
+
* the files to be done with it.
|
|
384
|
+
*/
|
|
385
|
+
expectEvent(type: string, act: () => void): Promise<void>;
|
|
386
|
+
}
|
|
387
|
+
export {};
|