docs(gui): regenerate graphs and sync the note's English pair
Generated docs follow the ui-models rename and the removed ui-settings-general package; the English note side picks up the feature-owner self-registration doctrine.
This commit is contained in:
75
packages/client/ui-theme/tests/appearance-row.spec.tsx
Normal file
75
packages/client/ui-theme/tests/appearance-row.spec.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
// @vitest-environment jsdom
|
||||
/** AppearanceRow behavior: three cubes, selection follows the persisted
|
||||
* preference, clicks drive setTheme. */
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
|
||||
import { createSnapshotStore, type SessionListState, type WorkspaceListState } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react'
|
||||
import { AppearanceRow } from '../src/client/AppearanceRow.tsx'
|
||||
import type { AppearanceRowComponentProps } from '../src/client/AppearanceRow.tsx'
|
||||
import { createAppearanceRowStore } from '../src/client/settings-store.ts'
|
||||
import type { ThemePreference } from '../src/client/index.ts'
|
||||
|
||||
afterEach(cleanup)
|
||||
|
||||
const COPY: Record<string, string> = {
|
||||
'appearance.title': 'Appearance',
|
||||
'appearance.light': 'Light',
|
||||
'appearance.dark': 'Dark',
|
||||
'appearance.system': 'System',
|
||||
}
|
||||
|
||||
/** Empty global standard-kit hooks (the row reads neither). */
|
||||
function emptySessions() {
|
||||
const store = createSnapshotStore<SessionListState>(
|
||||
{ ids: [], byId: {}, current: undefined, intent: undefined, phase: 'ready' })
|
||||
return bindSnapshotSelector(store)
|
||||
}
|
||||
function emptyWorkspaces() {
|
||||
const store = createSnapshotStore<WorkspaceListState>({
|
||||
items: [], intent: undefined, state: 'idle', phase: 'ready', error: null,
|
||||
baselinesReady: true, recentWorkspaceId: undefined,
|
||||
})
|
||||
return bindSnapshotSelector(store)
|
||||
}
|
||||
|
||||
function mount(preference: ThemePreference = 'system') {
|
||||
// Real store instance — the sanctioned zero-machinery path for tests.
|
||||
const store = createAppearanceRowStore().create()
|
||||
store.actions.sync(preference, 0)
|
||||
const setTheme = vi.fn()
|
||||
const props: AppearanceRowComponentProps = {
|
||||
useSessions: emptySessions(),
|
||||
useWorkspaces: emptyWorkspaces(),
|
||||
useStore: bindSnapshotSelector(store),
|
||||
actions: store.actions,
|
||||
t: (key: string) => COPY[key] ?? key,
|
||||
setTheme,
|
||||
}
|
||||
render(<AppearanceRow {...props} />)
|
||||
return { store, setTheme }
|
||||
}
|
||||
|
||||
const pressed = (name: RegExp): string | null =>
|
||||
screen.getByRole('button', { name }).getAttribute('aria-pressed')
|
||||
|
||||
describe('AppearanceRow', () => {
|
||||
it('renders the title and three cubes with the preference cube selected', () => {
|
||||
mount('dark')
|
||||
expect(screen.getByText('Appearance')).toBeDefined()
|
||||
expect(pressed(/Dark/)).toBe('true')
|
||||
expect(pressed(/Light/)).toBe('false')
|
||||
expect(pressed(/System/)).toBe('false')
|
||||
})
|
||||
|
||||
it('click drives setTheme; selection follows the store mirror, not the click echo', () => {
|
||||
const b = mount('dark')
|
||||
fireEvent.click(screen.getByRole('button', { name: /Light/ }))
|
||||
expect(b.setTheme).toHaveBeenCalledWith('light')
|
||||
// No store write yet: selection is unchanged.
|
||||
expect(pressed(/Dark/)).toBe('true')
|
||||
act(() => { b.store.actions.sync('light', 1) })
|
||||
expect(pressed(/Light/)).toBe('true')
|
||||
expect(pressed(/Dark/)).toBe('false')
|
||||
})
|
||||
})
|
||||
28
packages/client/ui-theme/tests/settings-store.spec.ts
Normal file
28
packages/client/ui-theme/tests/settings-store.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/** Appearance row store: snapshot-mirror action and the revision guard. */
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { createAppearanceRowStore } from '../src/client/settings-store.ts'
|
||||
|
||||
describe('createAppearanceRowStore', () => {
|
||||
it('init shape: system preference with revision at -1', () => {
|
||||
const store = createAppearanceRowStore().create()
|
||||
expect(store.getSnapshot()).toEqual({ preference: 'system', revision: -1 })
|
||||
})
|
||||
|
||||
it('sync mirrors the preference and advances the revision', () => {
|
||||
const store = createAppearanceRowStore().create()
|
||||
store.actions.sync('dark', 0)
|
||||
expect(store.getSnapshot()).toEqual({ preference: 'dark', revision: 0 })
|
||||
store.actions.sync('light', 2)
|
||||
expect(store.getSnapshot().preference).toBe('light')
|
||||
expect(store.getSnapshot().revision).toBe(2)
|
||||
})
|
||||
|
||||
it('revision guard drops stale and duplicate writes', () => {
|
||||
const store = createAppearanceRowStore().create()
|
||||
store.actions.sync('dark', 3)
|
||||
store.actions.sync('system', 2)
|
||||
store.actions.sync('system', 3)
|
||||
expect(store.getSnapshot().preference).toBe('dark')
|
||||
expect(store.getSnapshot().revision).toBe(3)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user