refactor: use arrays instead of rest parameters for builders (#7759)

This commit is contained in:
Suneet Tipirneni
2022-04-21 12:56:10 -04:00
committed by GitHub
parent f22245e9d0
commit 29293d7bbb
11 changed files with 66 additions and 69 deletions

View File

@@ -44,8 +44,8 @@ const rowWithSelectMenuData: APIActionRowComponent<APIMessageActionRowComponent>
describe('Action Row Components', () => { describe('Action Row Components', () => {
describe('Assertion Tests', () => { describe('Assertion Tests', () => {
test('GIVEN valid components THEN do not throw', () => { test('GIVEN valid components THEN do not throw', () => {
expect(() => new ActionRowBuilder().addComponents(new ButtonBuilder())).not.toThrowError(); expect(() => new ActionRowBuilder().addComponents([new ButtonBuilder()])).not.toThrowError();
expect(() => new ActionRowBuilder().setComponents(new ButtonBuilder())).not.toThrowError(); expect(() => new ActionRowBuilder().setComponents([new ButtonBuilder()])).not.toThrowError();
}); });
test('GIVEN valid JSON input THEN valid JSON output is given', () => { test('GIVEN valid JSON input THEN valid JSON output is given', () => {
@@ -128,13 +128,13 @@ describe('Action Row Components', () => {
.setCustomId('1234') .setCustomId('1234')
.setMaxValues(10) .setMaxValues(10)
.setMinValues(12) .setMinValues(12)
.setOptions( .setOptions([
new SelectMenuOptionBuilder().setLabel('one').setValue('one'), new SelectMenuOptionBuilder().setLabel('one').setValue('one'),
new SelectMenuOptionBuilder().setLabel('two').setValue('two'), new SelectMenuOptionBuilder().setLabel('two').setValue('two'),
); ]);
expect(new ActionRowBuilder().addComponents(button).toJSON()).toEqual(rowWithButtonData); expect(new ActionRowBuilder().addComponents([button]).toJSON()).toEqual(rowWithButtonData);
expect(new ActionRowBuilder().addComponents(selectMenu).toJSON()).toEqual(rowWithSelectMenuData); expect(new ActionRowBuilder().addComponents([selectMenu]).toJSON()).toEqual(rowWithSelectMenuData);
}); });
}); });
}); });

View File

@@ -43,29 +43,31 @@ describe('Select Menu Components', () => {
.setDefault(true) .setDefault(true)
.setEmoji({ name: 'test' }) .setEmoji({ name: 'test' })
.setDescription('description'); .setDescription('description');
expect(() => selectMenu().addOptions(option)).not.toThrowError(); expect(() => selectMenu().addOptions([option])).not.toThrowError();
expect(() => selectMenu().setOptions(option)).not.toThrowError(); expect(() => selectMenu().setOptions([option])).not.toThrowError();
expect(() => selectMenu().setOptions({ label: 'test', value: 'test' })).not.toThrowError(); expect(() => selectMenu().setOptions([{ label: 'test', value: 'test' }])).not.toThrowError();
expect(() => expect(() =>
selectMenu().addOptions({ selectMenu().addOptions([
label: 'test', {
value: 'test', label: 'test',
emoji: { value: 'test',
id: '123', emoji: {
name: 'test', id: '123',
animated: true, name: 'test',
animated: true,
},
}, },
}), ]),
).not.toThrowError(); ).not.toThrowError();
const options = new Array<APISelectMenuOption>(25).fill({ label: 'test', value: 'test' }); const options = new Array<APISelectMenuOption>(25).fill({ label: 'test', value: 'test' });
expect(() => selectMenu().addOptions(...options)).not.toThrowError(); expect(() => selectMenu().addOptions(options)).not.toThrowError();
expect(() => selectMenu().setOptions(...options)).not.toThrowError(); expect(() => selectMenu().setOptions(options)).not.toThrowError();
expect(() => expect(() =>
selectMenu() selectMenu()
.addOptions({ label: 'test', value: 'test' }) .addOptions([{ label: 'test', value: 'test' }])
.addOptions(...new Array<APISelectMenuOption>(24).fill({ label: 'test', value: 'test' })), .addOptions(new Array<APISelectMenuOption>(24).fill({ label: 'test', value: 'test' })),
).not.toThrowError(); ).not.toThrowError();
}); });
@@ -77,24 +79,24 @@ describe('Select Menu Components', () => {
expect(() => selectMenu().setDisabled(0)).toThrowError(); expect(() => selectMenu().setDisabled(0)).toThrowError();
expect(() => selectMenu().setPlaceholder(longStr)).toThrowError(); expect(() => selectMenu().setPlaceholder(longStr)).toThrowError();
// @ts-expect-error // @ts-expect-error
expect(() => selectMenu().addOptions({ label: 'test' })).toThrowError(); expect(() => selectMenu().addOptions([{ label: 'test' }])).toThrowError();
expect(() => selectMenu().addOptions({ label: longStr, value: 'test' })).toThrowError(); expect(() => selectMenu().addOptions([{ label: longStr, value: 'test' }])).toThrowError();
expect(() => selectMenu().addOptions({ value: longStr, label: 'test' })).toThrowError(); expect(() => selectMenu().addOptions([{ value: longStr, label: 'test' }])).toThrowError();
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', description: longStr })).toThrowError(); expect(() => selectMenu().addOptions([{ label: 'test', value: 'test', description: longStr }])).toThrowError();
// @ts-expect-error // @ts-expect-error
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', default: 100 })).toThrowError(); expect(() => selectMenu().addOptions([{ label: 'test', value: 'test', default: 100 }])).toThrowError();
// @ts-expect-error // @ts-expect-error
expect(() => selectMenu().addOptions({ value: 'test' })).toThrowError(); expect(() => selectMenu().addOptions([{ value: 'test' }])).toThrowError();
// @ts-expect-error // @ts-expect-error
expect(() => selectMenu().addOptions({ default: true })).toThrowError(); expect(() => selectMenu().addOptions([{ default: true }])).toThrowError();
const tooManyOptions = new Array<APISelectMenuOption>(26).fill({ label: 'test', value: 'test' }); const tooManyOptions = new Array<APISelectMenuOption>(26).fill({ label: 'test', value: 'test' });
expect(() => selectMenu().setOptions(...tooManyOptions)).toThrowError(); expect(() => selectMenu().setOptions(tooManyOptions)).toThrowError();
expect(() => expect(() =>
selectMenu() selectMenu()
.addOptions({ label: 'test', value: 'test' }) .addOptions([{ label: 'test', value: 'test' }])
.addOptions(...tooManyOptions), .addOptions(tooManyOptions),
).toThrowError(); ).toThrowError();
expect(() => { expect(() => {
@@ -112,7 +114,7 @@ describe('Select Menu Components', () => {
test('GIVEN valid JSON input THEN valid JSON history is correct', () => { test('GIVEN valid JSON input THEN valid JSON history is correct', () => {
expect( expect(
new SelectMenuBuilder(selectMenuDataWithoutOptions) new SelectMenuBuilder(selectMenuDataWithoutOptions)
.addOptions(new SelectMenuOptionBuilder(selectMenuOptionData)) .addOptions([new SelectMenuOptionBuilder(selectMenuOptionData)])
.toJSON(), .toJSON(),
).toEqual(selectMenuData); ).toEqual(selectMenuData);
expect(new SelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData); expect(new SelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);

View File

@@ -48,15 +48,11 @@ describe('Modals', () => {
test('GIVEN valid fields THEN builder does not throw', () => { test('GIVEN valid fields THEN builder does not throw', () => {
expect(() => expect(() =>
modal().setTitle('test').setCustomId('foobar').setComponents(new ActionRowBuilder()), modal().setTitle('test').setCustomId('foobar').setComponents([new ActionRowBuilder()]),
).not.toThrowError(); ).not.toThrowError();
}); });
test('GIVEN invalid fields THEN builder does throw', () => { test('GIVEN invalid fields THEN builder does throw', () => {
expect(() =>
// @ts-expect-error
modal().setTitle('test').setCustomId('foobar').setComponents([new ActionRowBuilder()]).toJSON(),
).toThrowError();
expect(() => modal().setTitle('test').setCustomId('foobar').toJSON()).toThrowError(); expect(() => modal().setTitle('test').setCustomId('foobar').toJSON()).toThrowError();
// @ts-expect-error // @ts-expect-error
expect(() => modal().setTitle('test').setCustomId(42).toJSON()).toThrowError(); expect(() => modal().setTitle('test').setCustomId(42).toJSON()).toThrowError();
@@ -87,11 +83,11 @@ describe('Modals', () => {
modal() modal()
.setTitle(modalData.title) .setTitle(modalData.title)
.setCustomId('custom id') .setCustomId('custom id')
.setComponents( .setComponents([
new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents( new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents([
new TextInputBuilder().setCustomId('custom id').setLabel('label').setStyle(TextInputStyle.Paragraph), new TextInputBuilder().setCustomId('custom id').setLabel('label').setStyle(TextInputStyle.Paragraph),
), ]),
) ])
.toJSON(), .toJSON(),
).toEqual(modalData); ).toEqual(modalData);
}); });

View File

@@ -322,7 +322,7 @@ describe('Embed', () => {
test('GIVEN an embed using Embed#addFields THEN returns valid toJSON data', () => { test('GIVEN an embed using Embed#addFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
embed.addFields({ name: 'foo', value: 'bar' }); embed.addFields([{ name: 'foo', value: 'bar' }]);
expect(embed.toJSON()).toStrictEqual({ expect(embed.toJSON()).toStrictEqual({
fields: [{ name: 'foo', value: 'bar', inline: undefined }], fields: [{ name: 'foo', value: 'bar', inline: undefined }],
@@ -331,7 +331,10 @@ describe('Embed', () => {
test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => { test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
embed.addFields({ name: 'foo', value: 'bar' }, { name: 'foo', value: 'baz' }); embed.addFields([
{ name: 'foo', value: 'bar' },
{ name: 'foo', value: 'baz' },
]);
expect(embed.spliceFields(0, 1).toJSON()).toStrictEqual({ expect(embed.spliceFields(0, 1).toJSON()).toStrictEqual({
fields: [{ name: 'foo', value: 'baz', inline: undefined }], fields: [{ name: 'foo', value: 'baz', inline: undefined }],
@@ -340,7 +343,7 @@ describe('Embed', () => {
test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => { test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
embed.addFields(...Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' }))); embed.addFields(Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' })));
expect(() => expect(() =>
embed.spliceFields(0, 3, ...Array.from({ length: 5 }, () => ({ name: 'foo', value: 'bar' }))), embed.spliceFields(0, 3, ...Array.from({ length: 5 }, () => ({ name: 'foo', value: 'bar' }))),
@@ -349,7 +352,7 @@ describe('Embed', () => {
test('GIVEN an embed using Embed#spliceFields that adds additional fields resulting in fields > 25 THEN throws error', () => { test('GIVEN an embed using Embed#spliceFields that adds additional fields resulting in fields > 25 THEN throws error', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
embed.addFields(...Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' }))); embed.addFields(Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' })));
expect(() => expect(() =>
embed.spliceFields(0, 3, ...Array.from({ length: 8 }, () => ({ name: 'foo', value: 'bar' }))), embed.spliceFields(0, 3, ...Array.from({ length: 8 }, () => ({ name: 'foo', value: 'bar' }))),
@@ -360,25 +363,21 @@ describe('Embed', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => expect(() =>
embed.setFields(...Array.from({ length: 25 }, () => ({ name: 'foo', value: 'bar' }))), embed.setFields(Array.from({ length: 25 }, () => ({ name: 'foo', value: 'bar' }))),
).not.toThrowError(); ).not.toThrowError();
}); });
test('GIVEN an embed using Embed#setFields that sets more than 25 fields THEN throws error', () => { test('GIVEN an embed using Embed#setFields that sets more than 25 fields THEN throws error', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => expect(() => embed.setFields(Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' })))).toThrowError();
embed.setFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
}); });
describe('GIVEN invalid field amount THEN throws error', () => { describe('GIVEN invalid field amount THEN throws error', () => {
test('', () => { test('', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => expect(() => embed.addFields(Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' })))).toThrowError();
embed.addFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
}); });
}); });
@@ -386,7 +385,7 @@ describe('Embed', () => {
test('', () => { test('', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'bar' })).toThrowError(); expect(() => embed.addFields([{ name: '', value: 'bar' }])).toThrowError();
}); });
}); });
@@ -394,7 +393,7 @@ describe('Embed', () => {
test('', () => { test('', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: 'a'.repeat(257), value: 'bar' })).toThrowError(); expect(() => embed.addFields([{ name: 'a'.repeat(257), value: 'bar' }])).toThrowError();
}); });
}); });
@@ -402,7 +401,7 @@ describe('Embed', () => {
test('', () => { test('', () => {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'a'.repeat(1025) })).toThrowError(); expect(() => embed.addFields([{ name: '', value: 'a'.repeat(1025) }])).toThrowError();
}); });
}); });
}); });

View File

@@ -38,7 +38,7 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
* @param components The components to add to this action row. * @param components The components to add to this action row.
* @returns * @returns
*/ */
public addComponents(...components: T[]) { public addComponents(components: T[]) {
this.components.push(...components); this.components.push(...components);
return this; return this;
} }
@@ -47,7 +47,7 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
* Sets the components in this action row * Sets the components in this action row
* @param components The components to set this row to * @param components The components to set this row to
*/ */
public setComponents(...components: T[]) { public setComponents(components: T[]) {
this.components.splice(0, this.components.length, ...components); this.components.splice(0, this.components.length, ...components);
return this; return this;
} }

View File

@@ -35,7 +35,7 @@ export class SelectMenuBuilder extends UnsafeSelectMenuBuilder {
return super.setDisabled(disabledValidator.parse(disabled)); return super.setDisabled(disabledValidator.parse(disabled));
} }
public override addOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) { public override addOptions(options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
optionsLengthValidator.parse(this.options.length + options.length); optionsLengthValidator.parse(this.options.length + options.length);
this.options.push( this.options.push(
...options.map((option) => ...options.map((option) =>
@@ -47,7 +47,7 @@ export class SelectMenuBuilder extends UnsafeSelectMenuBuilder {
return this; return this;
} }
public override setOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) { public override setOptions(options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
optionsLengthValidator.parse(options.length); optionsLengthValidator.parse(options.length);
this.options.splice( this.options.splice(
0, 0,

View File

@@ -67,7 +67,7 @@ export class UnsafeSelectMenuBuilder extends ComponentBuilder<APISelectMenuCompo
* @param options The options to add to this select menu * @param options The options to add to this select menu
* @returns * @returns
*/ */
public addOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) { public addOptions(options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
this.options.push( this.options.push(
...options.map((option) => ...options.map((option) =>
option instanceof UnsafeSelectMenuOptionBuilder ? option : new UnsafeSelectMenuOptionBuilder(option), option instanceof UnsafeSelectMenuOptionBuilder ? option : new UnsafeSelectMenuOptionBuilder(option),
@@ -80,7 +80,7 @@ export class UnsafeSelectMenuBuilder extends ComponentBuilder<APISelectMenuCompo
* Sets the options on this select menu * Sets the options on this select menu
* @param options The options to set on this select menu * @param options The options to set on this select menu
*/ */
public setOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) { public setOptions(options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
this.options.splice( this.options.splice(
0, 0,
this.options.length, this.options.length,

View File

@@ -9,7 +9,7 @@ export class UnsafeTextInputBuilder extends ComponentBuilder<APITextInputCompone
/** /**
* Sets the custom id for this text input * Sets the custom id for this text input
* @param customId The custom id of this text inputå * @param customId The custom id of this text input
*/ */
public setCustomId(customId: string) { public setCustomId(customId: string) {
this.data.custom_id = customId; this.data.custom_id = customId;

View File

@@ -38,10 +38,10 @@ export class UnsafeModalBuilder implements JSONEncodable<APIModalInteractionResp
* @param components The components to add to this modal * @param components The components to add to this modal
*/ */
public addComponents( public addComponents(
...components: ( components: (
| ActionRowBuilder<ModalActionRowComponentBuilder> | ActionRowBuilder<ModalActionRowComponentBuilder>
| APIActionRowComponent<APIModalActionRowComponent> | APIActionRowComponent<APIModalActionRowComponent>
)[] )[],
) { ) {
this.components.push( this.components.push(
...components.map((component) => ...components.map((component) =>
@@ -57,7 +57,7 @@ export class UnsafeModalBuilder implements JSONEncodable<APIModalInteractionResp
* Sets the components in this modal * Sets the components in this modal
* @param components The components to set this modal to * @param components The components to set this modal to
*/ */
public setComponents(...components: ActionRowBuilder<ModalActionRowComponentBuilder>[]) { public setComponents(components: ActionRowBuilder<ModalActionRowComponentBuilder>[]) {
this.components.splice(0, this.components.length, ...components); this.components.splice(0, this.components.length, ...components);
return this; return this;
} }

View File

@@ -17,12 +17,12 @@ import { EmbedAuthorOptions, EmbedFooterOptions, RGBTuple, UnsafeEmbedBuilder }
* Represents a validated embed in a message (image/video preview, rich embed, etc.) * Represents a validated embed in a message (image/video preview, rich embed, etc.)
*/ */
export class EmbedBuilder extends UnsafeEmbedBuilder { export class EmbedBuilder extends UnsafeEmbedBuilder {
public override addFields(...fields: APIEmbedField[]): this { public override addFields(fields: APIEmbedField[]): this {
// Ensure adding these fields won't exceed the 25 field limit // Ensure adding these fields won't exceed the 25 field limit
validateFieldLength(fields.length, this.data.fields); validateFieldLength(fields.length, this.data.fields);
// Data assertions // Data assertions
return super.addFields(...embedFieldsArrayPredicate.parse(fields)); return super.addFields(embedFieldsArrayPredicate.parse(fields));
} }
public override spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this { public override spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {

View File

@@ -44,7 +44,7 @@ export class UnsafeEmbedBuilder {
* *
* @param fields The fields to add * @param fields The fields to add
*/ */
public addFields(...fields: APIEmbedField[]): this { public addFields(fields: APIEmbedField[]): this {
if (this.data.fields) this.data.fields.push(...fields); if (this.data.fields) this.data.fields.push(...fields);
else this.data.fields = fields; else this.data.fields = fields;
return this; return this;
@@ -67,7 +67,7 @@ export class UnsafeEmbedBuilder {
* Sets the embed's fields (max 25). * Sets the embed's fields (max 25).
* @param fields The fields to set * @param fields The fields to set
*/ */
public setFields(...fields: APIEmbedField[]) { public setFields(fields: APIEmbedField[]) {
this.spliceFields(0, this.data.fields?.length ?? 0, ...fields); this.spliceFields(0, this.data.fields?.length ?? 0, ...fields);
return this; return this;
} }