Download apps/vscode/test/vsix-package.test.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 10.1 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/apps/vscode/test/vsix-package.test.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/apps/vscode/test/vsix-package.test.ts
-
curl -L -o vsix-package.test.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/apps/vscode/test/vsix-package.test.ts
10.1 kB
| /** | |
| * Scenario: maintainers package and inspect the VS Code extension on any host OS. | |
| * Responsibilities: six-target argument handling, actionable failures, isolated | |
| * dev state, manifest/resource hygiene, unresolved imports, and entry loading. | |
| * Wiring: real Node packaging/verifier CLIs and filesystem; VSIX directory | |
| * fixtures replace only the external Marketplace archive producer. | |
| * Run: pnpm --filter kimi-code exec vitest run --config vitest.config.ts test/vsix-package.test.ts | |
| */ | |
| import { spawnSync } from 'node:child_process'; | |
| import { mkdtemp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'; | |
| import { tmpdir } from 'node:os'; | |
| import { join, resolve } from 'node:path'; | |
| import { afterEach, describe, expect, it } from 'vitest'; | |
| const appRoot = resolve(import.meta.dirname, '..'); | |
| const packageScript = join(appRoot, 'scripts', 'vsix-package.mjs'); | |
| const verifierScript = join(appRoot, 'scripts', 'vsix-verify.mjs'); | |
| const prepareDevScript = join(appRoot, 'scripts', 'prepare-dev.mjs'); | |
| const tempDirs: string[] = []; | |
| afterEach(async () => { | |
| await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true }))); | |
| }); | |
| describe('VSIX package CLI (target planning and validation)', () => { | |
| it('plans all six supported targets when no target is supplied', async () => { | |
| const outputDir = await makeTempDir('kimi-package-plan-'); | |
| const result = runNode(packageScript, ['--dry-run', '--out-dir', outputDir]); | |
| expect(result.status).toBe(0); | |
| expect(result.stdout.match(/Would package /g)).toHaveLength(6); | |
| expect(result.stdout).toContain('kimi-code-darwin-x64.vsix'); | |
| expect(result.stdout).toContain('kimi-code-darwin-arm64.vsix'); | |
| expect(result.stdout).toContain('kimi-code-linux-x64.vsix'); | |
| expect(result.stdout).toContain('kimi-code-linux-arm64.vsix'); | |
| expect(result.stdout).toContain('kimi-code-win32-x64.vsix'); | |
| expect(result.stdout).toContain('kimi-code-win32-arm64.vsix'); | |
| }); | |
| it('accepts a Windows ARM target when the output path contains spaces', async () => { | |
| const root = await makeTempDir('kimi-package-windows-'); | |
| const outputDir = join(root, 'output with spaces'); | |
| const result = runNode(packageScript, [ | |
| '--', | |
| '--dry-run', | |
| '--target', | |
| 'win32-arm64', | |
| '--out-dir', | |
| outputDir, | |
| ]); | |
| expect(result.status).toBe(0); | |
| expect(result.stdout.match(/Would package /g)).toHaveLength(1); | |
| expect(result.stdout).toContain('kimi-code-win32-arm64.vsix'); | |
| }); | |
| it('rejects an unknown target before a build starts', () => { | |
| const result = runNode(packageScript, ['plan9-x64', '--dry-run']); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Unknown VSIX target "plan9-x64"'); | |
| expect(result.stderr).toContain('win32-arm64'); | |
| }); | |
| }); | |
| describe('VSIX verifier CLI (package contract and failure details)', () => { | |
| it('passes an unpacked Windows package when the entry is self-contained', async () => { | |
| const fixture = await makeVsixFixture('win32-x64'); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'win32-x64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(0); | |
| expect(result.stdout).toContain('static audit and entry import smoke passed (package-only)'); | |
| }); | |
| it('reports the expected target when the VSIX manifest has a different target', async () => { | |
| const fixture = await makeVsixFixture('darwin-arm64'); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'linux-x64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('VSIX manifest target is darwin-arm64, expected linux-x64'); | |
| }); | |
| it('names a missing required Webview resource', async () => { | |
| const fixture = await makeVsixFixture('darwin-x64'); | |
| await rm(join(fixture, 'extension', 'dist', 'webview.js')); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'darwin-x64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Required VSIX resource is missing: extension/dist/webview.js'); | |
| }); | |
| it('reports a bare runtime dependency left in the extension bundle', async () => { | |
| const fixture = await makeVsixFixture('linux-arm64'); | |
| await writeFile( | |
| join(fixture, 'extension', 'dist', 'extension.js'), | |
| "import leftPad from 'left-pad';\nexport function activate() { return leftPad; }\n", | |
| ); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'linux-arm64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Bare runtime dependency "left-pad"'); | |
| }); | |
| it('does not mistake a bundled this.require(...) method call for a runtime dependency', async () => { | |
| const fixture = await makeVsixFixture('darwin-arm64'); | |
| await writeFile( | |
| join(fixture, 'extension', 'dist', 'extension.js'), | |
| 'class HostEnvironment {\n' + | |
| ' require(field) { return this.info[field]; }\n' + | |
| ' get osKind() { return this.require("osKind"); }\n' + | |
| '}\n' + | |
| 'export function activate() { return new HostEnvironment(); }\n', | |
| ); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'darwin-arm64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(0); | |
| }); | |
| it('rejects generated session state inside the package', async () => { | |
| const fixture = await makeVsixFixture('win32-arm64'); | |
| const stateDir = join(fixture, 'extension', 'runtime', 'profile'); | |
| await mkdir(stateDir, { recursive: true }); | |
| await writeFile(join(stateDir, 'session.json'), '{}'); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'win32-arm64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Forbidden package path segment "runtime"'); | |
| }); | |
| it('rejects a persisted state directory inside the package', async () => { | |
| const fixture = await makeVsixFixture('win32-x64'); | |
| const stateDir = join(fixture, 'extension', 'state'); | |
| await mkdir(stateDir, { recursive: true }); | |
| await writeFile(join(stateDir, 'extension.json'), '{}'); | |
| const result = runNode(verifierScript, [ | |
| '--target', | |
| 'win32-x64', | |
| '--directory', | |
| fixture, | |
| ]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Forbidden package path segment "state"'); | |
| }); | |
| }); | |
| describe('Extension Development Host setup (isolated local state)', () => { | |
| it('creates the complete isolated directory layout for a debug launch', async () => { | |
| const parent = await makeTempDir('kimi-dev-profile-'); | |
| const baseDir = join(parent, 'vscode-extension-dev'); | |
| const result = runNode(prepareDevScript, ['--base-dir', baseDir]); | |
| expect(result.status).toBe(0); | |
| await expect(readFile(join(baseDir, 'workspace', 'README.md'), 'utf8')).resolves.toContain( | |
| 'Isolated Kimi Code extension development workspace', | |
| ); | |
| await expect(directoryExists(join(baseDir, 'user-data'))).resolves.toBe(true); | |
| await expect(directoryExists(join(baseDir, 'extensions'))).resolves.toBe(true); | |
| await expect(directoryExists(join(baseDir, 'kimi-home'))).resolves.toBe(true); | |
| }); | |
| it('refuses to clear a directory without the dedicated safety suffix', async () => { | |
| const unsafeDir = await makeTempDir('kimi-dev-unsafe-'); | |
| await writeFile(join(unsafeDir, 'keep.txt'), 'keep'); | |
| const result = runNode(prepareDevScript, ['--base-dir', unsafeDir]); | |
| expect(result.status).toBe(1); | |
| expect(result.stderr).toContain('Refusing to reset unsafe development directory'); | |
| await expect(readFile(join(unsafeDir, 'keep.txt'), 'utf8')).resolves.toBe('keep'); | |
| }); | |
| }); | |
| async function makeTempDir(prefix: string): Promise<string> { | |
| const dir = await mkdtemp(join(tmpdir(), prefix)); | |
| tempDirs.push(dir); | |
| return dir; | |
| } | |
| async function makeVsixFixture(target: string): Promise<string> { | |
| const root = await makeTempDir('kimi-vsix-fixture-'); | |
| const extensionDir = join(root, 'extension'); | |
| const distDir = join(extensionDir, 'dist'); | |
| const resourcesDir = join(extensionDir, 'resources'); | |
| await Promise.all([ | |
| mkdir(distDir, { recursive: true }), | |
| mkdir(resourcesDir, { recursive: true }), | |
| ]); | |
| const packageJson = await readFile(join(appRoot, 'package.json'), 'utf8'); | |
| await Promise.all([ | |
| writeFile(join(root, '[Content_Types].xml'), '<Types />'), | |
| writeFile( | |
| join(root, 'extension.vsixmanifest'), | |
| `<PackageManifest><Metadata><Identity TargetPlatform="${target}" /></Metadata></PackageManifest>`, | |
| ), | |
| writeFile(join(extensionDir, 'package.json'), packageJson), | |
| writeFile(join(extensionDir, 'readme.md'), '# Fixture\n'), | |
| writeFile(join(extensionDir, 'LICENSE.txt'), 'fixture license\n'), | |
| writeFile( | |
| join(distDir, 'extension.js'), | |
| "/** @type {import('../types/index').Extension} */\nimport * as vscode from 'vscode';\nexport function activate() { return vscode; }\n", | |
| ), | |
| writeFile(join(distDir, 'webview.js'), 'globalThis.__kimiWebview = true;\n'), | |
| writeFile(join(distDir, 'kimi-banner-dark.svg'), '<svg />'), | |
| writeFile(join(distDir, 'kimi-banner-light.svg'), '<svg />'), | |
| writeFile(join(distDir, 'kimi-logo.png'), 'fixture'), | |
| writeFile(join(resourcesDir, 'kimi-icon-storefront.png'), 'fixture'), | |
| writeFile(join(resourcesDir, 'kimi-icon.svg'), '<svg />'), | |
| ]); | |
| return root; | |
| } | |
| function runNode(script: string, args: string[]) { | |
| const result = spawnSync(process.execPath, [script, ...args], { | |
| cwd: appRoot, | |
| encoding: 'utf8', | |
| env: { ...process.env, VSCE_PAT: '', OVSX_PAT: '' }, | |
| }); | |
| if (result.error !== undefined) throw result.error; | |
| return { | |
| status: result.status, | |
| stdout: result.stdout ?? '', | |
| stderr: result.stderr ?? '', | |
| }; | |
| } | |
| async function directoryExists(path: string): Promise<boolean> { | |
| try { | |
| return (await stat(path)).isDirectory(); | |
| } catch { | |
| return false; | |
| } | |
| } | |