From 12536a6d037b58150f79be62ec75de5f3889a49c Mon Sep 17 00:00:00 2001 From: Haijian Wang <30408303+haijian-vaadin@users.noreply.github.com> Date: Mon, 20 Sep 2021 09:56:11 +0300 Subject: [PATCH] fix: NumberModel should read empty string as undefined (#112) --- frontend/packages/form/src/Models.ts | 7 +++++-- frontend/packages/form/test/Field.test.ts | 8 ++++---- frontend/packages/form/test/Model.test.ts | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/frontend/packages/form/src/Models.ts b/frontend/packages/form/src/Models.ts index 2457469de9..b1897f1bab 100644 --- a/frontend/packages/form/src/Models.ts +++ b/frontend/packages/form/src/Models.ts @@ -92,7 +92,7 @@ export class BooleanModel extends PrimitiveModel implements HasFromStri [_fromString] = Boolean; } -export class NumberModel extends PrimitiveModel implements HasFromString { +export class NumberModel extends PrimitiveModel implements HasFromString { static createEmptyValue = Number; constructor( @@ -105,7 +105,10 @@ export class NumberModel extends PrimitiveModel implements HasFromString super(parent, key, optional, new IsNumber(optional), ...validators); } - [_fromString](str: string): number { + [_fromString](str: string): number | undefined { + // Returning undefined is needed to support passing the validation when the value of an optional number field is + // an empty string + if (str === '') return undefined; return isNumeric(str) ? Number.parseFloat(str) : NaN; } } diff --git a/frontend/packages/form/test/Field.test.ts b/frontend/packages/form/test/Field.test.ts index 8b6d1a18dc..dce55140a3 100644 --- a/frontend/packages/form/test/Field.test.ts +++ b/frontend/packages/form/test/Field.test.ts @@ -271,11 +271,11 @@ describe('form/Field', () => { }); it('should update binder value on typing', async () => { - const cases: Array<[string, number]> = [ + const cases: Array<[string, number | undefined]> = [ ['1', 1], ['1.', NaN], // not allowed format ['1.2', 1.2], - ['', NaN], + ['', undefined], ['not a number', NaN], ['.', NaN], ['.1', 0.1], @@ -421,11 +421,11 @@ describe('form/Field', () => { }); it('should update binder value on typing', async () => { - const cases: Array<[string, number]> = [ + const cases: Array<[string, number | undefined]> = [ ['1', 1], ['1.', NaN], // not allowed format ['1.2', 1.2], - ['', NaN], + ['', undefined], ['not a number', NaN], ['.', NaN], ['.1', 0.1], diff --git a/frontend/packages/form/test/Model.test.ts b/frontend/packages/form/test/Model.test.ts index 8cc88300e6..5a07fe3754 100644 --- a/frontend/packages/form/test/Model.test.ts +++ b/frontend/packages/form/test/Model.test.ts @@ -61,14 +61,14 @@ describe('form/Model', () => { }); describe('_fromString', () => { - let fromString: (str: string) => number; + let fromString: (str: string) => number | undefined; beforeEach(() => { fromString = binder.model.fieldNumber[_fromString]; }); it('should disallow empty string', async () => { - expect(fromString('')).to.satisfy(Number.isNaN); + expect(fromString('')).to.equal(undefined); }); it('should integer format', async () => {