@@ -46,6 +46,9 @@ vi.mock("@/core/codemirror/editing/commands", () => ({
4646 foldAllBulk : vi . fn ( ) ,
4747 unfoldAllBulk : vi . fn ( ) ,
4848} ) ) ;
49+ vi . mock ( "@/core/wasm/utils" , ( ) => ( {
50+ isWasm : vi . fn ( ( ) => false ) ,
51+ } ) ) ;
4952vi . mock ( "../scrollCellIntoView" , async ( importOriginal ) => {
5053 const actual = await importOriginal ( ) ;
5154 return {
@@ -3428,3 +3431,99 @@ describe("createTracebackInfoAtom", () => {
34283431 expect ( traceback ) . toBeUndefined ( ) ;
34293432 } ) ;
34303433} ) ;
3434+
3435+ describe ( "setCells snapshot preservation" , ( ) => {
3436+ const CELL_A = cellId ( "A" ) ;
3437+ const CELL_B = cellId ( "B" ) ;
3438+ const newCells : CellData [ ] = [
3439+ {
3440+ id : CELL_A ,
3441+ name : "a" ,
3442+ code : "1" ,
3443+ edited : false ,
3444+ lastCodeRun : null ,
3445+ lastExecutionTime : null ,
3446+ config : { hide_code : false , disabled : false , column : null } ,
3447+ serializedEditorState : null ,
3448+ } ,
3449+ {
3450+ id : CELL_B ,
3451+ name : "b" ,
3452+ code : "2" ,
3453+ edited : false ,
3454+ lastCodeRun : null ,
3455+ lastExecutionTime : null ,
3456+ config : { hide_code : false , disabled : false , column : null } ,
3457+ serializedEditorState : null ,
3458+ } ,
3459+ ] ;
3460+
3461+ const hydratedState = ( ) =>
3462+ MockNotebook . notebookState ( {
3463+ cellData : {
3464+ [ CELL_A ] : { id : CELL_A , code : "1" } ,
3465+ [ CELL_B ] : { id : CELL_B , code : "2" } ,
3466+ } ,
3467+ cellRuntime : {
3468+ [ CELL_A ] : {
3469+ output : {
3470+ channel : "output" ,
3471+ mimetype : "text/plain" ,
3472+ data : "hydrated-A" ,
3473+ timestamp : 0 ,
3474+ } ,
3475+ } ,
3476+ [ CELL_B ] : {
3477+ consoleOutputs : [
3478+ {
3479+ channel : "stdout" ,
3480+ mimetype : "text/plain" ,
3481+ data : "hydrated-B-stdout" ,
3482+ timestamp : 0 ,
3483+ } ,
3484+ ] ,
3485+ } ,
3486+ } ,
3487+ } ) ;
3488+
3489+ beforeEach ( async ( ) => {
3490+ const { isWasm } = await import ( "@/core/wasm/utils" ) ;
3491+ vi . mocked ( isWasm ) . mockReturnValue ( true ) ;
3492+ } ) ;
3493+
3494+ it ( "preserves hydrated output in WASM" , ( ) => {
3495+ const next = exportedForTesting . reducer ( hydratedState ( ) , {
3496+ type : "setCells" ,
3497+ payload : newCells ,
3498+ } ) ;
3499+
3500+ expect ( next . cellRuntime [ CELL_A ] . output ) . toMatchObject ( {
3501+ data : "hydrated-A" ,
3502+ } ) ;
3503+ } ) ;
3504+
3505+ it ( "preserves console-only hydration in WASM" , ( ) => {
3506+ const next = exportedForTesting . reducer ( hydratedState ( ) , {
3507+ type : "setCells" ,
3508+ payload : newCells ,
3509+ } ) ;
3510+
3511+ expect ( next . cellRuntime [ CELL_B ] . consoleOutputs ) . toHaveLength ( 1 ) ;
3512+ expect ( next . cellRuntime [ CELL_B ] . consoleOutputs [ 0 ] ) . toMatchObject ( {
3513+ data : "hydrated-B-stdout" ,
3514+ } ) ;
3515+ } ) ;
3516+
3517+ it ( "resets cells with no prior runtime even in WASM" , ( ) => {
3518+ const empty = MockNotebook . notebookState ( { cellData : { } } ) ;
3519+ const next = exportedForTesting . reducer ( empty , {
3520+ type : "setCells" ,
3521+ payload : newCells ,
3522+ } ) ;
3523+
3524+ expect ( next . cellRuntime [ CELL_A ] . output ) . toBeNull ( ) ;
3525+ expect ( next . cellRuntime [ CELL_A ] . consoleOutputs ) . toEqual ( [ ] ) ;
3526+ expect ( next . cellRuntime [ CELL_B ] . output ) . toBeNull ( ) ;
3527+ expect ( next . cellRuntime [ CELL_B ] . consoleOutputs ) . toEqual ( [ ] ) ;
3528+ } ) ;
3529+ } ) ;
0 commit comments