forcedotcom / cli

Salesforce CLI
https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/
BSD 3-Clause "New" or "Revised" License
493 stars 78 forks source link

[my-command].run() is not a function #2114

Closed pgonzaleznetwork closed 1 year ago

pgonzaleznetwork commented 1 year ago

Summary

I'm creating a sf CLI plugin. I've tested the plugin, and it works as expected.

Now, I'm trying to get my tests to run, but they fail with run() is not a function

Steps To Reproduce:

  1. git clone this repo/branch https://github.com/pgonzaleznetwork/dxfolders-sfplugin/tree/fixTestingStructure
  2. npm install or yarn equivalent to get all dependencies, etc
  3. Run yarn jest-test and you'll see all test pass

The tests are testing the reorderFiles function directly, which the command DxdirArrange at /src/commands/dxdir/arrange is using.

I want to stop testing reorderFiles directly and instead test DxdirArrange.run().

  1. Open the file dxfolders/test/commands/dxdir/arrange.test.ts
  2. Comment out line 34 so that it reads // await reoderFiles();
  3. Uncomment line 35 so that it reads await DxdirArrange.run([]);
  4. Run yarn jest-test again

Expected result

The tests should pass, or at least they shouldn't fail with TypeError: DxdirArrange.run is not a function

I noticed that plugin-deploy-retrieve uses this pattern successfully. You can see on this line that the run method is being called directly.

Why is mine failing?

Actual result

All tests fail with TypeError: DxdirArrange.run is not a function

System Information

zsh 5.8 (x86_64-apple-darwin21.0)

{
  "cliVersion": "@salesforce/cli/1.74.7",
  "architecture": "darwin-x64",
  "nodeVersion": "node-v18.15.0",
  "osVersion": "Darwin 21.0.1",
  "shell": "zsh",
  "rootPath": "/Users/pgonzalez/.local/share/sfdx/client/7.196.7-025f341/sf",
  "pluginVersions": [
    "@oclif/plugin-autocomplete 2.1.8 (core)",
    "@oclif/plugin-commands 2.2.13 (core)",
    "@oclif/plugin-help 5.2.9 (core)",
    "@oclif/plugin-not-found 2.3.23 (core)",
    "@oclif/plugin-plugins 2.4.4 (core)",
    "@oclif/plugin-search 0.0.15 (core)",
    "@oclif/plugin-update 3.1.10 (core)",
    "@oclif/plugin-version 1.3.2 (core)",
    "@oclif/plugin-warn-if-update-available 2.0.33 (core)",
    "@oclif/plugin-which 2.2.18 (core)",
    "@salesforce/cli 1.74.7 (core)",
    "apex 2.2.12 (core)",
    "auth 2.7.12 (core)",
    "data 2.3.10 (core)",
    "deploy-retrieve 1.8.11 (core)",
    "dev 0.7.0 (user)",
    "env 2.1.6 (user)",
    "info 2.6.6 (core)",
    "limits 2.3.12 (core)",
    "login 1.2.5 (core)",
    "org 2.6.10 (core)",
    "schema 2.3.7 (core)",
    "settings 1.4.4 (core)",
    "sobject 0.1.16 (core)",
    "source 2.9.5 (core)",
    "telemetry 2.1.3 (core)",
    "templates 55.4.7 (core)",
    "trust 2.4.7 (core)",
    "user 2.3.8 (core)",
    "dxfolders 0.0.1 (link) /Users/pgonzalez/Documents/apps/sfplugin/dxfolders"
  ]
}

Additional information

Feel free to attach a screenshot.

github-actions[bot] commented 1 year ago

Thank you for filing this issue. We appreciate your feedback and will review the issue as soon as possible. Remember, however, that GitHub isn't a mechanism for receiving support under any agreement or SLA. If you require immediate assistance, contact Salesforce Customer Support.

mshanemc commented 1 year ago

Try updating oclif/core and sf-plugins-core to current versions.

pgonzaleznetwork commented 1 year ago

@mshanemc forgive the ignorance but can you give me exact commands to do that?

mshanemc commented 1 year ago

yarn upgrade @oclif/core@latest @salesforce/sf-plugins-core@latest

pgonzaleznetwork commented 1 year ago

Thanks. I'm still getting the same error. Here's the new sf info after upgrading those packages

{
  "cliVersion": "@salesforce/cli/1.74.7",
  "architecture": "darwin-x64",
  "nodeVersion": "node-v18.15.0",
  "osVersion": "Darwin 21.0.1",
  "shell": "zsh",
  "rootPath": "/Users/pgonzalez/.local/share/sfdx/client/7.196.7-025f341/sf",
  "pluginVersions": [
    "@oclif/plugin-autocomplete 2.1.8 (core)",
    "@oclif/plugin-commands 2.2.13 (core)",
    "@oclif/plugin-help 5.2.9 (core)",
    "@oclif/plugin-not-found 2.3.23 (core)",
    "@oclif/plugin-plugins 2.4.4 (core)",
    "@oclif/plugin-search 0.0.15 (core)",
    "@oclif/plugin-update 3.1.10 (core)",
    "@oclif/plugin-version 1.3.2 (core)",
    "@oclif/plugin-warn-if-update-available 2.0.33 (core)",
    "@oclif/plugin-which 2.2.18 (core)",
    "@salesforce/cli 1.74.7 (core)",
    "apex 2.2.12 (core)",
    "auth 2.7.12 (core)",
    "data 2.3.10 (core)",
    "deploy-retrieve 1.8.11 (core)",
    "dev 0.7.0 (user)",
    "env 2.1.6 (user)",
    "info 2.6.6 (core)",
    "limits 2.3.12 (core)",
    "login 1.2.5 (core)",
    "org 2.6.10 (core)",
    "schema 2.3.7 (core)",
    "settings 1.4.4 (core)",
    "sobject 0.1.16 (core)",
    "source 2.9.5 (core)",
    "telemetry 2.1.3 (core)",
    "templates 55.4.7 (core)",
    "trust 2.4.7 (core)",
    "user 2.3.8 (core)",
    "dxfolders 0.0.1 (link) /Users/pgonzalez/Documents/apps/sfplugin/dxfolders"
  ]
}
mshanemc commented 1 year ago

Thanks. I'm still getting the same error. Here's the new sf info after upgrading those packages

It shouldn't have changed the CLI, but should have changed the package.json in your plugin. (If you didn't run it from inside your plugin repo, sorry I forgot to tell you that)

pgonzaleznetwork commented 1 year ago

I tried again inside the plugin directory. Here's the output

yarn upgrade @oclif/core@latest @salesforce/sf-plugins-core@latest                                                               1 ↡
yarn upgrade v1.22.19
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/5] πŸ”  Validating package.json...
[2/5] πŸ”  Resolving packages...
[3/5] 🚚  Fetching packages...
[4/5] πŸ”—  Linking dependencies...
warning " > ts-node@10.9.1" has unmet peer dependency "@types/node@*".
warning "oclif > yeoman-environment@3.12.1" has unmet peer dependency "mem-fs@^1.2.0 || ^2.0.0".
warning "oclif > yeoman-environment@3.12.1" has unmet peer dependency "mem-fs-editor@^8.1.2 || ^9.0.0".
[5/5] πŸ”¨  Rebuilding all packages...
success Saved lockfile.
success Saved 2 new dependencies.
info Direct dependencies
β”œβ”€ @oclif/core@2.8.5
└─ @salesforce/sf-plugins-core@2.4.2
info All dependencies
β”œβ”€ @oclif/core@2.8.5
└─ @salesforce/sf-plugins-core@2.4.2
✨  Done in 17.03s.
pgonzalez@Pablos-MacBook-Pro:~/Documents/apps/sfplugin/dxfolders(fixTestingStructure⚑)

and the package.json file has been updated to

"dependencies": {
    "@oclif/core": "^2.8.5",
    "@salesforce/core": "^3.33.1",
    "@salesforce/kit": "^1.8.4",
    "@salesforce/sf-plugins-core": "^2.4.2",
    "got": "11.8.5",
    "jest": "^27.5.1",
    "jest-expect-message": "1.1.3",
    "mock-fs": "5.2.0",
    "sfdc-soup": "^18.4.0",
    "tslib": "^2"
  }

I still get TypeError: DxdirArrange.run is not a function

mshanemc commented 1 year ago

coincidentally, I just listened to a podcast discussing this project while mowing my grass this weekend. πŸ˜„

FWIW, we recommend doing what you were doing (testing functions/classes) vs. top-level command tests. We have a lot of top-level command "unit tests" that we've preserved but that's really too high of a level to be testing.

I made a PR to make it easier to see what I did. https://github.com/pgonzaleznetwork/dxfolders-sfplugin/pull/1

If you want to use npm instead of yarn, then the upgrade commands I provided earlier I think have an npm equivalent, and run those in the repo

pgonzaleznetwork commented 1 year ago

@mshanemc thanks! For some reason, I'm getting another error

 could not find package.json with {
      root: '/Users/pgonzalez/Documents/apps/sfplugin/dxfolders/test/commands/dxdir/arrange.test.ts'
    }

      33 |     mock(project);
      34 |     //await reoderFiles();
    > 35 |      await DxdirArrange.run([]);
         |     ^
      36 |   });
      37 |
      38 |   test('Top-level folders are created from prefixes', async () => {

      at Plugin.load (node_modules/@oclif/core/lib/config/plugin.js:114:19)
      at Config.load (node_modules/@oclif/core/lib/config/config.js:90:9)
      at Function.load (node_modules/@oclif/core/lib/config/config.js:83:9)
      at Function.run (node_modules/@oclif/core/lib/command.js:74:24)
      at test/commands/dxdir/arrange.test.ts:35:5

I have the same versions of the cli packages and I changed the import syntax to be exactly what you did on that PR. Thoughts?

mshanemc commented 1 year ago

I think following my suggestions made a mess of your project (running those initial commands not in the project put them into some higher directory, not asking if you were using yarn or npm probably messed up the lockfiles.

I'd try to get back to a good state, then do the bumps and import thing again and see if that helps.

pgonzaleznetwork commented 1 year ago

Sadly, I can't get this to work. I created a new branch from main which I consider to be stable.

I ran yarn upgrade @oclif/core@latest @salesforce/sf-plugins-core@latest and then added the following

import DxdirArrange from '../../../src/commands/dxdir/arrange';

And

beforeAll(async () => {
    mock(project);
    //await reoderFiles();
    await DxdirArrange.run(['--apex-dir', DEFAULT_PATH]);
  });

And again it fails with

could not find package.json with {
      root: '/Users/pgonzalez/Documents/apps/sfplugin/dxfolders/test/commands/dxdir/arrange.test.ts'
    }

      24 |       oExpect(ctx.stdout).to.contain('hello Astro');
      25 |     });
    > 26 | });
         |     ^
      27 |
      28 | describe('All tests', () => {
      29 |   const DEFAULT_PATH = 'force-app/main/default/classes/';

      at Plugin.load (node_modules/@oclif/core/lib/config/plugin.js:114:19)
      at Config.load (node_modules/@oclif/core/lib/config/config.js:90:9)
      at Function.load (node_modules/@oclif/core/lib/config/config.js:83:9)
      at Function.run (node_modules/@oclif/core/lib/command.js:74:24)
      at test/commands/dxdir/arrange.test.ts:26:5

Test Suites: 1 failed, 1 total

Note that the error is no longer run() is not a function which is good I guess, but the error is coming from oclif, not my code.

I'm using Jest with mock-fs which mocks the file system, if that helps.

Can you try reproducing your fix from main?

pgonzaleznetwork commented 1 year ago

@mshanemc I know there are more important bugs but just checking if you had a chance to look at the above. Thanks!

mshanemc commented 1 year ago

I have not, for the reason you mentioned. πŸ˜„ That node 18.16 bug was quite a goose chase.

mshanemc commented 1 year ago

Glad we got to connect at DF and hear that you got all this sorted.