mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 08:02:43 +00:00
* feat(native-chat): enable Windows structured sessions
* fix(codex): prove native Windows process identity
* style(codex): format Windows session seam
* fix Windows structured Codex admission
* fix(windows): reprobe missing process identity capability
* fix(windows): decide folder-workspace WSL routing before the click
Review found pathUsesWslUnc exported but unused, and the folder composer
hardcoding worktreeUsesWslPath:false. Together those meant a folder picked
under a \\wsl.localhost\ parent routed to structured chat, then got refused
by the host and fell back AFTER the click -- which defeats the lane's own
design goal that create cannot fail after the click.
The group's parentPath is in scope at submit and the workspace is created
under it, so the parent decides WSL-ness pre-click. Wires pathUsesWslUnc
there and adds tests for the helper, including the unhydrated-store case
that previously threw.
* fix(windows): collapse the gate derivation to one call, restoring max-lines
CI static analysis failed: launch-agent-in-new-tab.ts crossed the 300-line
oxlint ceiling. Adding a max-lines disable is forbidden, so the two gate
derivations collapse into one readWindowsStructuredGateInputs() call --
a store-backed site now adds one line and one import name instead of two.
Better shape anyway: one derivation entry point rather than two reads a
call site must remember to pair.
* fix(windows): engage the legacy fallback when the host THROWS a refusal
Review found a P1 this merge composes: neither parent could reach it. At the
lane head the only structured entry was launch-agent-in-new-tab (full
store-backed WSL check); on main all win32 was refused. The merge enables
win32 in creation flows that pass no projectRuntime, so a WSL folder
workspace, a WSL-configured repo, or a repair-required runtime now routes
structured -- and the host refuses correctly, but by THROWING rather than
returning {ok:false, refusal}.
Callers engage their legacy-terminal fallback on the refusal CLASS, so an
unmapped throw arrives as a generic RPC rejection: no fallback, empty
workspace, error toast, prompt stranded in the launch outbox. Pre-merge the
same action opened a legacy terminal agent.
Map the host's thrown definitive refusals onto the refusal class at the
launch boundary, so every creation flow -- present and future -- degrades to
the legacy terminal instead of stranding. Narrow predicate: unrelated
failures (ECONNRESET, empty message, non-Error) still propagate untouched.
Ablation-proven: removing the mapping reddens the fallback test.
* fix(windows): teach the mobile RPC double the status probe the lane added
CI's first-ever run on this lane caught a pre-existing lane defect. The lane
changed status.get to resolve through
runtime.getStatusAfterWindowsProcessStartTimeProbe(), but never taught the
mobile-surface runtime double about it, so status.get failed for mobile
clients with "not a function". The lane's own test list did not include this
file and the lane had zero CI, so nothing ever ran it.
The real runtime always implements the method; the double omitted it.
* chore: merge current main and regenerate the localization runtime catalog
CI static analysis failed on a stale en-runtime-required.json: main added
onboarding integration-capability keys, and the generated catalog is checked
against the PR MERGE result, not the branch alone -- so it read clean locally
while failing in CI. Merging current main (90780acb85) and regenerating.
Gates after the merge: pnpm tc 0, oxlint 0, changed-code quality 0/56,
7 gate/lane test files 69 tests green.
* fix: route structured launches by execution host platform
* fix: recover paired structured session mirror on host swap
* Revert "fix: recover paired structured session mirror on host swap"
This reverts commit 81bfca0007.
* Revert "fix: route structured launches by execution host platform"
This reverts commit 47abbd354a.
* fix(windows): refuse structured chat in a paired web client
Reverts the two review-loop commits (restoring a tree byte-identical to the
validated head) and closes the hole they were aiming at, without their cost.
A paired web client's `platform` describes the browser's machine, not the host
that will run the agent, so the Windows gate cannot be evaluated there. Before
this, a browser on macOS driving a Windows runtime read "not win32", skipped the
creation-time proof entirely and allowed structured chat — fail-OPEN, the
dangerous direction, bypassing the guarantee this lane is built on.
`isWebClient` is a required input like the other gate fields, so the compiler
enumerated all seven call sites. Refusal is synchronous and fail-closed: no
async round-trip, no null window, no cache to invalidate — unlike keying on an
asynchronously-fetched host platform, which would have made every desktop
launch wait on a round-trip to fix a paired-web-only hole.
Paired web therefore gets the legacy chat until the host publishes eligibility
itself; that is the proper fix and belongs in its own PR.
Ablation-proven: removing the guard reddens both refusal tests; the
desktop-unaffected test is a preservation check and passes either way.
Gates: tc 0, oxlint 0.
Known open: repos-onboarding-folder-startup.test.ts fails on this branch and
passes on plain main — under investigation, NOT caused by this commit.
* test(onboarding): mock the web-client check the store path now reaches
The web-client refusal added `isWebClientLocation()` to the launch-route
inputs, which this suite's store path reaches while adding the FIRST folder.
The suite stubs `window` as `{ api }` with no `location`, so the function
cleared its `typeof window === 'undefined'` guard and then threw on
`window.location.pathname`.
That threw inside addNonGitFolder's own catch, so folder-1 never activated;
folder-2 then returned early (a project already existed) before reaching the
call at all, leaving exactly one activation with no startup seed.
Test artifact, not a product defect: a real renderer always has
`window.location`, so the seeding path is intact for users. Mocking the module
is the convention 7 other suites already use, and keeps product code free of
defensive branches that only exist to satisfy a stub.
Ablation-proven: removing the mock reproduces the original failure exactly.
* fix(renderer): make the web-client check total over a partial window
isWebClientLocation() guarded `typeof window === 'undefined'` and then assumed
`window.location` existed. A window stubbed without a location cleared the
guard and threw on `.pathname`.
That matters because this branch put the call on the launch-routing path,
where the throw is swallowed by the caller's catch and silently becomes a
FAILED LAUNCH rather than a visible error. CI caught it as 9 failures in
launch-work-item-direct.test.ts.
I previously "fixed" this by mocking the module in the one suite I knew about.
That was whack-a-mole against an unbounded set, and it missed this one. The
defect is the partial-window assumption, so fix it there: the mock is removed
from the onboarding suite and both suites now pass on the hardening alone.
Ablation-proven: reverting to the unguarded form reddens 11 tests across the
new unit suite and launch-work-item-direct.
Gates: tc 0, oxlint 0, changed-code quality 0/58.
* Move Codex's Windows structured-chat eligibility onto the host createSupport probe
The renderer no longer decides Codex win32 eligibility: launchStructuredAgentSession
probes agentSession.createSupport for both providers, the host answers via
supportsCodexStructuredLocation (process start-time proof + WSL refusal), and the
create path re-checks live. Deletes the client-side windows gate module and its
routing inputs (windowsProcessStartTime, worktreeUsesWslPath, isWebClient, platform)
from six call sites. Splits killCodexAppServerProcessTree out of
codex-app-server-session to hold the max-lines ceiling without a disable.
* fix(ci): keep pnpm lockfile stable
* test(windows): align foreground snapshot flags
* Restore main's pane-snapshot flag contract
Main asks for CreationTime on both projections; this branch's hot-path
isolation went away with the async probe it served.
---------
Co-authored-by: Orca Worker <orca-worker@localhost>
Co-authored-by: Merge Sim <sim@local>
Co-authored-by: Merge Sim <merge@localhost>
403 lines
15 KiB
JavaScript
403 lines
15 KiB
JavaScript
import { existsSync, readFileSync } from 'node:fs'
|
|
import { removeTreeSync } from '../../src/shared/windows-transient-lock-removal.ts'
|
|
import { join } from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
gitLineEndingEnv,
|
|
initGitWorkTree,
|
|
mkTempProject,
|
|
runRebuildScript,
|
|
writeFakeElectronRebuild,
|
|
writeFakeLoadableNodePty,
|
|
writeFakeNodePtyConptyPayload,
|
|
writeFakeUsableElectronPackage,
|
|
writeFakeWindowsProcessTree,
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi,
|
|
writeFakeWindowsRegistry,
|
|
writeNodePtyPatchFile,
|
|
writePatchedNodePtyBuildArtifacts,
|
|
writeWindowsProcessTreePatchFile
|
|
} from './rebuild-native-deps-test-fixtures.mjs'
|
|
|
|
describe('rebuild-native-deps patched node-pty rebuild', () => {
|
|
it.skipIf(process.platform !== 'win32')(
|
|
'repairs a missing ConPTY runtime before probing without recompiling node-pty',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir, { nativeDir: '../build/Release/' })
|
|
writeFakeWindowsRegistry(projectDir)
|
|
writeFakeWindowsProcessTree(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, process.arch)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath,
|
|
npm_config_platform: 'win32',
|
|
npm_config_arch: process.arch
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain('Restored node-pty ConPTY runtime files')
|
|
expect(result.stdout).toContain(
|
|
'Native modules already load in Electron; skipping rebuild.'
|
|
)
|
|
expect(existsSync(rebuildLogPath)).toBe(false)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
it('stages windows-process-tree node-addon-api headers before a Windows rebuild', () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi(projectDir)
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{ npm_config_platform: 'win32', npm_config_arch: 'x64' },
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(
|
|
readFileSync(
|
|
join(
|
|
projectDir,
|
|
'node_modules',
|
|
'@vscode',
|
|
'windows-process-tree',
|
|
'deps',
|
|
'node-addon-api',
|
|
'napi.h'
|
|
),
|
|
'utf8'
|
|
)
|
|
).toBe('// napi.h\n')
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
|
|
const commandLineSourcePath = (projectDir) =>
|
|
join(
|
|
projectDir,
|
|
'node_modules',
|
|
'@vscode',
|
|
'windows-process-tree',
|
|
'src',
|
|
'process_commandline.cc'
|
|
)
|
|
|
|
// Why inside a git work tree: `git apply` run under one prefixes patch paths
|
|
// with the cwd-relative prefix, silently skips what does not match, and still
|
|
// exits 0. The package dir is always under the project root in production, so
|
|
// a fixture in %TEMP% alone would pass while the real repair did nothing.
|
|
//
|
|
// Why both line-ending modes: the patch is stored LF while upstream ships this
|
|
// source CRLF, so whether the pre-image matches depends on `core.autocrlf` --
|
|
// and under `false`, Git's own built-in default, it did not. The repair blinds
|
|
// git to the repo, so that value comes from global config, i.e. from whichever
|
|
// option the developer's installer wrote. Pinning both makes the case cover the
|
|
// host that breaks rather than the host that happens to run it.
|
|
for (const autocrlf of ['false', 'true']) {
|
|
it(`repairs an un-applied command-line patch in a work tree (autocrlf=${autocrlf})`, () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
initGitWorkTree(projectDir)
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi(projectDir, {
|
|
commandLinePatchApplied: false
|
|
})
|
|
writeWindowsProcessTreePatchFile(projectDir)
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{
|
|
npm_config_platform: 'win32',
|
|
npm_config_arch: 'x64',
|
|
...gitLineEndingEnv(autocrlf)
|
|
},
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(readFileSync(commandLineSourcePath(projectDir), 'utf8')).toContain(
|
|
'kProcessCommandLineInformation'
|
|
)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
}
|
|
|
|
// Why fail rather than build: an unpatched command-line reader compiles fine
|
|
// and then opens every process with PROCESS_VM_READ to walk its PEB, which is
|
|
// the primitive the patch exists to remove.
|
|
it('refuses a Windows rebuild when the command-line patch cannot be applied', () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
initGitWorkTree(projectDir)
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi(projectDir, { commandLinePatchApplied: false })
|
|
// No patch file, so the repair has nothing to apply.
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{ npm_config_platform: 'win32', npm_config_arch: 'x64' },
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status).not.toBe(0)
|
|
expect(result.stderr).toContain('process_commandline.cc')
|
|
expect(readFileSync(commandLineSourcePath(projectDir), 'utf8')).not.toContain(
|
|
'kProcessCommandLineInformation'
|
|
)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
|
|
it('refuses a Windows rebuild when the process creation-time patch is missing', () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi(projectDir, { creationTimePatchApplied: false })
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{ npm_config_platform: 'win32', npm_config_arch: 'x64' },
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status).not.toBe(0)
|
|
expect(result.stderr).toContain('process creation-time patch')
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
|
|
it('restores the ConPTY runtime payload after a Windows Electron rebuild', () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{ npm_config_platform: 'win32', npm_config_arch: 'x64' },
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain('Restored node-pty ConPTY runtime files for win10-x64')
|
|
const runtimeDir = join(projectDir, 'node_modules', 'node-pty', 'build', 'Release', 'conpty')
|
|
expect(readFileSync(join(runtimeDir, 'conpty.dll'), 'utf8')).toBe('conpty.dll x64')
|
|
expect(readFileSync(join(runtimeDir, 'OpenConsole.exe'), 'utf8')).toBe('OpenConsole.exe x64')
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
|
|
it.skipIf(process.platform !== 'win32')(
|
|
'does not rebuild a healthy node-pty when another Windows addon fails its probe',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir)
|
|
writeFakeWindowsProcessTree(projectDir)
|
|
writeFakeNodePtyConptyPayload(projectDir, process.arch)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath,
|
|
npm_config_platform: 'win32',
|
|
npm_config_arch: process.arch
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain('Rebuilding failed native modules: windows-native-registry')
|
|
const rebuildCall = JSON.parse(readFileSync(rebuildLogPath, 'utf8').trim())
|
|
expect(rebuildCall.onlyModules).toEqual(['windows-native-registry'])
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
it.skipIf(process.platform !== 'win32')(
|
|
'rebuilds a loadable ConPTY native that lacks Orca job ownership',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir, { ownsPtyJob: false })
|
|
writeFakeWindowsRegistry(projectDir)
|
|
writeFakeWindowsProcessTree(projectDir)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath,
|
|
npm_config_platform: 'win32',
|
|
npm_config_arch: process.arch
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain('Rebuilding failed native modules: node-pty')
|
|
expect(result.stdout).toContain('missing listJobProcessIds')
|
|
const rebuildCall = JSON.parse(readFileSync(rebuildLogPath, 'utf8').trim())
|
|
expect(rebuildCall.onlyModules).toEqual(['node-pty'])
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'rebuilds when Electron can load node-pty but patched build artifacts are missing',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir)
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir)
|
|
writeNodePtyPatchFile(projectDir)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain(
|
|
'Patched node-pty build artifacts are missing; rebuilding from source.'
|
|
)
|
|
|
|
const rebuildCall = JSON.parse(readFileSync(rebuildLogPath, 'utf8').trim())
|
|
expect(rebuildCall.onlyModules).toEqual(['node-pty'])
|
|
expect(rebuildCall.ignoreModules).toEqual(['cpu-features'])
|
|
expect(rebuildCall.force).toBe(true)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'keeps the Electron load-probe fast path once patched node-pty artifacts exist',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir)
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir, { nativeDir: '../build/Release/' })
|
|
writeNodePtyPatchFile(projectDir)
|
|
writePatchedNodePtyBuildArtifacts(projectDir)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain(
|
|
'Native modules already load in Electron; skipping rebuild.'
|
|
)
|
|
expect(existsSync(rebuildLogPath)).toBe(false)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'rebuilds when patched artifacts exist but Electron falls back to node-pty prebuilds',
|
|
() => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
|
writeFakeUsableElectronPackage(projectDir)
|
|
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
|
writeFakeLoadableNodePty(projectDir, { nativeDir: '../prebuilds/darwin-arm64/' })
|
|
writeNodePtyPatchFile(projectDir)
|
|
writePatchedNodePtyBuildArtifacts(projectDir)
|
|
|
|
const result = runRebuildScript(projectDir, {
|
|
ORCA_REBUILD_TEST_LOG: rebuildLogPath
|
|
})
|
|
|
|
expect(result.status, result.stderr).toBe(0)
|
|
expect(result.stdout).toContain('Rebuilding failed native modules: node-pty')
|
|
expect(result.stdout).toContain("expected build/Release so Orca's node-pty patch is active")
|
|
|
|
const rebuildCall = JSON.parse(readFileSync(rebuildLogPath, 'utf8').trim())
|
|
expect(rebuildCall.onlyModules).toEqual(['node-pty'])
|
|
expect(rebuildCall.force).toBe(true)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
}
|
|
)
|
|
|
|
// The binary this step produces is the one copied into the packaged app. The
|
|
// relay build checks its own artifact and ensure-native-runtime checks what it
|
|
// loads; nothing checked this one, so a rebuild that quietly emitted the
|
|
// upstream reader shipped. Both non-clean states have to fail, which is the
|
|
// caller the tri-state was missing: after a rebuild that reported success, an
|
|
// absent binary is a broken build, not an absence to shrug at.
|
|
for (const [addon, expected] of [
|
|
['unpatched', 'still imports ReadProcessMemory'],
|
|
['none', 'is not there']
|
|
]) {
|
|
it(`fails a Windows rebuild that leaves ${addon} windows-process-tree bytes`, () => {
|
|
const projectDir = mkTempProject()
|
|
|
|
try {
|
|
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
|
writeFakeElectronRebuild(projectDir, { addon })
|
|
writeFakeNodePtyConptyPayload(projectDir, 'x64')
|
|
writeFakeWindowsProcessTreeWithNodeAddonApi(projectDir)
|
|
|
|
const result = runRebuildScript(
|
|
projectDir,
|
|
{ npm_config_platform: 'win32', npm_config_arch: 'x64' },
|
|
['--platform=win32', '--arch=x64', '--force']
|
|
)
|
|
|
|
expect(result.status).not.toBe(0)
|
|
expect(result.stderr).toContain(expected)
|
|
} finally {
|
|
removeTreeSync(projectDir)
|
|
}
|
|
})
|
|
}
|
|
})
|