generator-discord 1.3.2 → 1.3.4

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.
@@ -6,5 +6,5 @@ edition = "2021"
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
7
 
8
8
  [dependencies]
9
- serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] }
9
+ serenity = { version = "0.11.7", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] }
10
10
  tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
@@ -10,7 +10,7 @@
10
10
  "build": "tsc"
11
11
  },
12
12
  "dependencies": {
13
- "discord.js": "^14.13.0",
13
+ "discord.js": "^14.14.1",
14
14
  "typescript": "^5.2.2"
15
15
  }
16
16
  }
@@ -0,0 +1,147 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { createHelpers } from 'yeoman-test';
3
+ import { spawn, exec } from 'child_process';
4
+ import * as dotenv from 'dotenv';
5
+ import path from 'path';
6
+ import url from 'url';
7
+
8
+ const __dirname = url.fileURLToPath(new URL('../', import.meta.url));
9
+ const DEFAULT_TIMEOUT = 60_000; // 1 minute
10
+
11
+ dotenv.config();
12
+
13
+ const { BOT_TOKEN } = process.env;
14
+ if (!BOT_TOKEN) {
15
+ throw new Error('You must specify a valid bot token in the BOT_TOKEN environment variable');
16
+ }
17
+
18
+ const defaultAnswers = {
19
+ botName: 'test-run-bot',
20
+ botType: 'typescript',
21
+ botToken: BOT_TOKEN,
22
+ openWithCode: false,
23
+ };
24
+
25
+ describe('Check if the templates work', () => {
26
+ const targetRoot = path.join(__dirname, 'test-temp');
27
+ const moduleRoot = path.join(__dirname, 'app');
28
+ const resultRoot = path.join(targetRoot, defaultAnswers.botName);
29
+
30
+ test('Should generate and run TypeScript Discord Bot', async () => {
31
+ const context = createHelpers({}).run(moduleRoot);
32
+
33
+ context.targetDirectory = targetRoot;
34
+ context.cleanTestDirectory(true);
35
+ await context
36
+ .onGenerator(generator => {
37
+ generator.destinationRoot(targetRoot);
38
+ })
39
+ .withAnswers(defaultAnswers)
40
+ .then(async () => {
41
+ const result = await runBot('node', ['./dist/src/index.js'], resultRoot, DEFAULT_TIMEOUT);
42
+ expect(result).toContain(BOT_OUTPUT_START);
43
+ });
44
+
45
+ context.cleanup();
46
+ }, 120_000);
47
+
48
+ test.skip('Should generate and run Python Discord Bot', async () => {
49
+ const context = createHelpers({}).run(moduleRoot);
50
+
51
+ context.targetDirectory = targetRoot;
52
+ context.cleanTestDirectory(true);
53
+ await context
54
+ .onGenerator(generator => {
55
+ generator.destinationRoot(targetRoot);
56
+ })
57
+ .withAnswers({ ...defaultAnswers, botType: 'python' })
58
+ .then(async () => {
59
+ // install dependencies
60
+ await exec('pip3 install -r requirements.txt', { cwd: resultRoot });
61
+
62
+ const result = await runBot('python', ['./main.py'], resultRoot, DEFAULT_TIMEOUT);
63
+ expect(result).toContain(BOT_OUTPUT_START);
64
+ });
65
+
66
+ context.cleanup();
67
+ }, 120_000);
68
+
69
+ test('Should generate and run JavaScript Discord Bot', async () => {
70
+ const context = createHelpers({}).run(moduleRoot);
71
+
72
+ context.targetDirectory = targetRoot;
73
+ context.cleanTestDirectory(true);
74
+ await context
75
+ .onGenerator(generator => {
76
+ generator.destinationRoot(targetRoot);
77
+ })
78
+ .withAnswers({ ...defaultAnswers, botType: 'javascript' })
79
+ .then(async () => {
80
+ const result = await runBot('node', ['./src/index.js'], resultRoot, DEFAULT_TIMEOUT);
81
+ expect(result).toContain(BOT_OUTPUT_START);
82
+ });
83
+
84
+ context.cleanup();
85
+ }, 120_000);
86
+
87
+ test('Should generate and run Rust Discord Bot', async () => {
88
+ const context = createHelpers({}).run(moduleRoot);
89
+
90
+ context.targetDirectory = targetRoot;
91
+ context.cleanTestDirectory(true);
92
+ await context
93
+ .onGenerator(generator => {
94
+ generator.destinationRoot(targetRoot);
95
+ })
96
+ .withAnswers({ ...defaultAnswers, botType: 'rust' })
97
+ .withArguments(['skip-build'])
98
+ .then(async () => {
99
+ const result = await runBot('cargo', ['run', '--release', '--quiet'] , resultRoot, 120_000); // 2 minutes
100
+ expect(result).toContain(BOT_OUTPUT_START);
101
+ });
102
+
103
+ context.cleanup();
104
+ }, 180_000); // 3 minutes
105
+ });
106
+
107
+ /** Run a command in a child process and return the output
108
+ * @param {string} command The command to run
109
+ * @param {string[]} args The arguments to pass to the command
110
+ * @param {string} root The root directory to run the command in
111
+ * @param {number} timeoutTime The time in milliseconds to wait before timing out
112
+ * @returns {Promise<string>} The output of the command
113
+ */
114
+ async function runBot(command: string, args: string[], root: string, timeoutTime: number): Promise<string> {
115
+ const childProcess = spawn(command, args, { cwd: root, timeout: timeoutTime });
116
+
117
+ const result = await new Promise<string>((resolve) => {
118
+ // timeout
119
+ const safetyTimeout = setTimeout(() => {
120
+ resolve('TIMEOUT');
121
+ }, timeoutTime);
122
+
123
+ // output
124
+ childProcess.stdout.on('data', (data) => {
125
+ clearTimeout(safetyTimeout);
126
+
127
+ resolve(data.toString());
128
+ });
129
+
130
+ childProcess.stderr.on('data', (data) => {
131
+ clearTimeout(safetyTimeout);
132
+
133
+ resolve(data.toString());
134
+ });
135
+
136
+ childProcess.on('close', () => {
137
+ clearTimeout(safetyTimeout);
138
+ });
139
+
140
+ });
141
+
142
+ childProcess.kill('SIGINT');
143
+ return result;
144
+ }
145
+
146
+
147
+ const BOT_OUTPUT_START = 'Bot is logged in as';
@@ -1,127 +0,0 @@
1
- import { describe, test } from 'vitest';
2
- import { createHelpers } from 'yeoman-test';
3
- import path from 'path';
4
- import url from 'url';
5
-
6
- const __dirname = url.fileURLToPath(new URL('../', import.meta.url));
7
-
8
-
9
- const defaultAnswers = {
10
- botName: 'test-bot',
11
- botType: 'typescript',
12
- botToken: 'xxx',
13
- openWithCode: false,
14
- };
15
-
16
- describe('Check yeoman generator works', () => {
17
- const targetRoot = path.join(__dirname, 'test-temp');
18
- const moduleRoot = path.join(__dirname, 'app');
19
- const resultRoot = path.join(targetRoot, defaultAnswers.botName);
20
-
21
- test('Should produce TypeScript files', async () => {
22
- const context = createHelpers({}).run(moduleRoot);
23
- const configJson = path.join(resultRoot, 'config.json');
24
-
25
- context.targetDirectory = targetRoot;
26
- context.cleanTestDirectory(true);
27
- await context
28
- .onGenerator(generator => {
29
- generator.destinationRoot(targetRoot);
30
- })
31
- .withAnswers(defaultAnswers)
32
- .withArguments(['skip-install', 'skip-build'])
33
- .then((result) => {
34
- const files = [
35
- configJson,
36
- resultRoot + '/src/index.ts',
37
- resultRoot + '/tsconfig.json',
38
- resultRoot + '/package.json',
39
- ];
40
- result.assertFile(files);
41
- result.assertJsonFileContent(configJson, CONFIG_JSON_EXPECTED);
42
- });
43
- // context.cleanup();
44
- }, 120_000);
45
-
46
- test('Should produce Python files', async () => {
47
- const context = createHelpers({}).run(moduleRoot);
48
- const mainPy = path.join(resultRoot, 'main.py');
49
-
50
- context.targetDirectory = targetRoot;
51
- context.cleanTestDirectory(true);
52
- await context
53
- .onGenerator(generator => {
54
- generator.destinationRoot(targetRoot);
55
- })
56
- .withAnswers({ ...defaultAnswers, botType: 'python' })
57
- .then((result) => {
58
- const files = [
59
- mainPy,
60
- resultRoot + '/requirements.txt',
61
- ];
62
- result.assertFile(files);
63
- // result.assertFileContent(mainPy, PYTHON_BOT_EXPECTED);
64
- });
65
- context.cleanup();
66
- }, 120_000);
67
-
68
- test('Should produce Rust files', async () => {
69
- const context = createHelpers({}).run(moduleRoot);
70
- const cargoToml = path.join(resultRoot, 'Cargo.toml');
71
-
72
- context.targetDirectory = targetRoot;
73
- context.cleanTestDirectory(true);
74
- await context
75
- .onGenerator(generator => {
76
- generator.destinationRoot(targetRoot);
77
- })
78
- .withAnswers({ ...defaultAnswers, botType: 'rust' })
79
- .then((result) => {
80
- const files = [
81
- resultRoot + '/src/main.rs',
82
- cargoToml
83
- ];
84
- result.assertFile(files);
85
- result.assertFileContent(cargoToml, CARGO_TOML_EXPECTED);
86
- });
87
- context.cleanup();
88
- }, 120_000);
89
- });
90
-
91
- const CONFIG_JSON_EXPECTED: Record<string, string> = {
92
- 'token': 'xxx'
93
- };
94
-
95
- const PYTHON_BOT_EXPECTED = `import discord
96
-
97
- intents = discord.Intents.default()
98
- intents.message_content = True
99
-
100
- client = discord.Client(intents=intents)
101
-
102
- @client.event
103
- async def on_ready():
104
- print(f'Bot is logged in as {client.user}')
105
-
106
- @client.event
107
- async def on_message(message):
108
- if message.author == client.user:
109
- return
110
-
111
- if message.content.startswith('!ping'):
112
- await message.channel.send('Pong!')
113
-
114
- client.run('${defaultAnswers.botToken}')
115
- `;
116
-
117
- const CARGO_TOML_EXPECTED = `[package]
118
- name = "${defaultAnswers.botName}"
119
- version = "0.1.0"
120
- edition = "2021"
121
-
122
- # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
123
-
124
- [dependencies]
125
- serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] }
126
- tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
127
- `;