Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add execInteractiveCmd #294

Merged
merged 12 commits into from
Sep 27, 2022
Merged

Conversation

mdonnalley
Copy link
Contributor

@mdonnalley mdonnalley commented Sep 20, 2022

Adds execInteractiveCmd for executing interactive commands in NUTs

Usage

import * as path from 'path';
import { TestSession, execInteractiveCmd, Interaction } from '@salesforce/cli-plugins-testkit';
import { env } from '@salesforce/kit';

describe('dev generate plugin NUTs', () => {
  let session: TestSession;

  before(async () => {
    env.setString('TESTKIT_EXECUTABLE_PATH', path.join(process.cwd(), 'bin', 'dev'));
    session = await TestSession.create({});
  });

  after(async () => {
    await session?.clean();
  });

  it('should do interactive things', async () => {
    const result = await execInteractiveCmd(
      'dev generate plugin',
      {
        // these keys are used to match the questions asked
        'internal Salesforce team': Interaction.Yes,
        'name of your new plugin': ['plugin-awesome', Interaction.ENTER],
        'description for your plugin': ['a description', Interaction.ENTER],
        'Select the existing "sf" commands you plan to extend': [
          Interaction.SELECT,
          Interaction.DOWN,
          Interaction.SELECT,
          Interaction.ENTER,
        ],
      },
      { cwd: session.dir, ensureExitCode: 0 }
    );
  });
});

@W-11787546@

@mdonnalley mdonnalley self-assigned this Sep 20, 2022
Copy link
Contributor

@peternhale peternhale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion

src/execCmd.ts Outdated
@@ -303,3 +303,125 @@ export function execCmd<T = Collection>(
}
}
}

function toString(arrOrString: string | string[]): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function toString(arrOrString: string | string[]): string {
function toString(arrOrString: Many<string>): string {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooh, Many is an unfortunate name for that

return arrOrString;
}

function toArray(arrOrString: Many<string>): string[] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ensureArray from kit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensureArray throws an error if the provided value isn't an array, which isn't what I'm doing here

@mshanemc
Copy link
Contributor

QA Notes:

❓ I think this should accept a type await execInteractiveCmd<MyResultType>() for consistency with the other execs and to make it more TS friendly. Unless we decided that interactive commands can never have json (even some of the confirmation prompt stuff might benefit)

👎🏻 execCmd (non-interactive) doesn't require you to pass in cwd--it runs by default in the project dir. I don't want this one to behave so differently (and your example uses session.dir instead of session.project.dir)

  • I get that some commands like the dev/generate need to run from outside a project, but I'm guessing most interactive commands will be project related?

unrelated to this PR, but probably related to oclif parser changes for multiple?

    icon: Flags.integer({
      char: 'i',
      required: true,
      min: 1,
      max: 100,
      default: 1,
      summary: messages.getMessage('flags.icon.summary'),
      description: messages.getMessage('flags.icon.description'),
    }),
  };

  public async run(): Promise<GenerateTabResult> {
    const { flags } = await this.parse(GenerateTab);
    const tabPath = path.join(flags.directory, `${flags.object}.tab-meta.xml`);

    const tab: GenerateTabResult['tab'] = {
      customObject: true,
      motif: tabDefs.find((tabDef) => tabDef.includes(`Custom${flags.icon}:`)),

Invalid type "number | number[]" of template literal expression.

@mdonnalley
Copy link
Contributor Author

@mshanemc I don't think it's possible to put a type on the return. The prompts go to stdout which makes parsing JSON impossible

@mshanemc mshanemc merged commit 6ddd4d6 into main Sep 27, 2022
@mshanemc mshanemc deleted the mdonnalley/test-interactive-cmds branch September 27, 2022 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants