All files / vendor unique.js

92.31% Statements 36/39
78.57% Branches 22/28
100% Functions 3/3
92.31% Lines 36/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88  1x           1x       1x     1x       1x 22x 5x   17x       1x 2x 2x 2x     1x     24x   24x 24x 24x 24x 24x   24x       24x       24x     24x       24x         24x 1x     23x 1x       22x     22x 5x 5x 5x     17x 17x       1x  
// the `unique` module
var unique = {};
 
// global results store
// currently uniqueness is global to entire faker instance
// this means that faker should currently *never* return duplicate values across all API methods when using `Faker.unique`
// it's possible in the future that some users may want to scope found per function call instead of faker instance
var found = {};
 
// global exclude list of results
// defaults to nothing excluded
var exclude = [];
 
// current iteration or retries of unique.exec ( current loop depth )
var currentIterations = 0;
 
// uniqueness compare function
// default behavior is to check value as key against object hash
var defaultCompare = function(obj, key) {
  if (typeof obj[key] === 'undefined') {
    return -1;
  }
  return 0;
};
 
// common error handler for messages
unique.errorMessage = function (now, code, opts) {
  console.error('error', code);
  console.log('found', Object.keys(found).length, 'unique entries before throwing error. \nretried:', currentIterations, '\ntotal time:', now - opts.startTime, 'ms');
  throw new Error(code + ' for uniqueness check \n\nMay not be able to generate any more unique values with current settings. \nTry adjusting maxTime or maxRetries parameters for faker.unique()')
};
 
unique.exec = function (method, args, opts) {
  //console.log(currentIterations)
 
  var now = new Date().getTime();
 
  opts = opts || {};
  opts.maxTime = opts.maxTime || 3;
  opts.maxRetries = opts.maxRetries || 50;
  opts.exclude = opts.exclude || exclude;
  opts.compare = opts.compare || defaultCompare;
 
  Iif (typeof opts.currentIterations !== 'number') {
    opts.currentIterations = 0;
  }
 
  Iif (typeof opts.startTime === 'undefined') {
    opts.startTime = new Date().getTime();
  }
 
  var startTime = opts.startTime;
 
  // support single exclude argument as string
  Iif (typeof opts.exclude === 'string') {
    opts.exclude = [opts.exclude];
  }
 
  if (opts.currentIterations > 0) {
    // console.log('iterating', currentIterations)
  }
 
  // console.log(now - startTime)
  if (now - startTime >= opts.maxTime) {
    return unique.errorMessage(now, 'Exceeded maxTime:' + opts.maxTime, opts);
  }
 
  if (opts.currentIterations >= opts.maxRetries) {
    return unique.errorMessage(now, 'Exceeded maxRetries:' + opts.maxRetries, opts);
  }
 
  // execute the provided method to find a potential satifised value
  var result = method.apply(this, args);
 
  // if the result has not been previously found, add it to the found array and return the value as it's unique
  if (opts.compare(found, result) === -1 && opts.exclude.indexOf(result) === -1) {
    found[result] = result;
    opts.currentIterations = 0;
    return result;
  } else {
    // console.log('conflict', result);
    opts.currentIterations++;
    return unique.exec(method, args, opts);
  }
};
 
module.exports = unique;