diff --git a/README.md b/README.md index 18c9babc..170ac140 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ To get started: fauna login ``` -4. Run CLI commands. Specify a `--database` path, including the [Region Group - identifier](https://docs.fauna.com/fauna/current/manage/region-groups/#id) and +4. Run CLI commands. Specify a `--database`, including the [Region + Group](https://docs.fauna.com/fauna/current/manage/region-groups/#id) and hierarchy, to run the command in. For example: ```shell diff --git a/src/cli.mjs b/src/cli.mjs index 4b9d9e44..9a068cb1 100644 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -122,7 +122,7 @@ function buildYargs(argvInput) { .strictCommands(true) .completion( "completion", - "Output bash/zsh script to enable shell completions. See command output for installation instructions.", + "Output a bash/zsh script for CLI auto-completions. See command output for installation instructions.", async function (currentWord, argv, defaultCompletions, done) { // this is pretty hard to debug - if you need to, run // `fauna --get-yargs-completions ` @@ -163,8 +163,7 @@ function buildYargs(argvInput) { ) .options({ color: { - description: - "Enable color formatting for the output. Uses ANSI escape codes. Enabled by default if supported by the terminal. Use `--no-color` or `--color=false` to disable.", + description: "Enable color formatting. Use --no-color to disable.", type: "boolean", // https://github.com/chalk/chalk?tab=readme-ov-file#chalklevel default: chalk.level > 0, @@ -173,15 +172,14 @@ function buildYargs(argvInput) { config: { type: "string", description: - "Path to a CLI config file to use. Use `--profile` to select a profile from the file.", + "Path to a CLI config file to use. If provided, you must specify a profile.", default: ".", group: "Config:", }, profile: { alias: "p", type: "string", - description: - "Profile from the CLI config file to use. Each profile specifies a set of CLI settings. Defaults to the 'default' profile when a config file is provided.", + description: "Profile from the CLI config file to use.", group: "Config:", }, json: { @@ -193,21 +191,21 @@ function buildYargs(argvInput) { quiet: { type: "boolean", description: - "Only output the results of the command. Useful for scripts, CI/CD, and automation workflows.", + "Suppress all log messages except fatal errors. Overrides --verbosity and --verbose-component.", default: false, group: "Output:", }, "verbose-component": { description: - "Components to emit diagnostic logs for. Takes precedence over the `--verbosity` flag. Pass components as a space-separated list, such as `--verbose-component fetch error`, or as separate flags, such as `--verbose-component fetch --verbose-component error`.", + "Components to emit logs for. Overrides the --verbosity flag. Pass values as a space-separated list. Ex: --verbose-component fetch error.", type: "array", default: [], - choices: ["fetch", "error", "config", "argv", "creds", "completion"], + choices: ["argv", "completion", "config", "creds", "error", "fetch"], group: "Debug:", }, verbosity: { description: - "Maximum verbosity level for log messages. Accepts 1 (fatal) to 5 (debug). Lower values represent more critical logs.", + "Least critical log level to emit. Accepts 1 (fatal) to 5 (debug). Lower values represent more critical logs.", type: "number", default: 0, group: "Debug:", diff --git a/src/commands/database/create.mjs b/src/commands/database/create.mjs index c15fe5e2..42c6cb93 100644 --- a/src/commands/database/create.mjs +++ b/src/commands/database/create.mjs @@ -80,7 +80,7 @@ function buildCreateCommand(yargs) { name: { type: "string", required: true, - description: "Name of the child database to create.", + description: "Name of the database to create.", }, typechecked: { type: "boolean", @@ -100,19 +100,23 @@ function buildCreateCommand(yargs) { .check(validateDatabaseOrSecret) .example([ [ - "$0 database create --name my_database --database us/example", - "Create a database named 'my_database' directly under 'us/example'.", + "$0 database create --name example --database us", + "Create the top-level 'example' database in the 'us' Region Group.", ], [ - "$0 database create --name my_database --secret my-secret", - "Create a database named 'my_database' directly under the database scoped to a secret.", + "$0 database create --name my_db --database us/example", + "Create the 'my_db' child database directly under 'us/example'.", ], [ - "$0 database create --name my_database --database us/example --typechecked", + "$0 database create --name my_db --secret my-secret", + "Create the 'my_db' child database directly under the database scoped to a secret.", + ], + [ + "$0 database create --name example --database us --typechecked", "Create a database with typechecking enabled.", ], [ - "$0 database create --name my_database --database us/example --protected", + "$0 database create --name example --database us --protected", "Create a database with protected mode enabled.", ], ]); @@ -120,7 +124,7 @@ function buildCreateCommand(yargs) { export default { command: "create", - description: "Create a child database.", + description: "Create a database.", builder: buildCreateCommand, handler: createDatabase, }; diff --git a/src/commands/database/delete.mjs b/src/commands/database/delete.mjs index 6d8e34b4..07293101 100644 --- a/src/commands/database/delete.mjs +++ b/src/commands/database/delete.mjs @@ -56,19 +56,23 @@ function buildDeleteCommand(yargs) { .check(validateDatabaseOrSecret) .example([ [ - "$0 database delete --name my_database --database us/example", - "Delete a database named 'my_database' directly under 'us/example'.", + "$0 database delete --name example --database us", + "Delete the top-level 'example' database in the 'us' Region Group.", ], [ - "$0 database delete --name my_database --secret my-secret", - "Delete a database named 'my_database' directly under the database scoped to a secret.", + "$0 database delete --name my_db --database us/example", + "Delete the 'my_db' child database directly under 'us/example'.", + ], + [ + "$0 database delete --name my_db --secret my-secret", + "Delete the 'my_db' child database directly under the database scoped to a secret.", ], ]); } export default { command: "delete", - description: "Delete a child database.", + description: "Delete a database.", builder: buildDeleteCommand, handler: deleteDatabase, }; diff --git a/src/commands/local.mjs b/src/commands/local.mjs index 91df5d0a..3b5b52f9 100644 --- a/src/commands/local.mjs +++ b/src/commands/local.mjs @@ -124,35 +124,35 @@ function buildLocalCommand(yargs) { return yargs .options({ "container-port": { - describe: "The port inside the container Fauna listens on.", + describe: "Port inside the container Fauna listens on.", type: "number", default: 8443, }, "host-port": { describe: - "The port on the host machine mapped to the container's port. This is the port you'll connect to Fauna on.", + "Port on the host machine mapped to the container's port. Clients send requests to Fauna on this port.", type: "number", default: 8443, }, "host-ip": { - describe: `The IP address to bind the container's exposed port on the host.`, + describe: `IP address to bind to the container's exposed port on the host.`, type: "string", default: "0.0.0.0", }, interval: { describe: - "The interval (in milliseconds) between health check attempts. Determines how often the CLI checks if the Fauna container is ready.", + "Interval, in milliseconds, between health check attempts. How often the CLI checks if the container is ready.", type: "number", default: 10000, }, "max-attempts": { describe: - "The maximum number of health check attempts before declaring the start Fauna continer process as failed.", + "Maximum number of health check attempts allowed before container startup fails.", type: "number", default: 100, }, name: { - describe: "The name to give the container.", + describe: "Name for the container.", type: "string", default: "faunadb", }, @@ -162,8 +162,7 @@ function buildLocalCommand(yargs) { default: true, }, database: { - describe: - "The name of a database to create in the container. Omit to create no database.", + describe: "Name of the database to create. Omit to create no database.", type: "string", }, typechecked: { @@ -185,7 +184,7 @@ function buildLocalCommand(yargs) { type: "string", alias: ["dir", "directory"], description: - "Path to a local directory containing `.fsl` files for the database. Valid only if --database is set.", + "Path to a local directory containing .fsl files for the database. Valid only if --database is set.", }, }) .check((argv) => { @@ -218,7 +217,23 @@ function buildLocalCommand(yargs) { ); } return true; - }); + }) + .example([ + ["$0 local", "Start a Fauna container with default name and ports."], + ["$0 local --name local-fauna", "Start a container named 'local-fauna'."], + [ + "$0 local --host-port 123 --container-port 6789", + "Map host port `1234` to container port `6789`.", + ], + [ + "$0 local --database example", + "Start a local Fauna container with the 'example' database.", + ], + [ + "$0 local --database example --dir /path/to/schema/dir", + "Start a local Fauna container with a database with specified schema.", + ], + ]); } export default { diff --git a/src/commands/login.mjs b/src/commands/login.mjs index 610b29d3..df416022 100644 --- a/src/commands/login.mjs +++ b/src/commands/login.mjs @@ -53,7 +53,7 @@ function buildLoginCommand(yargs) { export default { command: "login", - describe: "Log in to Fauna using a web-based browser flow.", + describe: "Log in to Fauna.", builder: buildLoginCommand, handler: doLogin, }; diff --git a/src/commands/query.mjs b/src/commands/query.mjs index 9538af28..50717eef 100644 --- a/src/commands/query.mjs +++ b/src/commands/query.mjs @@ -13,7 +13,6 @@ import { } from "../lib/errors.mjs"; import { formatError, - formatQueryInfo, formatQueryResponse, getSecret, } from "../lib/fauna-client.mjs"; @@ -71,6 +70,7 @@ const resolveInput = (argv) => { }; async function queryCommand(argv) { + const formatQueryInfo = container.resolve("formatQueryInfo"); const logger = container.resolve("logger"); // Run validation here instead of via check for more control over output @@ -152,7 +152,7 @@ function buildQueryCommand(yargs) { return yargsWithCommonConfigurableQueryOptions(yargs) .positional("fql", { type: "string", - description: "FQL query to run. Use `-` to read from stdin.", + description: "FQL query to run. Use - to read from stdin.", }) .nargs("fql", 1) .options({ diff --git a/src/commands/schema/abandon.mjs b/src/commands/schema/abandon.mjs index 835abcd2..c4304cc5 100644 --- a/src/commands/schema/abandon.mjs +++ b/src/commands/schema/abandon.mjs @@ -68,8 +68,7 @@ function buildAbandonCommand(yargs) { return yargsWithCommonQueryOptions(yargs) .options({ input: { - description: - "Prompt for input, such as confirmation. To disable prompts, use `--no-input` or `--input=false`. Disabled prompts are useful for scripts, CI/CD, and automation workflows.", + description: "Prompt for input. Use --no-input to disable.", default: true, type: "boolean", }, diff --git a/src/commands/schema/commit.mjs b/src/commands/schema/commit.mjs index 01132fab..0bf93eed 100644 --- a/src/commands/schema/commit.mjs +++ b/src/commands/schema/commit.mjs @@ -72,8 +72,7 @@ function buildCommitCommand(yargs) { return yargsWithCommonQueryOptions(yargs) .options({ input: { - description: - "Prompt for input, such as confirmation. To disable prompts, use `--no-input` or `--input=false`. Disabled prompts are useful for scripts, CI/CD, and automation workflows.", + description: "Prompt for input. Use --no-input to disable.", default: true, type: "boolean", }, diff --git a/src/commands/schema/diff.mjs b/src/commands/schema/diff.mjs index 10c4ead7..572846c5 100644 --- a/src/commands/schema/diff.mjs +++ b/src/commands/schema/diff.mjs @@ -132,23 +132,23 @@ function buildDiffCommand(yargs) { }) .example([ [ - "$0 schema diff --database us/example --dir /path/to/schema", + "$0 schema diff --database us/example --dir /path/to/schema/dir", "Compare the 'us/example' database's staged schema to the local schema. If no schema is staged, compare the database's active schema to the local schema.", ], [ - "$0 schema diff --database us/example --dir /path/to/schema --active", + "$0 schema diff --database us/example --dir /path/to/schema/dir --active", "Compare the 'us/example' database's active schema to the local schema.", ], [ - "$0 schema diff --secret my-secret --dir /path/to/schema --active", + "$0 schema diff --secret my-secret --dir /path/to/schema/dir --active", "Compare the active schema of the database scoped to a secret to the local schema.", ], [ - "$0 schema diff --database us/example --dir /path/to/schema --staged", + "$0 schema diff --database us/example --dir /path/to/schema/dir --staged", "Compare the 'us/example' database's active schema to its staged schema.", ], [ - "$0 schema diff --database us/example --dir /path/to/schema --text", + "$0 schema diff --database us/example --dir /path/to/schema/dir --text", "Show a text diff instead of a semantic diff.", ], ]); diff --git a/src/commands/schema/pull.mjs b/src/commands/schema/pull.mjs index e8ca6c66..a9ca1c43 100644 --- a/src/commands/schema/pull.mjs +++ b/src/commands/schema/pull.mjs @@ -152,20 +152,20 @@ function buildPullCommand(yargs) { }) .example([ [ - "$0 schema pull --database us/example --dir /path/to/schema", + "$0 schema pull --database us/example --dir /path/to/schema/dir", "Pull the 'us/example' database's staged schema.", ], [ - "$0 schema pull --secret my-secret --dir /path/to/schema", + "$0 schema pull --secret my-secret --dir /path/to/schema/dir", "Pull the staged schema for the database scoped to a secret.", ], [ - "$0 schema pull --database us/example --dir /path/to/schema --active", + "$0 schema pull --database us/example --dir /path/to/schema/dir --active", "Pull the 'us/example' database's active schema.", ], [ - "$0 schema pull --database us/example --dir /path/to/schema --delete", - "Delete `.fsl` files in the local directory that are not part of the pulled schema.", + "$0 schema pull --database us/example --dir /path/to/schema/dir --delete", + "Delete .fsl files in the local directory that are not part of the pulled schema.", ], ]); } diff --git a/src/commands/schema/push.mjs b/src/commands/schema/push.mjs index e87ec3bf..2b07c5f7 100644 --- a/src/commands/schema/push.mjs +++ b/src/commands/schema/push.mjs @@ -101,14 +101,13 @@ function buildPushCommand(yargs) { return yargsWithCommonQueryOptions(yargs) .options({ input: { - description: - "Prompt for input, such as confirmation. To disable prompts, use `--no-input` or `--input=false`. Disabled prompts are useful for scripts, CI/CD, and automation workflows.", + description: "Prompt for input. Use --no-input to disable.", default: true, type: "boolean", }, active: { description: - "Immediately apply the local schema to the database's active schema. Skips staging the schema. Can result in temporarily unavailable indexes.", + "Apply the local schema to the database's active schema. Can result in temporarily unavailable indexes.", type: "boolean", default: false, }, @@ -116,19 +115,19 @@ function buildPushCommand(yargs) { }) .example([ [ - "$0 schema push --database us/example --dir /path/to/schema", + "$0 schema push --database us/example --dir /path/to/schema/dir", "Stage schema changes for the 'us/example' database. If schema is already staged, replace the staged schema.", ], [ - "$0 schema push --secret my-secret --dir /path/to/schema", + "$0 schema push --secret my-secret --dir /path/to/schema/dir", "Stage schema changes for the database scoped to a secret. If schema is already staged, replace the staged schema.", ], [ - "$0 schema push --database us/example --dir /path/to/schema --active", + "$0 schema push --database us/example --dir /path/to/schema/dir --active", "Immediately apply changes to the 'us/example' database's active schema.", ], [ - "$0 schema push --database us/example --dir /path/to/schema --no-input", + "$0 schema push --database us/example --dir /path/to/schema/dir --no-input", "Run the command without input prompts.", ], ]); diff --git a/src/commands/schema/schema.mjs b/src/commands/schema/schema.mjs index e2d22dda..74f8488d 100644 --- a/src/commands/schema/schema.mjs +++ b/src/commands/schema/schema.mjs @@ -13,7 +13,7 @@ export const localSchemaOptions = { alias: ["directory", "dir"], type: "string", description: - "Path to a local directory containing `.fsl` files for the database.", + "Path to a local directory containing .fsl files for the database.", default: ".", }, }; diff --git a/src/commands/shell.mjs b/src/commands/shell.mjs index 2f338414..549dd4f9 100644 --- a/src/commands/shell.mjs +++ b/src/commands/shell.mjs @@ -12,11 +12,7 @@ import { validateDatabaseOrSecret, yargsWithCommonConfigurableQueryOptions, } from "../lib/command-helpers.mjs"; -import { - formatQueryInfo, - formatQueryResponse, - getSecret, -} from "../lib/fauna-client.mjs"; +import { formatQueryResponse, getSecret } from "../lib/fauna-client.mjs"; import { clearHistoryStorage, initHistoryStorage } from "../lib/file-util.mjs"; async function shellCommand(argv) { @@ -118,7 +114,7 @@ async function shellCommand(argv) { }, { cmd: "toggleInfo", - help: "Enable or disable the query info fields of the API response. Disabled by default. If enabled, outputs the included fields of the API response.", + help: "Enable or disable output of --include info. Disabled by default.", action: () => { shell.context.include = shell.context.include.length === 0 @@ -150,8 +146,9 @@ const getArgvOrCtx = (key, argv, ctx) => { // caches the logger, client, and performQuery for subsequent shell calls async function buildCustomEval(argv) { - const runQueryFromString = container.resolve("runQueryFromString"); const formatError = container.resolve("formatError"); + const formatQueryInfo = container.resolve("formatQueryInfo"); + const runQueryFromString = container.resolve("runQueryFromString"); return async (cmd, ctx, _filename, cb) => { try { diff --git a/src/config/setup-container.mjs b/src/config/setup-container.mjs index e9d14a60..600ffffe 100644 --- a/src/config/setup-container.mjs +++ b/src/config/setup-container.mjs @@ -22,6 +22,7 @@ import { makeRetryableFaunaRequest } from "../lib/db.mjs"; import * as faunaV10 from "../lib/fauna.mjs"; import { formatError, + formatQueryInfo, isQueryable, runQueryFromString, } from "../lib/fauna-client.mjs"; @@ -98,6 +99,7 @@ export const injectables = { // utilities for interacting with Fauna runQueryFromString: awilix.asValue(runQueryFromString), formatError: awilix.asValue(formatError), + formatQueryInfo: awilix.asValue(formatQueryInfo), faunaClientV10: awilix.asValue(faunaV10), faunaClientV4: awilix.asValue(faunaV4), isQueryable: awilix.asValue(isQueryable), diff --git a/src/config/setup-test-container.mjs b/src/config/setup-test-container.mjs index 426863bf..aa33630b 100644 --- a/src/config/setup-test-container.mjs +++ b/src/config/setup-test-container.mjs @@ -11,6 +11,7 @@ import { f, InMemoryWritableStream } from "../../test/helpers.mjs"; import { parseYargs } from "../cli.mjs"; import { makeRetryableFaunaRequest } from "../lib/db.mjs"; import * as faunaClientV10 from "../lib/fauna.mjs"; +import { formatQueryInfo } from "../lib/fauna-client.mjs"; import * as faunaClientV4 from "../lib/faunadb.mjs"; import buildLogger from "../lib/logger.mjs"; import { injectables, setupCommonContainer } from "./setup-container.mjs"; @@ -106,6 +107,7 @@ export function setupTestContainer() { runQueryFromString: awilix.asValue(stub().resolves({})), isQueryable: awilix.asValue(stub().resolves()), formatError: awilix.asValue(stub()), + formatQueryInfo: awilix.asValue(spy(formatQueryInfo)), faunaClientV10: awilix.asValue({ getClient: stub(), runQuery: stub(), diff --git a/src/lib/command-helpers.mjs b/src/lib/command-helpers.mjs index 8d522a08..bd997740 100644 --- a/src/lib/command-helpers.mjs +++ b/src/lib/command-helpers.mjs @@ -32,34 +32,34 @@ const COMMON_QUERY_OPTIONS = { alias: "u", type: "string", description: - "User used to run the command. You must first log in as the user using `fauna login`.", + "CLI user to run the command as. You must first log in as the user using 'fauna login'.", default: "default", group: "API:", }, local: { type: "boolean", describe: - 'Use a local Fauna container. If not otherwise specified, sets `--url` to http://localhost:8443 and `--secret` to "secret".', + "Use a local Fauna container. Sets --url to 'http://0.0.0.0:8443' and --secret to 'secret'.", default: false, group: "API:", }, url: { type: "string", description: - "URL for Fauna Core HTTP API requests made by the command. Defaults to https://db.fauna.com.", + "URL for Core HTTP API requests made by the command. Defaults to https://db.fauna.com.", group: "API:", }, secret: { type: "string", description: - "Authentication secret for Fauna Core HTTP API requests made by the command. Mutually exclusive with `--database` and `--role`.", + "Secret used for authentication. Can't be used with --database or --role.", required: false, group: "API:", }, "account-key": { type: "string", description: - "Fauna account key used for authentication. Negates the need for a user login. The key is used to generate short-lived database secrets for the CLI. Mutually exclusive with `--user` and `--secret`.", + "Fauna account key used for authentication. Can't be used with --user or --secret.", required: false, group: "API:", }, @@ -67,14 +67,13 @@ const COMMON_QUERY_OPTIONS = { alias: "d", type: "string", description: - "Path, including Region Group identifier and hierarchy, for the database to run the command in. Mutually exclusive with `--secret`.", + "Database, including Region Group and hierarchy, to run the command in. Ex: 'us/my_db', 'eu/parent_db/child_db', 'global/db'. Can't be used with --secret.", group: "API:", }, role: { alias: "r", type: "string", - description: - "Role used to run the command. Mutually exclusive with `--secret`.", + description: "Role used to run the command. Can't be used with --secret.", group: "API:", }, }; @@ -118,14 +117,14 @@ const COMMON_CONFIGURABLE_QUERY_OPTIONS = { timeout: { type: "number", description: - "Maximum runtime, in milliseconds, for Fauna Core HTTP API requests made by the command.", + "Maximum query runtime in milliseconds. Only applies to v10 queries.", default: 5000, group: "API:", }, - performanceHints: { + "performance-hints": { type: "boolean", description: - "Output the performance hints for the current query or nothing when no hints are available. Only applies to v10 queries. Sets '--include summary'", + "Output performance hints. Sets --include summary. Only applies to v10 queries. If no performance hints are returned, no hints are output.", default: false, group: "API:", }, @@ -133,7 +132,8 @@ const COMMON_CONFIGURABLE_QUERY_OPTIONS = { type: "array", choices: ["all", "none", ...QUERY_INFO_CHOICES], default: ["summary"], - describe: "Include additional query response data in the output.", + describe: + "Query response info to output. Pass values as a space-separated list. Ex: --include summary queryTags.", }, }; diff --git a/src/lib/docker-containers.mjs b/src/lib/docker-containers.mjs index 23fd99e1..dc8b039c 100644 --- a/src/lib/docker-containers.mjs +++ b/src/lib/docker-containers.mjs @@ -14,7 +14,7 @@ let color = false; * @param {number} options.containerPort The port inside the container Fauna listens on * @param {boolean} options.pull Whether to pull the latest image * @param {number} [options.interval] The interval (in milliseconds) between health check attempts - * @param {number} [options.maxAttempts] The maximum number of health check attempts before declaring the start Fauna continer process as failed + * @param {number} [options.maxAttempts] The maximum number of health check attempts before declaring the start Fauna container process as failed * @returns {Promise} */ export async function ensureContainerRunning({ diff --git a/test/query.mjs b/test/query.mjs index 1c9ca24f..40a54ce2 100644 --- a/test/query.mjs +++ b/test/query.mjs @@ -6,6 +6,7 @@ import sinon from "sinon"; import { run } from "../src/cli.mjs"; import { setupTestContainer as setupContainer } from "../src/config/setup-test-container.mjs"; +import { QUERY_INFO_CHOICES } from "../src/lib/command-helpers.mjs"; import { NETWORK_ERROR_MESSAGE } from "../src/lib/errors.mjs"; import { colorize } from "../src/lib/formatting/colorize.mjs"; import { @@ -309,7 +310,7 @@ describe("query", function () { it("can set the performanceHints option to true", async function () { await run( - `query "Database.all()" --performanceHints --secret=foo`, + `query "Database.all()" --performance-hints --secret=foo`, container, ); expect(runQueryFromString).to.have.been.calledWith( @@ -320,66 +321,91 @@ describe("query", function () { ); }); - // Add FormatQueryInfo to container in order to test which options are were passed - it.skip("can set the include option to an array"); - it.skip("can specify '--include all' to set all include options"); - it.skip("can specify '--include none' to set no include options"); + describe("query info", function () { + it("displays summary by default", async function () { + runQueryFromString.resolves({ + summary: "info at *query*:1: hello world", + data: "fql", + }); - it("displays summary by default", async function () { - runQueryFromString.resolves({ - summary: "info at *query*:1: hello world", - data: "fql", + await run( + `query "Database.all()" --performance-hints --secret=foo`, + container, + ); + + expect(logger.stderr).to.have.been.calledWith( + sinon.match(/hello world/), + ); + expect(container.resolve("codeToAnsi")).to.have.been.calledWith( + sinon.match(/hello world/), + "yaml", + ); + expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); }); - await run( - `query "Database.all()" --performanceHints --secret=foo`, - container, - ); + it("still displays performance hints if '--include none' is used", async function () { + runQueryFromString.resolves({ + summary: + "performance_hint: use a more efficient query\n1 | use a more efficient query", + data: "fql", + }); - expect(logger.stderr).to.have.been.calledWith(sinon.match(/hello world/)); - expect(container.resolve("codeToAnsi")).to.have.been.calledWith( - sinon.match(/hello world/), - "yaml", - ); - expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); - }); + await run( + `query "Database.all()" --performance-hints --secret=foo --include none`, + container, + ); - it("still displays performance hints if '--include none' is used", async function () { - runQueryFromString.resolves({ - summary: - "performance_hint: use a more efficient query\n1 | use a more efficient query", - data: "fql", + expect(logger.stderr).to.have.been.calledWith( + sinon.match(/use a more efficient query/), + ); + expect(container.resolve("codeToAnsi")).to.have.been.calledWith( + sinon.match(/use a more efficient query/), + "fql", + ); + expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); }); - await run( - `query "Database.all()" --performanceHints --secret=foo --include none`, - container, - ); + it("does not display anything if info fields are empty", async function () { + runQueryFromString.resolves({ + txn_ts: "", + schema_version: "", + summary: "", + query_tags: "", + stats: "", + data: "fql", + }); - expect(logger.stderr).to.have.been.calledWith( - sinon.match(/use a more efficient query/), - ); - expect(container.resolve("codeToAnsi")).to.have.been.calledWith( - sinon.match(/use a more efficient query/), - "fql", - ); - expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); - }); + await run(`query "test" --secret=foo --include all`, container); - it("does not display anything if info fields are empty", async function () { - runQueryFromString.resolves({ - txnTs: "", - schemaVersion: "", - summary: "", - queryTags: "", - stats: "", - data: "fql", + expect(logger.stderr).to.not.be.called; + expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); }); - await run(`query "Database.all()" --secret=foo --include all`, container); - - expect(logger.stderr).to.not.be.called; - expect(logger.stdout).to.have.been.calledWith(sinon.match(/fql/)); + QUERY_INFO_CHOICES.forEach((choice) => { + it(`displays ${choice} if '--include ${choice}' is used, but not others`, async function () { + runQueryFromString.resolves({ + txn_ts: "foo", + schema_version: "foo", + summary: "foo", + query_tags: "foo", + stats: "foo", + data: "fql", + }); + + await run(`query "test" --secret=foo --include ${choice}`, container); + + expect(logger.stderr).to.have.been.calledWith( + sinon.match(new RegExp(`${choice}:`)), + ); + + const ignoredChoices = QUERY_INFO_CHOICES.filter((o) => o !== choice); + for (const ignored of ignoredChoices) { + expect(logger.stderr).to.not.have.been.calledWith( + sinon.match(new RegExp(`${ignored}:`)), + ); + } + }); + }); }); it("can handle network errors", async function () { diff --git a/test/shell.mjs b/test/shell.mjs index f30959c6..22acfc17 100644 --- a/test/shell.mjs +++ b/test/shell.mjs @@ -364,7 +364,7 @@ describe("shell", function () { }); const runPromise = run( - `shell --secret "secret" --performanceHints --no-color --format json`, + `shell --secret "secret" --performance-hints --no-color --format json`, container, );