@@ -29,6 +29,7 @@ import {
2929 stringOption ,
3030} from "../lib/common/define-command" ;
3131import {
32+ canExecuteCommand ,
3233 createCommandFromDefinition ,
3334 registerBuiltInCommand ,
3435 registerCommand ,
@@ -1344,6 +1345,128 @@ describe("defineCommand", () => {
13441345 } ) ;
13451346 } ) ;
13461347
1348+ describe ( "canExecuteCommand" , ( ) => {
1349+ const createInProcessInjector = ( ) : IInjector => {
1350+ const testInjector = new Yok ( ) ;
1351+ testInjector . register ( "errors" , {
1352+ beginCommand : async ( action : ( ) => Promise < boolean > ) => action ( ) ,
1353+ failWithHelp : ( message : string ) => {
1354+ throw new Error ( message ) ;
1355+ } ,
1356+ fail : ( message : string ) => {
1357+ throw new Error ( message ) ;
1358+ } ,
1359+ reportCommandError : async ( ex : Error ) => {
1360+ throw ex ;
1361+ } ,
1362+ } ) ;
1363+ testInjector . register ( "hooksService" , HooksServiceStub ) ;
1364+ testInjector . register ( "logger" , LoggerStub ) ;
1365+ testInjector . register ( "staticConfig" , {
1366+ disableAnalytics : true ,
1367+ disableCommandHooks : true ,
1368+ } ) ;
1369+ testInjector . register ( "extensibilityService" , { } ) ;
1370+ testInjector . register ( "optionsTracker" , { } ) ;
1371+ testInjector . register ( "options" , {
1372+ validateOptions : ( ) : void => undefined ,
1373+ } ) ;
1374+ testInjector . register ( "commandsService" , CommandsService ) ;
1375+ return testInjector ;
1376+ } ;
1377+
1378+ it ( "returns the named command's own verdict without running it" , async ( ) => {
1379+ const testInjector = createInProcessInjector ( ) ;
1380+ let ran = false ;
1381+
1382+ runInInjectionContext ( testInjector , ( ) => {
1383+ registerCommand (
1384+ defineCommand ( {
1385+ name : "dctest-can-yes" ,
1386+ arguments : "any" ,
1387+ canExecute : ( context ) => context . args [ 0 ] === "ok" ,
1388+ run : ( ) => {
1389+ ran = true ;
1390+ } ,
1391+ } ) ,
1392+ ) ;
1393+ } ) ;
1394+
1395+ const verdicts = [
1396+ await runInInjectionContext ( testInjector , ( ) =>
1397+ canExecuteCommand ( "dctest-can-yes" , [ "ok" ] ) ,
1398+ ) ,
1399+ await runInInjectionContext ( testInjector , ( ) =>
1400+ canExecuteCommand ( "dctest-can-yes" , [ "nope" ] ) ,
1401+ ) ,
1402+ ] ;
1403+
1404+ assert . deepEqual ( verdicts , [ true , false ] ) ;
1405+ assert . isFalse ( ran ) ;
1406+ } ) ;
1407+
1408+ it ( "enforces the child's arguments policy before its canExecute" , async ( ) => {
1409+ const testInjector = createInProcessInjector ( ) ;
1410+ let consulted = false ;
1411+
1412+ runInInjectionContext ( testInjector , ( ) =>
1413+ registerCommand (
1414+ defineCommand ( {
1415+ name : "dctest-can-none" ,
1416+ canExecute : ( ) => {
1417+ consulted = true ;
1418+ return true ;
1419+ } ,
1420+ run : ( ) : void => undefined ,
1421+ } ) ,
1422+ ) ,
1423+ ) ;
1424+
1425+ await assert . isRejected (
1426+ runInInjectionContext ( testInjector , ( ) =>
1427+ canExecuteCommand ( "dctest-can-none" , [ "stray" ] ) ,
1428+ ) ,
1429+ / d o e s n ' t a c c e p t p a r a m e t e r s / ,
1430+ ) ;
1431+ assert . isFalse ( consulted ) ;
1432+ } ) ;
1433+
1434+ it ( "builds the child's setup from the child's own services" , async ( ) => {
1435+ const testInjector = createInProcessInjector ( ) ;
1436+ testInjector . register ( "gadgetService" , { ready : true } ) ;
1437+
1438+ runInInjectionContext ( testInjector , ( ) =>
1439+ registerCommand (
1440+ defineCommand ( {
1441+ name : "dctest-can-setup" ,
1442+ setup : ( ) => ( {
1443+ $gadgetService : inject < any > ( "gadgetService" ) ,
1444+ } ) ,
1445+ canExecute : ( context , services ) => services . $gadgetService . ready ,
1446+ run : ( ) : void => undefined ,
1447+ } ) ,
1448+ ) ,
1449+ ) ;
1450+
1451+ assert . isTrue (
1452+ await runInInjectionContext ( testInjector , ( ) =>
1453+ canExecuteCommand ( "dctest-can-setup" ) ,
1454+ ) ,
1455+ ) ;
1456+ } ) ;
1457+
1458+ it ( "fails by name for a command that is not registered" , async ( ) => {
1459+ const testInjector = createInProcessInjector ( ) ;
1460+
1461+ await assert . isRejected (
1462+ runInInjectionContext ( testInjector , ( ) =>
1463+ canExecuteCommand ( "dctest-can-missing" ) ,
1464+ ) ,
1465+ / U n k n o w n c o m m a n d ' d c t e s t - c a n - m i s s i n g ' / ,
1466+ ) ;
1467+ } ) ;
1468+ } ) ;
1469+
13471470 describe ( "positional argument specs" , ( ) => {
13481471 const platformCommand = ( extra : any = { } ) =>
13491472 createCommandFromDefinition (
0 commit comments