Skip to content

Commit

Permalink
Merge pull request #1442 from ytittes/master
Browse files Browse the repository at this point in the history
feat: add Å to SI accepted units
  • Loading branch information
sbliven authored Oct 22, 2024
2 parents 7b85666 + 05f352b commit 30dc21e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
47 changes: 47 additions & 0 deletions src/common/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Currently only covers converToSI
import { convertToSI } from "./utils";

describe("convertToSI", () => {
it("should convert a known unit to SI successfully", () => {
const result = convertToSI(1, "cm");
expect(result.valueSI).toBeCloseTo(0.01);
expect(result.unitSI).toEqual("m");
});

it("should convert angstrom to SI successfully", () => {
const result = convertToSI(1, "Å");
expect(result.valueSI).toBeCloseTo(1e-10);
expect(result.unitSI).toEqual("m");
});

it("should handle different versions of Å in unicode", () => {
const inputUnit = "\u212B"; // Old unicode representation of "Å", is not boolean equal to the one we added.
const result = convertToSI(1, inputUnit);
expect(result.valueSI).toBeCloseTo(1e-10);
expect(result.unitSI).toEqual("m");
});

it("should return the input value and unit if conversion fails", () => {
const result = convertToSI(1, "invalidUnit");
expect(result.valueSI).toEqual(1);
expect(result.unitSI).toEqual("invalidUnit");
});

it("should convert SI units correctly", () => {
const result = convertToSI(1000, "g");
expect(result.valueSI).toBeCloseTo(1);
expect(result.unitSI).toEqual("kg");
});

it("should handle already normalized units", () => {
const result = convertToSI(1, "m");
expect(result.valueSI).toEqual(1);
expect(result.unitSI).toEqual("m");
});

it("should handle negative values properly", () => {
const result = convertToSI(-5, "cm");
expect(result.valueSI).toBeCloseTo(-0.05);
expect(result.unitSI).toEqual("m");
});
});
14 changes: 11 additions & 3 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Logger } from "@nestjs/common";
import { inspect } from "util";
import { DateTime } from "luxon";
import { format, unit } from "mathjs";
import { format, unit, Unit, createUnit } from "mathjs";
import { Expression, FilterQuery, Model, PipelineStage } from "mongoose";
import { DatasetType } from "src/datasets/dataset-type.enum";
import {
Expand All @@ -13,14 +13,22 @@ import {
} from "./interfaces/common.interface";
import { ScientificRelation } from "./scientific-relation.enum";

// add Å to mathjs accepted units as equivalent to angstrom
const isAlphaOriginal = Unit.isValidAlpha;
Unit.isValidAlpha = function (c) {
return isAlphaOriginal(c) || c == "Å";
};
createUnit("Å", "1 angstrom");

export const convertToSI = (
inputValue: number,
inputUnit: string,
): { valueSI: number; unitSI: string } => {
try {
const normalizedUnit = inputUnit.normalize("NFC"); // catch and normalize the different versions of Å in unicode
// Workaround related to a bug reported at https://github.com/josdejong/mathjs/issues/3097 and https://github.com/josdejong/mathjs/issues/2499
const quantity = unit(inputValue, inputUnit)
.to(unit(inputUnit).toSI().toJSON().unit)
const quantity = unit(inputValue, normalizedUnit)
.to(unit(normalizedUnit).toSI().toJSON().unit)
.toJSON();
return { valueSI: Number(quantity.value), unitSI: quantity.unit };
} catch (error) {
Expand Down

0 comments on commit 30dc21e

Please sign in to comment.