@@ -268,18 +268,6 @@ impl Document {
268268 }
269269
270270 if new_ranges. len ( ) == 1 {
271- if change. is_whitespace ( ) {
272- self . move_ranges (
273- affected_range. end ( ) ,
274- change. diff_size ( ) ,
275- change. is_addition ( ) ,
276- ) ;
277-
278- self . content = new_content;
279-
280- return changed;
281- }
282-
283271 let affected_idx = affected_indices[ 0 ] ;
284272 let new_range = new_ranges[ 0 ] . add ( affected_range. start ( ) ) ;
285273 let ( old_id, old_range) = self . positions [ affected_idx] ;
@@ -290,22 +278,25 @@ impl Document {
290278 let new_id = self . id_generator . next ( ) ;
291279 self . positions [ affected_idx] = ( new_id, new_range) ;
292280
293- changed. push ( StatementChange :: Modified ( ModifiedStatement {
294- old_stmt : Statement {
295- id : old_id,
296- path : self . path . clone ( ) ,
297- } ,
298- old_stmt_text : self . content [ old_range] . to_string ( ) ,
299-
300- new_stmt : Statement {
301- id : new_id,
302- path : self . path . clone ( ) ,
303- } ,
304- new_stmt_text : changed_content[ new_ranges[ 0 ] ] . to_string ( ) ,
305- // change must be relative to the statement
306- change_text : change. text . clone ( ) ,
307- change_range : change_range. sub ( old_range. start ( ) ) ,
308- } ) ) ;
281+ if !change. is_whitespace ( ) {
282+ // whitespace-only changes should not invalidate the statement
283+ changed. push ( StatementChange :: Modified ( ModifiedStatement {
284+ old_stmt : Statement {
285+ id : old_id,
286+ path : self . path . clone ( ) ,
287+ } ,
288+ old_stmt_text : self . content [ old_range] . to_string ( ) ,
289+
290+ new_stmt : Statement {
291+ id : new_id,
292+ path : self . path . clone ( ) ,
293+ } ,
294+ new_stmt_text : changed_content[ new_ranges[ 0 ] ] . to_string ( ) ,
295+ // change must be relative to the statement
296+ change_text : change. text . clone ( ) ,
297+ change_range : change_range. sub ( old_range. start ( ) ) ,
298+ } ) ) ;
299+ }
309300
310301 self . content = new_content;
311302
@@ -447,12 +438,16 @@ mod tests {
447438 . expect ( "Unexpected scan error" )
448439 . ranges ;
449440
450- assert ! ( ranges. len( ) == d. positions. len( ) ) ;
441+ assert ! (
442+ ranges. len( ) == d. positions. len( ) ,
443+ "should have the correct amount of positions"
444+ ) ;
451445
452446 assert ! (
453447 ranges
454448 . iter( )
455- . all( |r| { d. positions. iter( ) . any( |( _, stmt_range) | stmt_range == r) } )
449+ . all( |r| { d. positions. iter( ) . any( |( _, stmt_range) | stmt_range == r) } ) ,
450+ "all ranges should be in positions"
456451 ) ;
457452 }
458453
@@ -648,6 +643,83 @@ mod tests {
648643 assert_document_integrity ( & d) ;
649644 }
650645
646+ #[ test]
647+ fn within_statements_2 ( ) {
648+ let path = PgLTPath :: new ( "test.sql" ) ;
649+ let input = "alter table deal alter column value drop not null;\n " ;
650+ let mut d = Document :: new ( path. clone ( ) , input. to_string ( ) , 0 ) ;
651+
652+ assert_eq ! ( d. positions. len( ) , 1 ) ;
653+
654+ let change1 = ChangeFileParams {
655+ path : path. clone ( ) ,
656+ version : 1 ,
657+ changes : vec ! [ ChangeParams {
658+ text: " " . to_string( ) ,
659+ range: Some ( TextRange :: new( 17 . into( ) , 17 . into( ) ) ) ,
660+ } ] ,
661+ } ;
662+
663+ let changed1 = d. apply_file_change ( & change1) ;
664+ assert_eq ! ( changed1. len( ) , 0 , "should not emit change" ) ;
665+ assert_eq ! (
666+ d. content,
667+ "alter table deal alter column value drop not null;\n "
668+ ) ;
669+ assert_document_integrity ( & d) ;
670+
671+ let change2 = ChangeFileParams {
672+ path : path. clone ( ) ,
673+ version : 2 ,
674+ changes : vec ! [ ChangeParams {
675+ text: " " . to_string( ) ,
676+ range: Some ( TextRange :: new( 18 . into( ) , 18 . into( ) ) ) ,
677+ } ] ,
678+ } ;
679+
680+ let changed2 = d. apply_file_change ( & change2) ;
681+ assert_eq ! ( changed2. len( ) , 0 ) ;
682+ assert_eq ! (
683+ d. content,
684+ "alter table deal alter column value drop not null;\n "
685+ ) ;
686+ assert_document_integrity ( & d) ;
687+
688+ let change3 = ChangeFileParams {
689+ path : path. clone ( ) ,
690+ version : 3 ,
691+ changes : vec ! [ ChangeParams {
692+ text: " " . to_string( ) ,
693+ range: Some ( TextRange :: new( 19 . into( ) , 19 . into( ) ) ) ,
694+ } ] ,
695+ } ;
696+
697+ let changed3 = d. apply_file_change ( & change3) ;
698+ assert_eq ! ( changed3. len( ) , 0 ) ;
699+ assert_eq ! (
700+ d. content,
701+ "alter table deal alter column value drop not null;\n "
702+ ) ;
703+ assert_document_integrity ( & d) ;
704+
705+ let change4 = ChangeFileParams {
706+ path : path. clone ( ) ,
707+ version : 4 ,
708+ changes : vec ! [ ChangeParams {
709+ text: " " . to_string( ) ,
710+ range: Some ( TextRange :: new( 20 . into( ) , 20 . into( ) ) ) ,
711+ } ] ,
712+ } ;
713+
714+ let changed4 = d. apply_file_change ( & change4) ;
715+ assert_eq ! ( changed4. len( ) , 0 ) ;
716+ assert_eq ! (
717+ d. content,
718+ "alter table deal alter column value drop not null;\n "
719+ ) ;
720+ assert_document_integrity ( & d) ;
721+ }
722+
651723 #[ test]
652724 fn julians_sample ( ) {
653725 let path = PgLTPath :: new ( "test.sql" ) ;
0 commit comments