diff --git a/lib/createAssertions.js b/lib/createAssertions.js new file mode 100644 index 0000000..d34f9e9 --- /dev/null +++ b/lib/createAssertions.js @@ -0,0 +1,56 @@ +const path = obj => path => + path.reduce((result, segment) => result && result[segment], obj); + +const pickSelector = path => { + const match = path.match(/^(res|unit)(::|$)/)[0]; + if (match === 'res::') return 0; + if (match === 'unit::') return 1; + return -1; +}; + +const parsePath = obj => pathString => { + + const paths = []; + + const normalised = pathString + .trim() + .replace(/^(res|unit)::/, '') + .split('::'); + + if (normalised[normalised.length - 1] === '&*') { + const push = path(obj)(normalised.slice(0, normalised.length - 1)); + if (Array.isArray(push)) Array.prototype.push.apply(paths, push); + else return Promise.reject( + `${push} is not an array. Cannot run '&*' operator!`); + } else { + paths.push(path(obj)(normalised)); + } + + return paths; + +}; + +const obj = { + doc: { + a: + { b: [5, 10] } + } +}; + +module.exports = (expectable, expect, docs) => { + const unitExpects = []; + + if (expectable.checks) { + unitExpects.push(expect(expectable.checks).isArray()); + expectable.checks.forEach(check => { + const [ pathToCheck, method, ...args ] = check; + const selector = pickSelector(pathToCheck); + const toChecks = parsePath(docs[selector])(pathToCheck); + toChecks.forEach(toCheck => + unitExpects.push( + expect(toCheck)[method](...args))); + }); + } + + return Promise.all(unitExpects); +}; diff --git a/lib/units/convertHook.js b/lib/units/convertHook.js new file mode 100644 index 0000000..a9aa6bc --- /dev/null +++ b/lib/units/convertHook.js @@ -0,0 +1,14 @@ +const Gunner = require('@klenty/gunner'); + +const processUnit = require('./processUnit'); + +module.exports = instance => when => hook => { + + const GunnerConstant = when === 'before' + ? Gunner.Start + : Gunner.End; + + return instance[when](GunnerConstant, state => + processUnit(hook, state)); + +}; diff --git a/lib/units/convertTest.js b/lib/units/convertTest.js new file mode 100644 index 0000000..8dbc04e --- /dev/null +++ b/lib/units/convertTest.js @@ -0,0 +1,43 @@ +const createAssertions = require('../createAssertions'); +const processUnit = require('./processUnit'); + +module.exports = instance => test => { + instance.test(test.description, async (expect, state) => { + const response = await processUnit(test, state); + + let expects = []; + const res = JSON.parse(response.res.text); + const responseData = { + status: response.status, + data: res.data, + errors: res.errors, + }; + + const awaitables = (test.expect || []).map(async ex => { + + if (ex.type === 'response') + Array.prototype.push.apply(expects, + await createAssertions( + ex, + expect, + [ responseData ], + )); + else if (ex.type === 'db') { + let data = await processUnit(ex, state); + if (Array.isArray(data)) + data = data.map(x => x._doc); + Array.prototype.push.apply(expects, + await createAssertions( + ex, + expect, + [ responseData, { doc: data } ] + )); + } else + return Promise.reject( + `${ex.type} is not a registered resource`); + }); + + await Promise.all(awaitables); + return expects; + }); +}; diff --git a/lib/units/processUnit.js b/lib/units/processUnit.js new file mode 100644 index 0000000..f9db515 --- /dev/null +++ b/lib/units/processUnit.js @@ -0,0 +1,39 @@ +const requestor = async (unit, request) => { + switch (unit.method) { + + case 'get': + return await request[unit.method](unit.path); + case 'post': + return await (request[unit.method](unit.path) + .type(unit.reqType || 'json') + .send(unit.body)); + + } +}; + +const dbAction = async (unit, db) => { + if (!unit.hasOwnProperty('method')) unit.method = 'findOne'; + const exec = [ 'create', 'insertMany' ].indexOf(unit.method) === -1; + const action = db[unit.collection][unit.method]( + unit.query || unit.insert, + unit.update || unit.queryList, + ); + + return !exec ? await action : action.exec(); +}; + +module.exports = async (unit, state) => { + const [ request, db ] = state['@start']; + switch (unit.type) { + + case 'request': + return await requestor(unit, request); + case 'db': + return await dbAction(unit, db); + default: + throw new Error( + `Unknown before hook type: ${unit.type}` + ); + + } +};