A test file under packages/client now says which face it covers:
`*.client.spec.{ts,tsx}` and its `*.client.{ts,tsx}` helpers belong to the
Client aggregate, `*.host.spec.ts` to the host aggregate. The carrier's four
node-half specs take the Host suffix.
The two suffixes are mutually exclusive, so each aggregate excludes the
other's and both keep one broad test glob: `exclude` wins over `include`, and
`packages/client/**` no longer has to be excluded wholesale from the host
program with per-file `files` entries carved back out of it. A Host-face spec
that reaches only Host source therefore needs no cross-face project
reference, which the split-project rule rejects.
vitest still discovers every file through `**/*.spec.{ts,tsx}`.
39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
/** Sidebar shell inset contract shared with the nested workspace browser. */
|
|
import { readFileSync } from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const css = readFileSync(fileURLToPath(new URL('../src/client/SidebarRoot.module.css', import.meta.url)), 'utf8')
|
|
|
|
/**
|
|
* Declarations of one exact selector, keyed by property.
|
|
* @param selector - exact selector text.
|
|
* @returns the normalized declarations, or undefined when absent.
|
|
*/
|
|
function declarations(selector: string): Map<string, string> | undefined {
|
|
const withoutComments = css.replace(/\/\*[\s\S]*?\*\//g, ' ')
|
|
for (const [, selectorList = '', body = ''] of withoutComments.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
|
if (!selectorList.split(',').map(value => value.trim()).includes(selector)) continue
|
|
const found = new Map<string, string>()
|
|
for (const part of body.split(';')) {
|
|
const colon = part.indexOf(':')
|
|
if (colon === -1) continue
|
|
found.set(part.slice(0, colon).trim(), part.slice(colon + 1).trim().replace(/\s+/g, ' '))
|
|
}
|
|
return found
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
describe('SidebarRoot.module.css inset', () => {
|
|
it('shares and cancels the wide shell trailing padding structurally', () => {
|
|
const root = declarations('.root')
|
|
expect(root?.get('--dsh-sidebar-inline-padding')).toBe('12px')
|
|
expect(root?.get('padding')).toBe('6px var(--dsh-sidebar-inline-padding)')
|
|
expect(declarations('.regionArea')?.get('margin-right')).toBe(
|
|
'calc(-1 * var(--dsh-sidebar-inline-padding))',
|
|
)
|
|
expect(declarations('.collapsed .regionArea')?.get('margin-right')).toBe('0')
|
|
})
|
|
})
|