mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 11:03:30 +01:00
refactor: builders (#10448)
BREAKING CHANGE: formatters export removed (prev. deprecated) BREAKING CHANGE: `SelectMenuBuilder` and `SelectMenuOptionBuilder` have been removed (prev. deprecated) BREAKING CHANGE: `EmbedBuilder` no longer takes camalCase options BREAKING CHANGE: `ActionRowBuilder` now has specialized `[add/set]X` methods as opposed to the current `[add/set]Components` BREAKING CHANGE: Removed `equals` methods BREAKING CHANGE: Sapphire -> zod for validation BREAKING CHANGE: Removed the ability to pass `null`/`undefined` to clear fields, use `clearX()` instead BREAKING CHANGE: Renamed all "slash command" symbols to instead use "chat input command" BREAKING CHANGE: Removed `ContextMenuCommandBuilder` in favor of `MessageCommandBuilder` and `UserCommandBuilder` BREAKING CHANGE: Removed support for passing the "string key"s of enums BREAKING CHANGE: Removed `Button` class in favor for specialized classes depending on the style BREAKING CHANGE: Removed nested `addX` styled-methods in favor of plural `addXs` Co-authored-by: Vlad Frangu <me@vladfrangu.dev> Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
@@ -7,8 +7,8 @@ import {
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
createComponentBuilder,
|
||||
PrimaryButtonBuilder,
|
||||
StringSelectMenuBuilder,
|
||||
StringSelectMenuOptionBuilder,
|
||||
} from '../../src/index.js';
|
||||
@@ -41,21 +41,14 @@ const rowWithSelectMenuData: APIActionRowComponent<APIMessageActionRowComponent>
|
||||
value: 'two',
|
||||
},
|
||||
],
|
||||
max_values: 10,
|
||||
min_values: 12,
|
||||
max_values: 2,
|
||||
min_values: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe('Action Row Components', () => {
|
||||
describe('Assertion Tests', () => {
|
||||
test('GIVEN valid components THEN do not throw', () => {
|
||||
expect(() => new ActionRowBuilder().addComponents(new ButtonBuilder())).not.toThrowError();
|
||||
expect(() => new ActionRowBuilder().setComponents(new ButtonBuilder())).not.toThrowError();
|
||||
expect(() => new ActionRowBuilder().addComponents([new ButtonBuilder()])).not.toThrowError();
|
||||
expect(() => new ActionRowBuilder().setComponents([new ButtonBuilder()])).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid JSON input THEN valid JSON output is given', () => {
|
||||
const actionRowData: APIActionRowComponent<APIMessageActionRowComponent> = {
|
||||
type: ComponentType.ActionRow,
|
||||
@@ -72,22 +65,10 @@ describe('Action Row Components', () => {
|
||||
style: ButtonStyle.Link,
|
||||
url: 'https://google.com',
|
||||
},
|
||||
{
|
||||
type: ComponentType.StringSelect,
|
||||
placeholder: 'test',
|
||||
custom_id: 'test',
|
||||
options: [
|
||||
{
|
||||
label: 'option',
|
||||
value: 'option',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(new ActionRowBuilder(actionRowData).toJSON()).toEqual(actionRowData);
|
||||
expect(new ActionRowBuilder().toJSON()).toEqual({ type: ComponentType.ActionRow, components: [] });
|
||||
expect(() => createComponentBuilder({ type: ComponentType.ActionRow, components: [] })).not.toThrowError();
|
||||
});
|
||||
|
||||
@@ -120,24 +101,23 @@ describe('Action Row Components', () => {
|
||||
value: 'two',
|
||||
},
|
||||
],
|
||||
max_values: 10,
|
||||
min_values: 12,
|
||||
max_values: 1,
|
||||
min_values: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(new ActionRowBuilder(rowWithButtonData).toJSON()).toEqual(rowWithButtonData);
|
||||
expect(new ActionRowBuilder(rowWithSelectMenuData).toJSON()).toEqual(rowWithSelectMenuData);
|
||||
expect(new ActionRowBuilder().toJSON()).toEqual({ type: ComponentType.ActionRow, components: [] });
|
||||
expect(() => createComponentBuilder({ type: ComponentType.ActionRow, components: [] })).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid builder options THEN valid JSON output is given 2', () => {
|
||||
const button = new ButtonBuilder().setLabel('test').setStyle(ButtonStyle.Primary).setCustomId('123');
|
||||
const button = new PrimaryButtonBuilder().setLabel('test').setCustomId('123');
|
||||
const selectMenu = new StringSelectMenuBuilder()
|
||||
.setCustomId('1234')
|
||||
.setMaxValues(10)
|
||||
.setMinValues(12)
|
||||
.setMaxValues(2)
|
||||
.setMinValues(2)
|
||||
.setOptions(
|
||||
new StringSelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
||||
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||
@@ -147,10 +127,39 @@ describe('Action Row Components', () => {
|
||||
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||
]);
|
||||
|
||||
expect(new ActionRowBuilder().addComponents(button).toJSON()).toEqual(rowWithButtonData);
|
||||
expect(new ActionRowBuilder().addComponents(selectMenu).toJSON()).toEqual(rowWithSelectMenuData);
|
||||
expect(new ActionRowBuilder().addComponents([button]).toJSON()).toEqual(rowWithButtonData);
|
||||
expect(new ActionRowBuilder().addComponents([selectMenu]).toJSON()).toEqual(rowWithSelectMenuData);
|
||||
expect(new ActionRowBuilder().addPrimaryButtonComponents(button).toJSON()).toEqual(rowWithButtonData);
|
||||
expect(new ActionRowBuilder().addStringSelectMenuComponent(selectMenu).toJSON()).toEqual(rowWithSelectMenuData);
|
||||
expect(new ActionRowBuilder().addPrimaryButtonComponents([button]).toJSON()).toEqual(rowWithButtonData);
|
||||
});
|
||||
|
||||
test('GIVEN 2 select menus THEN it throws', () => {
|
||||
const selectMenu = new StringSelectMenuBuilder()
|
||||
.setCustomId('1234')
|
||||
.setOptions(
|
||||
new StringSelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
||||
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
new ActionRowBuilder()
|
||||
.addStringSelectMenuComponent(selectMenu)
|
||||
.addStringSelectMenuComponent(selectMenu)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN a button and a select menu THEN it throws', () => {
|
||||
const button = new PrimaryButtonBuilder().setLabel('test').setCustomId('123');
|
||||
const selectMenu = new StringSelectMenuBuilder()
|
||||
.setCustomId('1234')
|
||||
.setOptions(
|
||||
new StringSelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
||||
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
new ActionRowBuilder().addStringSelectMenuComponent(selectMenu).addPrimaryButtonComponents(button).toJSON(),
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,45 +5,21 @@ import {
|
||||
type APIButtonComponentWithURL,
|
||||
} from 'discord-api-types/v10';
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import { buttonLabelValidator, buttonStyleValidator } from '../../src/components/Assertions.js';
|
||||
import { ButtonBuilder } from '../../src/components/button/Button.js';
|
||||
|
||||
const buttonComponent = () => new ButtonBuilder();
|
||||
import { PrimaryButtonBuilder, PremiumButtonBuilder, LinkButtonBuilder } from '../../src/index.js';
|
||||
|
||||
const longStr =
|
||||
'looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong';
|
||||
|
||||
describe('Button Components', () => {
|
||||
describe('Assertion Tests', () => {
|
||||
test('GIVEN valid label THEN validator does not throw', () => {
|
||||
expect(() => buttonLabelValidator.parse('foobar')).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid label THEN validator does throw', () => {
|
||||
expect(() => buttonLabelValidator.parse(null)).toThrowError();
|
||||
expect(() => buttonLabelValidator.parse('')).toThrowError();
|
||||
|
||||
expect(() => buttonLabelValidator.parse(longStr)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid style THEN validator does not throw', () => {
|
||||
expect(() => buttonStyleValidator.parse(3)).not.toThrowError();
|
||||
expect(() => buttonStyleValidator.parse(ButtonStyle.Secondary)).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid style THEN validator does throw', () => {
|
||||
expect(() => buttonStyleValidator.parse(7)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid fields THEN builder does not throw', () => {
|
||||
expect(() =>
|
||||
buttonComponent().setCustomId('custom').setStyle(ButtonStyle.Primary).setLabel('test'),
|
||||
).not.toThrowError();
|
||||
expect(() => new PrimaryButtonBuilder().setCustomId('custom').setLabel('test')).not.toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
const button = new PrimaryButtonBuilder()
|
||||
.setCustomId('custom')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel('test')
|
||||
.setDisabled(true)
|
||||
.setEmoji({ name: 'test' });
|
||||
|
||||
@@ -51,111 +27,41 @@ describe('Button Components', () => {
|
||||
}).not.toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setSKUId('123456789012345678').setStyle(ButtonStyle.Premium);
|
||||
const button = new PremiumButtonBuilder().setSKUId('123456789012345678');
|
||||
button.toJSON();
|
||||
}).not.toThrowError();
|
||||
|
||||
expect(() => buttonComponent().setURL('https://google.com')).not.toThrowError();
|
||||
expect(() => new LinkButtonBuilder().setURL('https://google.com')).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid fields THEN build does throw', () => {
|
||||
expect(() => {
|
||||
buttonComponent().setCustomId(longStr);
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
.setCustomId('custom')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setDisabled(true)
|
||||
.setLabel('test')
|
||||
.setURL('https://google.com')
|
||||
.setEmoji({ name: 'test' });
|
||||
|
||||
button.toJSON();
|
||||
new PrimaryButtonBuilder().setCustomId(longStr).toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
// @ts-expect-error: Invalid emoji
|
||||
const button = buttonComponent().setEmoji('test');
|
||||
const button = new PrimaryButtonBuilder().setEmoji('test');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Primary);
|
||||
const button = new PrimaryButtonBuilder();
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Primary).setCustomId('test');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Link);
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Primary).setLabel('test').setURL('https://google.com');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Link).setLabel('test');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent().setStyle(ButtonStyle.Primary).setSKUId('123456789012345678');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setLabel('button')
|
||||
.setSKUId('123456789012345678');
|
||||
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
.setStyle(ButtonStyle.Success)
|
||||
.setEmoji({ name: '😇' })
|
||||
.setSKUId('123456789012345678');
|
||||
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
.setCustomId('test')
|
||||
.setSKUId('123456789012345678');
|
||||
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
const button = buttonComponent()
|
||||
.setStyle(ButtonStyle.Link)
|
||||
.setURL('https://google.com')
|
||||
.setSKUId('123456789012345678');
|
||||
|
||||
const button = new PrimaryButtonBuilder().setCustomId('test');
|
||||
button.toJSON();
|
||||
}).toThrowError();
|
||||
|
||||
// @ts-expect-error: Invalid style
|
||||
expect(() => buttonComponent().setStyle(24)).toThrowError();
|
||||
expect(() => buttonComponent().setLabel(longStr)).toThrowError();
|
||||
expect(() => new PrimaryButtonBuilder().setCustomId('hi').setStyle(24).toJSON()).toThrowError();
|
||||
expect(() => new PrimaryButtonBuilder().setCustomId('hi').setLabel(longStr).toJSON()).toThrowError();
|
||||
// @ts-expect-error: Invalid parameter for disabled
|
||||
expect(() => buttonComponent().setDisabled(0)).toThrowError();
|
||||
expect(() => new PrimaryButtonBuilder().setCustomId('hi').setDisabled(0).toJSON()).toThrowError();
|
||||
// @ts-expect-error: Invalid emoji
|
||||
expect(() => buttonComponent().setEmoji('foo')).toThrowError();
|
||||
|
||||
expect(() => buttonComponent().setURL('foobar')).toThrowError();
|
||||
expect(() => new PrimaryButtonBuilder().setCustomId('hi').setEmoji('foo').toJSON()).toThrowError();
|
||||
});
|
||||
|
||||
test('GiVEN valid input THEN valid JSON outputs are given', () => {
|
||||
@@ -167,13 +73,12 @@ describe('Button Components', () => {
|
||||
disabled: true,
|
||||
};
|
||||
|
||||
expect(new ButtonBuilder(interactionData).toJSON()).toEqual(interactionData);
|
||||
expect(new PrimaryButtonBuilder(interactionData).toJSON()).toEqual(interactionData);
|
||||
|
||||
expect(
|
||||
buttonComponent()
|
||||
new PrimaryButtonBuilder()
|
||||
.setCustomId(interactionData.custom_id)
|
||||
.setLabel(interactionData.label!)
|
||||
.setStyle(interactionData.style)
|
||||
.setDisabled(interactionData.disabled)
|
||||
.toJSON(),
|
||||
).toEqual(interactionData);
|
||||
@@ -186,9 +91,7 @@ describe('Button Components', () => {
|
||||
url: 'https://google.com',
|
||||
};
|
||||
|
||||
expect(new ButtonBuilder(linkData).toJSON()).toEqual(linkData);
|
||||
|
||||
expect(buttonComponent().setLabel(linkData.label!).setDisabled(true).setURL(linkData.url));
|
||||
expect(new LinkButtonBuilder(linkData).toJSON()).toEqual(linkData);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,14 +11,14 @@ import {
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
createComponentBuilder,
|
||||
CustomIdButtonBuilder,
|
||||
StringSelectMenuBuilder,
|
||||
TextInputBuilder,
|
||||
} from '../../src/index.js';
|
||||
|
||||
describe('createComponentBuilder', () => {
|
||||
test.each([ButtonBuilder, StringSelectMenuBuilder, TextInputBuilder])(
|
||||
test.each([StringSelectMenuBuilder, TextInputBuilder])(
|
||||
'passing an instance of %j should return itself',
|
||||
(Builder) => {
|
||||
const builder = new Builder();
|
||||
@@ -42,7 +42,7 @@ describe('createComponentBuilder', () => {
|
||||
type: ComponentType.Button,
|
||||
};
|
||||
|
||||
expect(createComponentBuilder(button)).toBeInstanceOf(ButtonBuilder);
|
||||
expect(createComponentBuilder(button)).toBeInstanceOf(CustomIdButtonBuilder);
|
||||
});
|
||||
|
||||
test('GIVEN a select menu component THEN returns a StringSelectMenuBuilder', () => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { describe, test, expect } from 'vitest';
|
||||
import { StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from '../../src/index.js';
|
||||
|
||||
const selectMenu = () => new StringSelectMenuBuilder();
|
||||
const selectMenuWithId = () => new StringSelectMenuBuilder({ custom_id: 'hi' });
|
||||
const selectMenuOption = () => new StringSelectMenuOptionBuilder();
|
||||
|
||||
const longStr = 'a'.repeat(256);
|
||||
@@ -16,10 +17,10 @@ const selectMenuOptionData: APISelectMenuOption = {
|
||||
};
|
||||
|
||||
const selectMenuDataWithoutOptions = {
|
||||
type: ComponentType.SelectMenu,
|
||||
type: ComponentType.StringSelect,
|
||||
custom_id: 'test',
|
||||
max_values: 10,
|
||||
min_values: 3,
|
||||
max_values: 1,
|
||||
min_values: 1,
|
||||
disabled: true,
|
||||
placeholder: 'test',
|
||||
} as const;
|
||||
@@ -109,49 +110,87 @@ describe('Select Menu Components', () => {
|
||||
});
|
||||
|
||||
test('GIVEN invalid inputs THEN Select Menu does throw', () => {
|
||||
expect(() => selectMenu().setCustomId(longStr)).toThrowError();
|
||||
expect(() => selectMenu().setMaxValues(30)).toThrowError();
|
||||
expect(() => selectMenu().setMinValues(-20)).toThrowError();
|
||||
expect(() => selectMenu().setCustomId(longStr).toJSON()).toThrowError();
|
||||
expect(() => selectMenuWithId().setMaxValues(30).toJSON()).toThrowError();
|
||||
expect(() => selectMenuWithId().setMinValues(-20).toJSON()).toThrowError();
|
||||
// @ts-expect-error: Invalid disabled value
|
||||
expect(() => selectMenu().setDisabled(0)).toThrowError();
|
||||
expect(() => selectMenu().setPlaceholder(longStr)).toThrowError();
|
||||
expect(() => selectMenuWithId().setDisabled(0).toJSON()).toThrowError();
|
||||
expect(() => selectMenuWithId().setPlaceholder(longStr).toJSON()).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions({ label: 'test' })).toThrowError();
|
||||
expect(() => selectMenu().addOptions({ label: longStr, value: 'test' })).toThrowError();
|
||||
expect(() => selectMenu().addOptions({ value: longStr, label: 'test' })).toThrowError();
|
||||
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', description: longStr })).toThrowError();
|
||||
expect(() => selectMenuWithId().addOptions({ label: 'test' }).toJSON()).toThrowError();
|
||||
expect(() => selectMenuWithId().addOptions({ label: longStr, value: 'test' }).toJSON()).toThrowError();
|
||||
expect(() => selectMenuWithId().addOptions({ value: longStr, label: 'test' }).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId().addOptions({ label: 'test', value: 'test', description: longStr }).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
// @ts-expect-error: Invalid option
|
||||
selectMenuWithId().addOptions({ label: 'test', value: 'test', default: 100 }).toJSON(),
|
||||
).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', default: 100 })).toThrowError();
|
||||
expect(() => selectMenuWithId().addOptions({ value: 'test' }).toJSON()).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions({ value: 'test' })).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions({ default: true })).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions([{ label: 'test' }])).toThrowError();
|
||||
expect(() => selectMenu().addOptions([{ label: longStr, value: 'test' }])).toThrowError();
|
||||
expect(() => selectMenu().addOptions([{ value: longStr, label: 'test' }])).toThrowError();
|
||||
expect(() => selectMenu().addOptions([{ label: 'test', value: 'test', description: longStr }])).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions([{ label: 'test', value: 'test', default: 100 }])).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions([{ value: 'test' }])).toThrowError();
|
||||
// @ts-expect-error: Invalid option
|
||||
expect(() => selectMenu().addOptions([{ default: true }])).toThrowError();
|
||||
expect(() => selectMenuWithId().addOptions({ default: true }).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
// @ts-expect-error: Invalid option
|
||||
.addOptions([{ label: 'test' }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
.addOptions([{ label: longStr, value: 'test' }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
.addOptions([{ value: longStr, label: 'test' }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
.addOptions([{ label: 'test', value: 'test', description: longStr }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
// @ts-expect-error: Invalid option
|
||||
.addOptions([{ label: 'test', value: 'test', default: 100 }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
// @ts-expect-error: Invalid option
|
||||
.addOptions([{ value: 'test' }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenuWithId()
|
||||
// @ts-expect-error: Invalid option
|
||||
.addOptions([{ default: true }])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
|
||||
const tooManyOptions = Array.from<APISelectMenuOption>({ length: 26 }).fill({ label: 'test', value: 'test' });
|
||||
|
||||
expect(() => selectMenu().setOptions(...tooManyOptions)).toThrowError();
|
||||
expect(() => selectMenu().setOptions(tooManyOptions)).toThrowError();
|
||||
expect(() =>
|
||||
selectMenu()
|
||||
.setOptions(...tooManyOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() => selectMenu().setOptions(tooManyOptions).toJSON()).toThrowError();
|
||||
|
||||
expect(() =>
|
||||
selectMenu()
|
||||
.addOptions({ label: 'test', value: 'test' })
|
||||
.addOptions(...tooManyOptions),
|
||||
.addOptions(...tooManyOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
selectMenu()
|
||||
.addOptions([{ label: 'test', value: 'test' }])
|
||||
.addOptions(tooManyOptions),
|
||||
.addOptions(tooManyOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
|
||||
expect(() => {
|
||||
@@ -162,7 +201,8 @@ describe('Select Menu Components', () => {
|
||||
.setDefault(-1)
|
||||
// @ts-expect-error: Invalid emoji
|
||||
.setEmoji({ name: 1 })
|
||||
.setDescription(longStr);
|
||||
.setDescription(longStr)
|
||||
.toJSON();
|
||||
}).toThrowError();
|
||||
});
|
||||
|
||||
@@ -212,17 +252,16 @@ describe('Select Menu Components', () => {
|
||||
).toStrictEqual([selectMenuOptionData]);
|
||||
|
||||
expect(() =>
|
||||
makeStringSelectMenuWithOptions().spliceOptions(
|
||||
0,
|
||||
0,
|
||||
...Array.from({ length: 26 }, () => selectMenuOptionData),
|
||||
),
|
||||
makeStringSelectMenuWithOptions()
|
||||
.spliceOptions(0, 0, ...Array.from({ length: 26 }, () => selectMenuOptionData))
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
|
||||
expect(() =>
|
||||
makeStringSelectMenuWithOptions()
|
||||
.setOptions(Array.from({ length: 25 }, () => selectMenuOptionData))
|
||||
.spliceOptions(-1, 2, selectMenuOptionData, selectMenuOptionData),
|
||||
.spliceOptions(-1, 2, selectMenuOptionData, selectMenuOptionData)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
import { ComponentType, TextInputStyle, type APITextInputComponent } from 'discord-api-types/v10';
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import {
|
||||
labelValidator,
|
||||
maxLengthValidator,
|
||||
minLengthValidator,
|
||||
placeholderValidator,
|
||||
valueValidator,
|
||||
textInputStyleValidator,
|
||||
} from '../../src/components/textInput/Assertions.js';
|
||||
import { TextInputBuilder } from '../../src/components/textInput/TextInput.js';
|
||||
|
||||
const superLongStr = 'a'.repeat(5_000);
|
||||
@@ -16,56 +8,6 @@ const textInputComponent = () => new TextInputBuilder();
|
||||
|
||||
describe('Text Input Components', () => {
|
||||
describe('Assertion Tests', () => {
|
||||
test('GIVEN valid label THEN validator does not throw', () => {
|
||||
expect(() => labelValidator.parse('foobar')).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid label THEN validator does throw', () => {
|
||||
expect(() => labelValidator.parse(24)).toThrowError();
|
||||
expect(() => labelValidator.parse(undefined)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid style THEN validator does not throw', () => {
|
||||
expect(() => textInputStyleValidator.parse(TextInputStyle.Paragraph)).not.toThrowError();
|
||||
expect(() => textInputStyleValidator.parse(TextInputStyle.Short)).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid style THEN validator does throw', () => {
|
||||
expect(() => textInputStyleValidator.parse(24)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid min length THEN validator does not throw', () => {
|
||||
expect(() => minLengthValidator.parse(10)).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid min length THEN validator does throw', () => {
|
||||
expect(() => minLengthValidator.parse(-1)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid max length THEN validator does not throw', () => {
|
||||
expect(() => maxLengthValidator.parse(10)).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid min length THEN validator does throw 2', () => {
|
||||
expect(() => maxLengthValidator.parse(4_001)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid value THEN validator does not throw', () => {
|
||||
expect(() => valueValidator.parse('foobar')).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid value THEN validator does throw', () => {
|
||||
expect(() => valueValidator.parse(superLongStr)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid placeholder THEN validator does not throw', () => {
|
||||
expect(() => placeholderValidator.parse('foobar')).not.toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN invalid value THEN validator does throw 2', () => {
|
||||
expect(() => placeholderValidator.parse(superLongStr)).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN valid fields THEN builder does not throw', () => {
|
||||
expect(() => {
|
||||
textInputComponent().setCustomId('foobar').setLabel('test').setStyle(TextInputStyle.Paragraph).toJSON();
|
||||
@@ -84,9 +26,7 @@ describe('Text Input Components', () => {
|
||||
}).not.toThrowError();
|
||||
|
||||
expect(() => {
|
||||
// Issue #8107
|
||||
// @ts-expect-error: Shapeshift maps the enum key to the value when parsing
|
||||
textInputComponent().setCustomId('Custom').setLabel('Guess').setStyle('Short').toJSON();
|
||||
textInputComponent().setCustomId('Custom').setLabel('Guess').setStyle(TextInputStyle.Short).toJSON();
|
||||
}).not.toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user