From 728584f6714d7affcc2386e9fce952ad502e9013 Mon Sep 17 00:00:00 2001 From: Fernando Martin Garcia Del Angel Date: Sat, 19 Oct 2019 19:34:10 -0500 Subject: [PATCH] Changed quack behaviour and added Object Creator It's possible to quack the name of the function that was called or quack without any message. it's now possible to create new objects for test purposes --- index.js | 236 +++++++++++++++++++++++++++++++++++---------- package-lock.json | 54 +++++++++++ package.json | 2 + test.js | 45 +++++---- utilities/utils.js | 50 ---------- 5 files changed, 271 insertions(+), 116 deletions(-) delete mode 100644 utilities/utils.js diff --git a/index.js b/index.js index cecfc36..b62d5d4 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ - - + + // ,---, ,-. // .' .' `\ ,--/ /| // ,---.' \ ,--, ,--. :/ | __ ,-. @@ -16,21 +16,31 @@ // Built by: Fernando Martin Garcia Del Angel // Built because I was bored +/** + * Libraries to use + */ const StackTrace = require('stacktrace-js') -const utils = require('./utilities/utils') +const clone = require('clone') +const faker = require('faker') +const chalk = require('chalk') + +/** + * Quack + */ const QUACK = '🦆 {Quack}' /** * Quacks! - * @param {string} group Counts from a custom group + * @param {string} word Word or Group to be Quacked * @param {boolean} debug Prints the stack or not * @param {number} level Number of leves of stack to print * @param {boolean} detailed Prints the complete stack trace */ -function quack(group = QUACK, debug = false, level = 2, detailed = false) { - console.count(group) - if(debug) { - printStack(level,detailed) +function quack(word = '', debug = false, level = 2, detailed = false) { + var stack = StackTrace.getSync() + console.log(QUACK+' > '+(!word ? quack.caller.name : word)) + if (debug) { + printStack(level, detailed) } } @@ -39,18 +49,20 @@ function quack(group = QUACK, debug = false, level = 2, detailed = false) { * @param {number} level level of depth to print on the stack * @param {boolean} detailed prints the source or not */ -function printStack(level,detailed) { - var stack = StackTrace.getSync().slice(0,level) - for(var i = 0; i < stack.length; i++) { - stack[i] = utils.renameKeys(stack[i],{ - columnNumber: 'column', - lineNumber: 'line', - }) - if (!detailed) { - delete stack[i].source +function printStack(level, detailed) { + if (level) { + var stack = StackTrace.getSync().slice(0, level) + for (var i = 0; i < stack.length; i++) { + stack[i] = rename(stack[i], { + columnNumber: 'column', + lineNumber: 'line', + }) + if (!detailed) { + delete stack[i].source + } } + console.table(stack) } - console.table(stack) } /** @@ -60,26 +72,26 @@ function printStack(level,detailed) { function check(value) { console.log(QUACK) let type = '' - console.log('This value is of type %s',typeof value) + console.log('This value is of type %s', typeof value) console.group() - switch(typeof value) { - case 'number' : - console.log('-> Its value is %f',value) + switch (typeof value) { + case 'number': + console.log('-> Its value is %f', value) break - case 'object' : - if(utils.isEmpty(value)) { + case 'object': + if (isEmpty(value)) { console.log('-> Its value is empty') } else { if (value[0] == undefined) { - categorizer(value) + console.table(xray(value)) } else { console.log('-> Array type. First value structure:') - categorizer(value[0]) + console.table(xray(value[0])) } } break - case 'boolean' : - console.log('-> Its value is %s',value == null ? 'null' : value.toString()) + case 'boolean': + console.log('-> Its value is %s', value == null ? 'null' : value.toString()) } console.groupEnd() } @@ -107,50 +119,172 @@ function stop(group = QUACK) { * @param {any} expectedResult Expected result * @param {boolean} debug Flag to determine if the stack should be printed * @param {number} level Level of detail of the stack - * @param {flag} detailed Flag to determine if all data from the stack should be printed + * @param {flag} detailed Flag to determine if all data from the stack should be printed */ -async function test(testable,args,expectedResult, debug = false, level = 3, detailed = false) { +async function test(testable, args, expectedResult, debug = false, level = 3, detailed = false) { console.log(QUACK) - console.log('Function name: '+testable.name) + console.log('Function name: ' + testable.name) console.group('--Result') let result - switch(testable.constructor.name) { - case 'Function' : + switch (testable.constructor.name) { + case 'Function': result = testable(...args) - console.log('Function Result: '+result) - console.log('Expected Result: '+expectedResult) + console.log('Function Result: ' + result) + console.log('Expected Result: ' + expectedResult) console.log(result === expectedResult ? 'Test successful!' : 'Test failed!') break - case 'AsyncFunction' : + case 'AsyncFunction': result = await testable(...args) - console.log('Function Result: '+result) - console.log('Expected Result: '+expectedResult) + console.log('Function Result: ' + result) + console.log('Expected Result: ' + expectedResult) console.log(result === expectedResult ? 'Test successful!' : 'Test failed!') break - default : + default: console.log('dedault') break } - if(debug) { - printStack(level,detailed) + if (debug) { + printStack(level, detailed) } console.groupEnd('--Result') } /** - * Categorizes JSON elements - * @param {Object} obj Object element + * Renames the keys of a given object + * @param {Object} object Object whose keys will be changed (ex. {'a': 2}) + * @param {Object} changes Object that maps the required changes (ex. {a: 'b'}) => {'b':2 + * @returns {Object} Modified object with the new keys */ -function categorizer(obj) { +function rename(object, changes) { + if (!changes || typeof changes !== 'object') { + return object + } + + if (Array.isArray(object)) { + const newArray = [] + for (var i = 0; i < object.length; i++) { + newArray.push(rename(object[i], changes)) + } + return newArray + } else { + if (typeof object !== 'object') { + return object + } + var copy = clone(object) + + for (var key in changes) { + if (typeof changes[key] === 'object') { + if (copy.hasOwnProperty(key)) { + copy[key] = rename(copy[key], changes[key]) + continue + } + } + + if (copy.hasOwnProperty(key)) { + var temp = copy[key] + copy[changes[key]] = temp + delete copy[key] + } + } + return copy + } +} + +/** + * Checks if an Object is Empty + * @param {Object} obj Object to check for emptyness + * @returns Flag to indicate if it's empty or not + */ +function isEmpty(obj) { + for (var key in obj) { + if (obj.hasOwnProperty(key)) + return false; + } + return true; +} + +/** + * Categorizes JSON Elements into types and values + * @param {Object} obj Object to check + * @returns {Array} Array to be printed or checked + */ +function xray(obj) { var cats = [] for (var key in obj) { cats.push({ - Key : key, - Type : obj[key], - Value : typeof obj[key] + Key: key, + Type: obj[key], + Value: typeof obj[key] }) } - console.table(cats) + return cats +} + +/** + * Generates a random number + * @param {boolean} floating Flag to represent if desired value should be floating + * @param {number} min Minimum value to generate + * @param {number} max Maximum value to generate + * @returns Random number + */ +function random(floating = false, min = 0, max = Number.MAX_SAFE_INTEGER) { + let number = (Math.random() * (max - min)) + min + return !floating ? Math.floor(number) : number +} + +/** + * Generates an Object to use on tests based on a given schema + * @param {Object} schema Schema and Data Type to use on the fake object (ex. {'name':name, 'age':number, 'engaged':boolean}) + * @param {Number} amount Amount of fake Objects to create + * @returns Object with the required fake data + */ +function fake(schema) { + let fak = {} + let card = faker.helpers.contextualCard() + for (var key in schema) { + if (typeof schema[key] == 'object') { + fak[key] = fake(schema[key]) + } else { + switch (schema[key]) { + case 'age': + fak[key] = random(false, 18, 100) + break + case 'job': + fak[key] = faker.name.jobTitle() + break + case 'blood': + var bloodT = ['A', 'B', 'AB', 'O'] + var RH = ['+', '-'] + fak[key] = { 'type': bloodT[random(false, 0, bloodT.length)], 'rh': RH[random(false, 0, RH.length)] } + break + case 'color': + fak[key] = faker.commerce.color() + break + case 'ip' : + fak[key] = faker.internet.ip() + break + case 'password': + fak[key] = faker.internet.password() + break + case 'title' : + fak[key] = faker.name.title + break + case 'word' : + fak[key] = faker.lorem.word() + break + case 'sentence' : + fak[key] = faker.lorem.sentence() + break + case 'paragraphs' : + fak[key] = faker.lorem.paragraphs(3) + break + default : + fak[key] = card[schema[key]] + break + } + } + } + return fak } module.exports = { @@ -158,5 +292,9 @@ module.exports = { check, go, stop, - test + test, + rename, + xray, + random, + fake } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index feec419..ce93f96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,11 +4,42 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, "error-stack-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.4.tgz", @@ -17,6 +48,21 @@ "stackframe": "^1.1.0" } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "source-map": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", @@ -53,6 +99,14 @@ "stack-generator": "^2.0.4", "stacktrace-gps": "^3.0.3" } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } } } } diff --git a/package.json b/package.json index bf05ea7..b0c7cbb 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ }, "homepage": "https://github.com/a01334390/ducker#readme", "dependencies": { + "chalk": "^2.4.2", "clone": "^2.1.2", + "faker": "^4.1.0", "stacktrace-js": "^2.0.1" } } diff --git a/test.js b/test.js index 5cb7803..e058bd6 100644 --- a/test.js +++ b/test.js @@ -1,27 +1,38 @@ const ducker = require('./index') function sum (a,b) { + ducker.quack() return a + b } async function mult (a,b) { + ducker.quack('',true) return await a * b } -ducker.go() - ducker.quack([{ 'a': 1 }, { 'a': 2 }]) - ducker.quack('wow', true) - ducker.check(2) - ducker.check({ 'a': 2, 'b': 4 }) - ducker.check([{ 'a': 2, 'b': 4 }, { 'a': 2, 'b': 4 }]) - ducker.check([]) - ducker.check(false) - ducker.check(null) - ducker.quack() - ducker.quack() - ducker.quack() - ducker.quack() - ducker.test(sum,[1,2],3) - ducker.test(mult,[2,5],3,true) -ducker.stop() - +mult(5,4) +sum(1,2) +// ducker.quack('',true,-1) +// console.log(ducker.random(false,5,6)) +// console.log(ducker.fake({ +// name: 'name', +// email: 'email', +// username: 'username', +// email: 'email', +// address: 'address', +// phone: 'phone', +// website: 'website', +// birthday: 'dob', +// avatar: 'avatar', +// age: 'age', +// type: 'job', +// word: 'word', +// sentence: 'sentence', +// paragraphs: 'paragraphs', +// bloodT: 'blood', +// color: 'color', +// person : { +// name : 'name', +// age: 'age', +// } +// })) \ No newline at end of file diff --git a/utilities/utils.js b/utilities/utils.js deleted file mode 100644 index 38902f7..0000000 --- a/utilities/utils.js +++ /dev/null @@ -1,50 +0,0 @@ -var clone = require('clone') - -function renameKeys(object, changes) { - if (!changes || typeof changes !== 'object') { - return object - } - - if (Array.isArray(object)) { - const newArray = [] - for (var i = 0; i< object.length; i++) { - newArray.push(renameKeys(object[i], changes)) - } - return newArray - } else { - if (typeof object !== 'object') { - return object - } - var copy = clone(object) - - for (var key in changes) { - if (typeof changes[key] === 'object') { - if (copy.hasOwnProperty(key)) { - copy[key] = renameKeys(copy[key], changes[key]) - continue - } - } - - if (copy.hasOwnProperty(key)) { - var temp = copy[key] - - copy[changes[key]] = temp - delete copy[key] - } - } - return copy - } - } - - function isEmpty(obj) { - for(var key in obj) { - if(obj.hasOwnProperty(key)) - return false; - } - return true; -} - - module.exports = { - renameKeys, - isEmpty - } \ No newline at end of file