diff --git a/src/modules/Action.js b/src/modules/Action.js index c677a87..505d22c 100644 --- a/src/modules/Action.js +++ b/src/modules/Action.js @@ -14,13 +14,14 @@ function getQuery(searchParams) { } export default class Action { - constructor({ chronicle, id, ...values }) { + constructor({ chronicle, id, _id, _chronicle, ...values }) { this._context = {}; this._response = {}; this._request = {}; - this._chronicle = chronicle; + this._chronicle = chronicle || _chronicle; this.set(values); - this._id = id || uuid(); + this._id = id || _id || uuid(); + this._chronicle._actions.push(this); } static sanitizeHeaders(headers, config) { diff --git a/src/modules/Chronicle.js b/src/modules/Chronicle.js index 4253a71..f5dc699 100644 --- a/src/modules/Chronicle.js +++ b/src/modules/Chronicle.js @@ -1,6 +1,7 @@ import path from 'path'; import fs from 'fs-extra'; import cls from 'cls-hooked'; +import { v4 as uuid } from 'uuid'; import reporters from '../reporters'; import { DEFAULT_CLS_CONTEXT_KEY } from '../constants'; import Action from './Action'; @@ -9,6 +10,7 @@ export default class Chronicle { constructor(config = {}) { this._actions = []; this.setConfig(config); + this.id = config.id || uuid(); } useCLS(namespace, contextKey = DEFAULT_CLS_CONTEXT_KEY) { @@ -38,8 +40,6 @@ export default class Chronicle { chronicle : this }); - this._actions.push(action); - return action; } @@ -58,4 +58,34 @@ export default class Chronicle { await reporter.write(this._actions.map(a => a.data)); } + + split(splitfn) { + const splitted = new Map(); + + this._actions.forEach(item => { + const chrID = splitfn(item); + const curr = splitted.get(chrID) || []; + + curr.push(item); + splitted.set(chrID, curr); + }); + + return [ ...splitted.keys() ].map(groupId => { + const actions = splitted.get(groupId); + const chronicle = new Chronicle({ + ...this.config, + id : groupId + }); + + chronicle.clsEnabled = this.clsEnabled; + chronicle._cls = this._cls; + chronicle.contextBuilder = this.contextBuilder; + console.log('before: ', chronicle.id, chronicle._actions); + actions.forEach(action => new Action({ ...action, chronicle })); + console.log('actions: ', actions.length); + console.log('chronicle: ', chronicle.id, chronicle._actions); + + return chronicle; + }); + } } diff --git a/tests/mock/fixtures/actions.json b/tests/mock/fixtures/actions.json index 0a4f8c2..fd07ebf 100644 --- a/tests/mock/fixtures/actions.json +++ b/tests/mock/fixtures/actions.json @@ -51,5 +51,53 @@ "email": "nebawawaw@wopdoj.nr", "gender": "Female" } + }, + { + "context": { + "group": "Users", + "title": "update user gender" + }, + "url": "http://127.0.0.1:62887/users/2", + "method": "PATCH", + "reqHeaders": { + "Authorization": "dNFgil4tftWpLUjz" + }, + "resHeaders": { + "x-powered-by": "Express", + "content-length": "120" + }, + "reqBody": { + "gender": "Male" + }, + "resBody": { + "id": 2, + "first_name": "Eugenia", + "last_name": "Perry", + "email": "nusmad@pa.jp", + "gender": "Female" + } + }, + { + "context": { + "group": "Orders", + "title": "get order" + }, + "url": "http://127.0.0.1:62887/orders/1", + "method": "GET", + "reqHeaders": { + "Authorization": "dNFgil4tftWpLUjz" + }, + "resHeaders": { + "x-powered-by": "Express", + "content-length": "120" + }, + "reqBody": { + "gender": "Male" + }, + "resBody": { + "id": 1, + "link": "http://pabeve.ao/mum", + "country": "Turkmenistan" + } } ] \ No newline at end of file diff --git a/tests/package/chronicle-split.test.js b/tests/package/chronicle-split.test.js new file mode 100644 index 0000000..6e236d6 --- /dev/null +++ b/tests/package/chronicle-split.test.js @@ -0,0 +1,32 @@ +import { assert } from 'chai'; +import Test from '../Test'; +import chronicle from '../entry'; + +suite('Chronicle split'); + +const factory = new Test(chronicle); + +before(async () => { + await factory.startMockApp(); + await factory.cleanup(); + await factory.setActions(); +}); + +test('Split actions', function () { + const splitted = chronicle.split(action => { + return action.group; + }); + + assert.lengthOf(chronicle._actions, 4); + assert.lengthOf(splitted, 2); + const userGroup = splitted.find(s => s.id === 'Users'); + + assert.lengthOf(userGroup._actions, 3); + const orderGroup = splitted.find(s => s.id === 'Orders'); + + assert.lengthOf(orderGroup._actions, 1); +}); + +after(async () => { + await factory.cleanup(); +});