more tests & enforce structure
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e2503d22a0
commit
4fb0bed436
@ -12,5 +12,4 @@ steps:
|
|||||||
image: node
|
image: node
|
||||||
commands:
|
commands:
|
||||||
- yarn install
|
- yarn install
|
||||||
- yarn build
|
|
||||||
- yarn test
|
- yarn test
|
@ -22,7 +22,7 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test": "jest",
|
"test": "tsc && jest",
|
||||||
"release": "tsc && yarn publish",
|
"release": "tsc && yarn publish",
|
||||||
"lint": "eslint --fix"
|
"lint": "eslint --fix"
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,9 @@ abstract class Command implements ICommand {
|
|||||||
|
|
||||||
constructor(def: CommandDefinition) {
|
constructor(def: CommandDefinition) {
|
||||||
|
|
||||||
|
if (typeof def !== 'object') throw new Error('Missing command definition');
|
||||||
|
|
||||||
|
if (!def.name) throw new Error('Missing name for command');
|
||||||
this.name = def.name;
|
this.name = def.name;
|
||||||
|
|
||||||
this.aliases = def.aliases || [];
|
this.aliases = def.aliases || [];
|
||||||
@ -24,6 +27,8 @@ abstract class Command implements ICommand {
|
|||||||
if (opt instanceof CommandOption) this.options.push(opt);
|
if (opt instanceof CommandOption) this.options.push(opt);
|
||||||
else this.options.push(new CommandOption(opt));
|
else this.options.push(new CommandOption(opt));
|
||||||
}
|
}
|
||||||
|
if (this.options.some(opt => [OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(opt.type))
|
||||||
|
&& this.options.some(opt => ![OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(opt.type))) throw new Error('Cannot have subcommand(group)s on the same level as an option')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,16 +49,26 @@ class CommandOption implements ICommandOption {
|
|||||||
this.name = def.name;
|
this.name = def.name;
|
||||||
this.aliases = def.aliases || [];
|
this.aliases = def.aliases || [];
|
||||||
|
|
||||||
|
this.strict = def.strict || false;
|
||||||
|
this.type = def.type ?? OptionType.STRING;
|
||||||
|
this.flag = def.flag || false;
|
||||||
|
|
||||||
this.options = [];
|
this.options = [];
|
||||||
for (const opt of def.options || []) {
|
for (const opt of def.options || []) {
|
||||||
if (opt instanceof CommandOption) this.options.push(opt);
|
if (opt instanceof CommandOption) this.options.push(opt);
|
||||||
else this.options.push(new CommandOption(opt));
|
else this.options.push(new CommandOption(opt));
|
||||||
}
|
}
|
||||||
this.choices = def.choices || [];
|
|
||||||
|
|
||||||
this.strict = def.strict || false;
|
if (this.type === OptionType.SUB_COMMAND_GROUP && this.options.some(opt => opt.type === OptionType.SUB_COMMAND_GROUP)) throw new Error('Cannot nest subcommand groups');
|
||||||
this.type = def.type ?? OptionType.STRING;
|
if (this.type === OptionType.SUB_COMMAND && this.options.some(opt => opt.type === OptionType.SUB_COMMAND_GROUP)) throw new Error('Cannot have subcommand groups under a subcommand');
|
||||||
this.flag = def.flag || false;
|
if (this.type === OptionType.SUB_COMMAND && this.options.some(opt => opt.type === OptionType.SUB_COMMAND)) throw new Error('Cannot nest subcommands');
|
||||||
|
if (![OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(this.type)
|
||||||
|
&& this.options.some(opt => [OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(opt.type))) throw new Error('Cannot have subcommand(group)s under an option');
|
||||||
|
|
||||||
|
if (this.options.some(opt => [OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(opt.type))
|
||||||
|
&& this.options.some(opt => ![OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP].includes(opt.type))) throw new Error('Cannot have subcommand(group)s on the same level as an option')
|
||||||
|
|
||||||
|
this.choices = def.choices || [];
|
||||||
|
|
||||||
this.valueOptional = def.valueOptional || false;
|
this.valueOptional = def.valueOptional || false;
|
||||||
this.defaultValue = def.defaultValue ?? null;
|
this.defaultValue = def.defaultValue ?? null;
|
||||||
|
@ -20,7 +20,7 @@ const parser = new Parser({
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const parsed = await parser.parseMessage('test message.author')
|
const parsed = await parser.parseMessage('test message.author')
|
||||||
console.log(parsed)
|
// console.log(parsed)
|
||||||
})();
|
})();
|
||||||
|
|
||||||
test('', () => {
|
test('', () => {
|
||||||
|
@ -1,11 +1,70 @@
|
|||||||
const { inspect } = require('node:util');
|
const { inspect } = require('node:util');
|
||||||
const { Parser, Command, OptionType } = require('../build');
|
const { Parser, Command, OptionType } = require('../build');
|
||||||
|
|
||||||
|
test('Command definition', () => {
|
||||||
|
expect(() => new Command()).toThrow();
|
||||||
|
expect(() => new Command({})).toThrow();
|
||||||
|
expect(() => new Command(235345)).toThrow();
|
||||||
|
expect(() => new Command({ name: 'create' })).not.toThrow();
|
||||||
|
|
||||||
|
expect(() => new Command({
|
||||||
|
name: 'create',
|
||||||
|
options: [{
|
||||||
|
name: 'test',
|
||||||
|
type: OptionType.SUB_COMMAND,
|
||||||
|
options: [{
|
||||||
|
name:'dingus',
|
||||||
|
type: OptionType.SUB_COMMAND
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
})).toThrow();
|
||||||
|
|
||||||
|
expect(() => new Command({
|
||||||
|
name: 'create',
|
||||||
|
options: [{
|
||||||
|
name: 'test',
|
||||||
|
type: OptionType.STRING,
|
||||||
|
options: [{
|
||||||
|
name:'dingus',
|
||||||
|
type: OptionType.SUB_COMMAND
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
})).toThrow();
|
||||||
|
|
||||||
|
expect(() => new Command({
|
||||||
|
name: 'create',
|
||||||
|
options: [{
|
||||||
|
name: 'test',
|
||||||
|
type: OptionType.SUB_COMMAND_GROUP,
|
||||||
|
options: [{
|
||||||
|
name:'dingus',
|
||||||
|
type: OptionType.SUB_COMMAND
|
||||||
|
}]
|
||||||
|
}] })).not.toThrow();
|
||||||
|
})
|
||||||
|
|
||||||
test('Command Parser', async () => {
|
test('Command Parser', async () => {
|
||||||
const command = new Command({ name: 'create', options: [{ name: 'registration-code', aliases: ['code'], type: OptionType.SUB_COMMAND }, { name: 'test' }] });
|
const command = new Command({
|
||||||
|
name: 'create',
|
||||||
|
options: [{
|
||||||
|
name: 'registration-code',
|
||||||
|
aliases: ['code'],
|
||||||
|
type: OptionType.SUB_COMMAND,
|
||||||
|
options: [{
|
||||||
|
name: 'amount',
|
||||||
|
type: OptionType.INTEGER,
|
||||||
|
defaultValue: 1,
|
||||||
|
valueOptional: true
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
});
|
||||||
const parser = new Parser({ commands: [command], prefix: '' });
|
const parser = new Parser({ commands: [command], prefix: '' });
|
||||||
|
|
||||||
await expect(parser.parseMessage('create')).rejects.toThrow();
|
await expect(parser.parseMessage('create')).rejects.toThrow();
|
||||||
|
// Cannot have an option at the sub-command level
|
||||||
|
await expect(parser.parseMessage('create test')).rejects.toThrow();
|
||||||
|
|
||||||
|
await expect(parser.parseMessage('create code')).resolves.toHaveProperty('command.name', 'create');
|
||||||
|
await expect(parser.parseMessage('create code 1')).resolves.toHaveProperty('args.amount.value', 1);
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user