@@ -354,7 +354,6 @@ describe('generateColumnFillValues', () => {
354354 return result ;
355355 } , { } ) ;
356356 }
357- const queryInfo = QueryInfo . fromJsonForTests ( sampleSet2QueryInfo ) ;
358357 const lookupFk = 'lookup' ;
359358 const intFk = 'int' ;
360359 const floatFk = 'float' ;
@@ -363,6 +362,17 @@ describe('generateColumnFillValues', () => {
363362 const strFk = 'str' ;
364363 const quoteFk = 'quote' ;
365364 const mvFk = 'mv' ;
365+ const columns = {
366+ [ lookupFk ] : new QueryColumn ( { fieldKey : lookupFk , name : lookupFk , lookup : { isPublic : true } as QueryLookup } ) ,
367+ [ intFk ] : new QueryColumn ( { fieldKey : intFk , name : intFk , jsonType : 'int' } ) ,
368+ [ floatFk ] : new QueryColumn ( { fieldKey : floatFk , name : floatFk , jsonType : 'float' } ) ,
369+ [ strFk ] : new QueryColumn ( { fieldKey : strFk , name : strFk } ) ,
370+ [ dateFk ] : new QueryColumn ( { fieldKey : dateFk , name : dateFk , jsonType : 'date' } ) ,
371+ [ datetimeFk ] : new QueryColumn ( { fieldKey : datetimeFk , name : datetimeFk , jsonType : 'date' } ) ,
372+ [ quoteFk ] : new QueryColumn ( { fieldKey : quoteFk , name : quoteFk } ) ,
373+ [ mvFk ] : new QueryColumn ( { fieldKey : mvFk , name : mvFk , lookup : { multiValued : 'junction' } as QueryLookup } ) ,
374+ } ;
375+ const queryInfo = QueryInfo . fromJsonForTests ( { pkCols : [ lookupFk ] , columns } ) ;
366376 const editorModel = new EditorModel ( { } ) . merge ( {
367377 queryInfo,
368378 cellMessages : Map < string , CellMessage > ( {
@@ -430,7 +440,10 @@ describe('generateColumnFillValues', () => {
430440 ...makeCellValues ( quoteFk , [ [ 'S,1' ] , [ 'S,2' ] , [ '' ] ] ) ,
431441 ...makeCellValues ( mvFk , [ [ 'S,1' , 'S,2' ] , [ 'S2' , 'S3' ] , [ '' ] , [ '' ] ] ) ,
432442 } ) ,
433- orderedColumns : List ( [ lookupFk , intFk , floatFk , strFk , dateFk , datetimeFk ] ) ,
443+ columnMap : Object . keys ( columns ) . reduce ( ( result , key ) => {
444+ return result . set ( key , queryInfo . getColumn ( key ) ) ;
445+ } , Map < string , QueryColumn > ( ) ) ,
446+ orderedColumns : List ( [ lookupFk , intFk , floatFk , strFk , dateFk , datetimeFk , quoteFk , mvFk ] ) ,
434447 rowCount : 10 ,
435448 } ) as EditorModel ;
436449
@@ -574,8 +587,8 @@ describe('generateColumnFillValues', () => {
574587 genCellKey ( strFk , 2 ) ,
575588 genCellKey ( strFk , 3 ) ,
576589 ] ) ;
577- // Copied values with commas should be quoted
578- expect ( cellValues ) . toEqual ( [ '" S,1" ' , '" S,1" ' , '" S,1" ' ] ) ;
590+ // Copied values with commas on a non-multi-value column don't need quoting (tab delimiter)
591+ expect ( cellValues ) . toEqual ( [ 'S,1' , 'S,1' , 'S,1' ] ) ;
579592 } ) ;
580593
581594 // Issue 52412
@@ -1191,7 +1204,7 @@ describe('insertPastedData', () => {
11911204 expect ( cellMessages . get ( genCellKey ( mvtc , 2 ) ) ) . toEqual ( { message : 'Could not find "bad"' } ) ;
11921205 } ) ;
11931206
1194- test ( 'pasting string values with special characters, fromDragFill false ' , async ( ) => {
1207+ test ( 'pasting string values with special characters' , async ( ) => {
11951208 const em = baseEditorModel . applyChanges ( {
11961209 selectionCells : [ genCellKey ( fkOne , 0 ) , genCellKey ( fkOne , 1 ) , genCellKey ( fkOne , 2 ) ] ,
11971210 selectedColIdx : 0 ,
@@ -1209,51 +1222,45 @@ describe('insertPastedData', () => {
12091222 const cellValues = changes . cellValues ;
12101223 // Space is preserved as-is
12111224 expect ( cellValues . get ( genCellKey ( fkOne , 0 ) ) ) . toEqual ( List ( [ { display : 'hello world' , raw : 'hello world' } ] ) ) ;
1212- // Quoted comma: without fromDragFill, CSV quoting is NOT stripped
1225+ // Quoted comma: CSV quoting is stripped, comma preserved
12131226 expect ( cellValues . get ( genCellKey ( fkOne , 1 ) ) ) . toEqual (
1214- List ( [ { display : '" hello, world" ' , raw : '" hello, world" ' } ] )
1227+ List ( [ { display : 'hello, world' , raw : 'hello, world' } ] )
12151228 ) ;
1216- // Escaped double quotes: without fromDragFill, CSV escaping is NOT processed
1229+ // Escaped double quotes: CSV escaping is processed
12171230 expect ( cellValues . get ( genCellKey ( fkOne , 2 ) ) ) . toEqual (
1218- List ( [ { display : '" say "" hello""" ' , raw : '" say "" hello"" "' } ] )
1231+ List ( [ { display : 'say "hello"' , raw : 'say "hello"' } ] )
12191232 ) ;
12201233 } ) ;
12211234
1222- test ( 'drag fill string values with special characters, fromDragFill true' , async ( ) => {
1235+ test ( 'pasting multi-line value into a single cell' , async ( ) => {
1236+ const value = '"ab\ncd"' ;
12231237 const em = baseEditorModel . applyChanges ( {
1224- selectionCells : [
1225- genCellKey ( fkOne , 0 ) ,
1226- genCellKey ( fkOne , 1 ) ,
1227- genCellKey ( fkOne , 2 ) ,
1228- genCellKey ( fkOne , 3 ) ,
1229- genCellKey ( fkOne , 4 ) ,
1230- genCellKey ( fkOne , 5 ) ,
1231- ] ,
1238+ selectionCells : [ genCellKey ( fkOne , 0 ) ] ,
12321239 selectedColIdx : 0 ,
1233- selectedRowIdx : 5 ,
1240+ selectedRowIdx : 0 ,
12341241 } ) ;
1235- const changes = await validateAndInsertPastedData (
1236- em ,
1237- 'hello world\n"hello, world"\n"say ""hello"""' ,
1238- undefined ,
1239- true ,
1240- true ,
1241- undefined ,
1242- false ,
1243- [ [ genCellKey ( fkOne , 3 ) , genCellKey ( fkOne , 4 ) , genCellKey ( fkOne , 5 ) ] ] ,
1244- true
1245- ) ;
1242+ const changes = await validateAndInsertPastedData ( em , value , undefined , true , true , undefined , true ) ;
12461243 const cellValues = changes . cellValues ;
1247- // Original values unchanged
1248- expect ( cellValues . get ( genCellKey ( fkOne , 0 ) ) ) . toEqual ( List ( [ { display : 'qwer' , raw : 'qwer' } ] ) ) ;
1249- expect ( cellValues . get ( genCellKey ( fkOne , 1 ) ) ) . toEqual ( List ( [ { display : 'asdf' , raw : 'asdf' } ] ) ) ;
1250- expect ( cellValues . get ( genCellKey ( fkOne , 2 ) ) ) . toEqual ( List ( [ { display : 'zxcv' , raw : 'zxcv' } ] ) ) ;
1251- // Space: no CSV quoting to strip
1252- expect ( cellValues . get ( genCellKey ( fkOne , 3 ) ) ) . toEqual ( List ( [ { display : 'hello world' , raw : 'hello world' } ] ) ) ;
1253- // Quoted comma: fromDragFill strips CSV quoting, comma preserved in value
1254- expect ( cellValues . get ( genCellKey ( fkOne , 4 ) ) ) . toEqual ( List ( [ { display : 'hello, world' , raw : 'hello, world' } ] ) ) ;
1255- // Escaped double quotes: fromDragFill strips CSV quoting and unescapes ""
1256- expect ( cellValues . get ( genCellKey ( fkOne , 5 ) ) ) . toEqual ( List ( [ { display : 'say "hello"' , raw : 'say "hello"' } ] ) ) ;
1244+ expect ( cellValues . get ( genCellKey ( fkOne , 0 ) ) ) . toEqual ( List ( [ { display : 'ab\ncd' , raw : 'ab\ncd' } ] ) ) ;
1245+ expect ( changes . cellMessages . get ( genCellKey ( fkOne , 0 ) ) ) . toBeUndefined ( ) ;
1246+ } ) ;
1247+
1248+ test ( 'pasting multi-line values into multiple cells' , async ( ) => {
1249+ const value = '"ab\n' +
1250+ 'cd"\n' +
1251+ '"another\n' +
1252+ 'line"' ;
1253+ const em = baseEditorModel . applyChanges ( {
1254+ selectionCells : [ genCellKey ( fkOne , 0 ) , genCellKey ( fkOne , 1 ) ] ,
1255+ selectedColIdx : 0 ,
1256+ selectedRowIdx : 0 ,
1257+ } ) ;
1258+ const changes = await validateAndInsertPastedData ( em , value , undefined , true , true , undefined , true ) ;
1259+ const cellValues = changes . cellValues ;
1260+ expect ( cellValues . get ( genCellKey ( fkOne , 0 ) ) ) . toEqual ( List ( [ { display : 'ab\ncd' , raw : 'ab\ncd' } ] ) ) ;
1261+ expect ( cellValues . get ( genCellKey ( fkOne , 1 ) ) ) . toEqual (
1262+ List ( [ { display : 'another\nline' , raw : 'another\nline' } ] )
1263+ ) ;
12571264 } ) ;
12581265
12591266 test ( 'pasting exactly A,B into mvtc matches single valid value' , async ( ) => {
0 commit comments