diff --git a/lib/requests/index.js b/lib/requests/index.js index b4ba690..fd29c96 100644 --- a/lib/requests/index.js +++ b/lib/requests/index.js @@ -4,8 +4,6 @@ const { ForceDestroy } = require('./errors'); -let traceIdCounter = 0; - const createRequest = ({ timeout, match, @@ -14,12 +12,12 @@ const createRequest = ({ config = {}, counter, tag, - traceId, + trace, waitTime }) => { const request = { tag, - traceId, + trace, idx: counter, // consist of previous request meta that needs to be matched against match, @@ -79,7 +77,7 @@ const Request = ({ method, direction, config, - traceId = ++traceIdCounter + trace } = {} } = {}, timeout @@ -92,7 +90,7 @@ const Request = ({ direction, config, counter, - traceId, + trace, tag, waitTime }); diff --git a/lib/router/index.js b/lib/router/index.js index 8ccd6f3..b03b689 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -12,13 +12,59 @@ const Router = ({ const vectors = new Map(); vectors.set(V0.tag, V0); vectors.set(V1.tag, V1); + const findOpposite = (cur, collection) => { + const all = collection || vectors.keys(); + // dummy implementation + let v = all.next(); + if (v.value !== cur) { + return vectors.get(v.value); + } + return findOpposite(cur, all); + }; const pass = async({vector, packet}) => { - if(!vectors.get(vector)) { + const first = vectors.get(vector); + if(!first) { throw RouterErrorVectorNotFound( {vector} ); } + const second = findOpposite(vector); + const firstPacket = await first.pass({ + packet: { + ...packet, + meta: { + ...packet.meta, + direction: 'in' + } + } + }); + const secondPacket = await second.pass({ + packet: { + payload: firstPacket.payload, + meta: { + method: firstPacket.meta.method, + direction: 'out', + trace: firstPacket.meta.trace + } + } + }); + + const spp = await secondPacket.request.promise; + // third call with in order to create response + await first.pass({ + packet: { + payload: spp.packet.payload, + match: { + idx: firstPacket.request.idx, + tag: firstPacket.request.tag + }, + meta: { + trace: firstPacket.meta.trace + } + } + }); + return await firstPacket.request.promise; }; const rtr = { log, diff --git a/lib/vector/index.js b/lib/vector/index.js index d372486..11eb242 100644 --- a/lib/vector/index.js +++ b/lib/vector/index.js @@ -128,6 +128,7 @@ const Vector = ({ meta }, timeout: (errorFullPacket) => { + log('error', errorFullPacket); throw new Error('what to do?'); } }) @@ -141,6 +142,10 @@ const Vector = ({ } }; + const reverseDirection = (direction) => ( + (direction === 'in' && 'out') || 'in' + ); + const pass = async({ packet: { payload, @@ -158,7 +163,12 @@ const Vector = ({ const methodCallResult = await callMethod({ payload, error, - meta, + meta: { + method: acquired.request.method, + trace: acquired.request.trace, + direction: reverseDirection(acquired.request.direction), + ...meta + }, match, ctx: { ...globalCtx, @@ -185,7 +195,10 @@ const Vector = ({ methodCallResult ]) }; - return await last(fin); + // its a hook, only purpose is to call something + // at the end of the flow + await last(fin); + return fin; }; return { diff --git a/tests/unit/index.js b/tests/unit/index.js index 1c63741..bb62171 100644 --- a/tests/unit/index.js +++ b/tests/unit/index.js @@ -2,9 +2,10 @@ // require('./test.requests'); // require('./vector/test.vector.simple-checks'); // require('./vector/test.in-out-ok'); +// require('./vector/test.in-out-special.no-res-ok'); // require('./vector/test.in-na-out-ok'); // require('./vector/test.in-ok-out-na'); // require('./vector/test.in-na-out-na'); -// require('./vector/test.special.method'); +require('./vector/test.special.method'); // @TODO vector timeouts -require('./router/test.router'); +// require('./router/test.router'); diff --git a/tests/unit/test.requests.js b/tests/unit/test.requests.js index 4b308a2..c0a0eda 100644 --- a/tests/unit/test.requests.js +++ b/tests/unit/test.requests.js @@ -49,7 +49,7 @@ tap.test('Request', async(t) => { // timeout: (e) => e, packet: { match: {idx: ++idx, tag: tag1}, - meta: {traceId: -1} + meta: {trace: -1} } }); tt.same( @@ -58,7 +58,7 @@ tap.test('Request', async(t) => { 'index should be greater than 0' ); tt.same( - rq.traceId, + rq.trace, -1, 'trace id should be same as passed' ); diff --git a/tests/unit/vector/test.in-out-ok.js b/tests/unit/vector/test.in-out-ok.js index 14f5852..e24e0f9 100644 --- a/tests/unit/vector/test.in-out-ok.js +++ b/tests/unit/vector/test.in-out-ok.js @@ -74,4 +74,3 @@ tap.test('Vector: Existing Methods a.in and a.out', async(l0) => { l0.end(); } }); - diff --git a/tests/unit/vector/test.in-out-special.no-res-ok.js b/tests/unit/vector/test.in-out-special.no-res-ok.js new file mode 100644 index 0000000..4760104 --- /dev/null +++ b/tests/unit/vector/test.in-out-special.no-res-ok.js @@ -0,0 +1,78 @@ +const tap = require('tap'); +const { + vectorPassFactory, + timeOut, + vectorFactory, + methodRegisterFactory +} = require('../helpers'); + +const v1 = vectorFactory({config: {id: 'V'}}); +methodRegisterFactory(v1, 'a.in'); +methodRegisterFactory(v1, 'a.out'); +methodRegisterFactory(v1, '*.in', () => undefined); +methodRegisterFactory(v1, '*.out', () => undefined); + +tap.test('Vector: Existing Methods a.in and a.out, * methods also exists but returns no result', async(l0) => { + try { + const r1 = await vectorPassFactory( + v1, + ['Existing Methods a.in and a.out, dir in > out'], + false, + ['a','in'] + ); + setTimeout(async() => { + await vectorPassFactory( + v1, + r1.payload, + false, + ['a', 'out'], + {idx: r1.request.idx, tag: r1.request.tag} + ); + }, 500); + const {packet} = await r1.request.promise; + l0.same(packet, { + payload: [ + 'Existing Methods a.in and a.out, dir in > out', + '>a.in', + 'X:a.in', + '>a.out', + 'X:a.out' + ], + meta: {method: 'a', direction: 'out'}, + match: {idx: 1, tag: Symbol('V')} + }, 'packet struct should match, direction in > out'); + + const r2 = await vectorPassFactory( + v1, + ['Existing Methods a.in and a.out, dir out > in'], + false, + ['a', 'out'] + ); + setTimeout(async() => { + await vectorPassFactory( + v1, + r2.payload, + false, + ['a', 'in'], + {idx: r2.request.idx, tag: r2.request.tag} + ); + }, 500); + const {packet: p2} = await r2.request.promise; + l0.same(p2, { + payload: [ + 'Existing Methods a.in and a.out, dir out > in', + '>a.out', + 'X:a.out', + '>a.in', + 'X:a.in' + ], + meta: {method: 'a', direction: 'in'}, + match: {idx: 2, tag: Symbol('V')} + }, 'packet struct should match, direction out > in'); + } catch (e) { + console.error(e); + } finally { + v1.destroy(); + l0.end(); + } +}); \ No newline at end of file diff --git a/tests/unit/vector/test.special.method.js b/tests/unit/vector/test.special.method.js index 207ff6d..fb29ae2 100644 --- a/tests/unit/vector/test.special.method.js +++ b/tests/unit/vector/test.special.method.js @@ -9,7 +9,12 @@ const { const v1 = vectorFactory({config: {id: 'V'}}); methodRegisterFactory(v1, 'a.in'); methodRegisterFactory(v1, 'a.out'); +methodRegisterFactory(v1, 'throw.in'); +methodRegisterFactory(v1, 'throw.out'); methodRegisterFactory(v1, '*.in', ({payload, ...pass}) => { + if (pass.meta.method === 'throw') { + throw new Error('test'); + } return { ...pass, payload: payload.concat(['*.in']) @@ -28,61 +33,88 @@ methodRegisterFactory(w1, 'a.out'); tap.test('Vector: Special method (*) success cases', async(l0) => { try { - const r1 = await vectorPassFactory( + // const r1 = await vectorPassFactory( + // v1, + // ['Existing Methods a.in and a.out, dir in > out, special(*) method should be called'], + // false, + // ['a', 'in'] + // ); + // setTimeout(async() => { + // await vectorPassFactory( + // v1, + // r1.payload, + // false, + // ['a', 'out'], + // {idx: r1.request.idx, tag: r1.request.tag} + // ); + // }, 500); + // const {packet} = await r1.request.promise; + // l0.same(packet, { + // payload: [ + // 'Existing Methods a.in and a.out, dir in > out, special(*) method should be called', + // '>a.in', + // 'X:a.in', + // '>a.out', + // 'X:a.out' + // ], + // meta: {method: 'a', direction: 'out'}, + // match: {idx: 1, tag: Symbol('V')} + // }, 'packet struct should match, direction in > out'); + // ////////////////////////////////// + // const r2 = await vectorPassFactory( + // w1, + // ['Existing Methods a.in and a.out, dir in > out, special(*) method called should be skipped'], + // false, + // ['a', 'in'] + // ); + // setTimeout(async() => { + // await vectorPassFactory( + // w1, + // r2.payload, + // false, + // ['a', 'out'], + // {idx: r2.request.idx, tag: r2.request.tag} + // ); + // }, 500); + // const p2 = await r2.request.promise; + // l0.same(p2.packet, { + // payload: [ + // 'Existing Methods a.in and a.out, dir in > out, special(*) method called should be skipped', + // '>a.in', + // 'X:a.in', + // '>a.out', + // 'X:a.out' + // ], + // meta: {method: 'a', direction: 'out'}, + // match: {idx: 1, tag: Symbol('W')} + // }, 'packet struct should match, direction in > out'); + ////////////////////////////////// + const r3 = await vectorPassFactory( v1, - ['Existing Methods a.in and a.out, dir in > out, special(*) method should be called'], + ['Existing Methods throw.in and throw.out, dir in > out, special(*) method called should be skipped'], false, - ['a', 'in'] + ['throw', 'in'] ); setTimeout(async() => { await vectorPassFactory( v1, - r1.payload, - false, - ['a', 'out'], - {idx: r1.request.idx, tag: r1.request.tag} - ); - }, 500); - const {packet} = await r1.request.promise; - l0.same(packet, { - payload: [ - 'Existing Methods a.in and a.out, dir in > out, special(*) method should be called', - '>a.in', - 'X:a.in', - '*.in', - '>a.out', - 'X:a.out' - ], - meta: {method: 'a', direction: 'out'}, - match: {idx: 1, tag: Symbol('V')} - }, 'packet struct should match, direction in > out'); - ////////////////////////////////// - const r2 = await vectorPassFactory( - w1, - ['Existing Methods a.in and a.out, dir in > out, special(*) method called should be skipped'], - false, - ['a', 'in'] - ); - setTimeout(async() => { - await vectorPassFactory( - w1, - r2.payload, + r3.payload, false, - ['a', 'out'], - {idx: r2.request.idx, tag: r2.request.tag} + ['throw', 'out'], + {idx: r3.request.idx, tag: r3.request.tag} ); }, 500); - const p2 = await r2.request.promise; - l0.same(p2.packet, { + const p3 = await r3.request.promise; + l0.same(p3.packet, { payload: [ - 'Existing Methods a.in and a.out, dir in > out, special(*) method called should be skipped', - '>a.in', - 'X:a.in', - '>a.out', - 'X:a.out' + 'Existing Methods throw.in and throw.out, dir in > out, special(*) method called should be skipped', + '>throw.in', + 'X:throw.in', + '>throw.out', + 'X:throw.out' ], - meta: {method: 'a', direction: 'out'}, - match: {idx: 1, tag: Symbol('W')} + meta: {method: 'throw', direction: 'out'}, + match: {idx: 2, tag: Symbol('V')} }, 'packet struct should match, direction in > out'); } catch (e) { console.error(e); diff --git a/tests/unit/vector/test.vector.simple-checks.js b/tests/unit/vector/test.vector.simple-checks.js index 177116c..cff5287 100644 --- a/tests/unit/vector/test.vector.simple-checks.js +++ b/tests/unit/vector/test.vector.simple-checks.js @@ -14,7 +14,7 @@ tap.test('Vector: Simple checks and coverage', async(l0) => { l0.same(v1.ctx({a: 1}), {a: 1}, 'should return {a: 1}, first value that is set'); l0.same(v1.ctx({b: 2}), {a: 1, b: 2}, 'should return {a: 1, b: 2}, second value that is set, first should be there'); l0.same(v1.ctx({a: 6, b: 6}), {a: 6, b: 6}, 'should return {a: 6, b: 6}, overwrite both values'); - l0.same(v1.ctx({b: 5}), {a: 6, b: 5}, 'should return {a: 6, b: 5}, owerwrite only sec. value'); + l0.same(v1.ctx({b: 5}), {a: 6, b: 5}, 'should return {a: 6, b: 5}, overwrite only sec. value'); l0.same(v1.ctx(), {a: 6, b: 5}, 'should return {a: 6, b: 5}, no args when fn call, return what is it in'); v1.destroy(); l0.end();