From b8ecac3603c01764d83e2b8862f3b6f847321e85 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stephan=20M=C3=BCller?= Date: Mon, 14 May 2018 15:11:27 +0200 Subject: [PATCH] mgr/dashboard: Format small numbers correctly MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The issue was triggered by numbers that a lower than 1. Doing a logarithm with a number lower than 1 leads to negative value that is not handled anywhere in The formatter service as a result the final value will be quirky. The negative number will also be used as index in the units array, where it will return "undefined". Fixes #24081 Signed-off-by: Stephan Müller --- .../shared/services/formatter.service.spec.ts | 16 ++++++++++++++-- .../src/app/shared/services/formatter.service.ts | 16 +++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts index 42f64e9b20d10..d8755337c11b6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts @@ -1,11 +1,13 @@ import { TestBed } from '@angular/core/testing'; import { DimlessBinaryPipe } from '../pipes/dimless-binary.pipe'; +import { DimlessPipe } from '../pipes/dimless.pipe'; import { FormatterService } from './formatter.service'; describe('FormatterService', () => { let service: FormatterService; let dimlessBinaryPipe: DimlessBinaryPipe; + let dimlessPipe: DimlessPipe; const convertToBytesAndBack = (value: string, newValue?: string) => { expect(dimlessBinaryPipe.transform(service.toBytes(value))).toBe(newValue || value); @@ -17,6 +19,7 @@ describe('FormatterService', () => { }); service = new FormatterService(); dimlessBinaryPipe = new DimlessBinaryPipe(service); + dimlessPipe = new DimlessPipe(service); }); it('should be created', () => { @@ -39,7 +42,7 @@ describe('FormatterService', () => { expect(service.truncate(value, 6)).toBe('1234.567899'); expect(service.truncate(value, 7)).toBe('1234.567899'); expect(service.truncate(value, 10)).toBe('1234.567899'); - expect(service.truncate(100.00, 4)).toBe('100'); + expect(service.truncate(100.0, 4)).toBe('100'); }); }); @@ -50,14 +53,23 @@ describe('FormatterService', () => { expect(service.format_number(service, 1024, formats)).toBe('-'); expect(service.format_number(undefined, 1024, formats)).toBe('-'); expect(service.format_number(null, 1024, formats)).toBe('-'); - expect(service.format_number('0', 1024, formats)).toBe('-'); }); it('should test some values', () => { + expect(service.format_number('0', 1024, formats)).toBe('0B'); + expect(service.format_number('0.1', 1024, formats)).toBe('0.1B'); + expect(service.format_number('1.2', 1024, formats)).toBe('1.2B'); expect(service.format_number('1', 1024, formats)).toBe('1B'); expect(service.format_number('1024', 1024, formats)).toBe('1KiB'); expect(service.format_number(23.45678 * Math.pow(1024, 3), 1024, formats)).toBe('23.4568GiB'); }); + + it('should test some dimless values', () => { + expect(dimlessPipe.transform(0.6)).toBe('0.6 '); + expect(dimlessPipe.transform(1000.608)).toBe('1.0006k'); + expect(dimlessPipe.transform(1e10)).toBe('10G'); + expect(dimlessPipe.transform(2.37e16)).toBe('23.7P'); + }); }); describe('toBytes', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts index 341e1ee25231a..c4c610ad3e85a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts @@ -12,8 +12,10 @@ export class FormatterService { if (parts.length === 1) { return value; // integer } else { - return Number.parseFloat(value).toPrecision(decimals + parts[0].length) - .toString().replace(/0+$/, ''); + return Number.parseFloat(value) + .toPrecision(decimals + parts[0].length) + .toString() + .replace(/0+$/, ''); } } @@ -21,12 +23,12 @@ export class FormatterService { if (_.isString(n)) { n = Number(n); } - if (!(_.isNumber(n)) || n === 0) { + if (!_.isNumber(n)) { return '-'; } - const unit = Math.floor(Math.log(n) / Math.log(divisor)); - const truncatedFloat = this.truncate((n / Math.pow(divisor, unit)), decimals); - return truncatedFloat === '' ? '-' : (truncatedFloat + units[unit]); + const unit = n < 1 ? 0 : Math.floor(Math.log(n) / Math.log(divisor)); + const truncatedFloat = this.truncate(n / Math.pow(divisor, unit), decimals); + return truncatedFloat === '' ? '-' : truncatedFloat + units[unit]; } /** @@ -38,7 +40,7 @@ export class FormatterService { toBytes(value: string): number | null { const base = 1024; const units = ['b', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y']; - const m = RegExp('^(\\d+(\.\\d+)?) ?(\[' + units.join('') + '\](b|ib)?)?$', 'i').exec(value); + const m = RegExp('^(\\d+(.\\d+)?) ?([' + units.join('') + '](b|ib)?)?$', 'i').exec(value); if (m === null) { return null; } -- 2.47.3