Commit 5ebaa5ca authored by Miguel Rincon's avatar Miguel Rincon Committed by Peter Hegman

Allow spaces between number and unit in formatter

This change adds a new configuration option to number formatters to have
spaces (or other strings) separating the formatted number from units

The new option is called `unitSeparator`, and it can be passed to
formatters that use units, for example:

```
// default behavior
expect(kilobytes(1, 0)).toBe('1.0kB');

// new behavior
expect(kilobytes(1, 0, { unitSeparator: ' ' })).toBe('1.0 kB');
```
parent 861f5285
...@@ -5,7 +5,7 @@ import { formatNumber } from '~/locale'; ...@@ -5,7 +5,7 @@ import { formatNumber } from '~/locale';
* *
* @param {Number} number to be converted * @param {Number} number to be converted
* *
* @param {options.maxCharLength} Max output char length at the * @param {options.maxLength} Max output char length at the
* expense of precision, if the output is longer than this, * expense of precision, if the output is longer than this,
* the formatter switches to using exponential notation. * the formatter switches to using exponential notation.
* *
...@@ -16,16 +16,35 @@ import { formatNumber } from '~/locale'; ...@@ -16,16 +16,35 @@ import { formatNumber } from '~/locale';
* `formatNumber` such as `valueFactor`, `unit` and `style`. * `formatNumber` such as `valueFactor`, `unit` and `style`.
* *
*/ */
const formatNumberNormalized = (value, { maxCharLength, valueFactor = 1, ...options }) => { const formatNumberNormalized = (value, { maxLength, valueFactor = 1, ...options }) => {
const formatted = formatNumber(value * valueFactor, options); const formatted = formatNumber(value * valueFactor, options);
if (maxCharLength !== undefined && formatted.length > maxCharLength) { if (maxLength !== undefined && formatted.length > maxLength) {
// 123456 becomes 1.23e+8 // 123456 becomes 1.23e+8
return value.toExponential(2); return value.toExponential(2);
} }
return formatted; return formatted;
}; };
/**
* This function converts the old positional arguments into an options
* object.
*
* This is done so we can support legacy fractionDigits and maxLength as positional
* arguments, as well as the better options object.
*
* @param {Object|Number} options
* @returns {Object} options given to the formatter
*/
const getFormatterArguments = (options) => {
if (typeof options === 'object' && options !== null) {
return options;
}
return {
maxLength: options,
};
};
/** /**
* Formats a number as a string scaling it up according to units. * Formats a number as a string scaling it up according to units.
* *
...@@ -40,7 +59,9 @@ const scaledFormatter = (units, unitFactor = 1000) => { ...@@ -40,7 +59,9 @@ const scaledFormatter = (units, unitFactor = 1000) => {
return new RangeError(`unitFactor cannot have the value 0.`); return new RangeError(`unitFactor cannot have the value 0.`);
} }
return (value, fractionDigits) => { return (value, fractionDigits, options) => {
const { maxLength, unitSeparator = '' } = getFormatterArguments(options);
if (value === null) { if (value === null) {
return ''; return '';
} }
...@@ -66,11 +87,13 @@ const scaledFormatter = (units, unitFactor = 1000) => { ...@@ -66,11 +87,13 @@ const scaledFormatter = (units, unitFactor = 1000) => {
} }
const unit = units[scale]; const unit = units[scale];
const length = maxLength !== undefined ? maxLength - unit.length : undefined;
return `${formatNumberNormalized(num, { return `${formatNumberNormalized(num, {
maxLength: length,
maximumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits,
minimumFractionDigits: fractionDigits, minimumFractionDigits: fractionDigits,
})}${unit}`; })}${unitSeparator}${unit}`;
}; };
}; };
...@@ -78,14 +101,16 @@ const scaledFormatter = (units, unitFactor = 1000) => { ...@@ -78,14 +101,16 @@ const scaledFormatter = (units, unitFactor = 1000) => {
* Returns a function that formats a number as a string. * Returns a function that formats a number as a string.
*/ */
export const numberFormatter = (style = 'decimal', valueFactor = 1) => { export const numberFormatter = (style = 'decimal', valueFactor = 1) => {
return (value, fractionDigits, maxCharLength) => { return (value, fractionDigits, options) => {
return `${formatNumberNormalized(value, { const { maxLength } = getFormatterArguments(options);
maxCharLength,
return formatNumberNormalized(value, {
maxLength,
valueFactor, valueFactor,
style, style,
maximumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits,
minimumFractionDigits: fractionDigits, minimumFractionDigits: fractionDigits,
})}`; });
}; };
}; };
...@@ -93,15 +118,16 @@ export const numberFormatter = (style = 'decimal', valueFactor = 1) => { ...@@ -93,15 +118,16 @@ export const numberFormatter = (style = 'decimal', valueFactor = 1) => {
* Returns a function that formats a number as a string with a suffix. * Returns a function that formats a number as a string with a suffix.
*/ */
export const suffixFormatter = (unit = '', valueFactor = 1) => { export const suffixFormatter = (unit = '', valueFactor = 1) => {
return (value, fractionDigits, maxCharLength) => { return (value, fractionDigits, options) => {
const length = maxCharLength !== undefined ? maxCharLength - unit.length : undefined; const { maxLength, unitSeparator = '' } = getFormatterArguments(options);
const length = maxLength !== undefined ? maxLength - unit.length : undefined;
return `${formatNumberNormalized(value, { return `${formatNumberNormalized(value, {
maxCharLength: length, maxLength: length,
valueFactor, valueFactor,
maximumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits,
minimumFractionDigits: fractionDigits, minimumFractionDigits: fractionDigits,
})}${unit}`; })}${unitSeparator}${unit}`;
}; };
}; };
......
...@@ -126,9 +126,11 @@ export const getFormatter = (format = SUPPORTED_FORMATS.engineering) => { ...@@ -126,9 +126,11 @@ export const getFormatter = (format = SUPPORTED_FORMATS.engineering) => {
* *
* @function * @function
* @param {Number} value - Number to format * @param {Number} value - Number to format
* @param {Number} fractionDigits - precision decimals * @param {Object} options - Formatting options
* @param {Number} maxLength - Max length of formatted number * @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used. * if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const number = getFormatter(SUPPORTED_FORMATS.number); export const number = getFormatter(SUPPORTED_FORMATS.number);
...@@ -137,9 +139,11 @@ export const number = getFormatter(SUPPORTED_FORMATS.number); ...@@ -137,9 +139,11 @@ export const number = getFormatter(SUPPORTED_FORMATS.number);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is rendered as `100%` * @param {Number} value - Number to format, `1` is rendered as `100%`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} maxLength - Max length of formatted number * @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used. * if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const percent = getFormatter(SUPPORTED_FORMATS.percent); export const percent = getFormatter(SUPPORTED_FORMATS.percent);
...@@ -148,9 +152,11 @@ export const percent = getFormatter(SUPPORTED_FORMATS.percent); ...@@ -148,9 +152,11 @@ export const percent = getFormatter(SUPPORTED_FORMATS.percent);
* *
* @function * @function
* @param {Number} value - Number to format, `100` is rendered as `100%` * @param {Number} value - Number to format, `100` is rendered as `100%`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} maxLength - Max length of formatted number * @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used. * if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const percentHundred = getFormatter(SUPPORTED_FORMATS.percentHundred); export const percentHundred = getFormatter(SUPPORTED_FORMATS.percentHundred);
...@@ -159,9 +165,11 @@ export const percentHundred = getFormatter(SUPPORTED_FORMATS.percentHundred); ...@@ -159,9 +165,11 @@ export const percentHundred = getFormatter(SUPPORTED_FORMATS.percentHundred);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is rendered as `1s` * @param {Number} value - Number to format, `1` is rendered as `1s`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} maxLength - Max length of formatted number * @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used. * if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const seconds = getFormatter(SUPPORTED_FORMATS.seconds); export const seconds = getFormatter(SUPPORTED_FORMATS.seconds);
...@@ -170,9 +178,11 @@ export const seconds = getFormatter(SUPPORTED_FORMATS.seconds); ...@@ -170,9 +178,11 @@ export const seconds = getFormatter(SUPPORTED_FORMATS.seconds);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1ms` * @param {Number} value - Number to format, `1` is formatted as `1ms`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} maxLength - Max length of formatted number * @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used. * if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const milliseconds = getFormatter(SUPPORTED_FORMATS.milliseconds); export const milliseconds = getFormatter(SUPPORTED_FORMATS.milliseconds);
...@@ -182,7 +192,11 @@ export const milliseconds = getFormatter(SUPPORTED_FORMATS.milliseconds); ...@@ -182,7 +192,11 @@ export const milliseconds = getFormatter(SUPPORTED_FORMATS.milliseconds);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1B` * @param {Number} value - Number to format, `1` is formatted as `1B`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const decimalBytes = getFormatter(SUPPORTED_FORMATS.decimalBytes); export const decimalBytes = getFormatter(SUPPORTED_FORMATS.decimalBytes);
...@@ -192,7 +206,11 @@ export const decimalBytes = getFormatter(SUPPORTED_FORMATS.decimalBytes); ...@@ -192,7 +206,11 @@ export const decimalBytes = getFormatter(SUPPORTED_FORMATS.decimalBytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1kB` * @param {Number} value - Number to format, `1` is formatted as `1kB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const kilobytes = getFormatter(SUPPORTED_FORMATS.kilobytes); export const kilobytes = getFormatter(SUPPORTED_FORMATS.kilobytes);
...@@ -202,7 +220,11 @@ export const kilobytes = getFormatter(SUPPORTED_FORMATS.kilobytes); ...@@ -202,7 +220,11 @@ export const kilobytes = getFormatter(SUPPORTED_FORMATS.kilobytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1MB` * @param {Number} value - Number to format, `1` is formatted as `1MB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const megabytes = getFormatter(SUPPORTED_FORMATS.megabytes); export const megabytes = getFormatter(SUPPORTED_FORMATS.megabytes);
...@@ -212,7 +234,11 @@ export const megabytes = getFormatter(SUPPORTED_FORMATS.megabytes); ...@@ -212,7 +234,11 @@ export const megabytes = getFormatter(SUPPORTED_FORMATS.megabytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1GB` * @param {Number} value - Number to format, `1` is formatted as `1GB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const gigabytes = getFormatter(SUPPORTED_FORMATS.gigabytes); export const gigabytes = getFormatter(SUPPORTED_FORMATS.gigabytes);
...@@ -222,7 +248,11 @@ export const gigabytes = getFormatter(SUPPORTED_FORMATS.gigabytes); ...@@ -222,7 +248,11 @@ export const gigabytes = getFormatter(SUPPORTED_FORMATS.gigabytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1GB` * @param {Number} value - Number to format, `1` is formatted as `1GB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const terabytes = getFormatter(SUPPORTED_FORMATS.terabytes); export const terabytes = getFormatter(SUPPORTED_FORMATS.terabytes);
...@@ -232,7 +262,11 @@ export const terabytes = getFormatter(SUPPORTED_FORMATS.terabytes); ...@@ -232,7 +262,11 @@ export const terabytes = getFormatter(SUPPORTED_FORMATS.terabytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1PB` * @param {Number} value - Number to format, `1` is formatted as `1PB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const petabytes = getFormatter(SUPPORTED_FORMATS.petabytes); export const petabytes = getFormatter(SUPPORTED_FORMATS.petabytes);
...@@ -242,7 +276,11 @@ export const petabytes = getFormatter(SUPPORTED_FORMATS.petabytes); ...@@ -242,7 +276,11 @@ export const petabytes = getFormatter(SUPPORTED_FORMATS.petabytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1B` * @param {Number} value - Number to format, `1` is formatted as `1B`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const bytes = getFormatter(SUPPORTED_FORMATS.bytes); export const bytes = getFormatter(SUPPORTED_FORMATS.bytes);
...@@ -252,7 +290,11 @@ export const bytes = getFormatter(SUPPORTED_FORMATS.bytes); ...@@ -252,7 +290,11 @@ export const bytes = getFormatter(SUPPORTED_FORMATS.bytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1kB` * @param {Number} value - Number to format, `1` is formatted as `1kB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const kibibytes = getFormatter(SUPPORTED_FORMATS.kibibytes); export const kibibytes = getFormatter(SUPPORTED_FORMATS.kibibytes);
...@@ -262,7 +304,11 @@ export const kibibytes = getFormatter(SUPPORTED_FORMATS.kibibytes); ...@@ -262,7 +304,11 @@ export const kibibytes = getFormatter(SUPPORTED_FORMATS.kibibytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1MB` * @param {Number} value - Number to format, `1` is formatted as `1MB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const mebibytes = getFormatter(SUPPORTED_FORMATS.mebibytes); export const mebibytes = getFormatter(SUPPORTED_FORMATS.mebibytes);
...@@ -272,7 +318,11 @@ export const mebibytes = getFormatter(SUPPORTED_FORMATS.mebibytes); ...@@ -272,7 +318,11 @@ export const mebibytes = getFormatter(SUPPORTED_FORMATS.mebibytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1GB` * @param {Number} value - Number to format, `1` is formatted as `1GB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const gibibytes = getFormatter(SUPPORTED_FORMATS.gibibytes); export const gibibytes = getFormatter(SUPPORTED_FORMATS.gibibytes);
...@@ -282,7 +332,11 @@ export const gibibytes = getFormatter(SUPPORTED_FORMATS.gibibytes); ...@@ -282,7 +332,11 @@ export const gibibytes = getFormatter(SUPPORTED_FORMATS.gibibytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1GB` * @param {Number} value - Number to format, `1` is formatted as `1GB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const tebibytes = getFormatter(SUPPORTED_FORMATS.tebibytes); export const tebibytes = getFormatter(SUPPORTED_FORMATS.tebibytes);
...@@ -292,7 +346,11 @@ export const tebibytes = getFormatter(SUPPORTED_FORMATS.tebibytes); ...@@ -292,7 +346,11 @@ export const tebibytes = getFormatter(SUPPORTED_FORMATS.tebibytes);
* *
* @function * @function
* @param {Number} value - Number to format, `1` is formatted as `1PB` * @param {Number} value - Number to format, `1` is formatted as `1PB`
* @param {Number} fractionDigits - number of precision decimals * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - number of precision decimals
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const pebibytes = getFormatter(SUPPORTED_FORMATS.pebibytes); export const pebibytes = getFormatter(SUPPORTED_FORMATS.pebibytes);
...@@ -301,6 +359,10 @@ export const pebibytes = getFormatter(SUPPORTED_FORMATS.pebibytes); ...@@ -301,6 +359,10 @@ export const pebibytes = getFormatter(SUPPORTED_FORMATS.pebibytes);
* *
* @function * @function
* @param {Number} value - Value to format * @param {Number} value - Value to format
* @param {Number} fractionDigits - precision decimals - Defaults to 2 * @param {Object} options - Formatting options
* @param {Number} options.fractionDigits - precision decimals, defaults to 2
* @param {Number} options.maxLength - Max length of formatted number
* if length is exceeded, exponential format is used.
* @param {String} options.unitSeparator - Separator between value and unit
*/ */
export const engineering = getFormatter(); export const engineering = getFormatter();
...@@ -31,12 +31,17 @@ describe('unit_format/formatter_factory', () => { ...@@ -31,12 +31,17 @@ describe('unit_format/formatter_factory', () => {
expect(formatNumber(12.345, 4)).toBe('12.3450'); expect(formatNumber(12.345, 4)).toBe('12.3450');
}); });
it('formats a large integer with a length limit', () => { it('formats a large integer with a max length - using legacy positional argument', () => {
expect(formatNumber(10 ** 7, undefined)).toBe('10,000,000'); expect(formatNumber(10 ** 7, undefined)).toBe('10,000,000');
expect(formatNumber(10 ** 7, undefined, 9)).toBe('1.00e+7'); expect(formatNumber(10 ** 7, undefined, 9)).toBe('1.00e+7');
expect(formatNumber(10 ** 7, undefined, 10)).toBe('10,000,000'); expect(formatNumber(10 ** 7, undefined, 10)).toBe('10,000,000');
}); });
it('formats a large integer with a max length', () => {
expect(formatNumber(10 ** 7, undefined, { maxLength: 9 })).toBe('1.00e+7');
expect(formatNumber(10 ** 7, undefined, { maxLength: 10 })).toBe('10,000,000');
});
describe('formats with a different locale', () => { describe('formats with a different locale', () => {
let originalLang; let originalLang;
...@@ -92,7 +97,7 @@ describe('unit_format/formatter_factory', () => { ...@@ -92,7 +97,7 @@ describe('unit_format/formatter_factory', () => {
expect(formatSuffix(-1000000)).toBe('-1,000,000pop.'); expect(formatSuffix(-1000000)).toBe('-1,000,000pop.');
}); });
it('formats a floating point nugative number', () => { it('formats a floating point negative number', () => {
expect(formatSuffix(-0.1)).toBe('-0.1pop.'); expect(formatSuffix(-0.1)).toBe('-0.1pop.');
expect(formatSuffix(-0.1, 0)).toBe('-0pop.'); expect(formatSuffix(-0.1, 0)).toBe('-0pop.');
expect(formatSuffix(-0.1, 2)).toBe('-0.10pop.'); expect(formatSuffix(-0.1, 2)).toBe('-0.10pop.');
...@@ -108,10 +113,20 @@ describe('unit_format/formatter_factory', () => { ...@@ -108,10 +113,20 @@ describe('unit_format/formatter_factory', () => {
expect(formatSuffix(10 ** 10)).toBe('10,000,000,000pop.'); expect(formatSuffix(10 ** 10)).toBe('10,000,000,000pop.');
}); });
it('formats a large integer with a length limit', () => { it('formats using a unit separator', () => {
expect(formatSuffix(10, 0, { unitSeparator: ' ' })).toBe('10 pop.');
expect(formatSuffix(10, 0, { unitSeparator: ' x ' })).toBe('10 x pop.');
});
it('formats a large integer with a max length - using legacy positional argument', () => {
expect(formatSuffix(10 ** 7, undefined, 10)).toBe('1.00e+7pop.'); expect(formatSuffix(10 ** 7, undefined, 10)).toBe('1.00e+7pop.');
expect(formatSuffix(10 ** 10, undefined, 10)).toBe('1.00e+10pop.'); expect(formatSuffix(10 ** 10, undefined, 10)).toBe('1.00e+10pop.');
}); });
it('formats a large integer with a max length', () => {
expect(formatSuffix(10 ** 7, undefined, { maxLength: 10 })).toBe('1.00e+7pop.');
expect(formatSuffix(10 ** 10, undefined, { maxLength: 10 })).toBe('1.00e+10pop.');
});
}); });
describe('scaledSIFormatter', () => { describe('scaledSIFormatter', () => {
...@@ -143,6 +158,10 @@ describe('unit_format/formatter_factory', () => { ...@@ -143,6 +158,10 @@ describe('unit_format/formatter_factory', () => {
expect(formatGibibytes(10 ** 10)).toBe('10GB'); expect(formatGibibytes(10 ** 10)).toBe('10GB');
expect(formatGibibytes(10 ** 11)).toBe('100GB'); expect(formatGibibytes(10 ** 11)).toBe('100GB');
}); });
it('formats bytes using a unit separator', () => {
expect(formatGibibytes(1, 0, { unitSeparator: ' ' })).toBe('1 B');
});
}); });
describe('scaled format with offset', () => { describe('scaled format with offset', () => {
...@@ -174,6 +193,19 @@ describe('unit_format/formatter_factory', () => { ...@@ -174,6 +193,19 @@ describe('unit_format/formatter_factory', () => {
expect(formatGigaBytes(10 ** 9)).toBe('1EB'); expect(formatGigaBytes(10 ** 9)).toBe('1EB');
}); });
it('formats bytes using a unit separator', () => {
expect(formatGigaBytes(1, undefined, { unitSeparator: ' ' })).toBe('1 GB');
});
it('formats long byte numbers with max length - using legacy positional argument', () => {
expect(formatGigaBytes(1, 8, 7)).toBe('1.00e+0GB');
});
it('formats long byte numbers with max length', () => {
expect(formatGigaBytes(1, 8)).toBe('1.00000000GB');
expect(formatGigaBytes(1, 8, { maxLength: 7 })).toBe('1.00e+0GB');
});
it('formatting of too large numbers is not suported', () => { it('formatting of too large numbers is not suported', () => {
// formatting YB is out of range // formatting YB is out of range
expect(() => scaledSIFormatter('B', 9)).toThrow(); expect(() => scaledSIFormatter('B', 9)).toThrow();
...@@ -216,6 +248,10 @@ describe('unit_format/formatter_factory', () => { ...@@ -216,6 +248,10 @@ describe('unit_format/formatter_factory', () => {
expect(formatMilligrams(-100)).toBe('-100mg'); expect(formatMilligrams(-100)).toBe('-100mg');
expect(formatMilligrams(-(10 ** 4))).toBe('-10g'); expect(formatMilligrams(-(10 ** 4))).toBe('-10g');
}); });
it('formats using a unit separator', () => {
expect(formatMilligrams(1, undefined, { unitSeparator: ' ' })).toBe('1 mg');
});
}); });
}); });
...@@ -253,6 +289,10 @@ describe('unit_format/formatter_factory', () => { ...@@ -253,6 +289,10 @@ describe('unit_format/formatter_factory', () => {
expect(formatScaledBin(10 * 1024 ** 3)).toBe('10GiB'); expect(formatScaledBin(10 * 1024 ** 3)).toBe('10GiB');
expect(formatScaledBin(100 * 1024 ** 3)).toBe('100GiB'); expect(formatScaledBin(100 * 1024 ** 3)).toBe('100GiB');
}); });
it('formats using a unit separator', () => {
expect(formatScaledBin(1, undefined, { unitSeparator: ' ' })).toBe('1 B');
});
}); });
describe('scaled format with offset', () => { describe('scaled format with offset', () => {
...@@ -288,6 +328,10 @@ describe('unit_format/formatter_factory', () => { ...@@ -288,6 +328,10 @@ describe('unit_format/formatter_factory', () => {
expect(formatGibibytes(100 * 1024 ** 3)).toBe('100EiB'); expect(formatGibibytes(100 * 1024 ** 3)).toBe('100EiB');
}); });
it('formats using a unit separator', () => {
expect(formatGibibytes(1, undefined, { unitSeparator: ' ' })).toBe('1 GiB');
});
it('formatting of too large numbers is not suported', () => { it('formatting of too large numbers is not suported', () => {
// formatting YB is out of range // formatting YB is out of range
expect(() => scaledBinaryFormatter('B', 9)).toThrow(); expect(() => scaledBinaryFormatter('B', 9)).toThrow();
......
...@@ -74,10 +74,13 @@ describe('unit_format', () => { ...@@ -74,10 +74,13 @@ describe('unit_format', () => {
it('seconds', () => { it('seconds', () => {
expect(seconds(1)).toBe('1s'); expect(seconds(1)).toBe('1s');
expect(seconds(1, undefined, { unitSeparator: ' ' })).toBe('1 s');
}); });
it('milliseconds', () => { it('milliseconds', () => {
expect(milliseconds(1)).toBe('1ms'); expect(milliseconds(1)).toBe('1ms');
expect(milliseconds(1, undefined, { unitSeparator: ' ' })).toBe('1 ms');
expect(milliseconds(100)).toBe('100ms'); expect(milliseconds(100)).toBe('100ms');
expect(milliseconds(1000)).toBe('1,000ms'); expect(milliseconds(1000)).toBe('1,000ms');
expect(milliseconds(10_000)).toBe('10,000ms'); expect(milliseconds(10_000)).toBe('10,000ms');
...@@ -87,6 +90,7 @@ describe('unit_format', () => { ...@@ -87,6 +90,7 @@ describe('unit_format', () => {
it('decimalBytes', () => { it('decimalBytes', () => {
expect(decimalBytes(1)).toBe('1B'); expect(decimalBytes(1)).toBe('1B');
expect(decimalBytes(1, 1)).toBe('1.0B'); expect(decimalBytes(1, 1)).toBe('1.0B');
expect(decimalBytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 B');
expect(decimalBytes(10)).toBe('10B'); expect(decimalBytes(10)).toBe('10B');
expect(decimalBytes(10 ** 2)).toBe('100B'); expect(decimalBytes(10 ** 2)).toBe('100B');
...@@ -104,31 +108,37 @@ describe('unit_format', () => { ...@@ -104,31 +108,37 @@ describe('unit_format', () => {
it('kilobytes', () => { it('kilobytes', () => {
expect(kilobytes(1)).toBe('1kB'); expect(kilobytes(1)).toBe('1kB');
expect(kilobytes(1, 1)).toBe('1.0kB'); expect(kilobytes(1, 1)).toBe('1.0kB');
expect(kilobytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 kB');
}); });
it('megabytes', () => { it('megabytes', () => {
expect(megabytes(1)).toBe('1MB'); expect(megabytes(1)).toBe('1MB');
expect(megabytes(1, 1)).toBe('1.0MB'); expect(megabytes(1, 1)).toBe('1.0MB');
expect(megabytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 MB');
}); });
it('gigabytes', () => { it('gigabytes', () => {
expect(gigabytes(1)).toBe('1GB'); expect(gigabytes(1)).toBe('1GB');
expect(gigabytes(1, 1)).toBe('1.0GB'); expect(gigabytes(1, 1)).toBe('1.0GB');
expect(gigabytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 GB');
}); });
it('terabytes', () => { it('terabytes', () => {
expect(terabytes(1)).toBe('1TB'); expect(terabytes(1)).toBe('1TB');
expect(terabytes(1, 1)).toBe('1.0TB'); expect(terabytes(1, 1)).toBe('1.0TB');
expect(terabytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 TB');
}); });
it('petabytes', () => { it('petabytes', () => {
expect(petabytes(1)).toBe('1PB'); expect(petabytes(1)).toBe('1PB');
expect(petabytes(1, 1)).toBe('1.0PB'); expect(petabytes(1, 1)).toBe('1.0PB');
expect(petabytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 PB');
}); });
it('bytes', () => { it('bytes', () => {
expect(bytes(1)).toBe('1B'); expect(bytes(1)).toBe('1B');
expect(bytes(1, 1)).toBe('1.0B'); expect(bytes(1, 1)).toBe('1.0B');
expect(bytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 B');
expect(bytes(10)).toBe('10B'); expect(bytes(10)).toBe('10B');
expect(bytes(100)).toBe('100B'); expect(bytes(100)).toBe('100B');
...@@ -142,26 +152,31 @@ describe('unit_format', () => { ...@@ -142,26 +152,31 @@ describe('unit_format', () => {
it('kibibytes', () => { it('kibibytes', () => {
expect(kibibytes(1)).toBe('1KiB'); expect(kibibytes(1)).toBe('1KiB');
expect(kibibytes(1, 1)).toBe('1.0KiB'); expect(kibibytes(1, 1)).toBe('1.0KiB');
expect(kibibytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 KiB');
}); });
it('mebibytes', () => { it('mebibytes', () => {
expect(mebibytes(1)).toBe('1MiB'); expect(mebibytes(1)).toBe('1MiB');
expect(mebibytes(1, 1)).toBe('1.0MiB'); expect(mebibytes(1, 1)).toBe('1.0MiB');
expect(mebibytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 MiB');
}); });
it('gibibytes', () => { it('gibibytes', () => {
expect(gibibytes(1)).toBe('1GiB'); expect(gibibytes(1)).toBe('1GiB');
expect(gibibytes(1, 1)).toBe('1.0GiB'); expect(gibibytes(1, 1)).toBe('1.0GiB');
expect(gibibytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 GiB');
}); });
it('tebibytes', () => { it('tebibytes', () => {
expect(tebibytes(1)).toBe('1TiB'); expect(tebibytes(1)).toBe('1TiB');
expect(tebibytes(1, 1)).toBe('1.0TiB'); expect(tebibytes(1, 1)).toBe('1.0TiB');
expect(tebibytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 TiB');
}); });
it('pebibytes', () => { it('pebibytes', () => {
expect(pebibytes(1)).toBe('1PiB'); expect(pebibytes(1)).toBe('1PiB');
expect(pebibytes(1, 1)).toBe('1.0PiB'); expect(pebibytes(1, 1)).toBe('1.0PiB');
expect(pebibytes(1, 1, { unitSeparator: ' ' })).toBe('1.0 PiB');
}); });
describe('getFormatter', () => { describe('getFormatter', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment