Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions src/prompt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,167 @@
});
expect(result).to.be.true;
});

it("handles non-interactive with default", async () => {
const result = await prompt.confirm({
message: "Continue?",
nonInteractive: true,
default: false,
});
expect(result).to.be.false;
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.confirm({
message: "Continue?",
nonInteractive: true,
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Continue?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("input", () => {
it("handles non-interactive with default", async () => {
const result = await prompt.input({
message: "Name?",
nonInteractive: true,
default: "Inigo Montoya",
});
expect(result).to.equal("Inigo Montoya");
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.input({
message: "Name?",
nonInteractive: true,
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Name?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("checkbox", () => {
it("handles non-interactive with default", async () => {
const result = await prompt.checkbox({
message: "Tools?",
nonInteractive: true,
choices: ["hammer", "wrench", "saw"],
default: ["hammer", "wrench"],
});
expect(result).to.deep.equal(["hammer", "wrench"]);
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.checkbox({
message: "Tools?",
nonInteractive: true,
choices: ["hammer", "wrench", "saw"],
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Tools?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("select", () => {
it("handles non-interactive with default", async () => {
const result = await prompt.select({
message: "Tool?",
nonInteractive: true,
choices: ["hammer", "wrench", "saw"],
default: "wrench",
});
expect(result).to.equal("wrench");
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.select({
message: "Tool?",
nonInteractive: true,
choices: ["hammer", "wrench", "saw"],
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Tool?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("number", () => {
it("handles non-interactive with default", async () => {
const result = await prompt.number({
message: "Count?",
nonInteractive: true,
default: 42,
});
expect(result).to.equal(42);
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.number({
message: "Count?",
nonInteractive: true,
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Count?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("password", () => {
it("throws in non-interactive", async () => {
await expect(
prompt.password({
message: "Password?",
nonInteractive: true,
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Password?" does not have a default and cannot be answered in non-interactive mode',
);
});
});

describe("search", () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const source = (term: string | undefined) => {

Check warning on line 188 in src/prompt.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
Comment on lines +187 to +188
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To avoid using eslint-disable-next-line, you can prefix the unused term parameter with an underscore. This is a common convention to signal that a parameter is intentionally unused and satisfies the linter.

      const source = (_term: string | undefined) => {

return ["a", "b", "c"];
};

it("handles non-interactive with default", async () => {
const result = await prompt.search({
message: "Letter?",
nonInteractive: true,
source,
default: "b",
});
expect(result).to.equal("b");
});

it("throws in non-interactive without default", async () => {
await expect(
prompt.search({
message: "Letter?",
nonInteractive: true,
source,
}),
).to.be.rejectedWith(
FirebaseError,
'Question "Letter?" does not have a default and cannot be answered in non-interactive mode',
);
});
});
Comment on lines +54 to 214
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The tests for different prompt types in non-interactive mode are very similar and contain a lot of duplicated code. This reduces readability and maintainability.

To improve this, consider refactoring to a data-driven approach. You can define an array of test cases and iterate over it to generate the tests dynamically. This will make the test suite more concise and easier to extend.

Here is an example of how you could structure this:

const testCases = [
  {
    name: "confirm",
    promptFn: prompt.confirm,
    message: "Continue?",
    default: false,
    extraOpts: {},
    assertion: (result: boolean) => expect(result).to.be.false,
  },
  {
    name: "input",
    promptFn: prompt.input,
    message: "Name?",
    default: "Inigo Montoya",
    extraOpts: {},
    assertion: (result: string) => expect(result).to.equal("Inigo Montoya"),
  },
  {
    name: "checkbox",
    promptFn: prompt.checkbox,
    message: "Tools?",
    default: ["hammer", "wrench"],
    extraOpts: { choices: ["hammer", "wrench", "saw"] },
    assertion: (result: string[]) => expect(result).to.deep.equal(["hammer", "wrench"]),
  },
  // ... other test cases for select, number, search
];

testCases.forEach(({ name, promptFn, message, default: defaultValue, extraOpts, assertion }) => {
  describe(name, () => {
    it("handles non-interactive with default", async () => {
      const result = await (promptFn as any)({
        message,
        nonInteractive: true,
        default: defaultValue,
        ...extraOpts,
      });
      assertion(result);
    });

    it("throws in non-interactive without default", async () => {
      await expect(
        (promptFn as any)({
          message,
          nonInteractive: true,
          ...extraOpts,
        }),
      ).to.be.rejectedWith(
        FirebaseError,
        `Question "${message}" does not have a default and cannot be answered in non-interactive mode`,
      );
    });
  });
});

// The 'password' prompt is a special case and can be tested separately.
describe("password", () => {
  it("throws in non-interactive", async () => {
    await expect(
      prompt.password({
        message: "Password?",
        nonInteractive: true,
      }),
    ).to.be.rejectedWith(
      FirebaseError,
      'Question "Password?" does not have a default and cannot be answered in non-interactive mode',
    );
  });
});

});
});
Loading