Skip to content

Commit

Permalink
[H-0005] beautifyNumber util
Browse files Browse the repository at this point in the history
  • Loading branch information
kovalenkovpu committed Feb 14, 2023
1 parent 043000c commit 46149ff
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 1 deletion.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ No specific version of nodejs and npm is required, but for the usage as an npm p
- [Common Utilities](#common-utils)
- [removeByKey](#remove-by-key)
- [removeDeepByKey](#remove-deep-by-key)
- [beautifyNumber](#beautify-number)
- [List Utils](#list-utils)
- [findByPrimaryKey](#find-by-primary-key)
- [Contributing](#contributing)
Expand Down Expand Up @@ -212,6 +213,42 @@ const result = removeDeepByKey(['c'], target); -> { a: 'a', b: 'B' }
const targetEqualsResult = result === target; -> true
```

#### <a id="beautify-number"></a> beautifyNumber()

```ts
beautifyNumber(value: number, options: IBeautifyNumberOptions);
```

Produces a formatted string that was created out of the number provided as an input of the function.
Formatting rules:

- splits a whole part of a number by thousands
- adds a `joint` symbol between thousands
- adds a `delimiter` symbol between a whole and a floating part

#### Options

| Name | Type | Required | Default value |
| ------- | ------------------------ | -------- | -------------------------------- |
| value | `number` | + | - |
| options | `IBeautifyNumberOptions` | - | `{ delimiter: '.', joint: ' ' }` |

Examples:

```ts
// Whole numbers
const result = beautifyNumber(1000); -> '1 000'
const result = beautifyNumber(1_000); -> '1 000'

// With floating point
const result = beautifyNumber(1000.123); -> '1 000.123'
const result = beautifyNumber(1000.123, { delimiter: ',' }); -> '1 000,123'
const result = beautifyNumber(1000.123, { delimiter: ',', joint: '_' }); -> '1_000,123'

// Throws error
const result = beautifyNumber(1000.123, { delimiter: ',', joint: ',' }); -> [Error: Please provide different delimiter and joint values]
```

### <a id="list-utils"></a>List Utils

A common function for initializing a bag of useful traversing utilities for going over, finding and mutating nodes within some nested objects structures.
Expand All @@ -228,6 +265,7 @@ Might be useful if you want to create a set of handy functions at one place, bin
| initOptions | `IInitListUtilsOptions` | + | - |

##### `IInitListUtilsOptions`

| Property | Type | Default value |
| ----------- | -------- | ------------- |
| primaryKey | `string` | - |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "handilities",
"version": "0.0.6",
"version": "0.0.7",
"description": "Handy utilities for JS, TS, React in browser and server env",
"main": "lib",
"scripts": {
Expand Down
77 changes: 77 additions & 0 deletions src/common/__tests__/beautifyNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { sameJointAndDelimiterErrorMessage, beautifyNumber } from "../beautifyNumber";

describe("beautifyNumber", () => {
describe("beautifyNumber with no options passed", () => {
test.each([
[1, "1"],
[100, "100"],
[1000, "1 000"],
[100000, "100 000"],
[123456789, "123 456 789"],
])('converts "%s" into "%s"', (value, result) => {
expect(beautifyNumber(value)).toBe(result);
});
});

describe('beautifyNumber with the "," joint', () => {
test.each([
[1, "1"],
[100, "100"],
[1000, "1,000"],
[100000, "100,000"],
[123456789, "123,456,789"],
])('converts "%s" into "%s"', (value, result) => {
expect(beautifyNumber(value, { joint: "," })).toBe(result);
});
});

describe("beautifyNumber for floating numbers", () => {
test.each([
[1.12, "1.12"],
[100.123, "100.123"],
[1000.1234, "1 000.1234"],
[100000.12345, "100 000.12345"],
[123456789.0123456, "123 456 789.0123456"],
])('converts "%s" into "%s"', (value, result) => {
expect(beautifyNumber(value)).toBe(result);
});
});

describe('beautifyNumber for floating numbers with the "_" joint, and "," delimiter', () => {
test.each([
[1.12, "1,12"],
[100.123, "100,123"],
[1000.1234, "1_000,1234"],
[100000.12345, "100_000,12345"],
[123456789.0123456, "123_456_789,0123456"],
])('converts "%s" into "%s"', (value, result) => {
expect(beautifyNumber(value, { joint: "_", delimiter: "," })).toBe(result);
});
});

describe("beautifyNumber for negative floating numbers", () => {
test.each([
[-1.12, "-1.12"],
[-100.123, "-100.123"],
[-1000.1234, "-1 000.1234"],
[-100000.12345, "-100 000.12345"],
[-123456789.0123456, "-123 456 789.0123456"],
])('converts "%s" into "%s"', (value, result) => {
expect(beautifyNumber(value)).toBe(result);
});
});

test('works for "_" number notation', () => {
expect(beautifyNumber(12_001_123)).toBe("12 001 123");
});

test("throws the error if joint and delimiter are equal", () => {
try {
beautifyNumber(12_001_123, { joint: "", delimiter: "" });
} catch (error) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
expect(error.message).toContain(sameJointAndDelimiterErrorMessage);
}
});
});
37 changes: 37 additions & 0 deletions src/common/beautifyNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
interface IBeautifyNumberOptions {
delimiter?: string;
joint?: string;
}

interface IBeautifyNumber {
(value: number, options?: IBeautifyNumberOptions): string;
}

const sameJointAndDelimiterErrorMessage = "Please provide different delimiter and joint values";

const DEFAULT_DELIMITER = ".";
const DEFAULT_JOINT = " ";

/**
*
* @param value number to format based on options
* @param options "joint" symbol to add between thousands, and "delimiter" symbol to join whole and floating parts
* @returns string produced out of a formatted number
*/
const beautifyNumber: IBeautifyNumber = (value, options = {}) => {
const { delimiter = DEFAULT_DELIMITER, joint = DEFAULT_JOINT } = options;

if (delimiter === joint) {
const error = new Error(sameJointAndDelimiterErrorMessage);

throw error;
}

const [whole, decimal] = String(value).split(".");
const wholeWithJoint = whole.replace(/\B(?=(\d{3})+(?!\d))/g, joint);

return decimal ? `${wholeWithJoint}${delimiter}${decimal}` : wholeWithJoint;
};

export type { IBeautifyNumber, IBeautifyNumberOptions };
export { sameJointAndDelimiterErrorMessage, beautifyNumber };
3 changes: 3 additions & 0 deletions src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ export type { IRemoveByKey } from "./removeByKey";

export { initListUtils, findByPrimaryKey } from "./list-utils";
export type { IInitListUtilsOptions, IFindByPrimaryKeyMutation } from "./list-utils";

export { beautifyNumber } from "./beautifyNumber";
export type { IBeautifyNumber, IBeautifyNumberOptions } from "./beautifyNumber";

0 comments on commit 46149ff

Please sign in to comment.