isValidNumStr + tester

by joplomacedo

JavaScript

function isValidNumStr(str, {  max,  min,  decimals }) {
  //we could just do a isNaN check on the number version
  //of the string, but that would fail with cases
  // like "." , "-", "-0" so we deal with those first

  //if single minus
  if (str === '-') {
    return min < 0;
  }

  //only allow minus at start
  // !isNaN(2-2) would equal true
  if (![0, -1].includes(str.indexOf('-'))) {
    return false;
  }

  //self explanatory. we dont want this
  if (str.indexOf('-0') === 0) {
    return false;
  }

  //if starts with dot, check if it allows decimals
  if (str === '.') {
    return decimals > 0;
  }


  //lets check with isNaN now
  const num = +str;

  if (isNaN(num)) {
    return false;
  }

  //its a number. great. lets check if it works with
  // the options
  if (num > max || num < min) {
    return false;
  }

  //is decimal
  if (precision(num) > decimals) {
    return false;
  }
  

  return true;
}


function precision( num ) {
  const decimalPart = (''+num).split(".")[1];
  return decimalPart !== undefined ? decimalPart.length : 0;
}

function inc(value, amount, max) {
	let maxPrecision = Math.max(precision(value), precision(amount));
	let x = +(value + amount).toFixed(maxPrecision);
  return Math.min(x, max);
}

function dec(value, amount, min) {
	let maxPrecision = Math.max(precision(value), precision(amount));
	let x = +(value - amount).toFixed(maxPrecision);
  return Math.max(x, min);
}

function multiplyText(text, times) {
  let result = '';
  for (let i = 0; i < times; i++) {
    result += text;
  }
  return result;
}

function countOccurencesOf( str, occurencesOf ) {
	return str.split(occurencesOf).length - 1;
}

function test(name, fn, tests) {
  let title = `Testing: ${name}`;
  let delimiter = multiplyText('#', title.length);

  console.log(delimiter);
  console.log('Test: ' + name);

  tests.forEach((test, i) => {
    const {
      args,
      expected
    } = test;
    const result = fn(...args);
    const passed = expected ===...