snsin/project-lvl2-s381

View on GitHub
src/diff-ast.js

Summary

Maintainability
A
0 mins
Test Coverage
import { has, union, find } from 'lodash';

const isNested = (b, a, k) => has(b, k) && has(a, k)
  && (b[k] instanceof Object) && (a[k] instanceof Object);

const typeSelector = [
  {
    type: 'nested',
    predicate: (key, before, after) => isNested(before, after, key),
    create: (before, after, fn) => ({ children: fn(before, after) }),
  },
  {
    type: 'added',
    predicate: (key, before, after) => !has(before, key) && has(after, key),
    create: (beforeValue, value) => ({ value }),
  },
  {
    type: 'deleted',
    predicate: (key, before, after) => has(before, key) && !has(after, key),
    create: value => ({ value }),
  },
  {
    type: 'changed',
    predicate: (key, before, after) => has(before, key) && has(after, key)
      && before[key] !== after[key],
    create: (oldValue, newValue) => ({ newValue, oldValue }),
  },
  {
    type: 'unchanged',
    predicate: (key, before, after) => has(before, key) && has(after, key)
      && before[key] === after[key],
    create: value => ({ value }),
  },
];

const diffCalculation = (b, a) => {
  const keys = union(Object.keys(b), (Object.keys(a)));
  return keys.map((key) => {
    const { type, create } = find(typeSelector, typeInst => typeInst.predicate(key, b, a));
    return { type, key, ...create(b[key], a[key], diffCalculation) };
  });
};

export default diffCalculation;