@ -291,6 +291,98 @@ describe('insertParagraph — code → line break', () => {
} ) ;
} ) ;
// ── insertLineBreak: code / table route to \n at ANY depth ───────────────
//
// Regression guard for the audit's CRITICAL fix. insertLineBreak (Shift+Enter)
// must send code / table cells to a LITERAL newline — never an atomic break
// inline — at every nesting depth. Before the fix it inspected only the
// top-level block, so code / table nested in a callout or column received a
// break inline, which is illegal in code's text-only children (validate
// rejects it). The nested cases below fail against the pre-fix implementation.
describe ( 'insertLineBreak — code / table → \\n (incl. nested)' , ( ) = > {
it ( 'top-level code → literal newline, never a break node' , ( ) = > {
const d = doc ( { type : 'code' , children : [ { type : 'text' , text : 'x' } ] } ) ;
const sel = createCollapsedSelection ( [ 0 , 0 ] , 1 ) ;
const r = insertLineBreak ( createState ( d , sel ) ) ;
expect ( r . changed ) . toBe ( true ) ;
const code = r . state . document . children [ 0 ] ;
if ( code . type !== 'code' ) throw new Error ( 'expected code' ) ;
expect ( code . children . every ( ( c ) = > c . type === 'text' ) ) . toBe ( true ) ;
expect ( resolveTextNode ( r . state . document , [ 0 , 0 ] ) ! . text ) . toBe ( 'x\n' ) ;
} ) ;
it ( 'code nested in a callout → literal newline, never a break node' , ( ) = > {
const d = doc ( {
type : 'callout' ,
intent : 'risk' ,
children : [ { type : 'code' , children : [ { type : 'text' , text : 'x' } ] } ]
} ) ;
const sel = createCollapsedSelection ( [ 0 , 0 , 0 ] , 1 ) ;
const r = insertLineBreak ( createState ( d , sel ) ) ;
expect ( r . changed ) . toBe ( true ) ;
const callout = r . state . document . children [ 0 ] ;
if ( callout . type !== 'callout' ) throw new Error ( 'expected callout' ) ;
const code = callout . children [ 0 ] ;
if ( code . type !== 'code' ) throw new Error ( 'expected code' ) ;
// No break inline smuggled into the code's text-only children.
expect ( code . children . every ( ( c ) = > c . type === 'text' ) ) . toBe ( true ) ;
expect ( resolveTextNode ( r . state . document , [ 0 , 0 , 0 ] ) ! . text ) . toBe ( 'x\n' ) ;
} ) ;
it ( 'code nested in a column → literal newline, never a break node' , ( ) = > {
const d = doc ( {
type : 'columns' ,
columns : [
{ children : [ { type : 'code' , children : [ { type : 'text' , text : 'x' } ] } ] } ,
{ children : [ { type : 'paragraph' , children : [ { type : 'text' , text : '' } ] } ] }
]
} ) ;
const sel = createCollapsedSelection ( [ 0 , 0 , 0 , 0 ] , 1 ) ;
const r = insertLineBreak ( createState ( d , sel ) ) ;
expect ( r . changed ) . toBe ( true ) ;
expect ( resolveTextNode ( r . state . document , [ 0 , 0 , 0 , 0 ] ) ! . text ) . toBe ( 'x\n' ) ;
} ) ;
it ( 'table cell → literal newline (via Shift+Enter, not just Enter)' , ( ) = > {
const d = doc ( {
type : 'table' ,
rows : [
{
cells : [ { children : [ { type : 'paragraph' , children : [ { type : 'text' , text : 'cell' } ] } ] } ]
}
]
} ) ;
const sel = createCollapsedSelection ( [ 0 , 0 , 0 , 0 , 0 ] , 4 ) ;
const r = insertLineBreak ( createState ( d , sel ) ) ;
expect ( r . changed ) . toBe ( true ) ;
expect ( resolveTextNode ( r . state . document , [ 0 , 0 , 0 , 0 , 0 ] ) ! . text ) . toBe ( 'cell\n' ) ;
} ) ;
it ( 'table nested in a callout → literal newline in the cell' , ( ) = > {
const d = doc ( {
type : 'callout' ,
intent : 'risk' ,
children : [
{
type : 'table' ,
rows : [
{
cells : [
{ children : [ { type : 'paragraph' , children : [ { type : 'text' , text : 'cell' } ] } ] }
]
}
]
}
]
} ) ;
const sel = createCollapsedSelection ( [ 0 , 0 , 0 , 0 , 0 , 0 ] , 4 ) ;
const r = insertLineBreak ( createState ( d , sel ) ) ;
expect ( r . changed ) . toBe ( true ) ;
expect ( resolveTextNode ( r . state . document , [ 0 , 0 , 0 , 0 , 0 , 0 ] ) ! . text ) . toBe ( 'cell\n' ) ;
} ) ;
} ) ;
// ── Atomic blocks: image / divider ───────────────────────────────────────
describe ( 'insertParagraph — atomic blocks' , ( ) = > {