From d5de0bfe544ce3bddfeec22c7ca20004cdd9a273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Da=C3=9Fler?= Date: Sat, 29 Jun 2024 16:46:39 +0200 Subject: [PATCH] feat(): Implement base test fns for `pm` script. --- log | 10 ++++++ pm | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++---- pm-install | 4 +-- this | 6 ++++ 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/log b/log index e3c9afc..aaa8967 100755 --- a/log +++ b/log @@ -15,6 +15,10 @@ class Log extends This { console.log(str); } + success(str) { + console.log(this._echoInGreen(str)); + } + info(str) { console.log(`[INFO] ${str}`); } @@ -34,6 +38,12 @@ class Log extends This { this.echo(message); }); + this.program.command('success') + .argument('') + .action(message => { + this.success(message); + }); + this.program.command('info') .argument('') .action(message => { diff --git a/pm b/pm index 71ee66d..92b8c10 100755 --- a/pm +++ b/pm @@ -1,7 +1,6 @@ #!/usr/bin/env node const This = require('./this'); -const { Command } = require('commander'); // Example of subcommands which are implemented as stand-alone executable files. // @@ -14,9 +13,25 @@ class Pm extends This { super(); this.version = '0.0.1'; this.description = 'Fake package manager'; + super.init(); // initialize commander with overridden version and description + } - // implement commander abilities - this.program = new Command().name(this.scriptName).version(this.version).description(this.description); + install() { + this.program.command('install [name]', 'install one or more packages').alias('i'); + } + + search() { + this.program.command('search [query]', 'search with optional query').alias('s'); + } + + update() { + this.program.command('update', 'update installed packages', { + executableFile: 'myUpdateSubCommand', + }); + } + + list() { + this.program.command('list', 'list packages installed', { isDefault: false }); } // override This.discovery() @@ -25,12 +40,75 @@ class Pm extends This { return methods; } + // Basic test methods + _testListMethod() { + const pm = new Pm(); + const pmMethods = pm.listMethods(); + + const testMethods = + pmMethods.includes('install') && + pmMethods.includes('search') && + pmMethods.includes('update') && + pmMethods.includes('list') && + pmMethods.includes('discovery') && + pmMethods.includes('start'); + const testInternalMethods = !pmMethods.includes('_testListMethod'); + + console.assert(testMethods, 'Pm.listMethod() failed'); + console.assert( + testInternalMethods, + 'Pm.listMethod() for internal methods failed. Classes with _ should be ignored' + ); + + if (testMethods && testInternalMethods) { + this.execCmd(`${this.workingDir}/log success 'testListMethod passed'`); + } else { + this.execCmd(`${this.workingDir}/log error 'testListMethod failed'`); + } + } + + _testListProperties() { + const pm = new Pm(); + const pmProperties = pm.listProperties(); + + const testProperties = + pmProperties.includes('version') && pmProperties.includes('description') && pmProperties.includes('program'); + console.assert(testProperties, 'Pm.listProperties() failed'); + + if (testProperties) { + this.execCmd(`${this.workingDir}/log success 'testListProperties passed'`); + } else { + this.execCmd(`${this.workingDir}/log error 'testListProperties failed'`); + } + } + + _testGetClassName() { + const pm = new Pm(); + const pmClassName = pm.getClassName(); + + const testClassName = pmClassName === 'Pm'; + console.assert(testClassName, 'Pm.getClassName() failed'); + + if (testClassName) { + this.execCmd(`${this.workingDir}/log success 'testGetClassName passed'`); + } else { + this.execCmd(`${this.workingDir}/log error 'testGetClassName failed'`); + } + } + + selfTest() { + // Run tests + this._testListMethod(); + this._testListProperties(); + this._testGetClassName(); + } + start() { // Usage const pm = new Pm(); - // Output: Methods of ExampleClass: [ 'methodOne', 'methodTwo' ] - // Properties of ExampleClass: [ 'propertyOne', 'propertyTwo', 'version' ] and Version: 1.1.0 - // pm.discovery(); + // Output: Methods of Pm: [ 'methodOne', 'methodTwo' ] + // Properties of Pm: [ 'propertyOne', 'propertyTwo', 'version' ] and Version: 1.1.0 + //pm.discovery(); // this.program // .name(this.scriptName) @@ -70,3 +148,4 @@ const pm = new Pm(); // logDecoratedDiscovery(); pm.start(); +pm.selfTest(); diff --git a/pm-install b/pm-install index 42ec793..acdf0ce 100755 --- a/pm-install +++ b/pm-install @@ -29,8 +29,8 @@ class PmInstall extends This { // Debugging commander options and arguments const opts = util.inspect(this.program.opts(), { depth: null, colors: true, showHidden: true }); const args = util.inspect(this.program.args, { depth: null, colors: true, showHidden: true }); - this.execCmd(`./log echo 'Options: ${opts}'`); - this.execCmd(`./log echo 'Remaining arguments: ${args}'`); + this.execCmd(`${this.workingDir}/log echo 'Options: ${opts}'`); + this.execCmd(`${this.workingDir}/log echo 'Remaining arguments: ${args}'`); } else { this.program.outputHelp(); } diff --git a/this b/this index 5d6dc6f..6147b84 100644 --- a/this +++ b/this @@ -9,6 +9,7 @@ class This { this.version = '0.0.1'; // Default version, can be overridden in subclasses this.description = 'This is the parent class all other scripts should extend.' this.scriptName = path.parse(process.argv[1]).base; + this.workingDir = path.parse(process.argv[1]).dir; } init() { @@ -76,6 +77,11 @@ class This { return `\x1b[33m${str}\x1b[0m`; } + _echoInGreen(str) { + // Add ANSI escape codes to display text in green. + return `\x1b[32m${str}\x1b[0m`; + } + _getCurrentFunctionName() { // Create an Error object (but don't throw it) const err = new Error();