Skip to content

Commit 8a9c865

Browse files
committed
Migrate to type-safe context
Replace calls to `setContext` and `getContext` with type-specific accessor functions created by `createContext` [1]. Update the Bookmark and Folder component tests to use dedicated wrapper components that set the context using the typed accessor functions. Remove the legacy generic `ContextWrapper` wrapper component. [1] sveltejs/svelte#16948
1 parent ce57888 commit 8a9c865

12 files changed

+176
-91
lines changed

eslint.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export default defineConfig(
2323
'eslint.config.js',
2424
'svelte.config.js',
2525
'**/vite.*.ts',
26-
'./test/utils/ContextWrapper.svelte',
2726
]),
2827
{
2928
languageOptions: {

src/options/Options.svelte.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
33

44
import Options from '@Treetop/options/Options.svelte';
55

6-
import ContextWrapper from '../../test/utils/ContextWrapper.svelte';
7-
86
const setup = () => {
9-
render(ContextWrapper, {
10-
Component: Options,
11-
Props: {},
12-
Context: {},
13-
});
7+
render(Options);
148
};
159

1610
describe('Options', () => {

src/treetop/Bookmark.svelte

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
<script lang="ts">
2-
import { getContext } from 'svelte';
3-
import type { SvelteDate } from 'svelte/reactivity';
42
import lodashTruncate from 'lodash-es/truncate';
53
6-
import type * as Treetop from './types';
4+
import {
5+
getClock,
6+
getLastVisitTimeMap,
7+
getTooltips,
8+
getTruncate,
9+
} from './context';
710
import { truncateMiddle } from './utils';
811
912
interface Props {
@@ -14,11 +17,10 @@
1417
1518
let { nodeId, title, url }: Props = $props();
1619
17-
const lastVisitTimeMap: Treetop.LastVisitTimeMap =
18-
getContext('lastVisitTimeMap');
19-
const truncate = getContext<() => boolean>('truncate');
20-
const tooltips = getContext<() => boolean>('tooltips');
21-
const clock = getContext<SvelteDate>('clock');
20+
const lastVisitTimeMap = getLastVisitTimeMap();
21+
const truncate = getTruncate();
22+
const tooltips = getTooltips();
23+
const clock = getClock();
2224
2325
const lastVisitTime = $derived(lastVisitTimeMap.get(nodeId)!);
2426

src/treetop/Bookmark.svelte.test.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import { render, screen } from '@testing-library/svelte';
44
import escapeRegExp from 'lodash-es/escapeRegExp';
55
import { beforeEach, describe, expect, it } from 'vitest';
66

7-
import Bookmark from '@Treetop/treetop/Bookmark.svelte';
87
import type * as Treetop from '@Treetop/treetop/types';
98

10-
import ContextWrapper from '../../test/utils/ContextWrapper.svelte';
9+
import BookmarkWrapper from '../../test/utils/BookmarkWrapper.svelte';
1110

1211
let lastVisitTimeMap: Treetop.LastVisitTimeMap;
1312
let currentTruncate: boolean;
@@ -29,15 +28,14 @@ const MILLISECONDS_PER_HOUR =
2928
60; // minutes per hour
3029

3130
const setup = () => {
32-
render(ContextWrapper, {
33-
Component: Bookmark,
34-
Props: { nodeId, title, url },
35-
Context: {
36-
lastVisitTimeMap,
37-
truncate,
38-
tooltips,
39-
clock,
40-
},
31+
render(BookmarkWrapper, {
32+
lastVisitTimeMap,
33+
truncate,
34+
tooltips,
35+
clock,
36+
nodeId,
37+
title,
38+
url,
4139
});
4240
};
4341

src/treetop/Folder.svelte

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<script lang="ts">
2-
import { getContext } from 'svelte';
3-
42
import Bookmark from './Bookmark.svelte';
3+
import {
4+
getBuiltInFolderInfo,
5+
getFilterActive,
6+
getFilterSet,
7+
getFolderNodeMap,
8+
} from './context';
59
import Folder from './Folder.svelte';
610
import * as Treetop from './types';
711
@@ -12,11 +16,10 @@
1216
1317
let { nodeId, root = false }: Props = $props();
1418
15-
const builtInFolderInfo: Treetop.BuiltInFolderInfo =
16-
getContext('builtInFolderInfo');
17-
const folderNodeMap = getContext<Treetop.FolderNodeMap>('folderNodeMap');
18-
const filterActive = getContext<() => boolean>('filterActive');
19-
const filterSet = getContext<Treetop.FilterSet>('filterSet');
19+
const builtInFolderInfo = getBuiltInFolderInfo();
20+
const folderNodeMap = getFolderNodeMap();
21+
const filterActive = getFilterActive();
22+
const filterSet = getFilterSet();
2023
2124
const node = $derived(folderNodeMap.get(nodeId)!);
2225

src/treetop/Folder.svelte.test.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import { render, screen } from '@testing-library/svelte';
55
import type { MockInstance } from 'vitest';
66
import { beforeEach, describe, expect, it, vi } from 'vitest';
77

8-
import Folder from '@Treetop/treetop/Folder.svelte';
98
import type * as Treetop from '@Treetop/treetop/types';
109

11-
import ContextWrapper from '../../test/utils/ContextWrapper.svelte';
1210
import {
1311
createBookmarkNode,
1412
createFolderNode,
1513
} from '../../test/utils/factories';
14+
import FolderWrapper from '../../test/utils/FolderWrapper.svelte';
1615

1716
// Folder component requirements
1817
let builtInFolderInfo: Treetop.BuiltInFolderInfo;
@@ -31,22 +30,17 @@ let clock: SvelteDate;
3130
let rootNode: Treetop.FolderNode;
3231

3332
const setup = () => {
34-
render(ContextWrapper, {
35-
Component: Folder,
36-
Props: {
37-
nodeId,
38-
root: true,
39-
},
40-
Context: {
41-
builtInFolderInfo,
42-
folderNodeMap,
43-
lastVisitTimeMap,
44-
filterActive,
45-
filterSet,
46-
truncate,
47-
tooltips,
48-
clock,
49-
},
33+
render(FolderWrapper, {
34+
builtInFolderInfo,
35+
folderNodeMap,
36+
lastVisitTimeMap,
37+
filterActive,
38+
filterSet,
39+
truncate,
40+
tooltips,
41+
clock,
42+
nodeId,
43+
root: true,
5044
});
5145
};
5246

src/treetop/Treetop.svelte

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { onDestroy, onMount, setContext } from 'svelte';
2+
import { onDestroy, onMount } from 'svelte';
33
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
44
import { fade } from 'svelte/transition';
55
import LinearProgress from '@smui/linear-progress';
@@ -14,6 +14,16 @@
1414
import { BookmarksManager } from './BookmarksManager';
1515
import { createClock } from './clock.svelte';
1616
import ConfirmationDialog from './ConfirmationDialog.svelte';
17+
import {
18+
setBuiltInFolderInfo,
19+
setClock,
20+
setFilterActive,
21+
setFilterSet,
22+
setFolderNodeMap,
23+
setLastVisitTimeMap,
24+
setTooltips,
25+
setTruncate,
26+
} from './context';
1727
import FilterInput from './FilterInput.svelte';
1828
import { FilterManager } from './FilterManager';
1929
import Folder from './Folder.svelte';
@@ -47,8 +57,8 @@
4757
);
4858
4959
// Make select preferences available to other components
50-
setContext('truncate', truncate);
51-
setContext('tooltips', tooltips);
60+
setTruncate(truncate);
61+
setTooltips(tooltips);
5262
5363
//
5464
// Create bookmarks data and manager
@@ -90,12 +100,12 @@
90100
const clock = createClock();
91101
92102
// Make bookmark data available to other components
93-
setContext('builtInFolderInfo', builtInFolderInfo);
94-
setContext('folderNodeMap', folderNodeMap);
95-
setContext('lastVisitTimeMap', lastVisitTimeMap);
96-
setContext('filterActive', () => filterActive);
97-
setContext('filterSet', filterSet);
98-
setContext('clock', clock);
103+
setBuiltInFolderInfo(builtInFolderInfo);
104+
setFolderNodeMap(folderNodeMap);
105+
setLastVisitTimeMap(lastVisitTimeMap);
106+
setFilterActive(() => filterActive);
107+
setFilterSet(filterSet);
108+
setClock(clock);
99109
100110
//
101111
// Error notification

src/treetop/Treetop.svelte.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@ import { describe, expect, it, vi } from 'vitest';
33

44
import Treetop from '@Treetop/treetop/Treetop.svelte';
55

6-
import ContextWrapper from '../../test/utils/ContextWrapper.svelte';
76
import { createBrowserBookmarksTree } from '../../test/utils/factories';
87

98
const setup = () => {
10-
render(ContextWrapper, {
11-
Component: Treetop,
12-
Props: {
13-
rootBookmarkId: null,
14-
},
15-
Context: {},
9+
render(Treetop, {
10+
rootBookmarkId: null,
1611
});
1712
};
1813

src/treetop/context.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { createContext } from 'svelte';
2+
import type { SvelteDate } from 'svelte/reactivity';
3+
4+
import * as Treetop from './types';
5+
6+
export const [getBuiltInFolderInfo, setBuiltInFolderInfo] =
7+
createContext<Treetop.BuiltInFolderInfo>();
8+
9+
export const [getClock, setClock] = createContext<SvelteDate>();
10+
11+
export const [getFilterActive, setFilterActive] =
12+
createContext<() => boolean>();
13+
14+
export const [getFilterSet, setFilterSet] = createContext<Treetop.FilterSet>();
15+
16+
export const [getFolderNodeMap, setFolderNodeMap] =
17+
createContext<Treetop.FolderNodeMap>();
18+
19+
export const [getLastVisitTimeMap, setLastVisitTimeMap] =
20+
createContext<Treetop.LastVisitTimeMap>();
21+
22+
export const [getTooltips, setTooltips] =
23+
createContext<() => Treetop.PreferenceValue>();
24+
25+
export const [getTruncate, setTruncate] =
26+
createContext<() => Treetop.PreferenceValue>();

test/utils/BookmarkWrapper.svelte

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script lang="ts">
2+
// Wrapper component to test Bookmark component with context.
3+
import type { ComponentProps } from 'svelte';
4+
import type { SvelteDate } from 'svelte/reactivity';
5+
6+
import Bookmark from '@Treetop/treetop/Bookmark.svelte';
7+
import {
8+
setClock,
9+
setLastVisitTimeMap,
10+
setTooltips,
11+
setTruncate,
12+
} from '@Treetop/treetop/context';
13+
import * as Treetop from '@Treetop/treetop/types';
14+
15+
type BookmarkProps = ComponentProps<typeof Bookmark>;
16+
17+
type Props = BookmarkProps & {
18+
lastVisitTimeMap: Treetop.LastVisitTimeMap;
19+
truncate: () => boolean;
20+
tooltips: () => boolean;
21+
clock: SvelteDate;
22+
};
23+
24+
const { lastVisitTimeMap, truncate, tooltips, clock, ...props }: Props =
25+
$props();
26+
27+
setLastVisitTimeMap(lastVisitTimeMap);
28+
setTruncate(truncate);
29+
setTooltips(tooltips);
30+
setClock(clock);
31+
</script>
32+
33+
<Bookmark {...props} />

0 commit comments

Comments
 (0)