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
|
||||
commands:
|
||||
- yarn install
|
||||
- yarn build
|
||||
- yarn test
|
@ -22,7 +22,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"test": "tsc && jest",
|
||||
"release": "tsc && yarn publish",
|
||||
"lint": "eslint --fix"
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ abstract class Command implements ICommand {
|
||||
|
||||
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.aliases = def.aliases || [];
|
||||
@ -24,6 +27,8 @@ abstract class Command implements ICommand {
|
||||
if (opt instanceof CommandOption) this.options.push(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.aliases = def.aliases || [];
|
||||
|
||||
this.strict = def.strict || false;
|
||||
this.type = def.type ?? OptionType.STRING;
|
||||
this.flag = def.flag || false;
|
||||
|
||||
this.options = [];
|
||||
for (const opt of def.options || []) {
|
||||
if (opt instanceof CommandOption) this.options.push(opt);
|
||||
else this.options.push(new CommandOption(opt));
|
||||
}
|
||||
this.choices = def.choices || [];
|
||||
|
||||
this.strict = def.strict || false;
|
||||
this.type = def.type ?? OptionType.STRING;
|
||||
this.flag = def.flag || 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');
|
||||
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');
|
||||
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.defaultValue = def.defaultValue ?? null;
|
||||
|
@ -20,7 +20,7 @@ const parser = new Parser({
|
||||
|
||||
(async () => {
|
||||
const parsed = await parser.parseMessage('test message.author')
|
||||
console.log(parsed)
|
||||
// console.log(parsed)
|
||||
})();
|
||||
|
||||
test('', () => {
|
||||
|
@ -1,11 +1,70 @@
|
||||
const { inspect } = require('node:util');
|
||||
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 () => {
|
||||
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: '' });
|
||||
|
||||
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