Skip to content

Commit 8c28924

Browse files
committed
Add tests
1 parent 4c32054 commit 8c28924

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Application, Controller } from '@hotwired/stimulus';
11+
import { getByTestId, waitFor } from '@testing-library/dom';
12+
import { clearDOM, mountDOM } from '@symfony/stimulus-testing';
13+
import VueController from '../src/render_controller';
14+
import SimpleForm from './fixtures/SimpleForm.vue'
15+
16+
const startStimulus = () => {
17+
const application = Application.start();
18+
application.register('vue', VueController);
19+
};
20+
21+
window.resolveVueComponent = () => {
22+
return SimpleForm;
23+
};
24+
25+
describe('VueController', () => {
26+
it('reacts on field value changed', async () => {
27+
const container = mountDOM(`
28+
<div data-testid="component"
29+
data-controller="vue"
30+
data-vue-component-value="SimpleForm"
31+
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;}" />
32+
`);
33+
34+
const component = getByTestId(container, 'component');
35+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}');
36+
37+
startStimulus();
38+
39+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
40+
41+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}');
42+
43+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
44+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
45+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
46+
47+
field1.value = 'Devi Sund';
48+
field1.dispatchEvent(new Event('input'));
49+
50+
field2.value = 'Shanai Nance';
51+
field2.dispatchEvent(new Event('input'));
52+
53+
field3.value = 'Georgios Baylor';
54+
field3.dispatchEvent(new Event('input'));
55+
56+
await waitFor(() => expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Devi Sund","value2":"Shanai Nance","value3":"Georgios Baylor"}'));
57+
58+
clearDOM();
59+
});
60+
61+
it('reacts on props changed', async () => {
62+
const container = mountDOM(`
63+
<div data-testid="component"
64+
data-controller="vue"
65+
data-vue-component-value="SimpleForm"
66+
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;}" />
67+
`);
68+
69+
const component = getByTestId(container, 'component');
70+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}');
71+
72+
startStimulus();
73+
74+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
75+
76+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}');
77+
78+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
79+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
80+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
81+
82+
expect(field1).toHaveValue('Marshawn Caley');
83+
expect(field2).toHaveValue('Ontario Hopper');
84+
expect(field3).toHaveValue('Latria Gibb');
85+
86+
component.dataset.vuePropsValue = '{"value1":"Shon Pahl","value2":"Simi Kester","value3":"Shenelle Corso"}';
87+
88+
await waitFor(() => expect(field1).toHaveValue('Shon Pahl'));
89+
await waitFor(() => expect(field2).toHaveValue('Simi Kester'));
90+
await waitFor(() => expect(field3).toHaveValue('Shenelle Corso'));
91+
92+
clearDOM();
93+
});
94+
95+
it('reacts on props adding', async () => {
96+
const container = mountDOM(`
97+
<div data-testid="component"
98+
data-controller="vue"
99+
data-vue-component-value="SimpleForm"
100+
data-vue-props-value="{&quot;value1&quot;:&quot;Marshawn Caley&quot;}" />
101+
`);
102+
103+
const component = getByTestId(container, 'component');
104+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');
105+
106+
startStimulus();
107+
108+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
109+
110+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');
111+
112+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
113+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
114+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
115+
116+
expect(field1).toHaveValue('Marshawn Caley');
117+
expect(field2).toHaveValue('');
118+
expect(field3).toHaveValue('');
119+
120+
component.dataset.vuePropsValue = '{"value1":"Marshawn Caley","value2":"Abelino Dollard"}';
121+
122+
await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
123+
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
124+
await waitFor(() => expect(field3).toHaveValue(''));
125+
126+
component.dataset.vuePropsValue = '{"value1":"Marshawn Caley","value2":"Abelino Dollard","value3":"Ravan Farr"}';
127+
128+
await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
129+
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
130+
await waitFor(() => expect(field3).toHaveValue('Ravan Farr'));
131+
});
132+
133+
it('reacts on props removing', async () => {
134+
const container = mountDOM(`
135+
<div data-testid="component"
136+
data-controller="vue"
137+
data-vue-component-value="SimpleForm"
138+
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;}" />
139+
`);
140+
141+
const component = getByTestId(container, 'component');
142+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}');
143+
144+
startStimulus();
145+
146+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
147+
148+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}');
149+
150+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
151+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
152+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
153+
154+
expect(field1).toHaveValue('Trista Elbert');
155+
expect(field2).toHaveValue('Mistina Truax');
156+
expect(field3).toHaveValue('Chala Paddock');
157+
158+
component.dataset.vuePropsValue = '{"value1":"Trista Elbert","value3":"Chala Paddock"}';
159+
160+
await waitFor(() => expect(field1).toHaveValue('Trista Elbert'));
161+
await waitFor(() => expect(field2).toHaveValue(''));
162+
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));
163+
164+
component.dataset.vuePropsValue = '{"value3":"Chala Paddock"}';
165+
166+
await waitFor(() => expect(field1).toHaveValue(''));
167+
await waitFor(() => expect(field2).toHaveValue(''));
168+
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));
169+
});
170+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<script lang="ts" setup>
2+
// Before Vue 3.4
3+
import { computed } from 'vue';
4+
5+
declare interface Props {
6+
value1?: string;
7+
value2?: string;
8+
value3?: string;
9+
}
10+
11+
declare interface Emits {
12+
(e: 'update:value1', value: string): unknown;
13+
(e: 'update:value2', value: string): unknown;
14+
(e: 'update:value3', value: string): unknown;
15+
}
16+
17+
const props = withDefaults(defineProps<Props>(), {
18+
value1: '',
19+
value2: '',
20+
value3: '',
21+
});
22+
const emit = defineEmits<Emits>();
23+
24+
const useModel = <P extends Props, K extends keyof P, T extends Required<P>[K]>(propName: K) =>
25+
computed({
26+
get: (): T => props[propName],
27+
set: (value: T) => {
28+
emit(`update:${propName}`, value);
29+
},
30+
});
31+
32+
const value1 = useModel('value1');
33+
const value2 = useModel('value2');
34+
const value3 = useModel('value3');
35+
36+
// From Vue 3.4
37+
// const value1 = defineModel('value1');
38+
// const value2 = defineModel('value2');
39+
// const value3 = defineModel('value3');
40+
</script>
41+
42+
<template>
43+
<input data-testid="field-1" v-model="value1">
44+
<input data-testid="field-2" v-model="value2">
45+
<input data-testid="field-3" v-model="value3">
46+
</template>

0 commit comments

Comments
 (0)