Skip to content

Commit

Permalink
feat: support rounding the result when converting to the best unit
Browse files Browse the repository at this point in the history
Closes #563
  • Loading branch information
jonahsnider committed Dec 2, 2022
1 parent 932b680 commit 35413cc
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 8 deletions.
14 changes: 10 additions & 4 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ export type Angle = GetAliases<_ConversionFamilyId.Angle>;
// @public
export type Area = GetAliases<_ConversionFamilyId.Area>;

// @public
export type _BestConversion<Q extends number | bigint, U extends BestUnits> = {
quantity: SimplifyQuantity<Q>;
unit: U;
toString(toFixed?: number): `${SimplifyQuantity<Q>}${U}`;
};

// Warning: (ae-forgotten-export) The symbol "Best_2" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "bestUnits" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Indexes" needs to be exported by the entry point index.d.ts
Expand Down Expand Up @@ -86,7 +93,7 @@ export default convert;
// @public
export type Converter<Q extends number | bigint, U extends Unit> = {
to(to: U): SimplifyQuantity<Q>;
to<B extends BestUnits<UnitToFamily[U], K>, K extends Best_2.Kind = Best_2.Kind>(to: 'best', kind?: K | undefined): BestConversion<Q, B>;
to<B extends BestUnits<UnitToFamily[U], K>, K extends Best_2.Kind = Best_2.Kind>(to: 'best', kind?: K | undefined): _BestConversion<Q, B>;
};

// @public
Expand Down Expand Up @@ -138,9 +145,8 @@ export type Volume = GetAliases<_ConversionFamilyId.Volume>;

// Warnings were encountered during analysis:
//
// dist/src/types/common.d.ts:40:5 - (ae-forgotten-export) The symbol "SimplifyQuantity" needs to be exported by the entry point index.d.ts
// dist/src/types/common.d.ts:49:5 - (ae-forgotten-export) The symbol "UnitToFamily" needs to be exported by the entry point index.d.ts
// dist/src/types/common.d.ts:49:5 - (ae-forgotten-export) The symbol "BestConversion" needs to be exported by the entry point index.d.ts
// dist/src/types/common.d.ts:20:5 - (ae-forgotten-export) The symbol "SimplifyQuantity" needs to be exported by the entry point index.d.ts
// dist/src/types/common.d.ts:56:5 - (ae-forgotten-export) The symbol "UnitToFamily" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
29 changes: 29 additions & 0 deletions packages/convert/src/convert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,32 @@ describe('precision loss from converting to best', () => {
expect(result.toString()).toBe(`${1.5 + Number.EPSILON}d`);
});
});

describe('converting to best with rounding', () => {
describe('works when removing decimal places', () => {
testWithBuilds(mod => {
expect(mod.convert(123_456, 'm').to('best').toString(2)).toBe('123.46km');
expect(mod.convert(123_456, 'm').to('best').toString(0)).toBe('123km');
expect(mod.convert(1000, 'micrometer').to('best').toString(1)).toBe('1.0mm');
expect(mod.convert(1000, 'micrometer').to('best').toString(0)).toBe('1mm');
});
});

describe('works when adding decimal places', () => {
testWithBuilds(mod => {
expect(mod.convert(1000, 'm').to('best').toString(4)).toBe('1.0000km');
expect(mod.convert(1000, 'm').to('best').toString(0)).toBe('1km');
expect(mod.convert(1000, 'micrometer').to('best').toString(4)).toBe('1.0000mm');
expect(mod.convert(1000, 'micrometer').to('best').toString(0)).toBe('1mm');
});
});

describe('does nothing when omitted', () => {
testWithBuilds(mod => {
expect(mod.convert(123_456, 'm').to('best').toString()).toBe('123.45599999999999km');
expect(mod.convert(123_456, 'm').to('best').toString(undefined)).toBe('123.45599999999999km');
expect(mod.convert(1000, 'micrometer').to('best').toString()).toBe('1mm');
expect(mod.convert(1000, 'micrometer').to('best').toString(undefined)).toBe('1mm');
});
});
});
8 changes: 6 additions & 2 deletions packages/convert/src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,12 @@ export function to<Q extends number | bigint, U extends Unit, K extends Conversi
return {
quantity,
unit: bestUnit,
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
toString: () => (quantity + bestUnit) as `${SimplifyQuantity<Q>}${BestUnits<UnitToFamily[U], K>}`,
toString: this._isUsingBigInts
? // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
() => ((quantity as bigint) + bestUnit) as `${SimplifyQuantity<Q>}${BestUnits<UnitToFamily[U], K>}`
: (toFixed?: number) =>
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
((toFixed === undefined ? quantity : (quantity as number).toFixed(toFixed)) + bestUnit) as `${SimplifyQuantity<Q>}${BestUnits<UnitToFamily[U], K>}`,
};
}

Expand Down
2 changes: 1 addition & 1 deletion packages/convert/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export * from './convert-many.js';
export * from './convert.js';
export {convert as default} from './convert.js';
export * from './ms.js';
export type {BestUnits, Converter} from './types/common.js';
export type {BestUnits, Converter, BestConversion as _BestConversion} from './types/common.js';
export type {Angle, Area, Data, Energy, Force, GetAliases, Length, Mass, Power, Pressure, Temperature, Time, Unit, Volume} from './types/units.js';
9 changes: 8 additions & 1 deletion packages/convert/src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type BestUnits<

/**
* The return value from converting a unit to `'best'`.
* @public
*/
export type BestConversion<Q extends number | bigint, U extends BestUnits> = {
/**
Expand All @@ -29,8 +30,14 @@ export type BestConversion<Q extends number | bigint, U extends BestUnits> = {
/**
* Join the quantity and the unit together in a string.
* This method is automatically called when casting this object to a string, meaning you can safely do things like concatenate the object with a string.
*
* @param toFixed - The number of decimal places to include in the string.
* The result will be padded with zeros if necessary.
* Providing `undefined` will use the original number of decimal places.
* Providing `0` will round the number to the nearest integer.
* This option is ignored when converting `bigint`s.
*/
toString(): `${SimplifyQuantity<Q>}${U}`;
toString(toFixed?: number): `${SimplifyQuantity<Q>}${U}`;
};

/**
Expand Down

0 comments on commit 35413cc

Please sign in to comment.