Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
7-zete-7 committed Sep 28, 2024
1 parent 4c32054 commit fdec785
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 0 deletions.
170 changes: 170 additions & 0 deletions src/Vue/assets/test/controller_reactivity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Application, Controller } from '@hotwired/stimulus';
import { getByTestId, waitFor } from '@testing-library/dom';
import { clearDOM, mountDOM } from '@symfony/stimulus-testing';
import VueController from '../src/render_controller';
import SimpleForm from './fixtures/SimpleForm.vue'

const startStimulus = () => {
const application = Application.start();
application.register('vue', VueController);
};

window.resolveVueComponent = () => {
return SimpleForm;
};

describe('VueController', () => {
it('reacts on field value changed', async () => {
const container = mountDOM(`
<div data-testid="component"
data-controller="vue"
data-vue-component-value="SimpleForm"
data-vue-props-value="{&quot;value1&quot;:&quot;Derron Macgregor&quot;,&quot;value2&quot;:&quot;Tedrick Speers&quot;,&quot;value3&quot;:&quot;Janell Highfill&quot;}" />
`);

const component = getByTestId(container, 'component');
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}');

startStimulus();

await waitFor(() => expect(component).toHaveAttribute('data-v-app'));

expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}');

const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;

field1.value = 'Devi Sund';
field1.dispatchEvent(new Event('input'));

field2.value = 'Shanai Nance';
field2.dispatchEvent(new Event('input'));

field3.value = 'Georgios Baylor';
field3.dispatchEvent(new Event('input'));

await waitFor(() => expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Devi Sund","value2":"Shanai Nance","value3":"Georgios Baylor"}'));

clearDOM();
});

it('reacts on props changed', async () => {
const container = mountDOM(`
<div data-testid="component"
data-controller="vue"
data-vue-component-value="SimpleForm"
data-vue-props-value="{&quot;value1&quot;:&quot;Marshawn Caley&quot;,&quot;value2&quot;:&quot;Ontario Hopper&quot;,&quot;value3&quot;:&quot;Latria Gibb&quot;}" />
`);

const component = getByTestId(container, 'component');
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}');

startStimulus();

await waitFor(() => expect(component).toHaveAttribute('data-v-app'));

expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}');

const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;

expect(field1).toHaveValue('Marshawn Caley');
expect(field2).toHaveValue('Ontario Hopper');
expect(field3).toHaveValue('Latria Gibb');

component.dataset.vuePropsValue = '{"value1":"Shon Pahl","value2":"Simi Kester","value3":"Shenelle Corso"}';

await waitFor(() => expect(field1).toHaveValue('Shon Pahl'));
await waitFor(() => expect(field2).toHaveValue('Simi Kester'));
await waitFor(() => expect(field3).toHaveValue('Shenelle Corso'));

clearDOM();
});

it('reacts on props adding', async () => {
const container = mountDOM(`
<div data-testid="component"
data-controller="vue"
data-vue-component-value="SimpleForm"
data-vue-props-value="{&quot;value1&quot;:&quot;Marshawn Caley&quot;}" />
`);

const component = getByTestId(container, 'component');
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');

startStimulus();

await waitFor(() => expect(component).toHaveAttribute('data-v-app'));

expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');

const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;

expect(field1).toHaveValue('Marshawn Caley');
expect(field2).toHaveValue('');
expect(field3).toHaveValue('');

component.dataset.vuePropsValue = '{"value1":"Marshawn Caley","value2":"Abelino Dollard"}';

await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
await waitFor(() => expect(field3).toHaveValue(''));

component.dataset.vuePropsValue = '{"value1":"Marshawn Caley","value2":"Abelino Dollard","value3":"Ravan Farr"}';

await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
await waitFor(() => expect(field3).toHaveValue('Ravan Farr'));
});

it('reacts on props removing', async () => {
const container = mountDOM(`
<div data-testid="component"
data-controller="vue"
data-vue-component-value="SimpleForm"
data-vue-props-value="{&quot;value1&quot;:&quot;Trista Elbert&quot;,&quot;value2&quot;:&quot;Mistina Truax&quot;,&quot;value3&quot;:&quot;Chala Paddock&quot;}" />
`);

const component = getByTestId(container, 'component');
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}');

startStimulus();

await waitFor(() => expect(component).toHaveAttribute('data-v-app'));

expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}');

const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;

expect(field1).toHaveValue('Trista Elbert');
expect(field2).toHaveValue('Mistina Truax');
expect(field3).toHaveValue('Chala Paddock');

component.dataset.vuePropsValue = '{"value1":"Trista Elbert","value3":"Chala Paddock"}';

await waitFor(() => expect(field1).toHaveValue('Trista Elbert'));
await waitFor(() => expect(field2).toHaveValue(''));
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));

component.dataset.vuePropsValue = '{"value3":"Chala Paddock"}';

await waitFor(() => expect(field1).toHaveValue(''));
await waitFor(() => expect(field2).toHaveValue(''));
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));
});
});
45 changes: 45 additions & 0 deletions src/Vue/assets/test/fixtures/SimpleForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts" setup>
// Before Vue 3.4
import { computed } from 'vue';
declare interface Props {
value1?: string;
value2?: string;
value3?: string;
}
declare interface Emits {
(e: 'update:value1', value: string): unknown;
(e: 'update:value2', value: string): unknown;
(e: 'update:value3', value: string): unknown;
}
const props = withDefaults(defineProps<Props>(), {
value1: '',
value2: '',
value3: '',
});
const emit = defineEmits<Emits>();
const useModel = <P extends Props, K extends keyof P, T extends Required<P>[K]>(propName: K) => computed({
get: (): T => props[propName],
set: (value: T) => {
emit(`update:${propName}`, value);
},
});
const value1 = useModel('value1');
const value2 = useModel('value2');
const value3 = useModel('value3');
// From Vue 3.4
// const value1 = defineModel('value1');
// const value2 = defineModel('value2');
// const value3 = defineModel('value3');
</script>

<template>
<input data-testid="field-1" v-model="value1">
<input data-testid="field-2" v-model="value2">
<input data-testid="field-3" v-model="value3">
</template>

0 comments on commit fdec785

Please sign in to comment.