Skip to content

Commit b679e9c

Browse files
committed
Add tests
1 parent 4c32054 commit b679e9c

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
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(
36+
'data-vue-props-value',
37+
'{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}'
38+
);
39+
40+
startStimulus();
41+
42+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
43+
44+
expect(component).toHaveAttribute(
45+
'data-vue-props-value',
46+
'{"value1":"Derron Macgregor","value2":"Tedrick Speers","value3":"Janell Highfill"}'
47+
);
48+
49+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
50+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
51+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
52+
53+
field1.value = 'Devi Sund';
54+
field1.dispatchEvent(new Event('input'));
55+
56+
field2.value = 'Shanai Nance';
57+
field2.dispatchEvent(new Event('input'));
58+
59+
field3.value = 'Georgios Baylor';
60+
field3.dispatchEvent(new Event('input'));
61+
62+
await waitFor(() =>
63+
expect(component).toHaveAttribute(
64+
'data-vue-props-value',
65+
'{"value1":"Devi Sund","value2":"Shanai Nance","value3":"Georgios Baylor"}'
66+
)
67+
);
68+
69+
clearDOM();
70+
});
71+
72+
it('reacts on props changed', async () => {
73+
const container = mountDOM(`
74+
<div data-testid="component"
75+
data-controller="vue"
76+
data-vue-component-value="SimpleForm"
77+
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;}" />
78+
`);
79+
80+
const component = getByTestId(container, 'component');
81+
expect(component).toHaveAttribute(
82+
'data-vue-props-value',
83+
'{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}'
84+
);
85+
86+
startStimulus();
87+
88+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
89+
90+
expect(component).toHaveAttribute(
91+
'data-vue-props-value',
92+
'{"value1":"Marshawn Caley","value2":"Ontario Hopper","value3":"Latria Gibb"}'
93+
);
94+
95+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
96+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
97+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
98+
99+
expect(field1).toHaveValue('Marshawn Caley');
100+
expect(field2).toHaveValue('Ontario Hopper');
101+
expect(field3).toHaveValue('Latria Gibb');
102+
103+
component.dataset.vuePropsValue = '{"value1":"Shon Pahl","value2":"Simi Kester","value3":"Shenelle Corso"}';
104+
105+
await waitFor(() => expect(field1).toHaveValue('Shon Pahl'));
106+
await waitFor(() => expect(field2).toHaveValue('Simi Kester'));
107+
await waitFor(() => expect(field3).toHaveValue('Shenelle Corso'));
108+
109+
clearDOM();
110+
});
111+
112+
it('reacts on props adding', async () => {
113+
const container = mountDOM(`
114+
<div data-testid="component"
115+
data-controller="vue"
116+
data-vue-component-value="SimpleForm"
117+
data-vue-props-value="{&quot;value1&quot;:&quot;Marshawn Caley&quot;}" />
118+
`);
119+
120+
const component = getByTestId(container, 'component');
121+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');
122+
123+
startStimulus();
124+
125+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
126+
127+
expect(component).toHaveAttribute('data-vue-props-value', '{"value1":"Marshawn Caley"}');
128+
129+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
130+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
131+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
132+
133+
expect(field1).toHaveValue('Marshawn Caley');
134+
expect(field2).toHaveValue('');
135+
expect(field3).toHaveValue('');
136+
137+
component.dataset.vuePropsValue = '{"value1":"Marshawn Caley","value2":"Abelino Dollard"}';
138+
139+
await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
140+
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
141+
await waitFor(() => expect(field3).toHaveValue(''));
142+
143+
component.dataset.vuePropsValue =
144+
'{"value1":"Marshawn Caley","value2":"Abelino Dollard","value3":"Ravan Farr"}';
145+
146+
await waitFor(() => expect(field1).toHaveValue('Marshawn Caley'));
147+
await waitFor(() => expect(field2).toHaveValue('Abelino Dollard'));
148+
await waitFor(() => expect(field3).toHaveValue('Ravan Farr'));
149+
});
150+
151+
it('reacts on props removing', async () => {
152+
const container = mountDOM(`
153+
<div data-testid="component"
154+
data-controller="vue"
155+
data-vue-component-value="SimpleForm"
156+
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;}" />
157+
`);
158+
159+
const component = getByTestId(container, 'component');
160+
expect(component).toHaveAttribute(
161+
'data-vue-props-value',
162+
'{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}'
163+
);
164+
165+
startStimulus();
166+
167+
await waitFor(() => expect(component).toHaveAttribute('data-v-app'));
168+
169+
expect(component).toHaveAttribute(
170+
'data-vue-props-value',
171+
'{"value1":"Trista Elbert","value2":"Mistina Truax","value3":"Chala Paddock"}'
172+
);
173+
174+
const field1 = getByTestId(container, 'field-1') as HTMLInputElement;
175+
const field2 = getByTestId(container, 'field-2') as HTMLInputElement;
176+
const field3 = getByTestId(container, 'field-3') as HTMLInputElement;
177+
178+
expect(field1).toHaveValue('Trista Elbert');
179+
expect(field2).toHaveValue('Mistina Truax');
180+
expect(field3).toHaveValue('Chala Paddock');
181+
182+
component.dataset.vuePropsValue = '{"value1":"Trista Elbert","value3":"Chala Paddock"}';
183+
184+
await waitFor(() => expect(field1).toHaveValue('Trista Elbert'));
185+
await waitFor(() => expect(field2).toHaveValue(''));
186+
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));
187+
188+
component.dataset.vuePropsValue = '{"value3":"Chala Paddock"}';
189+
190+
await waitFor(() => expect(field1).toHaveValue(''));
191+
await waitFor(() => expect(field2).toHaveValue(''));
192+
await waitFor(() => expect(field3).toHaveValue('Chala Paddock'));
193+
});
194+
});
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)