all files / couch/util/ deep-equal.js

100% Statements 27/27
100% Branches 20/20
100% Functions 3/3
100% Lines 27/27
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61                            40×   34×       20× 20×   19×       16×       13×   12×                
import Ember from 'ember';
import CouchError from './error';
 
const {
  isArray,
  typeOf,
  merge
} = Ember;
 
export class DeepEqual {
 
  constructor(opts) {
    this.opts = merge({ Error: CouchError, allowEmberObjects: false }, opts);
  }
 
  typeOf(arg) {
    if(isArray(arg)) {
      return 'array';
    }
    return typeOf(arg);
  }
 
  isEqual(a, b) {
    let type = this.typeOf(a);
    if(type !== this.typeOf(b)) {
      return false;
    }
    if(type === 'object') {
      if(Object.keys(a).length !== Object.keys(b).length) {
        return false;
      }
      for(let key in a) {
        if(!this.isEqual(a[key], b[key])) {
          return false;
        }
      }
      return true;
    } else if(type === 'array') {
      if(a.length !== b.length) {
        return false;
      }
      for(let i = 0; i < a.length; i++) {
        if(!this.isEqual(a[i], b[i])) {
          return false;
        }
      }
      return true;
    } else if(type === 'instance' && !this.opts.allowEmberObjects) {
      throw new this.opts.Error({ error: 'deep-equal', reason: 'ember object instances are not allowed' });
    }
    return a === b;
  }
 
}
 
export default opts => {
  let deepEqual = new DeepEqual(opts);
  return deepEqual.isEqual.bind(deepEqual);
}