From 904c0165652d3fccb36a2f79406e9b1d64af1acc Mon Sep 17 00:00:00 2001 From: jenesius Date: Sat, 19 Oct 2024 00:22:16 +0300 Subject: [PATCH] feat: add test for autonomic forms, Hot fix for dispatching events to parent form from autonomic form. --- examples/autonomic-form/App.vue | 4 +- project/pages/test/App.vue | 87 ++++++------------------ project/pages/test/child-form.vue | 24 +++++++ project/pages/test/main.ts | 3 +- project/pages/test/parent-form.vue | 28 ++++++++ src/classes/Form.ts | 20 ++++-- src/classes/FormError.ts | 4 +- tests/units/form/form-changed.spec.ts | 18 +++++ tests/units/hooks/use-form-state.spec.ts | 44 ++++++++++++ 9 files changed, 156 insertions(+), 76 deletions(-) create mode 100644 project/pages/test/child-form.vue create mode 100644 project/pages/test/parent-form.vue diff --git a/examples/autonomic-form/App.vue b/examples/autonomic-form/App.vue index a9fea97..7b92028 100644 --- a/examples/autonomic-form/App.vue +++ b/examples/autonomic-form/App.vue @@ -5,15 +5,17 @@ + + - - - + \ No newline at end of file diff --git a/project/pages/test/child-form.vue b/project/pages/test/child-form.vue new file mode 100644 index 0000000..657d4cb --- /dev/null +++ b/project/pages/test/child-form.vue @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/project/pages/test/main.ts b/project/pages/test/main.ts index 7bd16a2..96fbad8 100644 --- a/project/pages/test/main.ts +++ b/project/pages/test/main.ts @@ -10,6 +10,7 @@ import InputTestDateLocal from "./input-test-date-local.vue"; import InputNativeDate from "./input-native-date.vue"; config({ + inputTypes: { country, "account-type": accountType, @@ -18,7 +19,7 @@ config({ 'local-date': InputTestDateLocal, 'native-date': InputNativeDate }, - // debug: true + debug: true }) createApp(App).mount('#app') diff --git a/project/pages/test/parent-form.vue b/project/pages/test/parent-form.vue new file mode 100644 index 0000000..2ffd94d --- /dev/null +++ b/project/pages/test/parent-form.vue @@ -0,0 +1,28 @@ + + + + + \ No newline at end of file diff --git a/src/classes/Form.ts b/src/classes/Form.ts index 9a57530..4af20f5 100644 --- a/src/classes/Form.ts +++ b/src/classes/Form.ts @@ -107,8 +107,11 @@ export default class Form extends EventEmitter implements FormDependence { * */ #changes = {}; get changes(): any { - if (this.parent && !this.autonomic) return getPropFromObject(this.parent.changes, Form.getTargetName(this)); - return this.#changes; + if (!this.parent || this.autonomic) return this.#changes; + + const parentChanges = this.parent.changes; + if (!this.name) throw FormError.FormWithoutName() + return getPropFromObject(parentChanges, this.name); } #values = {} @@ -454,8 +457,6 @@ export default class Form extends EventEmitter implements FormDependence { * Наша система построена так, что бы все значения идут от родителя к дочернему элементу (values, changes, event, other..) * */ dispatchEvent(event: T) { - - if (event instanceof CompareEvent) { debug.msg(`[%c${Form.restoreFullName(this)}%c] %c${event?.comparison.length ? 'found updates' : 'not effect'}%c`, debug.colorName, debug.colorDefault, @@ -464,7 +465,16 @@ export default class Form extends EventEmitter implements FormDependence { ) if (event.comparison.length) this.emit(Form.EVENT_CHANGED, this.changed); - + + // HOT FIX FOR AUTONOMIC FORM + { + let p = this.parent; + while(p) { + p.emit(Form.EVENT_CHANGED, p.changed); + p = p.parent; + } + } + // Проходим по всем дочерним элементам и уведомляем их this.dependencies.forEach(dep => { if (dep.name) { diff --git a/src/classes/FormError.ts b/src/classes/FormError.ts index a972937..2d01ebf 100644 --- a/src/classes/FormError.ts +++ b/src/classes/FormError.ts @@ -12,8 +12,8 @@ export default class FormError extends Error{ static RepeatDependingWithSameName(name: string, element: any) { return new FormError(`The element with the name ${name} has already been subscribed to the form.`, element); } - static ProxyFormWithoutName() { - return new FormError(`Can't create FormProxy without name.`); + static FormWithoutName() { + return new FormError(`For some case form should has the name.`); } static TryToGetValueWithoutName() { return new FormError(`Can't get value without name. Looks like form.getValueByName(). Current method has one required param.`) diff --git a/tests/units/form/form-changed.spec.ts b/tests/units/form/form-changed.spec.ts index 5851c78..a3a1fe9 100644 --- a/tests/units/form/form-changed.spec.ts +++ b/tests/units/form/form-changed.spec.ts @@ -69,5 +69,23 @@ describe("Form.changed", () => { form.cleanChangesByField("name"); expect(form.changed).toBe(false); }) + + test("With three parent", () => { + const grandParent = new Form({name: 'grand'}) + const parent = new Form({name: 'parent', parent: grandParent}) + const child = new Form({name: 'child', parent: parent}) + + + child.change({name: 'Jack'}) + + console.log(child.values) + console.log(child.changes) + console.log(parent.changes) + console.log(grandParent.changes) + + expect(grandParent.changed).toBe(true) + expect(parent.changed).toBe(true) + expect(child.changed).toBe(true) + }) }) \ No newline at end of file diff --git a/tests/units/hooks/use-form-state.spec.ts b/tests/units/hooks/use-form-state.spec.ts index 20c0fdb..1715d8a 100644 --- a/tests/units/hooks/use-form-state.spec.ts +++ b/tests/units/hooks/use-form-state.spec.ts @@ -26,4 +26,48 @@ describe("Use form state", () => { expect(formState.changed).toBe(false) }) test("After change/revert it should be updated", () => {}) + + test("Autonomic form: children changes should update status of parent form", () => { + const parent = new Form() + const child = new Form({ + parent, + name: "test", + autonomic: true + }) + + const parentState = useFormState(parent); + const childState = useFormState(parent); + + expect(parent.changed).toBe(false); + expect(child.changed).toBe(false); + + child.change({ + age: 18 + }) + + expect(parentState.changed).toBe(true); + expect(childState.changed).toBe(true); + }) + + test("", () => { + const grandParent = new Form({name: '0'}) + const parent = new Form({name: '1', parent: grandParent}) + const child = new Form({name: '2', parent, autonomic: true}) + + const grandParentState = useFormState(grandParent) + const parentState = useFormState(parent) + const childState = useFormState(child) + + child.change({name: 'Jack'}) + + expect(grandParent.changed).toBe(true) + expect(parent.changed).toBe(true) + expect(child.changed).toBe(true) + + expect(grandParentState.changed).toBe(true) + expect(parentState.changed).toBe(true) + expect(childState.changed).toBe(true) + + }) + }) \ No newline at end of file