Heizoinside/frontend-project-lvl2

View on GitHub
src/ast-builder.js

Summary

Maintainability
A
0 mins
Test Coverage

import _ from 'lodash';

const states = [
  {
    condition: (dataBefore, dataAfter, key) => _.has(dataBefore, key)
        && _.has(dataAfter, key) && dataBefore[key] === dataAfter[key],
    type: 'unchanged',
    process: (dataBefore, dataAfter) => ({ valueBefore: dataBefore, valueAfter: dataAfter }),
  },
  {
    condition: (dataBefore, dataAfter, key) => _.isObject(dataBefore[key])
      && _.isObject(dataAfter[key]),
    type: 'nested',
    process: (dataBefore, dataAfter, func) => ({ children: func(dataBefore, dataAfter) }),
  },
  {
    condition: (dataBefore, dataAfter, key) => _.has(dataBefore, key)
        && !_.has(dataAfter, key),
    type: 'deleted',
    process: (dataBefore) => ({ valueBefore: dataBefore }),
  },
  {
    condition: (dataBefore, dataAfter, key) => _.has(dataAfter, key)
        && !_.has(dataBefore, key),
    type: 'added',
    process: (dataBefore, dataAfter) => ({ valueAfter: dataAfter }),
  },
  {
    condition: (dataBefore, dataAfter, key) => dataBefore[key] !== dataAfter[key],
    type: 'changed',
    process: (dataBefore, dataAfter) => ({ valueBefore: dataBefore, valueAfter: dataAfter }),
  },
];
const getStateProcess = (dataBefore, dataAfter, key) => (
  states.find(({ condition }) => condition(dataBefore, dataAfter, key))
);

const buildAst = (objBefore, objAfter) => {
  const unionKeys = _.union(Object.keys(objBefore), Object.keys(objAfter));
  return unionKeys.sort().map((key) => {
    const { type, process } = getStateProcess(objBefore, objAfter, key);
    const values = process(objBefore[key], objAfter[key], buildAst);
    const node = {
      name: key,
      type,
      ...values,
    };
    return node;
  });
};

export default buildAst;