4

I already asked the question on Jest repository here. And also pushed a sample application here to reproduce the behavior. But for the sake of completeness here's the full story:
Essentially it's like this (./parsers.ts):

import yargs from "yargs";

export const parser = yargs
  .strict(true)
  .help()
  .commandDir("cmds")
  .demandCommand(1)
  .recommendCommands();

And in cmds folder, there's a remote.ts:

import { Argv } from "yargs";

export const command = "remote <command>";
export const describe = "Manage set of tracked repos";
export const handler = (yargs: Argv<any>) => {};
export const builder = (yargs: Argv<any>) => {
  return yargs
    .commandDir("remote_cmds")
    .demandCommand(1, 1)
    .recommendCommands();
};

And then there's add.ts:

import { Argv } from "yargs";

export const command = "add <name> <url>";
export const handler = (yargs: Argv<any>): void => {};
export const describe = "Add remote named <name> for repo at url <url>";
export const builder = (yargs: Argv<any>): Argv => {
  return yargs.demandCommand(0, 0);
};

Now I've got two more files:

// index.ts
import { parser } from "./parsers";
import { Arguments } from "yargs";

parser.parse("remote add foo", (err, argv, output) => {
  console.log("parsed argv: %s", JSON.stringify(argv));
  if (err) console.log("ERROR\n" + err);
  if (output) console.log("OUTPUT\n" + output);
});

When I run this, it fails, rightly so. Because remote add command expects two arguments. And if I pass correct input, it gives correct output. Meaning everything works just fine.

// parsers.test.ts
import { Arguments } from "yargs";
import { parser } from "./parsers";

describe("remote", () => {
  test("add", async () => {
    const argv = parser.parse("remote add foo", (err, argv, output) => {
      console.log(JSON.stringify(argv));
      if (err) console.log("ERROR\n" + err);
      if (output) console.log("OUTPUT\n" + output);
    });
    expect(argv.name).toEqual("foo");
  });
});

Also the Jest configuration is:

module.exports = {
  transform: {
    "^.+\\.ts?$": "ts-jest",
  },
  testEnvironment: "node",
  testRegex: "./src/.*\\.(test|spec)?\\.(ts|ts)$",
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
  roots: ["<rootDir>/src"],
};

But when I run the above test, it doesn't fail at all, as if the parser has no configuration. (The assertion interestingly fails because foo is not extracted as a property into argv which shows, again, the parser didn't pick up the configuration inside cmds folder.)

Not sure if it's a bug or feature; while testing yargs parsers, something is messing with the parser configuration so that, nothing from commands directories gets loaded into the parser.
How can I test my parser using Jest? Thanks.

Rad
  • 4,292
  • 8
  • 33
  • 71

0 Answers0