UNPKG

json-sql-builder

Version:

SQLBuilder to translate JSON dataformat like mongo to SQL

256 lines (221 loc) 8.16 kB
'use strict'; const SQLBuilder = require('./sqlbuilder'); const util = require('util') const colors = require('colors'); const _ = require('lodash'); let errors = []; let TestLogger = function() { this.messages = []; this.errors = []; this.fatal = false; this.success = true; }; TestLogger.prototype.error = function(message, fatal, errStack){ this.success = false; this.messages.push(message); if (fatal) { this.fatal = true; } if (errStack) { this.errors.push(errStack); } } TestLogger.prototype.hasErrors = function(){ return this.errors.length > 0; } TestLogger.prototype.successful = function(){ return this.success; } TestLogger.prototype.failed = function(testPath, sqlDialect, message, fatal, errStack){ if (message) { this.error(message, fatal, errStack); } if (sqlDialect) { console.log(' !! '.bold.red + (sqlDialect + ': ').yellow + testPath); } else { console.log(' !! '.bold.red + testPath); } return this; } TestLogger.prototype.newLine = function(){ this.messages.push(''); } function test(testName, testPath, testCase, supportedBy) { let log = new TestLogger(), result, jSQL; // make the tests for each system described in supportedBy _.forEach(supportedBy, (url, sqlDialect) => { // run test if the there is no specification on test for // supportedBy or if the current sqlDialect is available on the supportedBy option if (!(!testCase.supportedBy || testCase.supportedBy[sqlDialect])) { //skip test for not supported dialects return; } try { jSQL = new SQLBuilder(sqlDialect); // overwrite the Standard-quote function to get $1, $2, $3 ... // like the way the expectedResult will be documented jSQL.placeholder = function(){ // will return $1, $2, ... return '$' + this._values.length; }; jSQL.quoteChar = ''; //jSQL._initBuilder(); result = jSQL.build(testCase.test); } catch (err) { // check for an expected exception if (testCase.expectedResult.exception === err.message) { // this exception is okay -> Test successful done! return; } return log.failed(testPath, sqlDialect, ' ' + 'FATAL-ERROR: '.red + err.message.red, true/*fatal*/, err.stack); } // check the result sql - if we got an valid object if (!_.isPlainObject(result)) { return log.failed(testPath, sqlDialect, ' ' + 'ERROR: result is not an Object!'.red, true); } if (!_.isString(result.sql)) { return log.failed(testPath, sqlDialect, ' ' + 'ERROR: result.sql is not a String!'.red, true); } if (!_.isArray(result.values)) { return log.failed(testPath, sqlDialect, ' ' + 'ERROR: result.values is not an Array!'.red, true); } if (result.sql !== testCase.expectedResult.sql) { log.newLine(); log.error(' ' + (sqlDialect + ': ').yellow + 'SQL Statement failed'.red + '\n'); //log.error(' + expected'.green + ' - actual'.yellow + '\n'); log.error(' -|'.yellow + result.sql.yellow + '|'.yellow); log.error(' +|'.green + testCase.expectedResult.sql.green + '|'.green); } // check length of values equals expected let expectedValues = testCase.expectedResult.values || {}; let arrExpectedValues = Object.keys(expectedValues); if (arrExpectedValues.length !== result.values.length) { log.newLine(); log.error(' ' + (sqlDialect + ': ').yellow + 'Count of Parameters failed'.red + '\n'); log.error(' -'.yellow + (result.values.length+'').yellow + ' +'.green + (arrExpectedValues.length+'').green); } let max = arrExpectedValues.length; if (result.values && result.values.length > max) max = result.values.length; for (let i=0; i<max; i++) { let actualValue = result.values[i]; let expectedValue = expectedValues['$' + (i + 1)]; if (actualValue !== expectedValue){ log.newLine(); log.error(' ' + (sqlDialect + ': ').yellow + ('Parameter ' + (i + 1) + ' does not match').red); log.newLine(); log.error((' $' + (i + 1) + ': -').yellow + (typeof actualValue === typeof undefined ? (actualValue+'').grey : (actualValue+'').yellow)); log.error((' $' + (i + 1) + ': +').green + (typeof expectedValue === typeof undefined ? (expectedValue+'').grey : (expectedValue+'').green)); } } }); if (log.successful()) { console.log(' \u2714 '.green + testPath); // check mark } else { return log.failed(testPath); } return log; } function main() { let loggedTestResults = [] let testPath; let jSQL = new SQLBuilder(); console.log('Testing ...'.bold); // make tests for all helpers registered now _.forEach(jSQL._helpers2, (helper, helperName) => { //if (helperName != '$gt') return; console.log('\n\n ' + helperName.bold + ': ' + helper.description.grey); // iterate each example defined for the helper _.forEach(helper.examples, (examplesByType, typeName) => { console.log(' as ' + typeName); if (examplesByType.eachItemOf) { _.forEach(examplesByType.eachItemOf, (eachItemTypeTests, itemType)=>{ // check for value-based syntaxt and Tests if (eachItemTypeTests.basicUsage) { _.forEach(eachItemTypeTests, (testCase, testName) => { testPath = 'with an Item of Type '.grey + (itemType+'').grey + ' > '.grey + testName.replace('basicUsage', 'Basic Usage').grey; //process.stdout.write(' ' + testPath); loggedTestResults.push({ helper: helper, testPath: helperName + ' as ' + typeName + ' ' + testPath, testResult: test(testName, testPath, testCase, helper.supportedBy), }); }); } else { // value-based tests: _.forEach(eachItemTypeTests, (valueTests, value) => { _.forEach(valueTests, (testCase, testName) => { testPath = 'with an Item of Type '.grey + (itemType+'').grey + ' which has the value '.grey + (value+'').grey + ' > '.grey + testName.replace('basicUsage', 'Basic Usage').grey; //process.stdout.write(' ' + testPath); loggedTestResults.push({ helper: helper, testPath: helperName + ' as ' + typeName + ' ' + testPath, testResult: test(testName, testPath, testCase, helper.supportedBy), }); }); }); } }); } else { // check for a value-base syntax if (!_.isPlainObject(examplesByType.basicUsage)) { // value-based tests: _.forEach(examplesByType, (valueTests, value) => { _.forEach(valueTests, (testCase, testName) => { testPath = ' which has the value '.grey + (value+'').grey + ' > '.grey + testName.replace('basicUsage', 'Basic Usage').grey; loggedTestResults.push({ helper: helper, testPath: helperName + ' as ' + typeName + ' ' + testPath, testResult: test(testName, testPath, testCase, helper.supportedBy), }); }); }); } else { _.forEach(examplesByType, (testCase, testName) => { testPath = testName.replace('basicUsage', 'Basic Usage'); loggedTestResults.push({ helper: helper, testPath: helperName + ' as ' + typeName + ' ' + testPath, testResult: test(testName, testPath, testCase, helper.supportedBy), }); }); } } }); }); // evaluat test results; let passed = 0; let failed = 0; for(var i=0, max=loggedTestResults.length; i<max; i++) { var t = loggedTestResults[i]; if (t.testResult.successful()) { passed++ } else { failed++; if (failed == 1) { console.log('\n\n\nFailed Tests:\n'.bold); } console.log(' ' + failed + ') ' + t.testPath); _.forEach(t.testResult.messages, (msg) =>{ console.log(msg); }); if (t.testResult.fatal){ console.log(); console.log(t.testResult.errors[0].grey); } console.log('\n + expected'.green + ' - actual'.yellow + '\n'); } } console.log('\n\nSummary:\n'.bold); console.log(' ' + (passed + ' ' + (passed == 1 ? 'Test':'Tests') + ' passing').green); if (failed) { console.log(' ' + (failed + ' ' + (failed == 1 ? 'Test':'Tests') + ' failed').red); } console.log(); } // add some spaces /*for(let i=0; i<100; i++){ console.log(); }*/ main();