vbwdev/project-lvl2-s269

View on GitHub
src/diffGenerator.js

Summary

Maintainability
A
1 hr
Test Coverage
import _ from 'lodash';

const propertyActions = [
  {
    type: 'nested',
    check: (first, second, key) =>
      _.has(first, key) && _.has(second, key) && _.isPlainObject(first[key]) && _.isPlainObject(second[key]),
    process: (first, second, func) => ({ children: func(first, second) }),
  },
  {
    type: 'unchanged',
    check: (first, second, key) => _.has(first, key) && _.has(second, key) && first[key] === second[key],
    process: first => ({ value: first }),
  },
  {
    type: 'changed',
    check: (first, second, key) => _.has(first, key) && _.has(second, key) && first[key] !== second[key],
    process: (first, second) => ({ oldValue: first, newValue: second }),
  },
  {
    type: 'deleted',
    check: (first, second, key) => _.has(first, key) && !_.has(second, key),
    process: first => ({ value: first }),
  },
  {
    type: 'added',
    check: (first, second, key) => !_.has(first, key) && _.has(second, key),
    process: (first, second) => ({ value: second }),
  },
];

const getPropertyAction = (first, second, key) => {
  const type = _.find(propertyActions, ({ check }) => check(first, second, key));
  if (!type) {
    throw new Error('No suitable type found');
  }
  return type;
};

const generateDiff = (firstContent, secondContent) => {
  const keys = _.union(_.keys(firstContent), _.keys(secondContent));
  return keys.map((key) => {
    const { type, process } = getPropertyAction(firstContent, secondContent, key);
    const processedData = process(firstContent[key], secondContent[key], generateDiff);
    return { key, type, ...processedData };
  }, []);
};

export default generateDiff;