test(editor): align model and cursor custody fixtures with owner-close policy

This commit is contained in:
Neil
2026-10-06 17:46:39 -07:00
committed by Neil
parent c9f4cd7e27
commit 91bb636530
3 changed files with 22 additions and 7 deletions
@@ -38,10 +38,11 @@ it('keeps a live model and releases only its closed sibling', async () => {
it('preserves a shared URI until its final file owner closes', async () => {
const { store, attach, add } = createModelLifetimeFixture()
const { file, model } = add('shared-a')
store.setState({ openFiles: [file, { ...file, id: 'shared-b' }] })
store.setState({ openFiles: [file, { ...file, id: 'shared-b', readOnly: true }] })
attach()
store.getState().closeFile(file.id)
await Promise.resolve()
expect(store.getState().openFiles.map((openFile) => openFile.id)).toEqual(['shared-b'])
expect(model.isDisposed()).toBe(false)
store.getState().closeFile('shared-b')
await Promise.resolve()
@@ -1,7 +1,7 @@
// @vitest-environment happy-dom
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
import { afterEach, describe, expect, it, vi } from 'vitest'
import type { OpenFile } from '@/store/slices/editor'
import { buildOwnedEditorFileId, type OpenFile } from '@/store/slices/editor'
import type { WorktreeOperationRoute } from '@/lib/worktree-operation-route'
import {
attachModelLifetimeView,
@@ -35,6 +35,7 @@ function file(id: string, route: WorktreeOperationRoute, filePath = FILE_PATH):
...modelLifetimeFile(id),
filePath,
relativePath: 'same-path.txt',
runtimeEnvironmentId: route.runtimeEnvironmentId,
operationProvenance: {
ownershipProjection: 'explicit',
generation: {
@@ -249,6 +250,12 @@ describe('same-path models on different execution hosts', () => {
const { owners, store, attach } = createHostModels()
const local = owners[0]!
const runtime = owners[2]!
const migratedFile: OpenFile = {
...local.file,
id: buildOwnedEditorFileId(FILE_PATH, local.file.worktreeId, 'hub-a'),
runtimeEnvironmentId: 'hub-a',
operationProvenance: runtime.file.operationProvenance
}
const detach = attachModelLifetimeView(local.model)
edit(runtime.model, 'runtime independent edit')
attach()
@@ -257,8 +264,10 @@ describe('same-path models on different execution hosts', () => {
.getState()
.openFiles.map((opened) =>
opened.id === local.file.id
? { ...opened, operationProvenance: runtime.file.operationProvenance }
: opened
? migratedFile
: opened.id === runtime.file.id
? { ...opened, readOnly: true }
: opened
)
})
await Promise.resolve()
@@ -268,8 +277,9 @@ describe('same-path models on different execution hosts', () => {
expect(local.model.isDisposed()).toBe(true)
expect(runtime.model.isDisposed()).toBe(false)
expect(runtime.model.getValue()).toBe('runtime independent edit')
store.getState().closeFile(local.file.id)
store.getState().closeFile(migratedFile.id)
await Promise.resolve()
expect(store.getState().openFiles.some((opened) => opened.id === runtime.file.id)).toBe(true)
expect(runtime.model.isDisposed()).toBe(false)
await runtime.model.undo()
expect(runtime.model.getValue()).toBe(runtime.initial)
@@ -41,6 +41,7 @@ function startTracking(
describe('Monaco cursor-line ownership lifetime', () => {
it('releases positions after 250 distinct owned editor tabs close', () => {
const store = createEditorStore()
store.setState({ unifiedTabsByWorktree: {} })
for (let index = 0; index < 250; index += 1) {
const file = makeFile(`editor:wt-1:local:file-${index}`, `/repo/file-${index}.ts`)
store.setState({ openFiles: [file] })
@@ -57,8 +58,11 @@ describe('Monaco cursor-line ownership lifetime', () => {
it('isolates same-path positions and closes only the selected file identity', () => {
const store = createEditorStore()
const local = makeFile('editor:wt-1:local:file.ts', '/repo/file.ts')
const remote = makeFile('editor:wt-1:remote-a:file.ts', '/repo/file.ts')
store.setState({ openFiles: [local, remote] })
const remote = {
...makeFile('editor:wt-1:remote-a:file.ts', '/repo/file.ts'),
runtimeEnvironmentId: 'remote-a'
}
store.setState({ openFiles: [local, remote], unifiedTabsByWorktree: {} })
const localTracking = startTracking(store, local, 12)
const remoteTracking = startTracking(store, remote, 35)