All files / src/models Problem.js

0% Statements 0/34
0% Branches 0/10
0% Functions 0/8
0% Lines 0/32
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                                                                                                                                 
const PAREN_PAIRS = '❰❮❬❨❪﹙₍₎﹚❫❩❭❯❱';
const stringifyWithFnName = require( '../utils/stringifyWithFnName' );
const lazyDefine = require( '../utils/lazyDefine' );
 
function Problem( val, failsPredicate, subproblems, msg ) {
  this.isProblem = true;
 
  if ( arguments.length !== 4 ) {
    throw 'Problem arg len err';
  }
 
  this.val = val;
  this.name = 'Problem';
  this.failsPredicate = failsPredicate;
  // this.stack = (new Error()).stack;
  this.shortMessage = msg;
  this.subproblems = subproblems;
 
  lazyDefine( this, 'message', () => _constructMessage( this, 0 ) );
 
  this.toString = () => this.message;
}
 
function _constructMessage( { subproblems, val, shortMessage }, lvl ) {
  if ( Array.isArray( subproblems ) ) {
    var reasons;
    if ( subproblems.length === 0 ) {
      return `${shortMessage}; val: ${stringifyWithFnName( val, null, 2 )}`;
    } else {
      reasons = subproblems.map( ( r ) => {
        return `${_open( lvl )}${_constructMessage( r, lvl + 1 )}${_close( lvl )}`;
      } );
      return `${shortMessage}, because\n${_repeatStr( ' ', lvl * 2 )} ${reasons.join( ', ' )}`;
    }
  } else if ( typeof subproblems === 'object' ) {
    reasons = [];
    for ( var name in subproblems ) {
      if ( subproblems.hasOwnProperty( name ) ) {
        reasons.push( `-> ${name}: ${_open( lvl )} ${_constructMessage( subproblems[ name ], lvl + 1 )}${_close( lvl )}` );
      }
    }
    return `${shortMessage}, because\n${_repeatStr( ' ', lvl * 2 )} ${reasons.join( ', ' )}`;
  }
}
 
function _repeatStr( str, n ) {
  var r = '';
  for ( let i = 0; i < n; i += 1 ) {
    r += str;
  }
  return r;
}
 
function _open( lvl ) {
  return PAREN_PAIRS[ lvl ];
}
 
function _close( lvl ) {
  return PAREN_PAIRS[ PAREN_PAIRS.length - lvl - 1 ];
}
 
// Problem.prototype = new Error;
 
module.exports = Problem;