@fractorysolutions/safe-units
Version:
Type-safe TypeScript units of measure
306 lines • 16.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var __1 = require("../..");
var numberMeasure_1 = require("../numberMeasure");
describe("Number measures", function () {
var meters = numberMeasure_1.Measure.dimension("length", "m");
var seconds = numberMeasure_1.Measure.dimension("time", "s");
var kilograms = numberMeasure_1.Measure.dimension("mass", "kg");
var mps = meters.per(seconds);
var mps2 = mps.per(seconds);
describe("dimension", function () {
it("should create dimensions with value 1", function () {
expect(numberMeasure_1.Measure.dimension("foo", "f")).toEqual({
value: 1,
unit: { foo: ["f", "1"] },
symbol: "f",
});
});
});
describe("construction", function () {
it("should construct from a number of and a unit", function () {
var measure = numberMeasure_1.Measure.of(10, mps2);
expect(measure.value).toBe(10);
expect(measure.unit).toEqual(mps2.unit);
});
it("should construct from a number and another measure", function () {
var kilometer = numberMeasure_1.Measure.of(1000, meters);
var measure = numberMeasure_1.Measure.of(5.2, kilometer);
expect(measure.value).toBe(5200);
expect(measure.unit).toEqual(meters.unit);
});
it("should construct dimensionless values", function () {
var dimensionless = numberMeasure_1.Measure.dimensionless(3);
expect(dimensionless.value).toBe(3);
expect(dimensionless.unit).toEqual({});
});
});
describe("prefixes", function () {
var kilo = numberMeasure_1.Measure.prefix("k", 1000);
it("should scale the base unit", function () {
var km = kilo(meters);
expect(km.unit).toEqual(meters.unit);
expect(km.value).toBe(1000);
});
it("should apply a prefix when a symbol is present on the base unit", function () {
expect(kilo(meters).symbol).toBe("km");
});
it("should not apply a prefix when a symbol is not present on the base unit", function () {
var blargs = numberMeasure_1.Measure.of(1e-3, meters);
var kblargs = kilo(blargs);
expect(kblargs.symbol).toBeUndefined();
expect(kblargs.value).toBe(1);
});
});
describe("math", function () {
it("arithmetic", function () {
expect(numberMeasure_1.Measure.add(numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(-5, mps))).toEqual(numberMeasure_1.Measure.of(0, mps));
expect(numberMeasure_1.Measure.subtract(numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(-5, mps))).toEqual(numberMeasure_1.Measure.of(10, mps));
expect(numberMeasure_1.Measure.multiply(numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(10, seconds))).toEqual(numberMeasure_1.Measure.of(50, meters));
expect(numberMeasure_1.Measure.divide(numberMeasure_1.Measure.of(50, meters), numberMeasure_1.Measure.of(10, seconds))).toEqual(numberMeasure_1.Measure.of(5, mps));
});
it("abs", function () {
expect(numberMeasure_1.Measure.abs(numberMeasure_1.Measure.of(-10, mps))).toEqual(numberMeasure_1.Measure.of(10, mps));
});
it("cbrt", function () {
expect(numberMeasure_1.Measure.cbrt(numberMeasure_1.Measure.of(64, seconds.cubed()))).toEqual(numberMeasure_1.Measure.of(4, seconds));
});
it("ceil", function () {
expect(numberMeasure_1.Measure.ceil(numberMeasure_1.Measure.of(3.4, mps))).toEqual(numberMeasure_1.Measure.of(4, mps));
});
it("floor", function () {
expect(numberMeasure_1.Measure.floor(numberMeasure_1.Measure.of(7.8, mps))).toEqual(numberMeasure_1.Measure.of(7, mps));
});
it("hypot", function () {
expect(numberMeasure_1.Measure.hypot(numberMeasure_1.Measure.of(3, meters), numberMeasure_1.Measure.of(4, meters))).toEqual(numberMeasure_1.Measure.of(5, meters));
});
it("max", function () {
expect(numberMeasure_1.Measure.max(numberMeasure_1.Measure.of(10, mps), numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(15, mps))).toEqual(numberMeasure_1.Measure.of(15, mps));
});
it("min", function () {
expect(numberMeasure_1.Measure.min(numberMeasure_1.Measure.of(10, mps), numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(15, mps))).toEqual(numberMeasure_1.Measure.of(5, mps));
});
it("pow", function () {
expect(numberMeasure_1.Measure.pow(numberMeasure_1.Measure.of(3, meters), "4")).toEqual(numberMeasure_1.Measure.of(81, meters.toThe("4")));
});
it("round", function () {
expect(numberMeasure_1.Measure.round(numberMeasure_1.Measure.of(7.8, mps))).toEqual(numberMeasure_1.Measure.of(8, mps));
});
it("sqrt", function () {
expect(numberMeasure_1.Measure.sqrt(numberMeasure_1.Measure.of(25, meters.squared()))).toEqual(numberMeasure_1.Measure.of(5, meters));
});
it("sum", function () {
expect(numberMeasure_1.Measure.sum(numberMeasure_1.Measure.of(10, mps), numberMeasure_1.Measure.of(5, mps), numberMeasure_1.Measure.of(15, mps))).toEqual(numberMeasure_1.Measure.of(30, mps));
});
it("trunc", function () {
expect(numberMeasure_1.Measure.trunc(numberMeasure_1.Measure.of(-7.8, mps))).toEqual(numberMeasure_1.Measure.of(-7, mps));
});
});
describe("arithmetic", function () {
it("should negate", function () {
var value = numberMeasure_1.Measure.of(10, mps);
expect(value.negate()).toEqual(numberMeasure_1.Measure.of(-10, mps));
});
it("should add", function () {
var left = numberMeasure_1.Measure.of(10, mps);
var right = numberMeasure_1.Measure.of(5, mps);
expect(left.plus(right)).toEqual(numberMeasure_1.Measure.of(15, mps));
});
it("should subtract", function () {
var left = numberMeasure_1.Measure.of(10, seconds);
var right = numberMeasure_1.Measure.of(5, seconds);
expect(left.minus(right)).toEqual(numberMeasure_1.Measure.of(5, seconds));
});
it("should multiply", function () {
var left = numberMeasure_1.Measure.of(10, mps);
var right = numberMeasure_1.Measure.of(5, seconds);
expect(left.times(right)).toEqual(numberMeasure_1.Measure.of(50, meters));
});
it("should divide", function () {
var left = numberMeasure_1.Measure.of(10, mps);
var right = numberMeasure_1.Measure.of(5, seconds);
expect(left.over(right)).toEqual(numberMeasure_1.Measure.of(2, mps2));
expect(left.per(right)).toEqual(numberMeasure_1.Measure.of(2, mps2));
expect(left.div(right)).toEqual(numberMeasure_1.Measure.of(2, mps2));
});
it("should scale", function () {
var value = numberMeasure_1.Measure.of(10, mps);
expect(value.scale(2)).toEqual(numberMeasure_1.Measure.of(20, mps));
});
it("should exponentiate", function () {
var value = numberMeasure_1.Measure.of(10, meters);
expect(value.inverse()).toEqual(numberMeasure_1.Measure.of(0.1, meters.inverse()));
expect(value.reciprocal()).toEqual(numberMeasure_1.Measure.of(0.1, meters.inverse()));
expect(value.toThe("0")).toEqual(numberMeasure_1.Measure.dimensionless(1));
expect(value.toThe("1")).toEqual(numberMeasure_1.Measure.of(10, meters));
expect(value.squared()).toEqual(numberMeasure_1.Measure.of(100, meters.squared()));
expect(value.cubed()).toEqual(numberMeasure_1.Measure.of(1000, meters.cubed()));
});
});
describe("comparison", function () {
var zero = numberMeasure_1.Measure.of(0, meters);
var five = numberMeasure_1.Measure.of(5, meters);
var ten = numberMeasure_1.Measure.of(10, meters);
it("should compare less than", function () {
expect(five.lt(zero)).toBe(false);
expect(five.lt(five)).toBe(false);
expect(five.lt(ten)).toBe(true);
});
it("should compare less than or equal to", function () {
expect(five.lte(zero)).toBe(false);
expect(five.lte(five)).toBe(true);
expect(five.lte(ten)).toBe(true);
});
it("should compare equal to", function () {
expect(five.eq(zero)).toBe(false);
expect(five.eq(five)).toBe(true);
expect(five.eq(ten)).toBe(false);
});
it("should compare not equal to", function () {
expect(five.neq(zero)).toBe(true);
expect(five.neq(five)).toBe(false);
expect(five.neq(ten)).toBe(true);
});
it("should compare greater than or equal to", function () {
expect(five.gte(zero)).toBe(true);
expect(five.gte(five)).toBe(true);
expect(five.gte(ten)).toBe(false);
});
it("should compare greater than", function () {
expect(five.gt(zero)).toBe(true);
expect(five.gt(five)).toBe(false);
expect(five.gt(ten)).toBe(false);
});
});
describe("symbols", function () {
it("should assign a symbol via .of()", function () {
expect(numberMeasure_1.Measure.of(1000, meters, "km").symbol).toBe("km");
});
it("should copy assign a symbol via .withSymbol()", function () {
var original = numberMeasure_1.Measure.of(1000, meters);
var result = original.withSymbol("km");
expect(result).not.toBe(original);
expect(original.symbol).toBeUndefined();
expect(result.symbol).toBe("km");
});
it("should not pass along symbols through operations", function () {
var km = numberMeasure_1.Measure.of(1000, meters.squared()).withSymbol("km2");
var dm = numberMeasure_1.Measure.of(10, meters.squared()).withSymbol("dm2");
expect(km.negate().symbol).toBeUndefined();
expect(km.squared().symbol).toBeUndefined();
expect(km.inverse().symbol).toBeUndefined();
expect(km.plus(dm).symbol).toBeUndefined();
expect(km.minus(dm).symbol).toBeUndefined();
expect(km.times(dm).symbol).toBeUndefined();
expect(km.over(dm).symbol).toBeUndefined();
});
});
describe("formatting", function () {
function expectFormat(unit, formatted, formatter) {
expect(unit.toString(formatter)).toBe(formatted);
}
it("should format dimensionless units", function () {
expectFormat(numberMeasure_1.Measure.dimensionless(10), "10");
});
it("should format base units", function () {
expectFormat(meters, "1 m");
});
it("should format units with only positive exponents", function () {
expectFormat(meters.squared(), "1 m^2");
expectFormat(meters.times(seconds), "1 m * s");
expectFormat(meters.cubed().times(seconds.squared()), "1 m^3 * s^2");
});
it("should format units with only negative exponents", function () {
expectFormat(seconds.inverse(), "1 s^-1");
expectFormat(seconds.toThe("-2"), "1 s^-2");
expectFormat(seconds.toThe("-2").times(meters.toThe("-3")), "1 m^-3 * s^-2");
});
it("should format units with positive exponents and one negative exponent", function () {
expectFormat(meters.per(seconds), "1 m / s");
expectFormat(meters.squared().per(seconds.squared()), "1 m^2 / s^2");
expectFormat(meters.times(kilograms).per(seconds.squared()), "1 kg * m / s^2");
});
it("should format units with positive exponents and negative exponents", function () {
expectFormat(meters.per(seconds.times(kilograms)), "1 m / (kg * s)");
expectFormat(meters.squared().per(seconds.squared().times(kilograms)), "1 m^2 / (kg * s^2)");
expectFormat(meters
.cubed()
.times(kilograms)
.per(kilograms.cubed())
.per(seconds.squared()), "1 m^3 / (kg^2 * s^2)");
});
it("should have consistent formatting no matter how the unit is constructed", function () {
var metersTimesSecond = "1 m * s";
expectFormat(meters.times(seconds), metersTimesSecond);
expectFormat(seconds.times(meters), metersTimesSecond);
var metersPerSecond = "1 m / s";
expectFormat(meters.per(seconds), metersPerSecond);
expectFormat(seconds.inverse().times(meters), metersPerSecond);
});
it("should not format using symbol even if present", function () {
expect(numberMeasure_1.Measure.of(5, meters.squared()).withSymbol("m2").toString()).toBe("5 m^2");
expect(numberMeasure_1.Measure.dimensionless(0).withSymbol("rad").toString()).toBe("0");
});
it("should format measures as other measures with symbols", function () {
var kilometers = numberMeasure_1.Measure.of(1000, meters, "km");
expect(numberMeasure_1.Measure.of(10000, meters).in(kilometers)).toBe("10 km");
});
it("should use normal formatting if the other measure has no symbol", function () {
var kilometers = numberMeasure_1.Measure.of(1000, meters);
expect(numberMeasure_1.Measure.of(1000, meters).in(kilometers)).toBe("1000 m");
});
it("should use base unit symbols to format when available", function () {
var m = numberMeasure_1.Measure.dimension("test-length", "meter");
var s = numberMeasure_1.Measure.dimension("test-time", "second");
expect(m.toString()).toBe("1 meter");
expect(numberMeasure_1.Measure.of(1, m.per(s)).toString()).toBe("1 meter / second");
expect(numberMeasure_1.Measure.of(1, m.squared().per(s.squared())).toString()).toBe("1 meter^2 / second^2");
});
it("should use a custom formatter for values if provided", function () {
expectFormat(numberMeasure_1.Measure.of(3.14159, meters), "3.14 m", {
formatValue: function (value) { return value.toPrecision(3); },
});
});
it("should use a custom formatter for units if provided", function () {
expectFormat(numberMeasure_1.Measure.of(3.14159, meters), "3.14159 meters", {
formatUnit: function () { return "meters"; },
});
});
it("should use both custom formatters if provided", function () {
expectFormat(numberMeasure_1.Measure.of(3.14159, meters), "3.142 meters", {
formatValue: function (value) { return value.toPrecision(4); },
formatUnit: function () { return "meters"; },
});
});
it("should not use a custom formatter for units when expressing in terms of another measure", function () {
var kilometers = numberMeasure_1.Measure.of(1000, meters, "km");
expect(numberMeasure_1.Measure.of(20, kilometers).in(kilometers, {
formatValue: function (value) { return value.toExponential(); },
formatUnit: function () { return "kilometers"; },
})).toBe("2e+1 km");
});
it("should use a custom formatter for units when expressing in terms of another unit with no symbol", function () {
var kilometers = numberMeasure_1.Measure.of(1000, meters);
expect(numberMeasure_1.Measure.of(20, kilometers).in(kilometers, {
formatUnit: function () { return "meters"; },
})).toBe("20000 meters");
});
});
describe("conversion", function () {
it("should calculate meters to kilometers correctly", function () {
expect(numberMeasure_1.Measure.of(10000, meters).valueIn((0, __1.kilo)(meters))).toBe(10);
});
it("should calculate feet to meters correctly", function () {
expect(numberMeasure_1.Measure.of(10, __1.feet).valueIn(meters)).toBeCloseTo(3.048);
});
});
describe("utils", function () {
it("should clone", function () {
var original = numberMeasure_1.Measure.of(100, meters);
var copy = original.clone();
expect(original).not.toBe(copy);
expect(original).toEqual(copy);
});
});
});
//# sourceMappingURL=numberMeasureTests.js.map