Files
javascript-obfuscator-javas…/test/unit-tests/utils/NumberUtils.spec.ts
2025-12-04 00:09:10 +04:00

621 lines
19 KiB
TypeScript

import { assert } from 'chai';
import { NumberUtils } from '../../../src/utils/NumberUtils';
describe('NumberUtils', function () {
this.timeout(30000);
describe('toHex', () => {
describe('Variant #1: number `0`', () => {
const number: number = 0;
const expectedHexString = '0x0';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given decimal number', () => {
assert.equal(hexString, expectedHexString);
});
});
describe('Variant #2: number `10`', () => {
const number: number = 10;
const expectedHexString = '0xa';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given decimal number', () => {
assert.equal(hexString, expectedHexString);
});
});
describe('Variant #3: number `17`', () => {
const number: number = 17;
const expectedHexString = '0x11';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given decimal number', () => {
assert.equal(hexString, expectedHexString);
});
});
describe('Variant #4: number `536870912`', () => {
const number: number = 536870912;
const expectedHexString = '0x20000000';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given decimal number', () => {
assert.equal(hexString, expectedHexString);
});
});
describe('Variant #5: bigint number `10n`', () => {
// @ts-ignore
const number: bigint = 10n;
const expectedHexString = '0xan';
let hexString: string;
before(() => {
hexString = NumberUtils.toHex(number);
});
it('should create a string with hexadecimal value from a given bigint number', () => {
assert.equal(hexString, expectedHexString);
});
});
});
describe('extractIntegerAndDecimalParts', () => {
describe('Variant #1: number `0`', () => {
const number: number = 0;
const expectedParts: [number, number | null] = [0, null];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
});
describe('Variant #2: number `10`', () => {
const number: number = 10;
const expectedParts: [number, number | null] = [10, null];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
});
describe('Variant #3: number `-17`', () => {
const number: number = -17;
const expectedParts: [number, number | null] = [-17, null];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
});
describe('Variant #4: number `0.0000000001`', () => {
const number: number = 0.0000000001;
const expectedParts: [number, number | null] = [0, 0.0000000001];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
it('should return an initial number after sum of extracted parts', () => {
assert.equal(number, parts[0] + parts[1]!);
});
});
describe('Variant #5: number `10.0002`', () => {
const number: number = 10.0002;
const expectedParts: [number, number | null] = [10, 0.00019999999999953388];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts (with inaccuracy of float numbers)', () => {
assert.deepEqual(parts, expectedParts);
});
it('should return an initial number after sum of extracted parts', () => {
assert.equal(number, parts[0] + parts[1]!);
});
});
describe('Variant #6: number `1e-13`', () => {
const number: number = 1e-13;
const expectedParts: [number, number | null] = [0, 1e-13];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
it('should return an initial number after sum of extracted parts', () => {
assert.equal(number, parts[0] + parts[1]!);
});
});
describe('Variant #7: number `-1e-100`', () => {
const number: number = -1e-100;
const expectedParts: [number, number | null] = [-0, -1e-100];
let parts: [number, number | null];
before(() => {
parts = NumberUtils.extractIntegerAndDecimalParts(number);
});
it('should extract integer and decimal parts', () => {
assert.deepEqual(parts, expectedParts);
});
it('should return an initial number after sum of extracted parts', () => {
assert.equal(number, parts[0] + parts[1]!);
});
});
});
describe('isCeil', () => {
describe('given number is a ceil', () => {
const number: number = 4;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isCeil(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
describe('given number is a float', () => {
const number: number = 4.5;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isCeil(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('bigint number', () => {
// @ts-ignore
const number: bigint = 10n;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isCeil(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
});
describe('isPositive', () => {
describe('Variant #1: positive integer', () => {
const number: number = 2;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isPositive(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #2: positive zero', () => {
const number: number = 0;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isPositive(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #3: negative integer', () => {
const number: number = -2;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isPositive(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #4: negative zero', () => {
const number: number = -0;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isPositive(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #5: NaN', () => {
const number: number = NaN;
let testFunc: () => void;
before(() => {
testFunc = () => NumberUtils.isPositive(number);
});
it('should throw an error', () => {
assert.throw(testFunc, 'Given value is NaN');
});
});
});
describe('isUnsafeNumber', () => {
describe('Positive number', () => {
describe('Variant #1: positive small safe integer', () => {
const number: number = 100;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #2: positive big safe integer', () => {
const number: number = Number.MAX_SAFE_INTEGER;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #3: positive unsafe integer', () => {
const number: number = Number.MAX_SAFE_INTEGER + 1;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
});
describe('Negative number', () => {
describe('Variant #1: negative small safe integer', () => {
const number: number = -100;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #2: negative big safe integer', () => {
const number: number = Number.MIN_SAFE_INTEGER;
const expectedResult: boolean = false;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return false', () => {
assert.equal(result, expectedResult);
});
});
describe('Variant #3: negative unsafe integer', () => {
const number: number = Number.MIN_SAFE_INTEGER - 1;
const expectedResult: boolean = true;
let result: boolean;
before(() => {
result = NumberUtils.isUnsafeNumber(number);
});
it('should return true', () => {
assert.equal(result, expectedResult);
});
});
});
describe('NaN', () => {
const number: number = NaN;
let testFunc: () => void;
before(() => {
testFunc = () => NumberUtils.isUnsafeNumber(number);
});
it('should throw an error', () => {
assert.throw(testFunc, 'Given value is NaN');
});
});
});
describe('getFactors', () => {
describe('Positive numbers', () => {
describe('Variant #1: positive number `1`', () => {
const number: number = 1;
const expectedFactors: number[] = [-1, 1];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #2: positive number `2`', () => {
const number: number = 2;
const expectedFactors: number[] = [-2, -1, 1, 2];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #3: positive number `100`', () => {
const number: number = 100;
const expectedFactors: number[] = [
-100, -50, -25, -20, -10, -5, -4, -2, -1, 1, 2, 4, 5, 10, 20, 25, 50, 100
];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #4: positive number `9007199254740991`', () => {
const number: number = 9007199254740991;
const expectedFactors: number[] = [
Number.MIN_SAFE_INTEGER,
-1416003655831,
-129728784761,
-441650591,
-20394401,
-69431,
-6361,
-1,
1,
6361,
69431,
20394401,
441650591,
129728784761,
1416003655831,
Number.MAX_SAFE_INTEGER
];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
});
describe('Negative numbers', () => {
describe('Variant #1: negative number `-1`', () => {
const number: number = -1;
const expectedFactors: number[] = [-1, 1];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #2: negative number `-2`', () => {
const number: number = -2;
const expectedFactors: number[] = [-2, -1, 1, 2];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #3: negative number `-100`', () => {
const number: number = -100;
const expectedFactors: number[] = [
-100, -50, -25, -20, -10, -5, -4, -2, -1, 1, 2, 4, 5, 10, 20, 25, 50, 100
];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
describe('Variant #4: negative number `-9007199254740991`', () => {
const number: number = -9007199254740991;
const expectedFactors: number[] = [
Number.MIN_SAFE_INTEGER,
-1416003655831,
-129728784761,
-441650591,
-20394401,
-69431,
-6361,
-1,
1,
6361,
69431,
20394401,
441650591,
129728784761,
1416003655831,
Number.MAX_SAFE_INTEGER
];
let factors: number[];
before(() => {
factors = NumberUtils.getFactors(number);
});
it('should return factors of a number', () => {
assert.deepEqual(factors, expectedFactors);
});
});
});
describe('zero number', () => {
const number: number = 0;
let testFunc: () => void;
before(() => {
testFunc = () => NumberUtils.getFactors(number);
});
it('should throw an error', () => {
assert.throw(testFunc, Error);
});
});
});
});