Skip to content

Commit 716d25c

Browse files
committed
match: Add partial prop and Match tests
1 parent 0303a8e commit 716d25c

File tree

4 files changed

+131
-33
lines changed

4 files changed

+131
-33
lines changed

packages/match/src/index.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,35 @@ export function Match<
2525
T extends {[k in Tag]: PropertyKey},
2626
Tag extends PropertyKey,
2727
>(props: {
28-
on: T,
28+
on: T | null | undefined,
2929
tag: Tag,
3030
case: {[K in T[Tag]]: (v: Accessor<T & {[k in Tag]: K}>) => JSX.Element},
31+
partial?: false,
3132
}): JSX.Element
3233
export function Match<
3334
T extends {kind: PropertyKey},
3435
>(props: {
35-
on: T,
36+
on: T | null | undefined,
3637
case: {[K in T['kind']]: (v: Accessor<T & {[k in 'kind']: K}>) => JSX.Element},
38+
partial?: false,
39+
}): JSX.Element
40+
export function Match<
41+
T extends {[k in Tag]: PropertyKey},
42+
Tag extends PropertyKey,
43+
>(props: {
44+
on: T | null | undefined,
45+
tag: Tag,
46+
case: {[K in T[Tag]]?: (v: Accessor<T & {[k in Tag]: K}>) => JSX.Element},
47+
partial: true,
48+
}): JSX.Element
49+
export function Match<
50+
T extends {kind: PropertyKey},
51+
>(props: {
52+
on: T | null | undefined,
53+
case: {[K in T['kind']]?: (v: Accessor<T & {[k in 'kind']: K}>) => JSX.Element},
54+
partial: true,
3755
}): JSX.Element
3856
export function Match(props: any): any {
39-
const kind = createMemo(() => props.on[props.tag ?? 'kind'])
40-
return createMemo(() => props.case[kind()](() => props.on))
57+
const kind = createMemo(() => props.on?.[props.tag ?? 'kind'])
58+
return createMemo(() => props.case[kind()]?.(() => props.on))
4159
}
42-

packages/match/test/index.test.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/match/test/index.test.tsx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import * as v from "vitest";
2+
import * as s from "solid-js";
3+
import { Match } from "../src/index.js";
4+
5+
v.describe("Match", () => {
6+
v.test("match on kind field", () => {
7+
8+
type MyUnion = {
9+
kind: 'foo',
10+
foo: 'foo-value',
11+
} | {
12+
kind: 'bar',
13+
bar: 'bar-value',
14+
}
15+
16+
const [value, setValue] = s.createSignal<MyUnion>()
17+
18+
const data = s.createRoot(dispose => {
19+
return {
20+
dispose,
21+
result: s.children(() => <>
22+
<Match on={value()} case={{
23+
foo: v => <>{v().foo}</>,
24+
bar: v => <>{v().bar}</>,
25+
}} />
26+
</>)
27+
}
28+
})
29+
30+
v.expect(data.result()).toEqual(undefined);
31+
32+
setValue({kind: 'foo', foo: 'foo-value'});
33+
v.expect(data.result()).toEqual(<>foo-value</>);
34+
35+
setValue({kind: 'bar', bar: 'bar-value'});
36+
v.expect(data.result()).toEqual(<>bar-value</>);
37+
38+
data.dispose();
39+
});
40+
41+
v.test("match on type field", () => {
42+
43+
type MyUnion = {
44+
type: 'foo',
45+
foo: 'foo-value',
46+
} | {
47+
type: 'bar',
48+
bar: 'bar-value',
49+
}
50+
51+
const [value, setValue] = s.createSignal<MyUnion>()
52+
53+
const data = s.createRoot(dispose => {
54+
return {
55+
dispose,
56+
result: s.children(() => <>
57+
<Match on={value()} tag='type' case={{
58+
foo: v => <>{v().foo}</>,
59+
bar: v => <>{v().bar}</>,
60+
}} />
61+
</>)
62+
}
63+
})
64+
65+
v.expect(data.result()).toEqual(undefined);
66+
67+
setValue({type: 'foo', foo: 'foo-value'});
68+
v.expect(data.result()).toEqual(<>foo-value</>);
69+
70+
setValue({type: 'bar', bar: 'bar-value'});
71+
v.expect(data.result()).toEqual(<>bar-value</>);
72+
73+
data.dispose();
74+
});
75+
76+
v.test("partial match", () => {
77+
78+
type MyUnion = {
79+
kind: 'foo',
80+
foo: 'foo-value',
81+
} | {
82+
kind: 'bar',
83+
bar: 'bar-value',
84+
}
85+
86+
const [value, setValue] = s.createSignal<MyUnion>()
87+
88+
const data = s.createRoot(dispose => {
89+
return {
90+
dispose,
91+
result: s.children(() => <>
92+
<Match partial on={value()} case={{
93+
foo: v => <>{v().foo}</>,
94+
}} />
95+
</>)
96+
}
97+
})
98+
99+
v.expect(data.result()).toEqual(undefined);
100+
101+
setValue({kind: 'foo', foo: 'foo-value'});
102+
v.expect(data.result()).toEqual(<>foo-value</>);
103+
104+
setValue({kind: 'bar', bar: 'bar-value'});
105+
v.expect(data.result()).toEqual(undefined);
106+
107+
data.dispose();
108+
});
109+
});

packages/match/test/server.test.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)