@@ -115,7 +115,7 @@ impl LinkedChunkBuilder {
115
115
// New chunk has a next chunk, and it is the first chunk of the `LinkedChunk`.
116
116
if next_chunk != expected_next_chunk {
117
117
return Err ( LinkedChunkBuilderError :: CannotConnectTwoChunks {
118
- new_chunk : next_chunk ,
118
+ new_chunk : new_first_chunk . identifier ,
119
119
with_chunk : expected_next_chunk,
120
120
} ) ;
121
121
}
@@ -219,9 +219,10 @@ mod tests {
219
219
use assert_matches:: assert_matches;
220
220
221
221
use super :: {
222
- ChunkContent , ChunkIdentifier , ChunkIdentifierGenerator , LinkedChunkBuilder ,
223
- LinkedChunkBuilderError , RawChunk ,
222
+ ChunkContent , ChunkIdentifier , ChunkIdentifierGenerator , LinkedChunk , LinkedChunkBuilder ,
223
+ LinkedChunkBuilderError , RawChunk , Update ,
224
224
} ;
225
+ use crate :: linked_chunk:: Position ;
225
226
226
227
#[ test]
227
228
fn test_from_last_chunk_err_too_much_items ( ) {
@@ -314,6 +315,201 @@ mod tests {
314
315
assert!( linked_chunk. updates( ) . is_some( ) ) ;
315
316
} ) ;
316
317
}
318
+
319
+ #[ test]
320
+ fn test_insert_new_first_chunk_err_too_much_items ( ) {
321
+ let new_first_chunk = RawChunk {
322
+ previous : None ,
323
+ identifier : ChunkIdentifier :: new ( 0 ) ,
324
+ next : None ,
325
+ content : ChunkContent :: Items ( vec ! [ 'a' , 'b' , 'c' ] ) ,
326
+ } ;
327
+
328
+ let mut linked_chunk = LinkedChunk :: < 2 , char , ( ) > :: new ( ) ;
329
+
330
+ let result = LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) ;
331
+
332
+ assert_matches ! ( result, Err ( LinkedChunkBuilderError :: ChunkTooLarge { id } ) => {
333
+ assert_eq!( id, 0 ) ;
334
+ } ) ;
335
+ }
336
+
337
+ #[ test]
338
+ fn test_insert_new_first_chunk_err_is_not_first ( ) {
339
+ let new_first_chunk = RawChunk {
340
+ previous : Some ( ChunkIdentifier :: new ( 42 ) ) ,
341
+ identifier : ChunkIdentifier :: new ( 0 ) ,
342
+ next : None ,
343
+ content : ChunkContent :: Gap ( ( ) ) ,
344
+ } ;
345
+
346
+ let mut linked_chunk = LinkedChunk :: < 2 , char , ( ) > :: new ( ) ;
347
+
348
+ let result = LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) ;
349
+
350
+ assert_matches ! ( result, Err ( LinkedChunkBuilderError :: ChunkIsNotFirst { id } ) => {
351
+ assert_eq!( id, 0 ) ;
352
+ } ) ;
353
+ }
354
+
355
+ #[ test]
356
+ fn test_insert_new_first_chunk_err_missing_next_chunk ( ) {
357
+ let new_first_chunk = RawChunk {
358
+ previous : None ,
359
+ identifier : ChunkIdentifier :: new ( 0 ) ,
360
+ next : None ,
361
+ content : ChunkContent :: Gap ( ( ) ) ,
362
+ } ;
363
+
364
+ let mut linked_chunk = LinkedChunk :: < 2 , char , ( ) > :: new ( ) ;
365
+
366
+ let result = LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) ;
367
+
368
+ assert_matches ! ( result, Err ( LinkedChunkBuilderError :: MissingNextChunk { id } ) => {
369
+ assert_eq!( id, 0 ) ;
370
+ } ) ;
371
+ }
372
+
373
+ #[ test]
374
+ fn test_insert_new_first_chunk_err_cannot_connect_two_chunks ( ) {
375
+ let new_first_chunk = RawChunk {
376
+ previous : None ,
377
+ identifier : ChunkIdentifier :: new ( 1 ) ,
378
+ next : Some ( ChunkIdentifier :: new ( 42 ) ) ,
379
+ content : ChunkContent :: Gap ( ( ) ) ,
380
+ } ;
381
+
382
+ let mut linked_chunk = LinkedChunk :: < 2 , char , ( ) > :: new ( ) ;
383
+ linked_chunk. push_gap_back ( ( ) ) ;
384
+
385
+ let result = LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) ;
386
+
387
+ assert_matches ! ( result, Err ( LinkedChunkBuilderError :: CannotConnectTwoChunks { new_chunk, with_chunk } ) => {
388
+ assert_eq!( new_chunk, 1 ) ;
389
+ assert_eq!( with_chunk, 0 ) ;
390
+ } ) ;
391
+ }
392
+
393
+ #[ test]
394
+ fn test_insert_new_first_chunk_gap ( ) {
395
+ let new_first_chunk = RawChunk {
396
+ previous : None ,
397
+ identifier : ChunkIdentifier :: new ( 1 ) ,
398
+ next : Some ( ChunkIdentifier :: new ( 0 ) ) ,
399
+ content : ChunkContent :: Gap ( ( ) ) ,
400
+ } ;
401
+
402
+ let mut linked_chunk = LinkedChunk :: < 5 , char , ( ) > :: new_with_update_history ( ) ;
403
+ linked_chunk. push_items_back ( vec ! [ 'a' , 'b' ] ) ;
404
+
405
+ // Drain initial updates.
406
+ let _ = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
407
+
408
+ LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) . unwrap ( ) ;
409
+
410
+ // Iterate forwards to ensure forwards links are okay.
411
+ {
412
+ let mut chunks = linked_chunk. chunks ( ) ;
413
+
414
+ assert_matches ! ( chunks. next( ) , Some ( chunk) => {
415
+ assert_eq!( chunk. identifier( ) , 1 ) ;
416
+ assert!( chunk. is_gap( ) ) ;
417
+ } ) ;
418
+ assert_matches ! ( chunks. next( ) , Some ( chunk) => {
419
+ assert_eq!( chunk. identifier( ) , 0 ) ;
420
+ assert!( chunk. is_items( ) ) ;
421
+ } ) ;
422
+ assert ! ( chunks. next( ) . is_none( ) ) ;
423
+ }
424
+
425
+ // Iterate backwards to ensure backwards links are okay.
426
+ {
427
+ let mut rchunks = linked_chunk. rchunks ( ) ;
428
+
429
+ assert_eq ! ( rchunks. next( ) . unwrap( ) . identifier( ) , 0 ) ;
430
+ assert_eq ! ( rchunks. next( ) . unwrap( ) . identifier( ) , 1 ) ;
431
+ assert ! ( rchunks. next( ) . is_none( ) ) ;
432
+ }
433
+
434
+ // Check updates.
435
+ {
436
+ let updates = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
437
+
438
+ assert_eq ! ( updates. len( ) , 1 ) ;
439
+ assert_eq ! (
440
+ updates,
441
+ [ Update :: NewGapChunk {
442
+ previous: None ,
443
+ new: ChunkIdentifier :: new( 1 ) ,
444
+ next: Some ( ChunkIdentifier :: new( 0 ) ) ,
445
+ gap: ( ) ,
446
+ } ]
447
+ ) ;
448
+ }
449
+ }
450
+
451
+ #[ test]
452
+ fn test_insert_new_first_chunk_items ( ) {
453
+ let new_first_chunk = RawChunk {
454
+ previous : None ,
455
+ identifier : ChunkIdentifier :: new ( 1 ) ,
456
+ next : Some ( ChunkIdentifier :: new ( 0 ) ) ,
457
+ content : ChunkContent :: Items ( vec ! [ 'c' , 'd' ] ) ,
458
+ } ;
459
+
460
+ let mut linked_chunk = LinkedChunk :: < 5 , char , ( ) > :: new_with_update_history ( ) ;
461
+ linked_chunk. push_items_back ( vec ! [ 'a' , 'b' ] ) ;
462
+
463
+ // Drain initial updates.
464
+ let _ = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
465
+
466
+ LinkedChunkBuilder :: insert_new_first_chunk ( & mut linked_chunk, new_first_chunk) . unwrap ( ) ;
467
+
468
+ // Iterate forwards to ensure forwards links are okay.
469
+ {
470
+ let mut chunks = linked_chunk. chunks ( ) ;
471
+
472
+ assert_matches ! ( chunks. next( ) , Some ( chunk) => {
473
+ assert_eq!( chunk. identifier( ) , 1 ) ;
474
+ assert!( chunk. is_items( ) ) ;
475
+ } ) ;
476
+ assert_matches ! ( chunks. next( ) , Some ( chunk) => {
477
+ assert_eq!( chunk. identifier( ) , 0 ) ;
478
+ assert!( chunk. is_items( ) ) ;
479
+ } ) ;
480
+ assert ! ( chunks. next( ) . is_none( ) ) ;
481
+ }
482
+
483
+ // Iterate backwards to ensure backwards links are okay.
484
+ {
485
+ let mut rchunks = linked_chunk. rchunks ( ) ;
486
+
487
+ assert_eq ! ( rchunks. next( ) . unwrap( ) . identifier( ) , 0 ) ;
488
+ assert_eq ! ( rchunks. next( ) . unwrap( ) . identifier( ) , 1 ) ;
489
+ assert ! ( rchunks. next( ) . is_none( ) ) ;
490
+ }
491
+
492
+ // Check updates.
493
+ {
494
+ let updates = linked_chunk. updates ( ) . unwrap ( ) . take ( ) ;
495
+
496
+ assert_eq ! ( updates. len( ) , 2 ) ;
497
+ assert_eq ! (
498
+ updates,
499
+ [
500
+ Update :: NewItemsChunk {
501
+ previous: None ,
502
+ new: ChunkIdentifier :: new( 1 ) ,
503
+ next: Some ( ChunkIdentifier :: new( 0 ) ) ,
504
+ } ,
505
+ Update :: PushItems {
506
+ at: Position :: new( ChunkIdentifier :: new( 1 ) , 0 ) ,
507
+ items: vec![ 'c' , 'd' ]
508
+ }
509
+ ]
510
+ ) ;
511
+ }
512
+ }
317
513
}
318
514
319
515
/// A temporary chunk representation in the [`LinkedChunkBuilderTest`].
0 commit comments