Skip to content

Commit

Permalink
Merge pull request #113 from osu-cascades/rc-v2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ctsstc authored Apr 25, 2020
2 parents 51d377f + d4686d7 commit 92a6d58
Show file tree
Hide file tree
Showing 14 changed files with 2,289 additions and 2,014 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
node
v13.7
12 changes: 12 additions & 0 deletions __tests__/commands/__snapshots__/help.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Help Command Execute DMs commands with prefix and descriptions it still looks the same 1`] = `
"I am here to help! Well...mostly just make you chuckle at this point, let's be honest.
Here is a list of the commands that we've got right now:
\`\`\`
!one → I am number one.
!two → Two is not just a number.
!blueFish → Not a red fish.
\`\`\`"
`;
110 changes: 110 additions & 0 deletions __tests__/commands/help.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import Help from '../../src/commands/help';
import Commands from '../../src/library/commands';
import { message as mockMessage, MockedMessage } from '../mocks/discord';

// TODO: These should be in a factory/mock
const oneCommand = {
name: 'one',
description: 'I am number one.',
execute: jest.fn()
};

const twoCommand = {
name: 'two',
description: 'Two is not just a number.',
execute: jest.fn()
};

const blueFishCommand = {
name: 'blueFish',
description: 'Not a red fish.',
execute: jest.fn()
};

const commands = new Commands({
one: oneCommand,
two: twoCommand,
blueFish: blueFishCommand
});

let sendMock: MockedMessage;
let authorSend: MockedMessage;
beforeEach(() => {
sendMock = jest.fn();
mockMessage.reply = sendMock;
authorSend = jest.fn();
// @ts-ignore
mockMessage.author = {
send: authorSend
};
});

describe('Help Command', () => {
describe('Execute', () => {
beforeEach(() => {
Help.execute([], mockMessage, { commands });
});

test('Lets you know to check your DMs', () => {
expect(sendMock).lastCalledWith('sliding into your DMs...');
});

describe('DMs commands with prefix and descriptions', () => {
let message: string;
beforeEach(() => {
message = authorSend.mock.calls[0][0];
});

test('Snarky', () => {
const snark = "I am here to help! Well...mostly just make you chuckle " +
"at this point, let's be honest.";
expect(message).toContain(snark);
});

test('Command pretext header', () => {
const pretext = "Here is a list of the commands that we've got right now:";
expect(message).toContain(pretext);
});

test('Code block start', () => {
expect(message).toContain('```\n');
});

test('Code block end', () => {
const lines = message.split('\n');
const lastLine = lines[lines.length - 1];
expect(lastLine).toEqual('```');
});

test('it still looks the same', () => {
expect(message).toMatchSnapshot();
});

describe('Commands', () => {
test('one command', () => {
expect(message).toContain('!one');
});

test('one description', () => {
expect(message).toContain(oneCommand.description);
});

test('two command', () => {
expect(message).toContain('!two');
});

test('two description', () => {
expect(message).toContain(twoCommand.description);
});

test('blueFish command', () => {
expect(message).toContain('!blueFish');
});

test('BlueFish description', () => {
expect(message).toContain(blueFishCommand.description);
});
});
});
});
});
24 changes: 19 additions & 5 deletions __tests__/commands/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,24 @@ describe('Search Command', () => {
await Search.execute(['dingusy'], mockMessage);
expect(sendMock).lastCalledWith(results.items[0].link);
});
test('Malformed Response', async () => {
const mockedData = Promise.resolve({ data: {} });
axiosMock.get.mockResolvedValueOnce(mockedData);
await Search.execute(['NOPE'], mockMessage);
expect(sendMock).lastCalledWith("I'm Sorry Dave, I'm afraid I can't do that...");
describe('Malformed Response', () => {
let consoleErrorMock: jest.SpyInstance<void, any>;
beforeEach(async () => {
const mockedData = Promise.resolve({ data: {} });
axiosMock.get.mockResolvedValueOnce(mockedData);
consoleErrorMock = jest.spyOn(console, 'error')
.mockImplementation(() => undefined); // Prevent it from spewing into the test results
await Search.execute(['NOPE'], mockMessage);
});
afterEach(() => {
consoleErrorMock.mockRestore();
});
test('Responds with error message', async () => {
expect(sendMock).lastCalledWith("I'm Sorry Dave, I'm afraid I can't do that...");
});
test('Console logs an error', () => {
const errorMessage = "Malformed Google Search Response: {}";
expect(consoleErrorMock).lastCalledWith(errorMessage);
});
});
});
5 changes: 3 additions & 2 deletions __tests__/library/commandLoader.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import glob from 'glob';
import CommandLoader, { ICommandClasses } from '../../src/library/commandLoader';
import { COMMANDS_PATH_GLOB } from './../../src/library/commands';

describe('CommandLoader', () => {
let commandClasses: ICommandClasses;
const files = glob.sync(COMMANDS_PATH_GLOB);
const commandsPathGlob = './src/commands/*.ts';
const files = glob.sync(commandsPathGlob);

beforeEach(() => {
commandClasses = CommandLoader.getCommandClasses(files);
Expand All @@ -16,6 +16,7 @@ describe('CommandLoader', () => {
});
});

// More of an integration test against real commands
describe('Class names match their file names', () => {
test('they match their key name', () => {
for (let commandName of Object.keys(commandClasses)) {
Expand Down
45 changes: 36 additions & 9 deletions __tests__/library/commands.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,43 @@
import { ICommandClasses } from '../../src/library/commandLoader';
import Commands from '../../src/library/commands';
import ICommand from '../../src/library/iCommand';

// TODO: I feel like this class is too basic to test,
// and ultimately a wrapper for other classes that have been tested
// Might just remove it some day
describe('Commands', () => {
const commands = new Commands();
test('Has a command', () => {
expect(Object.keys(commands.all).length).toBeGreaterThan(0);
expect(commands.names.length).toBeGreaterThan(0);
let mockHelloCommand: ICommand;
let mockYetAnotherCommand: ICommand;
let mockCommands: ICommandClasses;
let commands: Commands;

beforeEach(() => {
// TODO: these should probably go into a factory/mock
mockHelloCommand = {
name: 'Hello',
description: 'Hello World',
execute: jest.fn()
};
mockYetAnotherCommand = {
name: 'YAC',
description: 'Yet Another Command!',
execute: jest.fn()
};
mockCommands = {
hello: mockHelloCommand,
yac: mockYetAnotherCommand
};
commands = new Commands(mockCommands);
});

test('.names returns command names', () => {
const commandNames = ['hello', 'yac'];
expect(commands.names).toEqual(commandNames);
});

test('Can fetch a command', () => {
const first = commands.names[0];
expect(commands.get(first)).not.toBeUndefined();
const helloCommand = commands.get('hello');
expect(helloCommand).toBe(mockHelloCommand);
});

test('Finds the longest name', () => {
expect(commands.longestNameLength()).toEqual(5);
});
});
Loading

0 comments on commit 92a6d58

Please sign in to comment.