Skip to content

Commit

Permalink
feat(formatUtils): add formatWeight utility function (#67)
Browse files Browse the repository at this point in the history
* Add formatWeight to formatUtils module
* Correct docs
* Shorten tests
  • Loading branch information
raptisj authored Mar 27, 2024
1 parent 2cf7683 commit fbb08a2
Show file tree
Hide file tree
Showing 8 changed files with 357 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-taxis-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tsevdos/el-utils": minor
---

Create a formatUtils module and add a formatWeight util
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ The library is currently split into the following modules:
- [getQuarters()](https://github.com/tsevdos/elUtils/blob/main/docs/dateUtils.md#getQuarters)
- [getEras()](https://github.com/tsevdos/elUtils/blob/main/docs/dateUtils.md#getEras)

- [**`formatUtils`**](https://github.com/tsevdos/elUtils/blob/main/docs/formatUtils.md)

- [formatWeight()](https://github.com/tsevdos/elUtils/blob/main/docs/formatUtils.md#formatWeight)

## Contribute

See the [Contributing guide](https://github.com/tsevdos/elUtils/blob/main/CONTRIBUTING.md).
Expand Down
173 changes: 173 additions & 0 deletions data/weights.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
{
"weights": {
"pound": {
"international": "(lb)",
"el": {
"full": "λίβρες",
"short": "lb",
"full_single": "λίβρα"
},
"en": {
"full": "pounds",
"short": "lb",
"full_single": "pound"
}
},
"centigram": {
"international": "(cg)",
"el": {
"full": "εκατοστόγραμμα",
"short": "cg",
"full_single": "εκατοστόγραμμο"
},
"en": {
"full": "centigrams",
"short": "cg",
"full_single": "centigram"
}
},
"carat": {
"international": "(ct)",
"el": {
"full": "καράτια",
"short": "ct",
"full_single": "καράτι"
},
"en": {
"full": "carats",
"short": "ct",
"full_single": "carat"
}
},
"dram": {
"international": "(dr)",
"el": {
"full": "δράμια",
"short": "dr",
"full_single": "δράμι"
},
"en": {
"full": "drams",
"short": "dr",
"full_single": "dram"
}
},
"gram": {
"international": "(g)",
"el": {
"full": "γραμμάρια",
"short": "g",
"full_single": "γραμμάριο"
},
"en": {
"full": "grams",
"short": "g",
"full_single": "gram"
}
},
"grain": {
"international": "(gr)",
"el": {
"full": "κόκκους",
"short": "gr",
"full_single": "κόκκος"
},
"en": {
"full": "grains",
"short": "gr",
"full_single": "grain"
}
},
"hectogram": {
"international": "(hg)",
"el": {
"full": "εκατόγραμμα",
"short": "hg",
"full_single": "εκατόγραμμο"
},
"en": {
"full": "hectograms",
"short": "hg",
"full_single": "hectogram"
}
},
"kilogram": {
"international": "(kg)",
"el": {
"full": "κιλά",
"short": "kg",
"full_single": "κιλό"
},
"en": {
"full": "kilograms",
"short": "kg",
"full_single": "kilogram"
}
},
"kilonewton": {
"international": "(kN)",
"el": {
"full": "κιλονιούτον",
"short": "kN",
"full_single": "κιλονιούτον"
},
"en": {
"full": "kilonewtons",
"short": "kN",
"full_single": "kilonewton"
}
},
"milligram": {
"international": "(mg)",
"el": {
"full": "χιλιοστόγραμμα",
"short": "mg",
"full_single": "χιλιοστόγραμμο"
},
"en": {
"full": "milligrams",
"short": "mg",
"full_single": "milligram"
}
},
"nanogram": {
"international": "(ng)",
"el": {
"full": "νανογραμμάρια",
"short": "ng",
"full_single": "νανογραμμάριο"
},
"en": {
"full": "nanograms",
"short": "ng",
"full_single": "nanogram"
}
},
"ounce": {
"international": "(oz)",
"el": {
"full": "ουγγιές",
"short": "oz",
"full_single": "ουγγιά"
},
"en": {
"full": "ounces",
"short": "oz",
"full_single": "ounce"
}
},
"ton": {
"international": "(t)",
"el": {
"full": "τόνοι",
"short": "t",
"full_single": "τόνος"
},
"en": {
"full": "tons",
"short": "t",
"full_single": "ton"
}
}
}
}
26 changes: 26 additions & 0 deletions docs/formatUtils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# FormatUtils

> The **`formatUtils`** module provides functions for formating data such as weight, speed, time, price, numbers, dates etc.
## Table of Contents

- [**formatWeight()**](#formatWeight)

---

### formatWeight()<a id='formatWeight'></a>

**Description**: Given a type of weight and a value it returns a string that appends the SI symbol and handles the plural/single state.

**Parameters:**

**`value`**: The weight value as a number

**`options`**: An object specifying formating options.

- **`type`**: The type of weight(e.g. pounds, centigrams, kilograms etc.) you want to format.
- **`locale`** (optional, default: "el"): The locale for the type of weight("el" for Greek, "en" for English).
- **`format`** (optional, default: "full"): Makes the weight text short(e.g. p) or full(e.g. pound).
- **`withInternational`** (optional): Appends the International System of Units(SI) symbol at the end(e.g. 2 pounds (lb)).

**Return Type**: A string.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 84 additions & 0 deletions src/__tests__/formatUtils/formatWeight.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { formatWeight, WeightTypes } from "../../formatUtils";

const testSingleValue = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => {
expect(formatWeight(1, { type: typeWeight })).toBe(expectedGrData);
expect(formatWeight(1, { type: typeWeight, locale: "el", format: "full" })).toBe(expectedGrData);
expect(formatWeight(1, { type: typeWeight, locale: "en", format: "full" })).toBe(expectedEnData);
};

const testPluralValue = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => {
expect(formatWeight(2, { type: typeWeight })).toBe(expectedGrData);
expect(formatWeight(2, { type: typeWeight, locale: "el", format: "full" })).toBe(expectedGrData);
expect(formatWeight(2, { type: typeWeight, locale: "en", format: "full" })).toBe(expectedEnData);
};

const testValueWithShortString = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => {
expect(formatWeight(2, { type: typeWeight, format: "short" })).toBe(expectedGrData);
expect(formatWeight(2, { type: typeWeight, locale: "el", format: "short" })).toBe(expectedGrData);
expect(formatWeight(2, { type: typeWeight, format: "short", locale: "en" })).toBe(expectedEnData);
};

const testValueWithInternational = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => {
expect(formatWeight(2, { type: typeWeight, withInternational: true })).toBe(expectedGrData);
expect(formatWeight(2, { type: typeWeight, locale: "en", withInternational: true })).toBe(expectedEnData);
};

describe("formatWeight", () => {
// Pounds
it("returns single pound string", () => {
const expectedGrData = "1 λίβρα";
const expectedEnData = "1 pound";

testSingleValue("pound", expectedGrData, expectedEnData);
});

it("returns multiple pounds string", () => {
const expectedGrData = "2 λίβρες";
const expectedEnData = "2 pounds";

testPluralValue("pound", expectedGrData, expectedEnData);
});

it("returns multiple pounds with short string", () => {
const expectedGrData = "2 lb";
const expectedEnData = "2 lb";

testValueWithShortString("pound", expectedGrData, expectedEnData);
});

it("returns multiple pounds string with international symbol appended", () => {
const expectedGrData = "2 λίβρες (lb)";
const expectedEnData = "2 pounds (lb)";

testValueWithInternational("pound", expectedGrData, expectedEnData);
});

// Centigrams
it("returns single centigram string", () => {
const expectedGrData = "1 εκατοστόγραμμο";
const expectedEnData = "1 centigram";

testSingleValue("centigram", expectedGrData, expectedEnData);
});

it("returns multiple centigrams string", () => {
const expectedGrData = "2 εκατοστόγραμμα";
const expectedEnData = "2 centigrams";

testPluralValue("centigram", expectedGrData, expectedEnData);
});

it("returns multiple centigrams with short string", () => {
const expectedGrData = "2 cg";
const expectedEnData = "2 cg";

testValueWithShortString("centigram", expectedGrData, expectedEnData);
});

it("returns multiple centigrams string with international symbol appended", () => {
const expectedGrData = "2 εκατοστόγραμμα (cg)";
const expectedEnData = "2 centigrams (cg)";

testValueWithInternational("centigram", expectedGrData, expectedEnData);
});
});
62 changes: 62 additions & 0 deletions src/formatUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import weightsData from "../data/weights.json";

export type WeightTypes =
| "pound"
| "kilogram"
| "centigram"
| "carat"
| "dram"
| "gram"
| "grain"
| "hectogram"
| "kilonewton"
| "milligram"
| "nanogram"
| "ounce"
| "ton";

type FormatWeightsOptions = {
locale?: "el" | "en";
type?: WeightTypes;
} & (
| {
format?: "full" | "full_single";
withInternational?: boolean;
}
| {
// we don't want to have both a short format and the international symbol
// since we will end up with "two" symbols e.g 1 lb (lb)
format?: "short";
withInternational?: never;
}
);

type WithInternationalOptions = Pick<FormatWeightsOptions, "type">;

// helper to add international symbol
const withInternationalSymbol = (value: string, options: WithInternationalOptions = {}): string => {
const { type = "pound" } = options;

if (weightsData.weights[type].international) {
return `${value} ${weightsData.weights[type].international}`;
}

return value;
};

export const formatWeight = (value: number, options: FormatWeightsOptions = {}): string => {
const { locale = "el", format = "full", type = "pound", withInternational = false } = options;
let getFormat = format;

if (getFormat !== "short") {
getFormat = value > 1 ? "full" : "full_single";
}

const result = `${value} ${weightsData.weights[type][locale][getFormat]}`;

if (withInternational) {
return withInternationalSymbol(result, { type });
}

return result;
};
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export {
} from "./geoUtils";
export { getDays, getMonths, getQuarters, getEras } from "./dateUtils";
export { validatePostalCode, validateAMKA } from "./validationUtils";
export { formatWeight } from "./formatUtils";

0 comments on commit fbb08a2

Please sign in to comment.