diff --git a/lib/convert/v1.js b/lib/convert/v1.js index 8700cdc..cea7bf1 100644 --- a/lib/convert/v1.js +++ b/lib/convert/v1.js @@ -16,7 +16,65 @@ module.exports = function (decl) { entity.modName && (item.mods = [{ name: entity.modName }]); entity.modVal && (item.mods[0].vals = [{ name: entity.modVal }]); - acc.push(entity.elem ? { name: entity.block, elems: [item] } : item); + const result = entity.elem ? { name: entity.block, elems: [item] } : item; + + if (result.elems && entity.elem) { + // If exists block with existing elems property + const elemsAddition = acc.find( + curEntity => curEntity.name === entity.block && curEntity.elems + ); + if (elemsAddition) { + // check if elem exists + const curElem = elemsAddition.elems.find(elem => elem.name === entity.elem); + curElem || elemsAddition.elems.push(result.elems[0]); + } else { + acc.push(result); + } + + // If such element already exists and we have mod + const modsAddition = acc.find(curEntity => { + const curElem = curEntity.elems ? + curEntity.elems.find(elem => elem.name === entity.elem) : false; + return curEntity.name === entity.block && curElem; + }); + if (entity.modName) { + const curElem = modsAddition.elems.find(elem => elem.name === entity.elem); + if (curElem.mods) { + // have an array of mods in elem + // check if such mod already exists + const curMod = curElem.mods.find( + mod => mod.name === entity.modName + ); + if (curMod) { + // check if val already exists + const curVal = curMod.vals.find(val => + val.name === entity.modVal + ); + curVal || curMod.vals.push(result.elems[0].mods[0].vals[0]); + } else { + // add new mod + curElem.mods.push(result.elems[0].mods[0]); + } + } + } + } else if (entity.modName) { + const curBlock = acc.find(curEntity => curEntity.name === entity.block && curEntity.mods); + // if block with mods prop exists search for such mod + if (curBlock) { + const curMod = curBlock.mods.find(mod => mod.name === entity.modName); + if (curMod) { + // if such mod exists push new val + curMod.vals.push(result.mods[0].vals[0]); + } else { + // if no such mod push new mod + curBlock.mods.push(result.mods[0]); + } + } else { + acc.push(result); + } + } else { + acc.push(result); + } return acc; }, []); }; diff --git a/test/convert/v1.test.js b/test/convert/v1.test.js index 52e84f2..3453dd5 100644 --- a/test/convert/v1.test.js +++ b/test/convert/v1.test.js @@ -8,22 +8,138 @@ test('must return empty decl', t => { t.deepEqual(convert([], { format: 'v1' }), []); }); -test('must transform deps to bemdecl', t => { +// test('must transform deps to bemdecl', t => { +// const input = [ +// { entity: { block: 'block1' }, tech: null }, +// { entity: { block: 'block1', modName: 'mod1', modVal: true }, tech: null }, +// { entity: { block: 'block1', modName: 'mod1', modVal: 'val1' }, tech: null }, +// { entity: { block: 'block1', elem: 'elem1' }, tech: null }, +// { entity: { block: 'block1', elem: 'elem1', modName: 'mod2', modVal: true }, tech: null }, +// { entity: { block: 'block1', elem: 'elem1', modName: 'mod2', modVal: 'val2' }, tech: null } +// ]; +// const output = [ +// { name: 'block1' }, +// { name: 'block1', mods: [{ name: 'mod1', vals: [{ name: true }] }] }, +// { name: 'block1', mods: [{ name: 'mod1', vals: [{ name: 'val1' }] }] }, +// { name: 'block1', elems: [{ name: 'elem1' }] }, +// { name: 'block1', elems: [{ name: 'elem1', mods: [{ name: 'mod2', vals: [{ name: true }] }] }] }, +// { name: 'block1', elems: [{ name: 'elem1', mods: [{ name: 'mod2', vals: [{ name: 'val2' }] }] }] } +// ]; + +// t.deepEqual( +// convert(input, { format: 'v1' }), +// output +// ); +// }); +// +test('must split elems of one block', t => { const input = [ { entity: { block: 'block1' }, tech: null }, - { entity: { block: 'block1', modName: 'mod1', modVal: true }, tech: null }, - { entity: { block: 'block1', modName: 'mod1', modVal: 'val1' }, tech: null }, { entity: { block: 'block1', elem: 'elem1' }, tech: null }, - { entity: { block: 'block1', elem: 'elem1', modName: 'mod2', modVal: true }, tech: null }, + { entity: { block: 'block1', elem: 'elem2' }, tech: null } + ]; + const output = [ + { name: 'block1' }, + { name: 'block1', elems: [{ name: 'elem1' }, { name: 'elem2' }] } + ]; + + t.deepEqual( + convert(input, { format: 'v1' }), + output + ); +}); + +test('must split mods of one block', t => { + const input = [ + { entity: { block: 'block1' }, tech: null }, + { entity: { block: 'block1', modName: 'mod1', modVal: 'val1' }, tech: null }, + { entity: { block: 'block1', modName: 'mod2', modVal: 'val2' }, tech: null } + ]; + const output = [ + { name: 'block1' }, + { + name: 'block1', + mods: [ + { name: 'mod1', vals: [{ name: 'val1' }] }, + { name: 'mod2', vals: [{ name: 'val2' }] } + ] + } + ]; + + t.deepEqual( + convert(input, { format: 'v1' }), + output + ); +}); + +test('must split vals of mods block', t => { + const input = [ + { entity: { block: 'block1' }, tech: null }, + { entity: { block: 'block1', modName: 'mod1', modVal: true }, tech: null }, + { entity: { block: 'block1', modName: 'mod1', modVal: 'val1' }, tech: null } + ]; + const output = [ + { name: 'block1' }, + { + name: 'block1', + mods: [ + { name: 'mod1', vals: [{ name: true }, { name: 'val1' }] } + ] + } + ]; + + t.deepEqual( + convert(input, { format: 'v1' }), + output + ); +}); + +test('must split elem mods of block', t => { + const input = [ + { entity: { block: 'block1' }, tech: null }, + { entity: { block: 'block1', elem: 'elem1', modName: 'mod1', modVal: 'val1' }, tech: null }, { entity: { block: 'block1', elem: 'elem1', modName: 'mod2', modVal: 'val2' }, tech: null } ]; const output = [ { name: 'block1' }, - { name: 'block1', mods: [{ name: 'mod1', vals: [{ name: true }] }] }, - { name: 'block1', mods: [{ name: 'mod1', vals: [{ name: 'val1' }] }] }, - { name: 'block1', elems: [{ name: 'elem1' }] }, - { name: 'block1', elems: [{ name: 'elem1', mods: [{ name: 'mod2', vals: [{ name: true }] }] }] }, - { name: 'block1', elems: [{ name: 'elem1', mods: [{ name: 'mod2', vals: [{ name: 'val2' }] }] }] } + { + name: 'block1', + elems: [ + { + name: 'elem1', + mods: [ + { name: 'mod1', vals: [{ name: 'val1' }] }, { name: 'mod2', vals: [{ name: 'val2' }] } + ] + } + ] + } + ]; + + t.deepEqual( + convert(input, { format: 'v1' }), + output + ); +}); + +test('must split vals of elem mods', t => { + const input = [ + { entity: { block: 'block1' }, tech: null }, + { entity: { block: 'block1', elem: 'elem1', modName: 'mod1', modVal: 'val1' }, tech: null }, + { entity: { block: 'block1', elem: 'elem1', modName: 'mod1', modVal: 'val2' }, tech: null } + ]; + const output = [ + { name: 'block1' }, + { + name: 'block1', + elems: [ + { + name: 'elem1', + mods: [ + { name: 'mod1', vals: [{ name: 'val1' }, { name: 'val2' }] } + ] + } + ] + } ]; t.deepEqual(