Skip to content
This repository has been archived by the owner on Feb 9, 2023. It is now read-only.

Commit

Permalink
refactor: use less custom code
Browse files Browse the repository at this point in the history
Remove most util functions in favor of lodash. Replace custom Argument type with yargs Argument
type.

Allow @ mention as prefix.

Improve logging and config handling
  • Loading branch information
mloberg committed Nov 7, 2020
1 parent a67d4f4 commit f9ff308
Show file tree
Hide file tree
Showing 32 changed files with 1,578 additions and 3,105 deletions.
3,905 changes: 1,153 additions & 2,752 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 17 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"node": ">=12"
},
"scripts": {
"test": "jest --detectOpenHandles --coverage --verbose",
"test:watch": "jest --verbose --watch",
"test": "BOT_TOKEN=test jest --detectOpenHandles --coverage --verbose",
"test:watch": "npm run test -- --watch",
"build": "tsc",
"start": "node -r dotenv/config dist/index.js",
"watch": "concurrently -k -p \"[{name}]\" -n \"TypeScript,Node\" -c \"cyan.bold,green.bold\" \"npm run watch:ts\" \"npm run watch:node\"",
Expand All @@ -18,27 +18,33 @@
"fix": "npm run lint -- --fix"
},
"dependencies": {
"discord.js": "^12.3.1",
"discord.js": "^12.4.1",
"dotenv": "^8.2.0",
"joi": "^17.3.0",
"lodash": "^4.17.20",
"node-fetch": "^2.6.1",
"yargs": "^16.0.3"
"pino": "^6.7.0",
"yargs": "^16.1.0"
},
"devDependencies": {
"@tsconfig/node12": "^1.0.7",
"@types/jest": "^26.0.14",
"@types/jest": "^26.0.15",
"@types/lodash": "^4.14.165",
"@types/node": "^14.14.6",
"@types/node-fetch": "^2.5.7",
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@types/pino": "^6.3.3",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"concurrently": "^5.3.0",
"eslint": "^7.10.0",
"eslint-config-prettier": "^6.12.0",
"eslint": "^7.13.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-simple-import-sort": "^5.0.3",
"jest": "^26.6.1",
"nodemon": "^2.0.4",
"jest": "^26.6.3",
"nodemon": "^2.0.6",
"pino-pretty": "^4.3.0",
"prettier": "^2.1.2",
"ts-jest": "^26.4.3",
"typescript": "^4.0.3"
"typescript": "^4.0.5"
}
}
28 changes: 13 additions & 15 deletions src/commands/35.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ const mocks = {
reply: jest.fn(),
};

jest.mock('discord.js', () => {
return {
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
reply: mocks.reply,
};
}),
};
});
jest.mock('discord.js', () => ({
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
reply: mocks.reply,
};
}),
}));

describe('_3.5 configuration', () => {
it('should have basic command infomation', () => {
Expand Down Expand Up @@ -51,7 +49,7 @@ describe('_3.5', () => {
[['Use', 'Magic', 'Device'], 'INT (Arcana)'],
[['Ride'], 'WIS (Animal Handling) or DEX (Acrobatics)'],
])('returns a comprable 5e skill for %s', async (search, result) => {
await command.run(message, { _: search });
await command.run(message, { $0: '3.5', _: search });

expect(mocks.reply).toHaveBeenCalledTimes(1);
expect(mocks.reply).toHaveBeenCalledWith(result);
Expand All @@ -63,7 +61,7 @@ describe('_3.5', () => {

it('throws an error on invalid skill', async () => {
try {
await command.run(message, { _: ['foo'] });
await command.run(message, { $0: '3.5', _: ['foo'] });

fail('expected error to be thrown');
} catch (err) {
Expand Down
3 changes: 2 additions & 1 deletion src/commands/35.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Message } from 'discord.js';
import { Arguments } from 'yargs';

import { FriendlyError } from '../error';
import { Arguments, Command, Dictionary } from '../types';
import { Command, Dictionary } from '../types';

export const conversion: Dictionary<string> = {
appraise: 'INT',
Expand Down
32 changes: 15 additions & 17 deletions src/commands/elixir.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ const mocks = {
reply: jest.fn(),
};

jest.mock('discord.js', () => {
return {
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
delete: mocks.delete,
reply: mocks.reply,
};
}),
};
});
jest.mock('discord.js', () => ({
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
delete: mocks.delete,
reply: mocks.reply,
};
}),
}));

describe('_elixir configuration', () => {
it('should have basic command infomation', () => {
Expand Down Expand Up @@ -48,7 +46,7 @@ describe('_elixir', () => {
});

it('returns an elixir', async () => {
const reply = await command.run(message, { _: [] });
const reply = await command.run(message, { $0: 'elixir', _: [] });

expect(mocks.delete).toHaveBeenCalledTimes(1);
expect(reply).toBe(message);
Expand All @@ -58,8 +56,8 @@ describe('_elixir', () => {
});

it('returns an elixir for a dice roll', async () => {
const one = await command.run(message, { _: [1] });
const two = await command.run(message, { _: [], roll: 4 });
const one = await command.run(message, { $0: 'elixir', _: ['1'] });
const two = await command.run(message, { $0: 'elixir', _: [], roll: 4 });

expect(mocks.delete).toHaveBeenCalledTimes(2);
expect(one).toBe(message);
Expand Down
5 changes: 3 additions & 2 deletions src/commands/elixir.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Message } from 'discord.js';
import { Arguments } from 'yargs';

import { Arguments, Command } from '../types';
import { Command } from '../types';
import { roll } from '../utils';

export const elixirs = [
Expand All @@ -17,7 +18,7 @@ const command: Command = {
alias: ['elx'],
description: 'Craft an experimental elixir',
async run(message: Message, args: Arguments): Promise<Message> {
const dice = args.roll || args._[0] || roll('d6');
const dice = Number(args.roll || args._[0] || roll('d6'));
const result = elixirs[dice - 1];

await message.delete();
Expand Down
32 changes: 15 additions & 17 deletions src/commands/event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,20 @@ const mocks = {
send: jest.fn(),
};

jest.mock('discord.js', () => {
return {
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
delete: mocks.delete,
channel: {
send: mocks.send,
},
};
}),
};
});
jest.mock('discord.js', () => ({
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
delete: mocks.delete,
channel: {
send: mocks.send,
},
};
}),
}));

describe('_event configuration', () => {
it('should have basic command infomation', () => {
Expand Down Expand Up @@ -50,7 +48,7 @@ describe('_event', () => {
});

it('returns a random event', async () => {
const reply = await command.run(message, { _: [] });
const reply = await command.run(message, { $0: 'event', _: [] });

expect(mocks.delete).toHaveBeenCalledTimes(1);
expect(reply).toBe(message.channel);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/event.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Message } from 'discord.js';
import { sample } from 'lodash';

import { Command } from '../types';
import { random } from '../utils';

export const events = [
'A door opens',
Expand Down Expand Up @@ -32,7 +32,7 @@ const command: Command = {
async run(message: Message): Promise<Message> {
await message.delete();

return message.channel.send(random(events));
return message.channel.send(sample(events) ?? 'Something happens');
},
};

Expand Down
32 changes: 15 additions & 17 deletions src/commands/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ const mocks = {
send: jest.fn(),
};

jest.mock('discord.js', () => {
return {
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
channel: {
send: mocks.send,
},
};
}),
};
});
jest.mock('discord.js', () => ({
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Message: jest.fn().mockImplementation(() => {
return {
channel: {
send: mocks.send,
},
};
}),
}));

describe('_help configuration', () => {
it('should have basic command infomation', () => {
Expand Down Expand Up @@ -48,22 +46,22 @@ describe('_help', () => {
});

it('returns a list of all commands', async () => {
const reply = await help.run(message, { _: [] });
const reply = await help.run(message, { $0: 'help', _: [] });

expect(reply).toEqual(message.channel);
expect(mocks.send).toMatchSnapshot();
});

it.each(['help', 'treasure', 'event'])('returns the details for the %s command', async (cmd) => {
const reply = await help.run(message, { _: [cmd] });
const reply = await help.run(message, { $0: 'help', _: [cmd] });

expect(reply).toEqual(message.channel);
expect(mocks.send).toMatchSnapshot();
});

it('returns an error if an invalid command is given', async () => {
try {
await help.run(message, { _: ['invalid'] });
await help.run(message, { $0: 'help', _: ['invalid'] });

fail('expected error to be thrown');
} catch (err) {
Expand Down
17 changes: 9 additions & 8 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Message } from 'discord.js';
import { Arguments } from 'yargs';

import config from '../config';
import { FriendlyError } from '../error';
import { Arguments, Command } from '../types';
import { env } from '../utils';
import { Command } from '../types';
import conversion from './35';
import elixir from './elixir';
import event from './event';
Expand All @@ -14,8 +15,6 @@ import spell from './spell';
import treasure from './treasure';
import wildMagic from './wildMagic';

const prefix = env('BOT_PREFIX', '_');

export class Commands {
private commands: Command[] = [];

Expand All @@ -37,13 +36,13 @@ export const help: Command = {
description: 'Get help with commands',
alias: ['commands'],
usage: '[COMMAND]',
async run(message: Message, args: Arguments): Promise<Message> {
async run(message: Message, args: Arguments): Promise<Message | Message[]> {
if (!args._.length) {
return message.channel.send(
[
'Here is a list of available commands:',
commands.list().join(', '),
`Get more details with "${prefix}help [command]"`,
`Get more details with "${config.prefix}help [command]"`,
],
{ split: true },
);
Expand All @@ -61,10 +60,12 @@ export const help: Command = {
help.push(`*aliases*: ${command.alias.join(', ')}`);
}
if (command.usage) {
help.push(`*usage*: \`${prefix}${command.name} ${command.usage}\``);
help.push(`*usage*: \`${config.prefix}${command.name} ${command.usage}\``);
}
if (command.examples) {
help.push(`*examples*: ${command.examples.map((e) => `\`${prefix}${command.name} ${e}\``).join(', ')}`);
help.push(
`*examples*: ${command.examples.map((e) => `\`${config.prefix}${command.name} ${e}\``).join(', ')}`,
);
}

return message.channel.send(help, { split: true });
Expand Down
Loading

0 comments on commit f9ff308

Please sign in to comment.