Skip to content

Commit 3f8c6f5

Browse files
author
Larry Botha
committed
test(form component): refactor tests to test stores available via context
1 parent 29aeea0 commit 3f8c6f5

File tree

3 files changed

+83
-21
lines changed

3 files changed

+83
-21
lines changed

test/specs/components/fixtures/input.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
export let field;
66
77
const context = getContext(key);
8-
const form = context.form;
8+
const {form} = context;
99
</script>
1010

1111
<label for={field}>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
import {getContext} from 'svelte';
3+
import {key} from '../../../../lib';
4+
5+
const context = getContext(key);
6+
7+
export let storeProp;
8+
9+
const store = context[storeProp];
10+
</script>
11+
12+
<div {...$$restProps}>
13+
{JSON.stringify($store)}
14+
</div>

test/specs/components/form.spec.js

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {render, fireEvent, waitFor} from '@testing-library/svelte';
2-
import {writable, get as svelteGet} from 'svelte/store';
32

43
import Input from './fixtures/input.svelte';
4+
import StoreContextInspector from './fixtures/store-context-inspector.svelte';
55

66
import Form from 'lib/components/Form.svelte';
77

@@ -10,58 +10,106 @@ const defaultProps = {
1010
onSubmit() {},
1111
};
1212

13-
const get = (store) => {
14-
/**
15-
* not sure why we need to invoke `get` twice, but we do
16-
*/
17-
return svelteGet(svelteGet(store));
18-
};
19-
2013
describe('Form', () => {
21-
test('-> exposes `form` prop via slot properties', async () => {
14+
test('-> exposes `form` store to children via context', async () => {
2215
const inputId = 'foo';
2316
const props = {
2417
...defaultProps,
2518
initialValues: {[inputId]: ''},
2619
};
27-
let form = writable({});
28-
const {getByLabelText} = render(
29-
<Form {...props} let_form={form}>
20+
const {getByLabelText, getByTestId} = render(
21+
<Form {...props}>
3022
<Input field={inputId} />
23+
24+
<StoreContextInspector data-testid="values" storeProp="form" />
3125
</Form>,
3226
);
3327
const input = getByLabelText(inputId);
28+
const valuesEl = getByTestId('values');
29+
let values = JSON.parse(valuesEl.textContent);
3430

35-
expect(get(form)).toHaveProperty('foo', '');
31+
expect(values[inputId]).toBe(props.initialValues[inputId]);
32+
expect(input.value).toBe(values[inputId]);
3633

3734
const value = 'bar';
3835

3936
await fireEvent.input(input, {target: {value}});
4037

41-
expect(get(form)).toHaveProperty('foo', value);
38+
values = JSON.parse(valuesEl.textContent);
39+
40+
expect(values[inputId]).toBe(value);
41+
expect(input.value).toBe(value);
4242
});
4343

44-
test('-> exposes `state` prop via slot properties', async () => {
44+
test('-> exposes `state` store to children via context', async () => {
4545
const inputId = 'foo';
4646
const props = {
4747
...defaultProps,
4848
initialValues: {[inputId]: ''},
4949
};
50-
let state = writable({});
51-
const {getByLabelText} = render(
52-
<Form {...props} let_state={state}>
50+
const {getByLabelText, getByTestId} = render(
51+
<Form {...props}>
5352
<Input field={inputId} />
53+
54+
<StoreContextInspector data-testid="state" storeProp="state" />
5455
</Form>,
5556
);
5657
const input = getByLabelText(inputId);
58+
const stateEl = getByTestId('state');
59+
let state = JSON.parse(stateEl.textContent);
60+
61+
expect(state).toHaveProperty('isModified', false);
62+
63+
const value = 'bar';
64+
65+
await fireEvent.input(input, {target: {value}});
66+
67+
state = JSON.parse(stateEl.textContent);
68+
expect(state).toHaveProperty('isModified', true);
69+
});
70+
71+
test('-> exposes `errors` store to children via context', async () => {
72+
const inputId = 'foo';
73+
const validationError = `${inputId} is required`;
74+
const props = {
75+
initialValues: {[inputId]: ''},
76+
validate: (values) => {
77+
if (!values[inputId]) {
78+
return {[inputId]: validationError};
79+
}
80+
},
81+
};
82+
const {getByTestId, getByLabelText, getByRole} = render(
83+
<Form {...props}>
84+
<Input field={inputId} />
85+
<StoreContextInspector data-testid="error" storeProp="errors" />
86+
87+
<button type="submit">submit</button>
88+
</Form>,
89+
);
90+
const input = getByLabelText(inputId);
91+
const button = getByRole('button');
92+
const errorEl = getByTestId('error');
93+
let errors = JSON.parse(errorEl.textContent);
94+
95+
expect(errors).toHaveProperty(inputId, '');
96+
97+
await fireEvent.click(button);
5798

58-
expect(get(state)).toHaveProperty('isModified', false);
99+
await waitFor(() => {
100+
errors = JSON.parse(errorEl.textContent);
101+
expect(errors).toHaveProperty(inputId, validationError);
102+
});
59103

60104
const value = 'bar';
61105

62106
await fireEvent.input(input, {target: {value}});
107+
await fireEvent.click(button);
63108

64-
expect(get(state)).toHaveProperty('isModified', true);
109+
await waitFor(() => {
110+
errors = JSON.parse(errorEl.textContent);
111+
expect(errors).toHaveProperty(inputId, '');
112+
});
65113
});
66114

67115
test.each`

0 commit comments

Comments
 (0)