Files
deepseek-harness/packages/util/environment/tests/environment.spec.ts
T
imccyu ec601ca13d build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.

Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.

The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.

Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:13 +08:00

70 lines
3.0 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import {
createEnvironmentSnapshot, DSH_ENVIRONMENT_KEY, environmentOf,
} from '../src/index.ts'
const layered = createEnvironmentSnapshot([
{ source: 'process', values: { SHARED: 'from-process', ONLY_PROCESS: 'p' } },
{ source: 'project-env', path: '/work/.env', values: { SHARED: 'from-project', ONLY_PROJECT: 'j' } },
{ source: 'user-env', path: '/home/.dsh/.env', values: { SHARED: 'from-user', ONLY_USER: 'u' } },
])
describe('createEnvironmentSnapshot', () => {
it('resolves across every layer, most trusted first, and reports the winning source', () => {
expect(layered.get('SHARED')).toEqual({ value: 'from-process', source: 'process' })
expect(layered.get('ONLY_PROJECT')).toEqual({ value: 'j', source: 'project-env', path: '/work/.env' })
expect(layered.get('ONLY_USER')).toEqual({ value: 'u', source: 'user-env', path: '/home/.dsh/.env' })
expect(layered.get('ABSENT')).toBeUndefined()
})
it('filters layers without changing their trust order', () => {
// The point of getFrom: a routing field that must never come from a
// project directory cannot be reached by reordering, only by listing it.
expect(layered.getFrom('ONLY_PROJECT', ['process', 'user-env'])).toBeUndefined()
expect(layered.getFrom('SHARED', ['user-env', 'process']))
.toEqual({ value: 'from-process', source: 'process' })
expect(layered.getFrom('SHARED', [])).toBeUndefined()
})
it('copies each layer, so a later mutation of the source object cannot change it', () => {
const values: Record<string, string> = { KEY: 'first' }
const snapshot = createEnvironmentSnapshot([{ source: 'process', values }])
values.KEY = 'second'
values.LATE = 'added'
expect(snapshot.get('KEY')).toEqual({ value: 'first', source: 'process' })
expect(snapshot.get('LATE')).toBeUndefined()
})
it('keeps an empty value as a present value, for its owner to judge', () => {
const snapshot = createEnvironmentSnapshot([{ source: 'process', values: { EMPTY: '' } }])
expect(snapshot.get('EMPTY')).toEqual({ value: '', source: 'process' })
})
it('orders lookups canonically regardless of construction order', () => {
const reversed = createEnvironmentSnapshot([
{ source: 'user-env', path: '/u', values: { K: 'u' } },
{ source: 'process', values: { K: 'p' } },
])
expect(reversed.get('K')).toEqual({ value: 'p', source: 'process' })
})
})
describe('environmentOf', () => {
it('returns the launcher snapshot when the product CLI provided one', () => {
const ctx = new Context()
ctx.provide(DSH_ENVIRONMENT_KEY, layered)
expect(environmentOf(ctx)).toBe(layered)
})
it('falls back to the inherited environment as the only layer', () => {
vi.stubEnv('DSH_ENV_SPEC_FALLBACK', 'ambient')
try {
const snapshot = environmentOf(new Context())
expect(snapshot.get('DSH_ENV_SPEC_FALLBACK')).toEqual({ value: 'ambient', source: 'process' })
} finally {
vi.unstubAllEnvs()
}
})
})