Skip to content

Commit

Permalink
feat(StringSelectMenu): add spliceOptions() (#8937)
Browse files Browse the repository at this point in the history
* feat(StringSelectMenu): add `spliceOptions()`

* fix: requested changes

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
almeidx and kodiakhq[bot] authored Dec 25, 2022
1 parent bec51de commit a6941d5
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 4 deletions.
49 changes: 49 additions & 0 deletions packages/builders/__tests__/components/selectMenu.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ const selectMenuData: APISelectMenuComponent = {
options: [selectMenuOptionData],
};

function makeStringSelectMenuWithOptions() {
const selectMenu = new StringSelectMenuBuilder();
selectMenu.addOptions(
{ label: 'foo', value: 'bar' },
{ label: 'foo2', value: 'bar2' },
{ label: 'foo3', value: 'bar3' },
);
return selectMenu;
}

function mapStringSelectMenuOptionBuildersToJson(selectMenu: StringSelectMenuBuilder) {
return selectMenu.options.map((option) => option.toJSON());
}

describe('Select Menu Components', () => {
describe('Assertion Tests', () => {
test('GIVEN valid inputs THEN Select Menu does not throw', () => {
Expand Down Expand Up @@ -176,5 +190,40 @@ describe('Select Menu Components', () => {
).toEqual(selectMenuData);
expect(new StringSelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);
});

test('GIVEN a StringSelectMenuBuilder using StringSelectMenuBuilder#spliceOptions works', () => {
expect(
mapStringSelectMenuOptionBuildersToJson(makeStringSelectMenuWithOptions().spliceOptions(0, 1)),
).toStrictEqual([
{ label: 'foo2', value: 'bar2' },
{ label: 'foo3', value: 'bar3' },
]);

expect(
mapStringSelectMenuOptionBuildersToJson(
makeStringSelectMenuWithOptions().spliceOptions(0, 1, selectMenuOptionData),
),
).toStrictEqual([selectMenuOptionData, { label: 'foo2', value: 'bar2' }, { label: 'foo3', value: 'bar3' }]);

expect(
mapStringSelectMenuOptionBuildersToJson(
makeStringSelectMenuWithOptions().spliceOptions(0, 3, selectMenuOptionData),
),
).toStrictEqual([selectMenuOptionData]);

expect(() =>
makeStringSelectMenuWithOptions().spliceOptions(
0,
0,
...Array.from({ length: 26 }, () => selectMenuOptionData),
),
).toThrowError();

expect(() =>
makeStringSelectMenuWithOptions()
.setOptions(Array.from({ length: 25 }, () => selectMenuOptionData))
.spliceOptions(-1, 2, selectMenuOptionData, selectMenuOptionData),
).toThrowError();
});
});
});
51 changes: 47 additions & 4 deletions packages/builders/src/components/selectMenu/StringSelectMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,61 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
* @param options - The options to set on this select menu
*/
public setOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
return this.spliceOptions(0, this.options.length, ...options);
}

/**
* Removes, replaces, or inserts options in the string select menu.
*
* @remarks
* This method behaves similarly
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice}.
*
* It's useful for modifying and adjusting order of the already-existing options of a string select menu.
* @example
* Remove the first option
* ```ts
* selectMenu.spliceOptions(0, 1);
* ```
* @example
* Remove the first n option
* ```ts
* const n = 4
* selectMenu.spliceOptions(0, n);
* ```
* @example
* Remove the last option
* ```ts
* selectMenu.spliceOptions(-1, 1);
* ```
* @param index - The index to start at
* @param deleteCount - The number of options to remove
* @param options - The replacing option objects or builders
*/
public spliceOptions(
index: number,
deleteCount: number,
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
) {
// eslint-disable-next-line no-param-reassign
options = normalizeArray(options);
optionsLengthValidator.parse(options.length);
this.options.splice(
0,
this.options.length,

const clone = [...this.options];

clone.splice(
index,
deleteCount,
...options.map((option) =>
option instanceof StringSelectMenuOptionBuilder
? option
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
),
);

optionsLengthValidator.parse(clone.length);

this.options.splice(0, this.options.length, ...clone);

return this;
}

Expand Down

0 comments on commit a6941d5

Please sign in to comment.