From 6bce4a6970990e713fee823f9c55a380643faaab Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Tue, 19 Feb 2019 17:06:13 -0600 Subject: [PATCH 1/4] add validation meta --- src/widget-core/meta/InputValidity.ts | 22 +++++ tests/widget-core/unit/meta/InputValidity.ts | 87 ++++++++++++++++++++ tests/widget-core/unit/meta/all.ts | 1 + 3 files changed, 110 insertions(+) create mode 100644 src/widget-core/meta/InputValidity.ts create mode 100644 tests/widget-core/unit/meta/InputValidity.ts diff --git a/src/widget-core/meta/InputValidity.ts b/src/widget-core/meta/InputValidity.ts new file mode 100644 index 000000000..8de3cc731 --- /dev/null +++ b/src/widget-core/meta/InputValidity.ts @@ -0,0 +1,22 @@ +import Base from './Base'; + +export class InputValidity extends Base { + get(key: string | number, value: string) { + const node = this.getNode(key) as HTMLFormElement | undefined; + + if (!node) { + return { valid: undefined, message: '' }; + } + + if (value !== node.value) { + setTimeout(() => this.invalidate()); + } + + return { + valid: node.validity.valid, + message: node.validationMessage + }; + } +} + +export default InputValidity; diff --git a/tests/widget-core/unit/meta/InputValidity.ts b/tests/widget-core/unit/meta/InputValidity.ts new file mode 100644 index 000000000..bce094224 --- /dev/null +++ b/tests/widget-core/unit/meta/InputValidity.ts @@ -0,0 +1,87 @@ +const { registerSuite } = intern.getPlugin('jsdom'); +const { assert } = intern.getPlugin('chai'); +// import global from '../../../../src/shim/global'; +import { createSandbox, SinonStub } from 'sinon'; +import InputValidity from '../../../../src/widget-core/meta/InputValidity'; + +import NodeHandler from '../../../../src/widget-core/NodeHandler'; +import WidgetBase from '../../../../src/widget-core/WidgetBase'; + +const sandbox = createSandbox(); +let bindInstance: WidgetBase; +let invalidateStub: SinonStub; +let nodeHandler: NodeHandler; + +registerSuite('meta - InputValidity', { + async before() { + bindInstance = new WidgetBase(); + }, + + beforeEach() { + invalidateStub = sandbox.stub(); + nodeHandler = new NodeHandler(); + }, + + afterEach() { + sandbox.restore(); + }, + + tests: { + 'returns default values when node is not found'() { + sandbox.stub(nodeHandler, 'get').returns(undefined); + const validity = new InputValidity({ + invalidate: invalidateStub, + nodeHandler, + bind: bindInstance + }); + + const { message, valid } = validity.get('test', 'testValue'); + assert.strictEqual(message, ''); + assert.isUndefined(valid); + }, + + 'returns the validity and message for the element'() { + sandbox.stub(nodeHandler, 'get').returns({ + validity: { valid: false }, + value: 'testValue', + validationMessage: 'test validation message' + }); + const validity = new InputValidity({ + invalidate: invalidateStub, + nodeHandler, + bind: bindInstance + }); + + const { message, valid } = validity.get('test', 'testValue'); + assert.strictEqual(message, 'test validation message'); + assert.isFalse(valid); + }, + + async 'calls invalidate if node values do not match'() { + const nodeHandler = new NodeHandler(); + const nodeStub = sandbox + .stub(nodeHandler, 'get') + .withArgs('input') + .returns({ + validity: { valid: true }, + value: 'test1', + validationMessage: '' + }); + + const validity = new InputValidity({ + invalidate: invalidateStub, + nodeHandler, + bind: bindInstance + }); + + validity.get('input', 'test2'); + return new Promise((resolve) => { + setTimeout(() => { + assert.isTrue(invalidateStub.calledOnce); + nodeStub.reset(); + resolve(); + }, 10); + }); + } + } +}); diff --git a/tests/widget-core/unit/meta/all.ts b/tests/widget-core/unit/meta/all.ts index c19b19bdd..7f8bfb008 100644 --- a/tests/widget-core/unit/meta/all.ts +++ b/tests/widget-core/unit/meta/all.ts @@ -3,6 +3,7 @@ import './meta'; import './Dimensions'; import './Drag'; import './Focus'; +import './InputValidity'; import './Intersection'; import './Resize'; import './WebAnimation'; From b6caafa0ac7b029991bbc48a74079946803ffd6a Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Tue, 19 Feb 2019 18:37:12 -0600 Subject: [PATCH 2/4] remove commented out code --- tests/widget-core/unit/meta/InputValidity.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/widget-core/unit/meta/InputValidity.ts b/tests/widget-core/unit/meta/InputValidity.ts index bce094224..8d1dca18d 100644 --- a/tests/widget-core/unit/meta/InputValidity.ts +++ b/tests/widget-core/unit/meta/InputValidity.ts @@ -1,6 +1,5 @@ const { registerSuite } = intern.getPlugin('jsdom'); const { assert } = intern.getPlugin('chai'); -// import global from '../../../../src/shim/global'; import { createSandbox, SinonStub } from 'sinon'; import InputValidity from '../../../../src/widget-core/meta/InputValidity'; From 36bc2ad247eb1ae02cb30325b18822e09afe8e44 Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Tue, 19 Feb 2019 18:47:27 -0600 Subject: [PATCH 3/4] add comment to validation meta about setTimeout --- src/widget-core/meta/InputValidity.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widget-core/meta/InputValidity.ts b/src/widget-core/meta/InputValidity.ts index 8de3cc731..379c59c76 100644 --- a/src/widget-core/meta/InputValidity.ts +++ b/src/widget-core/meta/InputValidity.ts @@ -9,7 +9,11 @@ export class InputValidity extends Base { } if (value !== node.value) { + // if the vdom is out of sync with the real dom our + // validation check will be one render behind. + // Call invalidate on the next loop. setTimeout(() => this.invalidate()); + return { valid: undefined, message: '' }; } return { From 0777041cda40dca3dbad04546ee9e8528662d309 Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Wed, 20 Feb 2019 07:47:06 -0600 Subject: [PATCH 4/4] remove unnecessary return statement --- src/widget-core/meta/InputValidity.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widget-core/meta/InputValidity.ts b/src/widget-core/meta/InputValidity.ts index 379c59c76..689890fee 100644 --- a/src/widget-core/meta/InputValidity.ts +++ b/src/widget-core/meta/InputValidity.ts @@ -13,7 +13,6 @@ export class InputValidity extends Base { // validation check will be one render behind. // Call invalidate on the next loop. setTimeout(() => this.invalidate()); - return { valid: undefined, message: '' }; } return {