Skip to content

Commit

Permalink
add number utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrkulpinski committed Apr 26, 2024
1 parent a979e7d commit 285408d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 11 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@curiousleaf/utils",
"description": "A lightweight set of utilities",
"version": "1.0.26",
"version": "1.0.27",
"license": "MIT",
"type": "module",
"author": {
Expand All @@ -15,7 +15,7 @@
"scripts": {
"build": "bun build ./src/index.ts --outdir ./dist && bun run build:declaration",
"build:declaration": "tsc --emitDeclarationOnly",
"lint": "bun biome lint .",
"lint": "bun biome lint --apply .",
"format": "bun biome format --write ."
},
"dependencies": {
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,11 @@ export const setInputValue = (
) => {
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype,
'value',
"value",
)?.set

nativeInputValueSetter?.call(input, value)

// Trigger a change event if the value was changed
triggerChange && input?.dispatchEvent(new Event('input', { bubbles: true }))
triggerChange && input?.dispatchEvent(new Event("input", { bubbles: true }))
}
30 changes: 28 additions & 2 deletions src/numbers/numbers.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from "bun:test"

import { keepNumberInRange, parseNumericValue } from "./numbers"
import { keepNumberInRange, parseNumericValue, preciseRound } from "./numbers"

describe("keepNumberInRange", () => {
it("returns the same value if no range is specified", () => {
Expand Down Expand Up @@ -34,6 +34,32 @@ describe("parseNumericValue", () => {
})

it("returns the original string if it cannot be parsed", () => {
expect(parseNumericValue("not a number")).toBe("not a number")
expect(parseNumericValue("not a number")).toBe(undefined)
})
})

describe("preciseRound", () => {
it("rounds to 2 decimal places by default", () => {
expect(preciseRound(2.345)).toEqual(2.35)
})

it("rounds to specified decimal places", () => {
expect(preciseRound(2.34567, 3)).toEqual(2.346)
})

it("handles rounding up at 0.5 exactly", () => {
expect(preciseRound(2.005, 2)).toEqual(2.01)
})

it("handles negative numbers", () => {
expect(preciseRound(-2.345)).toEqual(-2.34)
})

it("rounds to 0 decimal places correctly", () => {
expect(preciseRound(2.5, 0)).toEqual(3)
})

it("trims the number of decimal places if the value is an integer", () => {
expect(preciseRound(2.0000003, 2)).toEqual(2)
})
})
23 changes: 18 additions & 5 deletions src/numbers/numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,24 @@ export const keepNumberInRange = (value: number, min?: number, max?: number) =>

/**
* Parse a string into a numeric value.
* @param string - The string to parse.
* @returns The parsed numeric value, or the original string if it cannot be parsed.
* @param value - The value to parse into a numeric value.
* @returns The parsed numeric value, or `undefined` if the value cannot be parsed.
*/
export const parseNumericValue = (string: string) => {
const number = Number.parseFloat(string)
export const parseNumericValue = (value?: string | number | null) => {
if (value === undefined || value === null) return undefined
const parsed = Number.parseFloat(value.toString())

return Number.isNaN(number) ? string : number
return Number.isNaN(parsed) ? undefined : parsed
}

/**
* Rounds a number to a specified number of decimal places, with an adjustment for floating point precision.
* @param value - The number to round.
* @param decimals - The number of decimal places to round to. Defaults to 2.
* @returns The rounded number.
*/
export const preciseRound = (value: number, decimals = 2) => {
const factor = Math.pow(10, decimals)

return Math.round((value + Number.EPSILON) * factor) / factor
}

0 comments on commit 285408d

Please sign in to comment.