Skip to content

Commit

Permalink
Add formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
ogroppo committed Nov 2, 2023
1 parent 8b600aa commit e8e3571
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 25 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# deverything

## 0.34.0

### Minor Changes

- formatters

## 0.33.0

### Minor Changes
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ Contributions always welcome!
- `isInt()`
- `isEven()`
- `isOdd()`
- `isPositive()`
- `isNegative()`
- `isPositiveInt()`
- `isNegativeInt()`
- `isNumeric()`
-`isObject()` if it's a js plain Object
- `isPromise()`
Expand Down Expand Up @@ -90,6 +90,10 @@ Contributions always welcome!
- `truncate()` truncate text, does not break emojis
- `uniqueValues()` gets unique values in an array

### Formatters

- `formatNumber()` 1000 => "1,000" or "1K"

### Random data generators

These functions are optimized for low entropy random data generation useful for Unit Testing, Storybook, Pass real validations, Reverse hacking, Penetration testing...
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deverything",
"version": "0.33.0",
"version": "0.34.0",
"description": "Everything you need for Dev",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
Expand Down Expand Up @@ -29,6 +29,7 @@
"fake",
"generator",
"helpers",
"formatters",
"numbers",
"random",
"testing",
Expand Down
31 changes: 31 additions & 0 deletions src/formatters/formatNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, test } from "@jest/globals";
import { formatNumber } from "./formatNumber";
import { randomInt } from "../random/randomInt";

describe("formatNumber", () => {
test("should return the same number if test is under a thousand", () => {
const value = randomInt(0, 999);
expect(formatNumber(value, { compact: true })).toBe(`${value}`);
});

test("should return a string in compact K notation if value is one thousand or above", () => {
const value = randomInt(1000, 9999);
expect(formatNumber(value, { compact: true })).toContain("K");
});

test("should return a string in compact M notation if value is one million or above", () => {
const value = randomInt(1000000, 9999999);
expect(formatNumber(value, { compact: true })).toContain("M");
});

test("should return a string with thousand separator but no compact notation", () => {
const formattedValue = formatNumber(randomInt(1000000, 9999999));
expect(formattedValue).not.toContain("M");
expect(formattedValue).toContain(",");
});

test("Retains floating point up to 3", () => {
const formattedValue = formatNumber(123456.123456);
expect(formattedValue).toEqual("123,456.123");
});
});
22 changes: 22 additions & 0 deletions src/formatters/formatNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
*
* @example formatNumber(1000, { compact: true }) // 1K
* @example formatNumber(1111, { maxDigits: 2 }) // 1,100
* @example formatNumber(111111.123123123) // 111,111.123
*/
export const formatNumber = (
value: number,
{
compact,
maxDigits,
}: {
compact?: boolean;
maxDigits?: number;
} = {}
): string => {
const formatter = Intl.NumberFormat("en", {
notation: compact ? "compact" : "standard",
maximumSignificantDigits: maxDigits,
});
return formatter.format(value);
};
1 change: 1 addition & 0 deletions src/formatters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./formatNumber";
1 change: 1 addition & 0 deletions src/helpers/arrayDiff.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { uniqueValues } from "./uniqueValues";

// TODO: optimize with maps?
export const arrayDiff = (arr1: any[], arr2: any[]) => {
return uniqueValues(
arr1
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/truncate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isPositive } from "../validators/isNumber";
import { isPositiveInt } from "../validators/isNumber";

export const truncate = (arg: string, limit: number, ellipsis = "...") => {
if (!isPositive(limit)) return arg;
if (!isPositiveInt(limit)) return arg;

const argArray = [...arg]; // convert string to array, emoji and unicode safe

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./math";
export * from "./random";
export * from "./types";
export * from "./validators";
export * from "./formatters";
30 changes: 15 additions & 15 deletions src/validators/isNumber.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { expect, it, describe } from "@jest/globals";
import {
isEven,
isInt,
isNegative,
isNegativeInt,
isNumber,
isOdd,
isPositive,
isPositiveInt,
} from "./isNumber";

describe("isNumber", function () {
Expand Down Expand Up @@ -78,24 +78,24 @@ describe("isNumber", function () {
});
});

describe("isPositive", function () {
describe("isPositiveInt", function () {
it("checks correctly", function () {
expect(isPositive(1)).toBe(true);
expect(isPositive(0)).toBe(false);
expect(isPositive(Infinity)).toBe(false);
expect(isPositive(-0)).toBe(false);
expect(isPositive("0" as unknown as number)).toBe(false);
expect(isPositiveInt(1)).toBe(true);
expect(isPositiveInt(0)).toBe(false);
expect(isPositiveInt(Infinity)).toBe(false);
expect(isPositiveInt(-0)).toBe(false);
expect(isPositiveInt("0" as unknown as number)).toBe(false);
});
});

describe("isNegative", function () {
describe("isNegativeInt", function () {
it("checks correctly", function () {
expect(isNegative(1)).toBe(false);
expect(isNegative(-1e12)).toBe(true);
expect(isNegative(0)).toBe(false);
expect(isNegative(Infinity)).toBe(false);
expect(isNegative(-0)).toBe(false);
expect(isNegative("0" as unknown as number)).toBe(false);
expect(isNegativeInt(1)).toBe(false);
expect(isNegativeInt(-1e12)).toBe(true);
expect(isNegativeInt(0)).toBe(false);
expect(isNegativeInt(Infinity)).toBe(false);
expect(isNegativeInt(-0)).toBe(false);
expect(isNegativeInt("0" as unknown as number)).toBe(false);
});
});
});
20 changes: 15 additions & 5 deletions src/validators/isNumber.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
export const isInt = (arg: number) => Number.isInteger(arg);
export const isInt = (arg: any) => Number.isInteger(arg);

export const isEven = (arg: number) => isInt(arg) && !(arg % 2);
export const isEven = (arg: any) => isInt(arg) && !(arg % 2);

export const isOdd = (arg: number) => isInt(arg) && !!(arg % 2);
export const isOdd = (arg: any) => isInt(arg) && !!(arg % 2);

export const isPositive = (arg: number) => isInt(arg) && arg > 0;
/**
* @deprecated use isPositiveInt instead
*/
export const isPositive = (arg: any) => isInt(arg) && arg > 0;

export const isNegative = (arg: number) => isInt(arg) && arg < 0;
export const isPositiveInt = (arg: any) => isInt(arg) && arg > 0;

/**
* @deprecated use isNegativeInt instead
*/
export const isNegative = (arg: any) => isInt(arg) && arg < 0;

export const isNegativeInt = (arg: any) => isInt(arg) && arg < 0;

export const isNumber = (arg: any): arg is number => {
return (
Expand Down

0 comments on commit e8e3571

Please sign in to comment.