All files support-lib.js

85.71% Statements 48/56
50% Branches 17/34
100% Functions 12/12
90.69% Lines 39/43

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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                      30x   30x 8x 8x 8x 8x 8x 8x 8x 22x   8x                 30x 1x                 30x 1x               33x   30x 1x     30x   30x 30x 240x 240x 95x 95x 94x 92x               30x 240x 2x   240x 7x   1x   2x 2x         3x 3x         1x             30x            
/**
 * Universidad de La Laguna
 * Escuela Superior de Ingeniería y Tecnología
 * Grado en Ingeniería Informática
 * Procesadores de Lenguajes
 *
 * @author Juan Rodríguez Suárez
 * @since Mar 04 2024
 * @desc Contains some support functions to work with complex numbers.
 */
 
const Complex = require('complex.js');
 
Complex.prototype.factorial = function() {
  Iif (this.im !== 0) throw new Error(`Imaginary part must be zero. Instead is ${this.im}`);
  let n = this.re;
  Iif (!Number.isInteger(n)) throw new Error(`Not an Integer number ${n}`);
  Iif ( n < 0) throw new Error(`Factorial of negative number ${n}`);
  let result = Complex(1);
  Iif (n === 0) return result;
  for (let i = 1; i <= n; i++) {
    result = result.mul(i);
  }
  return Complex({re: result.re, im: this.im});
};
 
/**
 * @brief Returns the maximum of two complex numbers
 * @param {Complex} a - The first number
 * @param {Complex} b - The second number
 * @returns {Complex} The maximum
 */
const max = function(a, b) {
  return a.re > b.re ? a : a.re === b.re && a.im >= b.im ? a : b;
}
 
/**
 * @brief Returns the minimum of two complex numbers
 * @param {Complex} a - The first number
 * @param {Complex} b - The second number
 * @returns {Complex} The minimum
 */
const min = function(a, b) {
  return a.re < b.re ? a : a.re === b.re && a.im <= b.im ? a : b;
}
 
/**
 * @brief Prints a complex number
 * @param {Complex} x - The input
 * @returns {Complex} The input
 */
const print = x => { console.log(x.toString()); return x; } 
 
Complex.prototype.lessThan = function(other) {
  return this.re < other.re || (this.re === other.re && this.im < other.im);
}
 
const OPERATORS = new Set(['add', 'sub', 'mul', 'div', 'pow', 'equals', 'neg', 'lessThan']);
 
let oldComplex = Object.create(null);
for (let op of OPERATORS) {
  oldComplex[op] = Complex.prototype[op];
  Complex.prototype[op] = function(other) {
    try {
      if (typeof other === 'function') return other[op](this);
      if (typeof other === 'boolean') return this[op](Complex(Number(other)));
      return oldComplex[op].call(this, other);
    }
    catch (e) {
      throw new Error(`Complex numbers do not support the operation ${op} for ${other}\n${e}`);
    }
  }
}
 
for (let op of OPERATORS) {
  Boolean.prototype[op] = function(other) {
    return Complex(Number(this))[op](other);
  }
  Function.prototype[op] = function(other) {
    switch (typeof other) {
      case 'boolean':
        return (...args) => this(...args)[op](Complex(Number(other)));
      case 'object':
        Eif (other instanceof Complex) {
          return (...args) => this(...args)[op](other);
        } else {
          throw new Error(`Function does not support the operation ${op} for ${other}`);
        }
      case 'function':
        try {
          return (...args) => this(...args)[op](other(...args));
        } catch (e) {
          throw new Error(`Function does not support the operation ${op} for function ${other}`);
        }
      case 'undefined':
        return (...args) => this(...args)[op]();
      default:
        throw new Error(`Unsupported ${op} for type ${typeof other}`);
    }
  }
}
 
module.exports = {
  print,
  max,
  min,
  Complex
};