Skip to content

Commit 30ecace

Browse files
committed
test(combo): Added defaultValue tests
1 parent c7ed565 commit 30ecace

File tree

3 files changed

+128
-72
lines changed

3 files changed

+128
-72
lines changed

src/components/combo/combo.spec.ts

Lines changed: 101 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { spy } from 'sinon';
33

44
import { defineComponents } from '../common/definitions/defineComponents.js';
55
import {
6-
FormAssociatedTestBed,
76
type ValidationContainerTestsParams,
7+
createFormAssociatedTestBed,
88
runValidationContainerTests,
99
} from '../common/utils.spec.js';
1010
import type IgcInputComponent from '../input/input.js';
@@ -1240,7 +1240,7 @@ describe('Combo', () => {
12401240
});
12411241

12421242
describe('Form integration', () => {
1243-
const spec = new FormAssociatedTestBed<IgcComboComponent<City>>(
1243+
const spec = createFormAssociatedTestBed<IgcComboComponent<City>>(
12441244
html`<igc-combo
12451245
name="combo"
12461246
.data=${cities}
@@ -1254,63 +1254,55 @@ describe('Combo', () => {
12541254
await spec.setup(IgcComboComponent.tagName);
12551255
});
12561256

1257-
it('is form associated', async () => {
1257+
it('is form associated', () => {
12581258
expect(spec.element.form).to.equal(spec.form);
12591259
});
12601260

12611261
it('is not associated on submit if no value', async () => {
1262-
spec.element.value = [];
1263-
await elementUpdated(spec.element);
1264-
1265-
expect(spec.submit()?.get(spec.element.name)).to.be.null;
1262+
// FIXME: The combo value setter does not update the form state in a synchronous manner
1263+
// FIXME: delegating to a @watch callback.
1264+
await spec.setProperties({ value: [] });
1265+
spec.assertSubmitHasValue(null);
12661266
});
12671267

12681268
it('is associated on submit with value-key (single)', async () => {
1269-
spec.element.singleSelect = true;
1270-
await elementUpdated(spec.element);
1271-
1272-
spec.element.value = ['BG01', 'BG02'];
1273-
await elementUpdated(spec.element);
1274-
1275-
expect(spec.submit()?.get(spec.element.name)).to.equal('BG01');
1269+
await spec.setProperties({ singleSelect: true });
1270+
await spec.setProperties({ value: ['BG01', 'BG02'] });
1271+
spec.assertSubmitHasValue('BG01');
12761272
});
12771273

1278-
it('is associated on submit with value-key (multiple)', async () => {
1279-
expect(spec.submit()?.get(spec.element.name)).to.equal('BG01');
1280-
expect(spec.submit()?.getAll(spec.element.name)).to.eql(['BG01', 'BG02']);
1274+
it('is associated on submit with value-key (multiple)', () => {
1275+
spec.assertSubmitHasValue('BG01');
1276+
spec.assertSubmitHasValues(['BG01', 'BG02']);
12811277
});
12821278

12831279
it('is associated on submit without value-key (single)', async () => {
12841280
const [first, second, _] = cities;
12851281

1286-
spec.element.valueKey = undefined;
1287-
spec.element.singleSelect = true;
1288-
await elementUpdated(spec.element);
1282+
await spec.setProperties({ valueKey: undefined, singleSelect: true });
12891283
spec.element.select([first, second]);
12901284
await elementUpdated(spec.element);
12911285

1292-
expect(spec.submit()?.get(spec.element.name)).not.to.be.null;
1286+
expect(spec.formData.getAll(spec.element.name)).lengthOf(1);
1287+
spec.assertSubmitPasses();
12931288
});
12941289

12951290
it('is associated on submit without value-key (multiple)', async () => {
12961291
const [first, second, _] = cities;
12971292

1298-
spec.element.valueKey = undefined;
1293+
await spec.setProperties({ valueKey: undefined });
12991294
spec.element.select([first, second]);
13001295
await elementUpdated(spec.element);
13011296

1302-
expect(spec.submit()?.get(spec.element.name)).not.to.be.null;
1303-
expect(spec.submit()?.getAll(spec.element.name).length).to.eql(2);
1297+
expect(spec.formData.getAll(spec.element.name)).lengthOf(2);
1298+
spec.assertSubmitPasses();
13041299
});
13051300

13061301
it('is correctly reset on form reset (multiple)', async () => {
13071302
const initial = spec.element.value;
13081303

1309-
spec.element.setAttribute('value', '["BG01", "BG02"]');
1310-
await elementUpdated(spec.element);
1311-
1312-
spec.element.value = [];
1313-
await elementUpdated(spec.element);
1304+
await spec.setAttributes({ value: JSON.stringify(['BG01', 'BG02']) });
1305+
await spec.setProperties({ value: [] });
13141306

13151307
spec.reset();
13161308
expect(spec.element.value).to.eql(initial);
@@ -1320,11 +1312,8 @@ describe('Combo', () => {
13201312
// Initial value is a multiple array. The combo defaults to the first item
13211313
const initial = [spec.element.value[0]];
13221314

1323-
spec.element.singleSelect = true;
1324-
await elementUpdated(spec.element);
1325-
1326-
spec.element.value = ['US01'];
1327-
await elementUpdated(spec.element);
1315+
await spec.setProperties({ singleSelect: true });
1316+
await spec.setProperties({ value: ['US01'] });
13281317

13291318
expect(spec.element.value).to.eql(['US01']);
13301319

@@ -1333,31 +1322,26 @@ describe('Combo', () => {
13331322
});
13341323

13351324
it('should reset to the new default value after setAttribute() call (multiple)', async () => {
1336-
spec.element.setAttribute('value', JSON.stringify(['US01', 'US02']));
1337-
spec.element.value = [];
1325+
await spec.setAttributes({ value: JSON.stringify(['US01', 'US02']) });
1326+
await spec.setProperties({ value: [] });
13381327

13391328
spec.reset();
13401329
expect(spec.element.value).to.eql(['US01', 'US02']);
1341-
expect(spec.submit()?.getAll(spec.element.name)).to.eql(
1342-
spec.element.value
1343-
);
1330+
spec.assertSubmitHasValues(spec.element.value);
13441331
});
13451332

13461333
it('should reset to the new default value after setAttribute() call (single)', async () => {
1347-
spec.element.singleSelect = true;
1348-
await elementUpdated(spec.element);
1349-
1350-
spec.element.setAttribute('value', JSON.stringify(['US01']));
1351-
spec.element.value = [];
1334+
await spec.setProperties({ singleSelect: true });
1335+
await spec.setAttributes({ value: JSON.stringify(['US01']) });
1336+
await spec.setProperties({ value: [] });
13521337

13531338
spec.reset();
1339+
13541340
expect(spec.element.value).to.eql(['US01']);
1355-
expect(spec.submit()?.getAll(spec.element.name)).to.eql(
1356-
spec.element.value
1357-
);
1341+
spec.assertSubmitHasValue('US01');
13581342
});
13591343

1360-
it('reflects disabled ancestor state', async () => {
1344+
it('reflects disabled ancestor state', () => {
13611345
spec.setAncestorDisabledState(true);
13621346
expect(spec.element.disabled).to.be.true;
13631347

@@ -1366,17 +1350,14 @@ describe('Combo', () => {
13661350
});
13671351

13681352
it('fulfils required constraint', async () => {
1369-
spec.element.value = [];
1370-
spec.element.required = true;
1371-
await elementUpdated(spec.element);
1372-
spec.submitFails();
1353+
await spec.setProperties({ value: [], required: true });
1354+
spec.assertSubmitFails();
13731355

1374-
spec.element.value = ['BG01', 'BG02'];
1375-
await elementUpdated(spec.element);
1376-
spec.submitValidates();
1356+
await spec.setProperties({ value: ['BG01', 'BG02'] });
1357+
spec.assertSubmitPasses();
13771358
});
13781359

1379-
it('fulfils custom constraint', async () => {
1360+
it('fulfils custom constraint', () => {
13801361
spec.element.setCustomValidity('invalid');
13811362
spec.submitFails();
13821363

@@ -1385,6 +1366,70 @@ describe('Combo', () => {
13851366
});
13861367
});
13871368

1369+
describe('defaultValue', () => {
1370+
const value = ['BG01', 'BG02'];
1371+
1372+
describe('Form integration', () => {
1373+
const spec = createFormAssociatedTestBed<IgcComboComponent<City>>(html`
1374+
<igc-combo
1375+
name="combo"
1376+
.data=${cities}
1377+
.defaultValue=${value}
1378+
value-key="id"
1379+
display-key="name"
1380+
></igc-combo>
1381+
`);
1382+
1383+
beforeEach(async () => {
1384+
await spec.setup(IgcComboComponent.tagName);
1385+
});
1386+
1387+
it('correct initial state', () => {
1388+
spec.assertIsPristine();
1389+
expect(spec.element.value).to.eql(value);
1390+
});
1391+
1392+
it('is correctly submitted', () => {
1393+
spec.assertSubmitHasValues(value);
1394+
});
1395+
1396+
it('is correctly reset', async () => {
1397+
await spec.setProperties({ value: [] });
1398+
spec.reset();
1399+
1400+
expect(spec.element.value).to.eql(value);
1401+
});
1402+
});
1403+
1404+
describe('Validation', () => {
1405+
const spec = createFormAssociatedTestBed<IgcComboComponent<City>>(html`
1406+
<igc-combo
1407+
name="combo"
1408+
.data=${cities}
1409+
.defaultValue=${[]}
1410+
value-key="id"
1411+
display-key="name"
1412+
></igc-combo>
1413+
`);
1414+
1415+
beforeEach(async () => {
1416+
await spec.setup(IgcComboComponent.tagName);
1417+
});
1418+
1419+
it('fails required validation', () => {
1420+
spec.assertIsPristine();
1421+
spec.assertSubmitFails();
1422+
});
1423+
1424+
it('passes required validation', async () => {
1425+
await spec.setProperties({ defaultValue: value });
1426+
spec.assertIsPristine();
1427+
1428+
spec.assertSubmitHasValues(value);
1429+
});
1430+
});
1431+
});
1432+
13881433
describe('Validation message slots', () => {
13891434
it('', async () => {
13901435
const testParameters: ValidationContainerTestsParams<IgcComboComponent>[] =

src/components/common/utils.spec.ts

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,22 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
2929
/**
3030
* The form associated component for the test bed.
3131
*/
32-
public get element() {
32+
public get element(): T {
3333
return this._element;
3434
}
3535

3636
/**
3737
* The form element from the test bed.
3838
*/
39-
public get form() {
39+
public get form(): HTMLFormElement {
4040
return this._form;
4141
}
4242

43-
public get valid() {
43+
public get formData(): FormData {
44+
return new FormData(this._form);
45+
}
46+
47+
public get valid(): boolean {
4448
return this.element.checkValidity();
4549
}
4650

@@ -53,7 +57,7 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
5357
* Called in the async `beforeEach` test hook callback. Pass in the
5458
* query selector for the component.
5559
*/
56-
public async setup(qs: string) {
60+
public async setup(qs: string): Promise<void> {
5761
this._form = await fixture<HTMLFormElement>(
5862
html`<form><fieldset>${this.template}</fieldset></form>`
5963
);
@@ -65,7 +69,7 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
6569
}
6670

6771
/** Resets the form controls. */
68-
public reset() {
72+
public reset(): void {
6973
this.form.reset();
7074
}
7175

@@ -116,7 +120,7 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
116120
public async setProperties(
117121
props: { [K in keyof T]?: T[K] },
118122
waitForUpdate = true
119-
) {
123+
): Promise<void> {
120124
Object.assign(this.element, props);
121125
if (waitForUpdate) {
122126
await elementUpdated(this.element);
@@ -131,9 +135,9 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
131135
* If the `waitForUpdate` parameter is `true`, the function waits for the element to be updated before returning.
132136
*/
133137
public async setAttributes(
134-
attributes: { [K in keyof T]?: T[K] },
138+
attributes: { [K in keyof T]?: T[K] | string },
135139
waitForUpdate = true
136-
) {
140+
): Promise<void> {
137141
for (const [attr, value] of Object.entries(attributes)) {
138142
this.element.setAttribute(attr, `${value}`);
139143
}
@@ -146,15 +150,23 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
146150
* Whether the form is submitted and contains the given 'value'
147151
* in its form data.
148152
*/
149-
public assertSubmitHasValue(value: unknown, msg?: string) {
153+
public assertSubmitHasValue(value: unknown, msg?: string): void {
150154
expect(this.submitV2().get(this.element.name), msg).to.eql(value);
151155
}
152156

157+
/**
158+
* Whether the form is submitted and contains the given 'value'
159+
* in its form data.
160+
*/
161+
public assertSubmitHasValues(value: unknown, msg?: string): void {
162+
expect(this.submitV2().getAll(this.element.name), msg).to.eql(value);
163+
}
164+
153165
/**
154166
* Whether the form fails to submit.
155167
* The component will be in invalid state and the form data will be empty.
156168
*/
157-
public assertSubmitFails(msg?: string) {
169+
public assertSubmitFails(msg?: string): void {
158170
expect(this.submitV2() === initialFormData, msg).to.be.true;
159171
expect(this.valid, msg).to.be.false;
160172
}
@@ -164,25 +176,25 @@ export class FormAssociatedTestBed<T extends IgcFormControl> {
164176
* The component will be in valid state and the form data will include the
165177
* component name and value.
166178
*/
167-
public assertSubmitPasses(msg?: string) {
179+
public assertSubmitPasses(msg?: string): void {
168180
expect(this.submitV2() === initialFormData, msg).to.be.false;
169181
expect(this.valid, msg).to.be.true;
170182
}
171183

172-
public submitValidates(msg?: string) {
184+
public submitValidates(msg?: string): void {
173185
expect(this.submit(), msg).not.to.be.undefined;
174186
expect(this.valid, msg).to.be.true;
175187
}
176188

177-
public submitFails(msg?: string) {
189+
public submitFails(msg?: string): void {
178190
expect(this.submit(), msg).to.be.undefined;
179191
expect(this.valid, msg).to.be.false;
180192
}
181193

182194
/**
183195
* Whether the form element is in 'pristine' state.
184196
*/
185-
public assertIsPristine(msg?: string) {
197+
public assertIsPristine(msg?: string): void {
186198
// biome-ignore lint/complexity/useLiteralKeys: Pristine state test
187199
expect(this.element['_pristine'], msg).to.be.true;
188200
}

src/components/date-picker/date-picker.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,8 +900,7 @@ describe('Date picker', () => {
900900
});
901901

902902
it('should reset to the new default value after setAttribute() call', () => {
903-
// FIXME:
904-
spec.setAttributes({ value: today.native.toISOString() as any });
903+
spec.setAttributes({ value: today.native.toISOString() });
905904
spec.setProperties({ value: today.add('day', 180).native });
906905
spec.reset();
907906

0 commit comments

Comments
 (0)