@@ -2702,7 +2702,7 @@ mod tests {
27022702 }
27032703
27042704 #[ test]
2705- fn test_replace_gap_at ( ) -> Result < ( ) , Error > {
2705+ fn test_replace_gap_at_middle ( ) -> Result < ( ) , Error > {
27062706 use super :: Update :: * ;
27072707
27082708 let mut linked_chunk = LinkedChunk :: < 3 , char , ( ) > :: new_with_update_history ( ) ;
@@ -2734,125 +2734,154 @@ mod tests {
27342734 ) ;
27352735
27362736 // Replace a gap in the middle of the linked chunk.
2737- {
2738- let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2739- assert_eq ! ( gap_identifier, ChunkIdentifier ( 1 ) ) ;
2737+ let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2738+ assert_eq ! ( gap_identifier, ChunkIdentifier ( 1 ) ) ;
27402739
2741- let new_chunk =
2742- linked_chunk. replace_gap_at ( [ 'd' , 'e' , 'f' , 'g' , 'h' ] , gap_identifier) ?;
2743- assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 3 ) ) ;
2744- assert_items_eq ! (
2745- linked_chunk,
2746- [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ]
2747- ) ;
2748- assert_eq ! (
2749- linked_chunk. updates( ) . unwrap( ) . take( ) ,
2750- & [
2751- NewItemsChunk {
2752- previous: Some ( ChunkIdentifier ( 1 ) ) ,
2753- new: ChunkIdentifier ( 3 ) ,
2754- next: Some ( ChunkIdentifier ( 2 ) ) ,
2755- } ,
2756- PushItems { at: Position ( ChunkIdentifier ( 3 ) , 0 ) , items: vec![ 'd' , 'e' , 'f' ] } ,
2757- NewItemsChunk {
2758- previous: Some ( ChunkIdentifier ( 3 ) ) ,
2759- new: ChunkIdentifier ( 4 ) ,
2760- next: Some ( ChunkIdentifier ( 2 ) ) ,
2761- } ,
2762- PushItems { at: Position ( ChunkIdentifier ( 4 ) , 0 ) , items: vec![ 'g' , 'h' ] } ,
2763- RemoveChunk ( ChunkIdentifier ( 1 ) ) ,
2764- ]
2765- ) ;
2766- }
2740+ let new_chunk = linked_chunk. replace_gap_at ( [ 'd' , 'e' , 'f' , 'g' , 'h' ] , gap_identifier) ?;
2741+ assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 3 ) ) ;
2742+ assert_items_eq ! (
2743+ linked_chunk,
2744+ [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ]
2745+ ) ;
2746+ assert_eq ! (
2747+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2748+ & [
2749+ NewItemsChunk {
2750+ previous: Some ( ChunkIdentifier ( 1 ) ) ,
2751+ new: ChunkIdentifier ( 3 ) ,
2752+ next: Some ( ChunkIdentifier ( 2 ) ) ,
2753+ } ,
2754+ PushItems { at: Position ( ChunkIdentifier ( 3 ) , 0 ) , items: vec![ 'd' , 'e' , 'f' ] } ,
2755+ NewItemsChunk {
2756+ previous: Some ( ChunkIdentifier ( 3 ) ) ,
2757+ new: ChunkIdentifier ( 4 ) ,
2758+ next: Some ( ChunkIdentifier ( 2 ) ) ,
2759+ } ,
2760+ PushItems { at: Position ( ChunkIdentifier ( 4 ) , 0 ) , items: vec![ 'g' , 'h' ] } ,
2761+ RemoveChunk ( ChunkIdentifier ( 1 ) ) ,
2762+ ]
2763+ ) ;
2764+
2765+ assert_eq ! ( linked_chunk. num_items( ) , 9 ) ;
2766+
2767+ Ok ( ( ) )
2768+ }
2769+
2770+ #[ test]
2771+ fn test_replace_gap_at_end ( ) -> Result < ( ) , Error > {
2772+ use super :: Update :: * ;
2773+
2774+ let mut linked_chunk = LinkedChunk :: < 3 , char , ( ) > :: new_with_update_history ( ) ;
2775+
2776+ // Ignore initial update.
2777+ let _ = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
2778+
2779+ linked_chunk. push_items_back ( [ 'a' , 'b' ] ) ;
2780+ linked_chunk. push_gap_back ( ( ) ) ;
2781+ assert_items_eq ! ( linked_chunk, [ 'a' , 'b' ] [ -] ) ;
2782+ assert_eq ! (
2783+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2784+ & [
2785+ PushItems { at: Position ( ChunkIdentifier ( 0 ) , 0 ) , items: vec![ 'a' , 'b' ] } ,
2786+ NewGapChunk {
2787+ previous: Some ( ChunkIdentifier ( 0 ) ) ,
2788+ new: ChunkIdentifier ( 1 ) ,
2789+ next: None ,
2790+ gap: ( ) ,
2791+ } ,
2792+ ]
2793+ ) ;
27672794
27682795 // Replace a gap at the end of the linked chunk.
2769- {
2770- linked_chunk. push_gap_back ( ( ) ) ;
2771- assert_items_eq ! (
2772- linked_chunk,
2773- [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ] [ -]
2774- ) ;
2775- assert_eq ! (
2776- linked_chunk. updates( ) . unwrap( ) . take( ) ,
2777- & [ NewGapChunk {
2796+ let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2797+ assert_eq ! ( gap_identifier, ChunkIdentifier ( 1 ) ) ;
2798+
2799+ let new_chunk = linked_chunk. replace_gap_at ( [ 'w' , 'x' , 'y' , 'z' ] , gap_identifier) ?;
2800+ assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 2 ) ) ;
2801+ assert_items_eq ! (
2802+ linked_chunk,
2803+ [ 'a' , 'b' ] [ 'w' , 'x' , 'y' ] [ 'z' ]
2804+ ) ;
2805+ assert_eq ! (
2806+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2807+ & [
2808+ NewItemsChunk {
2809+ previous: Some ( ChunkIdentifier ( 1 ) ) ,
2810+ new: ChunkIdentifier ( 2 ) ,
2811+ next: None ,
2812+ } ,
2813+ PushItems { at: Position ( ChunkIdentifier ( 2 ) , 0 ) , items: vec![ 'w' , 'x' , 'y' ] } ,
2814+ NewItemsChunk {
27782815 previous: Some ( ChunkIdentifier ( 2 ) ) ,
2779- new: ChunkIdentifier ( 5 ) ,
2816+ new: ChunkIdentifier ( 3 ) ,
27802817 next: None ,
2781- gap: ( ) ,
2782- } ]
2783- ) ;
2818+ } ,
2819+ PushItems { at: Position ( ChunkIdentifier ( 3 ) , 0 ) , items: vec![ 'z' ] } ,
2820+ RemoveChunk ( ChunkIdentifier ( 1 ) ) ,
2821+ ]
2822+ ) ;
27842823
2785- let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2786- assert_eq ! ( gap_identifier, ChunkIdentifier ( 5 ) ) ;
2824+ assert_eq ! ( linked_chunk. num_items( ) , 6 ) ;
27872825
2788- let new_chunk = linked_chunk. replace_gap_at ( [ 'w' , 'x' , 'y' , 'z' ] , gap_identifier) ?;
2789- assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 6 ) ) ;
2790- assert_items_eq ! (
2791- linked_chunk,
2792- [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ] [ 'w' , 'x' , 'y' ] [ 'z' ]
2793- ) ;
2794- assert_eq ! (
2795- linked_chunk. updates( ) . unwrap( ) . take( ) ,
2796- & [
2797- NewItemsChunk {
2798- previous: Some ( ChunkIdentifier ( 5 ) ) ,
2799- new: ChunkIdentifier ( 6 ) ,
2800- next: None ,
2801- } ,
2802- PushItems { at: Position ( ChunkIdentifier ( 6 ) , 0 ) , items: vec![ 'w' , 'x' , 'y' ] } ,
2803- NewItemsChunk {
2804- previous: Some ( ChunkIdentifier ( 6 ) ) ,
2805- new: ChunkIdentifier ( 7 ) ,
2806- next: None ,
2807- } ,
2808- PushItems { at: Position ( ChunkIdentifier ( 7 ) , 0 ) , items: vec![ 'z' ] } ,
2809- RemoveChunk ( ChunkIdentifier ( 5 ) ) ,
2810- ]
2811- ) ;
2812- }
2826+ Ok ( ( ) )
2827+ }
2828+
2829+ #[ test]
2830+ fn test_replace_gap_at_beginning ( ) -> Result < ( ) , Error > {
2831+ use super :: Update :: * ;
2832+
2833+ let mut linked_chunk = LinkedChunk :: < 3 , char , ( ) > :: new_with_update_history ( ) ;
2834+
2835+ // Ignore initial update.
2836+ let _ = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
2837+
2838+ linked_chunk. push_items_back ( [ 'a' , 'b' ] ) ;
2839+ assert_items_eq ! ( linked_chunk, [ 'a' , 'b' ] ) ;
2840+ assert_eq ! (
2841+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2842+ & [ PushItems { at: Position ( ChunkIdentifier ( 0 ) , 0 ) , items: vec![ 'a' , 'b' ] } , ]
2843+ ) ;
28132844
28142845 // Replace a gap at the beginning of the linked chunk.
2815- {
2816- let position_of_a = linked_chunk. item_position ( |item| * item == 'a' ) . unwrap ( ) ;
2817- linked_chunk. insert_gap_at ( ( ) , position_of_a) . unwrap ( ) ;
2818- assert_items_eq ! (
2819- linked_chunk,
2820- [ -] [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ] [ 'w' , 'x' , 'y' ] [ 'z' ]
2821- ) ;
2822- assert_eq ! (
2823- linked_chunk. updates( ) . unwrap( ) . take( ) ,
2824- & [ NewGapChunk {
2825- previous: None ,
2826- new: ChunkIdentifier ( 8 ) ,
2827- next: Some ( ChunkIdentifier ( 0 ) ) ,
2828- gap: ( ) ,
2829- } ]
2830- ) ;
2846+ let position_of_a = linked_chunk. item_position ( |item| * item == 'a' ) . unwrap ( ) ;
2847+ linked_chunk. insert_gap_at ( ( ) , position_of_a) . unwrap ( ) ;
2848+ assert_items_eq ! (
2849+ linked_chunk,
2850+ [ -] [ 'a' , 'b' ]
2851+ ) ;
2852+ assert_eq ! (
2853+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2854+ & [ NewGapChunk {
2855+ previous: None ,
2856+ new: ChunkIdentifier ( 1 ) ,
2857+ next: Some ( ChunkIdentifier ( 0 ) ) ,
2858+ gap: ( ) ,
2859+ } ]
2860+ ) ;
28312861
2832- let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2833- assert_eq ! ( gap_identifier, ChunkIdentifier ( 8 ) ) ;
2862+ let gap_identifier = linked_chunk. chunk_identifier ( Chunk :: is_gap) . unwrap ( ) ;
2863+ assert_eq ! ( gap_identifier, ChunkIdentifier ( 1 ) ) ;
28342864
2835- let new_chunk = linked_chunk. replace_gap_at ( [ 'p' ] , gap_identifier) ?;
2836- assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 9 ) ) ;
2837- assert_items_eq ! (
2838- linked_chunk,
2839- [ 'p' ] [ 'a' , 'b' ] [ 'd' , 'e' , 'f' ] [ 'g' , 'h' ] [ 'l' , 'm' ] [ 'w' , 'x' , 'y' ] [ 'z' ]
2840- ) ;
2841- assert_eq ! (
2842- linked_chunk. updates( ) . unwrap( ) . take( ) ,
2843- & [
2844- NewItemsChunk {
2845- previous: Some ( ChunkIdentifier ( 8 ) ) ,
2846- new: ChunkIdentifier ( 9 ) ,
2847- next: Some ( ChunkIdentifier ( 0 ) ) ,
2848- } ,
2849- PushItems { at: Position ( ChunkIdentifier ( 9 ) , 0 ) , items: vec![ 'p' ] } ,
2850- RemoveChunk ( ChunkIdentifier ( 8 ) ) ,
2851- ]
2852- ) ;
2853- }
2865+ let new_chunk = linked_chunk. replace_gap_at ( [ 'x' ] , gap_identifier) ?;
2866+ assert_eq ! ( new_chunk. identifier( ) , ChunkIdentifier ( 2 ) ) ;
2867+ assert_items_eq ! (
2868+ linked_chunk,
2869+ [ 'x' ] [ 'a' , 'b' ]
2870+ ) ;
2871+ assert_eq ! (
2872+ linked_chunk. updates( ) . unwrap( ) . take( ) ,
2873+ & [
2874+ NewItemsChunk {
2875+ previous: Some ( ChunkIdentifier ( 1 ) ) ,
2876+ new: ChunkIdentifier ( 2 ) ,
2877+ next: Some ( ChunkIdentifier ( 0 ) ) ,
2878+ } ,
2879+ PushItems { at: Position ( ChunkIdentifier ( 2 ) , 0 ) , items: vec![ 'x' ] } ,
2880+ RemoveChunk ( ChunkIdentifier ( 1 ) ) ,
2881+ ]
2882+ ) ;
28542883
2855- assert_eq ! ( linked_chunk. num_items( ) , 14 ) ;
2884+ assert_eq ! ( linked_chunk. num_items( ) , 3 ) ;
28562885
28572886 Ok ( ( ) )
28582887 }
0 commit comments