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

Commit

Permalink
feat(command): add new table command to roll on a magic item table
Browse files Browse the repository at this point in the history
  • Loading branch information
mloberg committed Dec 21, 2020
1 parent 41ff5fe commit 9d53022
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"scripts": {
"test": "BOT_TOKEN=test jest --detectOpenHandles --coverage --verbose",
"test:watch": "npm run test -- --watch",
"watch:test": "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 Down
4 changes: 2 additions & 2 deletions src/commands/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports[`_help returns a list of all commands 1`] = `
Array [
Array [
"Here is a list of available commands:",
"help, 3.5, elixir, event, item, madness, ping, prune, spell, treasure, wild",
"help, 3.5, elixir, event, item, madness, ping, prune, spell, table, treasure, wild",
"Get more details with \\"_help [command]\\"",
],
Object {
Expand All @@ -23,7 +23,7 @@ exports[`_help returns a list of all commands 1`] = `
Array [
Array [
"Here is a list of available commands:",
"help, 3.5, elixir, event, item, madness, ping, prune, spell, treasure, wild",
"help, 3.5, elixir, event, item, madness, ping, prune, spell, table, treasure, wild",
"Get more details with \\"_help [command]\\"",
],
Object {
Expand Down
2 changes: 2 additions & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import madness from './madness';
import ping from './ping';
import prune from './prune';
import spell from './spell';
import table from './table';
import treasure from './treasure';
import wildMagic from './wildMagic';

Expand Down Expand Up @@ -83,6 +84,7 @@ commands.register(madness);
commands.register(ping);
commands.register(prune);
commands.register(spell);
commands.register(table);
commands.register(treasure);
commands.register(wildMagic);

Expand Down
85 changes: 85 additions & 0 deletions src/commands/table.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Client, Guild, Message, TextChannel } from 'discord.js';

import { FriendlyError } from '../error';
import command from './table';

const mocks = {
delete: jest.fn(),
reply: jest.fn(),
};

jest.mock('discord.js', () => ({
Client: jest.fn(),
Guild: jest.fn(),
TextChannel: jest.fn(),
Collection: jest.fn(),
Message: jest.fn().mockImplementation(() => ({
delete: mocks.delete,
reply: mocks.reply,
})),
}));
jest.mock('../data/table', () => ({
a: new Array(100).fill('foo'),
b: [...new Array(98).fill('bar'), 'test', 'foobar'],
c: new Array(100).fill(() => 'baz'),
}));

describe('_table configuration', () => {
it('should have basic command infomation', () => {
expect(command.name).toEqual('table');
expect(command.description).toEqual('Roll on the magic item tables');
expect(command.usage).toEqual('TABLE [ROLL]');
});

it('should not have an alias', () => {
expect(command.alias).toBeUndefined();
});
});

describe('_table', () => {
let message: Message;

beforeEach(() => {
mocks.delete.mockClear();
mocks.reply.mockClear();

const client = new Client();
const guild = new Guild(client, {});
const channel = new TextChannel(guild, {});
message = new Message(client, {}, channel);
});

it('returns a value from the given table', async () => {
await command.run(message, { $0: 'table', _: ['a'] });

expect(mocks.delete).toBeCalledTimes(1);
expect(mocks.reply).toBeCalledTimes(1);
expect(mocks.reply).toHaveBeenCalledWith('foo');
});

it('returns a value for a dice roll', async () => {
await command.run(message, { $0: 'table', _: ['b', '99'] });

expect(mocks.delete).toBeCalledTimes(1);
expect(mocks.reply).toBeCalledTimes(1);
expect(mocks.reply).toHaveBeenCalledWith('test');
});

it('returns a resolved value', async () => {
await command.run(message, { $0: 'table', _: ['C'] });

expect(mocks.delete).toBeCalledTimes(1);
expect(mocks.reply).toBeCalledTimes(1);
expect(mocks.reply).toHaveBeenCalledWith('baz');
});

it('throws an error if invalid table given', async () => {
try {
await command.run(message, { $0: 'table', _: [] });
fail('expected error to be thrown');
} catch (err) {
expect(err instanceof FriendlyError).toBe(true);
expect(err.message).toEqual('Unknown table "-".');
}
});
});
31 changes: 31 additions & 0 deletions src/commands/table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Message } from 'discord.js';
import { isString } from 'lodash';
import { Arguments } from 'yargs';

import magicItemTable from '../data/table';
import { FriendlyError } from '../error';
import { Command } from '../types';
import { roll } from '../utils';

const command: Command = {
name: 'table',
description: 'Roll on the magic item tables',
usage: 'TABLE [ROLL]',
async run(message: Message, args: Arguments) {
const index = (args._[0] || '-').toLowerCase();
const dice = Number(args._[1] || roll('d100'));

const table = magicItemTable[index];
if (!table) {
throw new FriendlyError(`Unknown table "${index}".`);
}

const item = table[dice - 1];

await message.delete();

return message.reply(isString(item) ? item : await item());
},
};

export default command;
4 changes: 2 additions & 2 deletions src/commands/treasure.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Message } from 'discord.js';
import { sample } from 'lodash';
import { isString, sample } from 'lodash';
import { Arguments } from 'yargs';

import { crIndex, hoard, individual } from '../data/treasure';
Expand Down Expand Up @@ -37,7 +37,7 @@ const command: Command = {

for (let index = 0; index < roll(key); index++) {
const item = sample(value) ?? '';
const resolved = typeof item === 'string' ? item : await item();
const resolved = isString(item) ? item : await item();
reply.push(`* ${type}: ${resolved}`);
}
}
Expand Down

0 comments on commit 9d53022

Please sign in to comment.