@@ -773,3 +773,138 @@ Deno.test("FormattedString - Static join method", () => {
773
773
assertEquals ( combinedResult . rawEntities [ 1 ] ?. offset , 28 ) ; // After "Start: TextWithEntities and "
774
774
assertEquals ( combinedResult . rawEntities [ 1 ] ?. length , 7 ) ; // "Caption"
775
775
} ) ;
776
+
777
+ Deno . test ( "FormattedString - Instance slice method" , ( ) => {
778
+ // Test the example from the problem statement
779
+ const originalText = "hello bold and italic world" ;
780
+ const entities : MessageEntity [ ] = [
781
+ { type : "bold" , offset : 6 , length : 4 } ,
782
+ { type : "italic" , offset : 15 , length : 6 } ,
783
+ ] ;
784
+ const original = new FormattedString ( originalText , entities ) ;
785
+
786
+ const sliced = original . slice ( 6 , 20 ) ;
787
+
788
+ assertInstanceOf ( sliced , FormattedString ) ;
789
+ assertEquals ( sliced . rawText , "bold and itali" ) ;
790
+ assertEquals ( sliced . rawEntities . length , 2 ) ;
791
+
792
+ // Test bold entity adjustment
793
+ assertEquals ( sliced . rawEntities [ 0 ] ?. type , "bold" ) ;
794
+ assertEquals ( sliced . rawEntities [ 0 ] ?. offset , 0 ) ;
795
+ assertEquals ( sliced . rawEntities [ 0 ] ?. length , 4 ) ;
796
+
797
+ // Test italic entity adjustment
798
+ assertEquals ( sliced . rawEntities [ 1 ] ?. type , "italic" ) ;
799
+ assertEquals ( sliced . rawEntities [ 1 ] ?. offset , 9 ) ;
800
+ assertEquals ( sliced . rawEntities [ 1 ] ?. length , 5 ) ;
801
+ } ) ;
802
+
803
+ Deno . test ( "FormattedString - slice method edge cases" , ( ) => {
804
+ const text = "Hello World Test" ;
805
+ const entities : MessageEntity [ ] = [
806
+ { type : "bold" , offset : 0 , length : 5 } , // "Hello"
807
+ { type : "italic" , offset : 6 , length : 5 } , // "World"
808
+ { type : "code" , offset : 12 , length : 4 } , // "Test"
809
+ ] ;
810
+ const original = new FormattedString ( text , entities ) ;
811
+
812
+ // Test slice without parameters (should return full copy)
813
+ const fullSlice = original . slice ( ) ;
814
+ assertInstanceOf ( fullSlice , FormattedString ) ;
815
+ assertEquals ( fullSlice . rawText , text ) ;
816
+ assertEquals ( fullSlice . rawEntities . length , 3 ) ;
817
+ assertEquals ( fullSlice . rawEntities [ 0 ] ?. type , "bold" ) ;
818
+ assertEquals ( fullSlice . rawEntities [ 1 ] ?. type , "italic" ) ;
819
+ assertEquals ( fullSlice . rawEntities [ 2 ] ?. type , "code" ) ;
820
+
821
+ // Test slice with only start parameter
822
+ const partialSlice = original . slice ( 6 ) ;
823
+ assertEquals ( partialSlice . rawText , "World Test" ) ;
824
+ assertEquals ( partialSlice . rawEntities . length , 2 ) ;
825
+ assertEquals ( partialSlice . rawEntities [ 0 ] ?. type , "italic" ) ;
826
+ assertEquals ( partialSlice . rawEntities [ 0 ] ?. offset , 0 ) ;
827
+ assertEquals ( partialSlice . rawEntities [ 0 ] ?. length , 5 ) ;
828
+
829
+ // Test slice that partially overlaps entities
830
+ const overlappingSlice = original . slice ( 3 , 9 ) ;
831
+ assertEquals ( overlappingSlice . rawText , "lo Wor" ) ;
832
+ assertEquals ( overlappingSlice . rawEntities . length , 2 ) ;
833
+
834
+ // Bold entity should be partially included
835
+ assertEquals ( overlappingSlice . rawEntities [ 0 ] ?. type , "bold" ) ;
836
+ assertEquals ( overlappingSlice . rawEntities [ 0 ] ?. offset , 0 ) ;
837
+ assertEquals ( overlappingSlice . rawEntities [ 0 ] ?. length , 2 ) ; // "lo"
838
+
839
+ // Italic entity should be partially included
840
+ assertEquals ( overlappingSlice . rawEntities [ 1 ] ?. type , "italic" ) ;
841
+ assertEquals ( overlappingSlice . rawEntities [ 1 ] ?. offset , 3 ) ;
842
+ assertEquals ( overlappingSlice . rawEntities [ 1 ] ?. length , 3 ) ; // "Wor"
843
+
844
+ // Test slice that excludes all entities
845
+ const noEntitiesSlice = original . slice ( 1 , 2 ) ;
846
+ assertEquals ( noEntitiesSlice . rawText , "e" ) ;
847
+ assertEquals ( noEntitiesSlice . rawEntities . length , 1 ) ;
848
+ assertEquals ( noEntitiesSlice . rawEntities [ 0 ] ?. type , "bold" ) ;
849
+ assertEquals ( noEntitiesSlice . rawEntities [ 0 ] ?. offset , 0 ) ;
850
+ assertEquals ( noEntitiesSlice . rawEntities [ 0 ] ?. length , 1 ) ;
851
+ } ) ;
852
+
853
+ Deno . test ( "FormattedString - slice method with empty string" , ( ) => {
854
+ const empty = new FormattedString ( "" , [ ] ) ;
855
+ const sliced = empty . slice ( 0 , 0 ) ;
856
+
857
+ assertInstanceOf ( sliced , FormattedString ) ;
858
+ assertEquals ( sliced . rawText , "" ) ;
859
+ assertEquals ( sliced . rawEntities . length , 0 ) ;
860
+ } ) ;
861
+
862
+ Deno . test ( "FormattedString - slice method boundary conditions" , ( ) => {
863
+ const text = "abcdef" ;
864
+ const entities : MessageEntity [ ] = [
865
+ { type : "bold" , offset : 1 , length : 4 } , // "bcde"
866
+ ] ;
867
+ const original = new FormattedString ( text , entities ) ;
868
+
869
+ // Test slice at entity boundaries
870
+ const exactSlice = original . slice ( 1 , 5 ) ;
871
+ assertEquals ( exactSlice . rawText , "bcde" ) ;
872
+ assertEquals ( exactSlice . rawEntities . length , 1 ) ;
873
+ assertEquals ( exactSlice . rawEntities [ 0 ] ?. type , "bold" ) ;
874
+ assertEquals ( exactSlice . rawEntities [ 0 ] ?. offset , 0 ) ;
875
+ assertEquals ( exactSlice . rawEntities [ 0 ] ?. length , 4 ) ;
876
+
877
+ // Test slice that goes beyond text length
878
+ const beyondSlice = original . slice ( 0 , 100 ) ;
879
+ assertEquals ( beyondSlice . rawText , text ) ;
880
+ assertEquals ( beyondSlice . rawEntities . length , 1 ) ;
881
+
882
+ // Test slice with negative start (should be treated as 0)
883
+ const negativeStart = original . slice ( - 5 , 3 ) ;
884
+ assertEquals ( negativeStart . rawText , "abc" ) ;
885
+ assertEquals ( negativeStart . rawEntities . length , 1 ) ;
886
+ assertEquals ( negativeStart . rawEntities [ 0 ] ?. type , "bold" ) ;
887
+ assertEquals ( negativeStart . rawEntities [ 0 ] ?. offset , 1 ) ;
888
+ assertEquals ( negativeStart . rawEntities [ 0 ] ?. length , 2 ) ; // "bc"
889
+ } ) ;
890
+
891
+ Deno . test ( "FormattedString - slice method creates deep copy" , ( ) => {
892
+ const original = new FormattedString ( "hello world" , [
893
+ { type : "bold" , offset : 0 , length : 5 } ,
894
+ ] ) ;
895
+
896
+ const sliced = original . slice ( 0 , 7 ) ;
897
+
898
+ // Verify it's a different object
899
+ assertInstanceOf ( sliced , FormattedString ) ;
900
+ assertEquals ( sliced !== original , true ) ;
901
+ assertEquals ( sliced . rawEntities !== original . rawEntities , true ) ;
902
+ assertEquals ( sliced . rawEntities [ 0 ] !== original . rawEntities [ 0 ] , true ) ;
903
+
904
+ // Verify the sliced result has the correct content
905
+ assertEquals ( sliced . rawText , "hello w" ) ;
906
+ assertEquals ( sliced . rawEntities . length , 1 ) ;
907
+ assertEquals ( sliced . rawEntities [ 0 ] ?. type , "bold" ) ;
908
+ assertEquals ( sliced . rawEntities [ 0 ] ?. offset , 0 ) ;
909
+ assertEquals ( sliced . rawEntities [ 0 ] ?. length , 5 ) ;
910
+ } ) ;
0 commit comments