Skip to content

Commit 2e7526b

Browse files
committed
test(combo-box): add generics tests
1 parent 15a51ea commit 2e7526b

File tree

2 files changed

+107
-5
lines changed

2 files changed

+107
-5
lines changed

tests/ComboBox/ComboBox.test.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import { ComboBox } from "carbon-components-svelte";
33
import type { ComponentProps } from "svelte";
44
5-
export let items: ComponentProps<ComboBox>["items"] = [
6-
{ id: "0", text: "Slack" },
7-
{ id: "1", text: "Email" },
8-
{ id: "2", text: "Fax" },
5+
export let items = [
6+
{ id: "0", text: "Slack", price: 100 },
7+
{ id: "1", text: "Email", price: 200 },
8+
{ id: "2", text: "Fax", price: 300 },
99
];
1010
export let selectedId: ComponentProps<ComboBox>["selectedId"] = undefined;
1111
export let value = "";

tests/ComboBox/ComboBox.test.ts

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { render, screen } from "@testing-library/svelte";
22
import type { ComponentProps } from "svelte";
3+
import { expectTypeOf } from "vitest";
34
import { user } from "../setup-tests";
45
import ComboBox from "./ComboBox.test.svelte";
56
import ComboBoxCustom from "./ComboBoxCustom.test.svelte";
@@ -38,7 +39,7 @@ describe("ComboBox", () => {
3839

3940
expect(consoleLog).toHaveBeenCalledWith("select", {
4041
selectedId: "1",
41-
selectedItem: { id: "1", text: "Email" },
42+
selectedItem: { id: "1", text: "Email", price: 200 },
4243
});
4344
expect(getInput()).toHaveValue("Email");
4445
});
@@ -524,4 +525,105 @@ describe("ComboBox", () => {
524525
await user.click(document.body);
525526
expect(input).toHaveValue("Email");
526527
});
528+
529+
describe("Generics", () => {
530+
it("should support custom item types with generics", () => {
531+
type Product = {
532+
id: string;
533+
text: string;
534+
price: number;
535+
category: string;
536+
inStock: boolean;
537+
};
538+
539+
const products: Product[] = [
540+
{
541+
id: "1",
542+
text: "Laptop",
543+
price: 999,
544+
category: "Electronics",
545+
inStock: true,
546+
},
547+
{
548+
id: "2",
549+
text: "Phone",
550+
price: 599,
551+
category: "Electronics",
552+
inStock: false,
553+
},
554+
];
555+
556+
expectTypeOf<typeof products>().toEqualTypeOf<Product[]>();
557+
558+
const itemToString = (item: Product) => `${item.text} - $${item.price}`;
559+
expectTypeOf(itemToString).parameter(0).toEqualTypeOf<Product>();
560+
expectTypeOf(itemToString).returns.toEqualTypeOf<string>();
561+
562+
const shouldFilterItem = (item: Product, value: string) =>
563+
item.category.toLowerCase().includes(value.toLowerCase()) ||
564+
item.text.toLowerCase().includes(value.toLowerCase());
565+
expectTypeOf(shouldFilterItem).parameter(0).toEqualTypeOf<Product>();
566+
expectTypeOf(shouldFilterItem).parameter(1).toEqualTypeOf<string>();
567+
expectTypeOf(shouldFilterItem).returns.toEqualTypeOf<boolean>();
568+
569+
type SelectEvent = CustomEvent<{
570+
selectedId: string;
571+
selectedItem: Product;
572+
}>;
573+
expectTypeOf<
574+
SelectEvent["detail"]["selectedItem"]
575+
>().toEqualTypeOf<Product>();
576+
});
577+
578+
it("should provide type-safe access to custom properties in callbacks", () => {
579+
type Tag = {
580+
id: number;
581+
text: string;
582+
color: string;
583+
usageCount: number;
584+
};
585+
586+
// itemToString can access custom properties
587+
const itemToString = (item: Tag) => {
588+
expectTypeOf(item).toHaveProperty("color");
589+
expectTypeOf(item).toHaveProperty("usageCount");
590+
return `${item.text} (${item.usageCount})`;
591+
};
592+
593+
// shouldFilterItem can access custom properties
594+
const shouldFilterItem = (item: Tag, value: string) => {
595+
expectTypeOf(item).toHaveProperty("color");
596+
expectTypeOf(item).toHaveProperty("usageCount");
597+
return (
598+
item.color.includes(value) || item.usageCount > parseInt(value, 10)
599+
);
600+
};
601+
602+
expectTypeOf(itemToString).parameter(0).toEqualTypeOf<Tag>();
603+
expectTypeOf(shouldFilterItem).parameter(0).toEqualTypeOf<Tag>();
604+
});
605+
606+
it("should support slot props with generic item type", () => {
607+
type MenuItem = {
608+
id: string;
609+
text: string;
610+
icon: string;
611+
shortcut?: string;
612+
};
613+
614+
type SlotProps = { item: MenuItem; index: number };
615+
616+
const slotItem: MenuItem = {
617+
id: "1",
618+
text: "Save",
619+
icon: "save-icon",
620+
shortcut: "Ctrl+S",
621+
};
622+
623+
// Slot should provide item with custom properties
624+
expectTypeOf<SlotProps["item"]>().toEqualTypeOf<MenuItem>();
625+
expectTypeOf(slotItem).toHaveProperty("icon");
626+
expectTypeOf(slotItem).toHaveProperty("shortcut");
627+
});
628+
});
527629
});

0 commit comments

Comments
 (0)