Skip to content

Commit

Permalink
feat: add test for autonomic forms, Hot fix for dispatching events to…
Browse files Browse the repository at this point in the history
… parent form from autonomic form.
  • Loading branch information
Jenesius committed Oct 18, 2024
1 parent 85b2838 commit 904c016
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 76 deletions.
4 changes: 3 additions & 1 deletion examples/autonomic-form/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
<station-form />

<button @click = "showChanges">Changes</button>
<button @click = "showChanges" v-if = "formState.changed">Save</button>
</div>
</template>

<script setup lang='ts'>
import {Form, FormField} from "../../src";
import {Form, FormField, useFormState} from "../../src";
import StationForm from "./station-form.vue";
const form = new Form();
const formState = useFormState(form);
// @ts-ignore
window.theForm = form;
function showChanges() {
Expand Down
87 changes: 20 additions & 67 deletions project/pages/test/App.vue
Original file line number Diff line number Diff line change
@@ -1,75 +1,28 @@
<template>
<div class="container-examples">
<div :key = "values">Values: {{values}}</div>

<div :key = "changes">Changes: {{changes}}</div>
<div :key = "pureValue">Pure values: {{pureValue}}</div>
<div :key = "pureAvailabilities">Pure av: {{pureAvailabilities}}</div>
<script setup lang="ts">
<input-field name = "birthday" type = "date" label = "Placeholder" />
import {useFormValues, Form, FormField} from "../../../src/index";
import ParentForm from "./parent-form.vue";
<input-field name = "birthday" type = "date" label = "Other mask" mask = "MM/DD/YYYY" :handlers = "[testFrom, testTo]"/>
const form = new Form({
name: "grand"
})
const values = useFormValues(form);
// @ts-ignore
window.theForm = form;
</script>

<template>
<div class="container">
<form-field name="username" label="username"/>
{{ values }}
<parent-form/>
</div>
</template>

<script setup lang='ts'>
import Form from "../../../src/classes/Form";
import {ref} from "vue";
import copyObject from "./../../../src/utils/copy-object";
import {InputField} from "../../../src/index";
import DateController from "../../../src/controllers/date-controller";
// @ts-ignore
const form = window.form = new Form({
name: "main",
parent:false
});
const show = ref(false);
setInterval(() => {
if (!form) return;
values.value = copyObject(form?.values);
changes.value = copyObject(form.changes);
pureValue.value = copyObject(form.TEST_PURE_VALUE);
pureAvailabilities.value = copyObject(form.TEST_PURE_AVAILABILITIES)
}, 50);
const values = ref(0);
const changes = ref({});
const pureValue= ref({});
const pureAvailabilities = ref({})
const name = ref('username');
function change() {
name.value = name.value === 'username' ? 'age' : 'username';
<style scoped>
.container {
padding: 20px;
border: 2px solid black;
}
function clean() {
form.cleanValues();
}
function testFrom(date: unknown) {
if (typeof date !== 'string') return null;
return new Date(date)
}
function testTo(str?: string) {
if (typeof str !== 'string') return null;
const p = DateController.ConvertToDate(str, "MM/DD/YYYY");
if (!p) return null;
return DateController.GetPrettyDate(p, 'YYYY-MM-DD')
}
</script>

<style>
</style>
</style>
24 changes: 24 additions & 0 deletions project/pages/test/child-form.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
import {useFormValues, Form, FormField} from "../../../src/index";
const form = new Form({
name: "child"
})
const values = useFormValues(form);
</script>

<template>
<div class="container">
<form-field name="username" label="username"/>
{{ values }}
</div>
</template>

<style scoped>
.container {
padding: 20px;
border: 2px solid black;
}
</style>
3 changes: 2 additions & 1 deletion project/pages/test/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -18,7 +19,7 @@ config({
'local-date': InputTestDateLocal,
'native-date': InputNativeDate
},
// debug: true
debug: true
})

createApp(App).mount('#app')
28 changes: 28 additions & 0 deletions project/pages/test/parent-form.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script setup lang="ts">
import {useFormValues, Form, FormField} from "../../../src/index";
import ChildForm from "./child-form.vue";
const form = new Form({
name: "parent"
})
const values = useFormValues(form);
</script>

<template>

<div class="container">
<form-field name="username" label="username"/>
{{ values }}

<child-form/>
</div>
</template>

<style scoped>
.container {
padding: 20px;
border: 2px solid black;
}
</style>
20 changes: 15 additions & 5 deletions src/classes/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down Expand Up @@ -454,8 +457,6 @@ export default class Form extends EventEmitter implements FormDependence {
* Наша система построена так, что бы все значения идут от родителя к дочернему элементу (values, changes, event, other..)
* */
dispatchEvent<T extends FormEvent>(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,
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions src/classes/FormError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.`)
Expand Down
18 changes: 18 additions & 0 deletions tests/units/form/form-changed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})

})
44 changes: 44 additions & 0 deletions tests/units/hooks/use-form-state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)

})

})

0 comments on commit 904c016

Please sign in to comment.