@@ -438,6 +438,107 @@ def before
438
438
expect ( write_buffer ) . to be ( :empty? )
439
439
end
440
440
end
441
+
442
+ with "#discard_until" do
443
+ it "can discard data until pattern" do
444
+ server . write ( "hello\n world\n test" )
445
+ server . close
446
+
447
+ # Discard until "\n" - should return chunk ending with the pattern
448
+ chunk = client . discard_until ( "\n " )
449
+ expect ( chunk ) . not . to be_nil
450
+ expect ( chunk ) . to be ( :end_with? , "\n " )
451
+ # Read the remaining data to verify it starts with "world"
452
+ expect ( client . read ( 5 ) ) . to be == "world"
453
+
454
+ # Discard until "t" - should return chunk ending with the pattern
455
+ chunk = client . discard_until ( "t" )
456
+ expect ( chunk ) . not . to be_nil
457
+ expect ( chunk ) . to be ( :end_with? , "t" )
458
+ # Read remaining data
459
+ expect ( client . read ) . to be == "est"
460
+ end
461
+
462
+ it "returns nil when pattern not found and discards all data" do
463
+ server . write ( "hello world" )
464
+ server . close
465
+
466
+ expect ( client . discard_until ( "\n " ) ) . to be_nil
467
+ # Data should still be available since pattern was not found
468
+ expect ( client . read ) . to be == "hello world"
469
+ end
470
+
471
+ it "can discard with a limit" do
472
+ server . write ( "hello\n world\n " )
473
+ server . close
474
+
475
+ # Use peek to verify initial buffer state
476
+ expect ( client . peek ) . to be == "hello\n world\n "
477
+
478
+ # Limit too small to find pattern - discards up to limit
479
+ expect ( client . discard_until ( "\n " , limit : 4 ) ) . to be_nil
480
+
481
+ # Use peek to verify that 4 bytes were discarded
482
+ expect ( client . peek ) . to be == "o\n world\n "
483
+
484
+ # After discarding 4 bytes, should find pattern in remaining data
485
+ chunk = client . discard_until ( "\n " , limit : 5 )
486
+ expect ( chunk ) . not . to be_nil
487
+ expect ( chunk ) . to be ( :end_with? , "\n " )
488
+
489
+ # Use peek to verify final buffer state
490
+ expect ( client . peek ) . to be == "world\n "
491
+ expect ( client . read ) . to be == "world\n "
492
+ end
493
+
494
+ it "handles patterns spanning buffer boundaries" do
495
+ # Use a small block size to force the pattern to span boundaries
496
+ client . block_size = 3
497
+
498
+ server . write ( "ab" )
499
+ server . flush
500
+ server . write ( "cdef" )
501
+ server . close
502
+
503
+ # Pattern "cd" spans the boundary between "ab" and "cdef"
504
+ chunk = client . discard_until ( "cd" )
505
+ expect ( chunk ) . not . to be_nil
506
+ expect ( chunk ) . to be ( :end_with? , "cd" )
507
+ expect ( client . read ) . to be == "ef"
508
+ end
509
+
510
+ it "handles large patterns efficiently" do
511
+ large_pattern = "X" * 20 # Trigger sliding window logic
512
+ server . write ( "some data before" )
513
+ server . write ( large_pattern )
514
+ server . write ( "some data after" )
515
+ server . close
516
+
517
+ chunk = client . discard_until ( large_pattern )
518
+ expect ( chunk ) . not . to be_nil
519
+ expect ( chunk ) . to be ( :end_with? , large_pattern )
520
+ expect ( client . read ) . to be == "some data after"
521
+ end
522
+
523
+ with "with 1-byte block size" do
524
+ it "can discard data with a multi-byte pattern" do
525
+ server . write ( "hello\n world\n " )
526
+ server . close
527
+
528
+ client . block_size = 1
529
+
530
+ chunk1 = client . discard_until ( "\n " )
531
+ expect ( chunk1 ) . not . to be_nil
532
+ expect ( chunk1 ) . to be ( :end_with? , "\n " )
533
+
534
+ chunk2 = client . discard_until ( "\n " )
535
+ expect ( chunk2 ) . not . to be_nil
536
+ expect ( chunk2 ) . to be ( :end_with? , "\n " )
537
+
538
+ expect ( client . discard_until ( "\n " ) ) . to be_nil
539
+ end
540
+ end
541
+ end
441
542
end
442
543
443
544
ABidirectionalStream = Sus ::Shared ( "a bidirectional stream" ) do
0 commit comments