|
#!/usr/bin/env node |
|
const { program } = require("commander"); |
|
const { cosmiconfigSync } = require("cosmiconfig"); |
|
const { script } = require("./script"); |
|
import { Options } from "./types"; |
|
const version = "VERSION"; |
|
|
|
/** |
|
* Below is an example of a Node CLI program. |
|
* The program's action function accepts an "options" argument, |
|
* which informs the function's behavior. |
|
* Code comments within the action function specifiy how unit tests |
|
* can be written to ensure that each option is respected correctly. |
|
* -- |
|
* Directory structure: |
|
* src/ |
|
* __tests__ |
|
* - program.test.ts // tests the CLI program options argument unrelated to the script |
|
* - script.test.ts // tests the script unrelated to the CLI program |
|
* - program.ts |
|
* - script.ts |
|
*/ |
|
|
|
// used to grab a config file for the Node CLI program to read from |
|
const explorer = cosmiconfigSync("config"); |
|
|
|
/** |
|
* action |
|
* @param {Name} string |
|
* @param {Org} string |
|
* @param {Options} options |
|
*/ |
|
export function action(name, org, options: Options = {}): void { |
|
/** |
|
* our CLI unit tests should now test the config and that it can be accessed via an option or via cosmiconfig (a config finder) |
|
* if option.config is defined, that should take presedence |
|
* if option.config is defined, it should have x, y, z contents |
|
* if defaultConfig is defined (via cosmiconfig), it should not be an empty object |
|
* if the defaultConfig is defined, it should x,y,z contents |
|
*/ |
|
const { config: defaultConfig = {} } = options?.config |
|
? explorer.load(options.config) |
|
: explorer.search() || {}; |
|
|
|
/** |
|
* our CLI unit tests should now test which urls are loaded |
|
* if option.url is defined, that should take presedence over the defaultConfig.urls or the URLS constant |
|
* if defaultConfig.url is defined, that should take presedence over the URLS constant |
|
*/ |
|
const urls = options?.urls || defaultConfig?.urls || URLS; |
|
|
|
/** |
|
* by exiting via the options.isTestingCLI, |
|
* we should now test the options as listed in the scenerios above |
|
*/ |
|
if (options.isTestingCLI) { |
|
/** |
|
* the console.info log provides a mechanism |
|
* to print stdout (standard output) to the terminal for executed child process |
|
* a tool called stdoutJSON (soon stdoutToJSON) can be used to convert the stdout back the parsable JSON |
|
* https://github.com/yowainwright/stdoutJSON |
|
*/ |
|
console.info({ options, urls, cookies, segmentRequest }); |
|
return; |
|
} |
|
/** |
|
* The script function is tested seperately in separate unit tests in a separate file |
|
* AKA the UI test scenerios above should only test the CLI program's options and config |
|
*/ |
|
script({ options, name, org }); |
|
} |
|
|
|
program |
|
.version(version) |
|
.description("tests cli") |
|
.option("-u, --urls [urls...]", "urls to run scripts on") |
|
.option("-c, --config <config>", "config file to use") |
|
.option("-t, --isTestingCLI", "enables CLI testing, no scripts are run") |
|
.action(action) |
|
.parse(process.argv); |