Skip to content

Commit d8ad8f4

Browse files
authored
Merge pull request #331 from fcollonval/ft/command-description-2
Allow describedBy to be an async function
2 parents 129221f + 0c67d9b commit d8ad8f4

File tree

2 files changed

+102
-12
lines changed

2 files changed

+102
-12
lines changed

packages/commands/src/index.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,18 @@ export class CommandRegistry {
156156
*
157157
* @param id - The id of the command of interest.
158158
*
159+
* @param args - The arguments for the command.
160+
*
159161
* @returns The description for the command.
160162
*/
161-
describedBy(id: string): { args: ReadonlyJSONObject | null } {
163+
describedBy(
164+
id: string,
165+
args: ReadonlyPartialJSONObject = JSONExt.emptyObject
166+
): Promise<CommandRegistry.Description> {
162167
let cmd = this._commands[id];
163-
return cmd?.describedBy ?? { args: null };
168+
return Promise.resolve(
169+
cmd?.describedBy.call(undefined, args) ?? { args: null }
170+
);
164171
}
165172

166173
/**
@@ -671,6 +678,11 @@ export namespace CommandRegistry {
671678
*/
672679
export type Dataset = { readonly [key: string]: string };
673680

681+
/**
682+
* Commands description.
683+
*/
684+
export type Description = { args: ReadonlyJSONObject | null };
685+
674686
/**
675687
* An options object for creating a command.
676688
*
@@ -704,7 +716,9 @@ export namespace CommandRegistry {
704716
* For now, the command arguments are the only one that can be
705717
* described.
706718
*/
707-
describedBy?: { args?: ReadonlyJSONObject };
719+
describedBy?:
720+
| Partial<Description>
721+
| CommandFunc<Partial<Description> | Promise<Partial<Description>>>;
708722

709723
/**
710724
* The label for the command.
@@ -1263,7 +1277,9 @@ namespace Private {
12631277
*/
12641278
export interface ICommand {
12651279
readonly execute: CommandFunc<any>;
1266-
readonly describedBy: { args: ReadonlyJSONObject | null };
1280+
readonly describedBy: CommandFunc<
1281+
CommandRegistry.Description | Promise<CommandRegistry.Description>
1282+
>;
12671283
readonly label: CommandFunc<string>;
12681284
readonly mnemonic: CommandFunc<number>;
12691285
readonly icon: CommandFunc<VirtualElement.IRenderer | undefined>;
@@ -1287,7 +1303,18 @@ namespace Private {
12871303
): ICommand {
12881304
return {
12891305
execute: options.execute,
1290-
describedBy: { args: null, ...options.describedBy },
1306+
describedBy: asFunc<
1307+
CommandRegistry.Description | Promise<CommandRegistry.Description>
1308+
>(
1309+
typeof options.describedBy === 'function'
1310+
? (options.describedBy as CommandFunc<
1311+
CommandRegistry.Description | Promise<CommandRegistry.Description>
1312+
>)
1313+
: { args: null, ...options.describedBy },
1314+
() => {
1315+
return { args: null };
1316+
}
1317+
),
12911318
label: asFunc(options.label, emptyStringFunc),
12921319
mnemonic: asFunc(options.mnemonic, negativeOneFunc),
12931320
icon: asFunc(options.icon, undefinedFunc),

packages/commands/tests/src/index.spec.ts

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { expect } from 'chai';
1212

1313
import { CommandRegistry } from '@lumino/commands';
1414

15-
import { JSONObject } from '@lumino/coreutils';
15+
import { JSONObject, ReadonlyJSONObject } from '@lumino/coreutils';
1616

1717
import { Platform } from '@lumino/domutils';
1818

@@ -329,7 +329,7 @@ describe('@lumino/commands', () => {
329329
});
330330

331331
describe('#describedBy()', () => {
332-
it('should get the description for a specific command', () => {
332+
it('should get the description for a specific command', async () => {
333333
const description = {
334334
args: {
335335
properties: {},
@@ -344,16 +344,79 @@ describe('@lumino/commands', () => {
344344
describedBy: description
345345
};
346346
registry.addCommand('test', cmd);
347-
expect(registry.describedBy('test')).to.deep.equal(description);
347+
expect(await registry.describedBy('test')).to.deep.equal(description);
348348
});
349349

350-
it('should return an empty description if the command is not registered', () => {
351-
expect(registry.describedBy('foo')).to.deep.equal({ args: null });
350+
it('should accept a function', async () => {
351+
const description = {
352+
args: {
353+
properties: {},
354+
additionalProperties: false,
355+
type: 'object'
356+
}
357+
};
358+
359+
let cmd = {
360+
execute: (args: JSONObject) => {
361+
return args;
362+
},
363+
describedBy: () => description
364+
};
365+
registry.addCommand('test', cmd);
366+
expect(await registry.describedBy('test')).to.deep.equal(description);
352367
});
353368

354-
it('should default to an empty description for a command', () => {
369+
it('should accept an asynchronous function', async () => {
370+
const description = {
371+
args: {
372+
properties: {},
373+
additionalProperties: false,
374+
type: 'object'
375+
}
376+
};
377+
378+
let cmd = {
379+
execute: (args: JSONObject) => {
380+
return args;
381+
},
382+
describedBy: () => Promise.resolve(description)
383+
};
384+
registry.addCommand('test', cmd);
385+
expect(await registry.describedBy('test')).to.deep.equal(description);
386+
});
387+
388+
it('should accept args', async () => {
389+
const description = {
390+
properties: {},
391+
additionalProperties: false,
392+
type: 'object'
393+
};
394+
395+
let cmd = {
396+
execute: (args: JSONObject) => {
397+
return args;
398+
},
399+
describedBy: (args: ReadonlyJSONObject) => {
400+
return {
401+
args
402+
};
403+
}
404+
};
405+
registry.addCommand('test', cmd);
406+
expect(
407+
await registry.describedBy('test', description as any)
408+
).to.deep.equal({ args: description });
409+
});
410+
411+
it('should return an empty description if the command is not registered', async () => {
412+
expect(await registry.describedBy('foo')).to.deep.equal({ args: null });
413+
});
414+
415+
it('should default to an empty description for a command', async () => {
355416
registry.addCommand('test', NULL_COMMAND);
356-
expect(registry.describedBy('test')).to.deep.equal({ args: null });
417+
expect(await registry.describedBy('test')).to.deep.equal({
418+
args: null
419+
});
357420
});
358421
});
359422

0 commit comments

Comments
 (0)