@@ -747,6 +747,151 @@ TEST_P(ByteStringTest, EndsWith) {
747
747
GetMediumOrLargeCord ().size () - kSmallByteStringCapacity )));
748
748
}
749
749
750
+ TEST_P (ByteStringTest, Find) {
751
+ ByteString byte_string = ByteString (GetAllocator (), GetMediumStringView ());
752
+
753
+ // Find string_view
754
+ EXPECT_THAT (byte_string.Find (" A string" ), Optional (0 ));
755
+ EXPECT_THAT (
756
+ byte_string.Find (" small string optimization!" ),
757
+ Optional (GetMediumStringView ().find (" small string optimization!" )));
758
+ EXPECT_THAT (byte_string.Find (" not found" ), Eq (absl::nullopt ));
759
+ EXPECT_THAT (byte_string.Find (" " ), Optional (0 ));
760
+ EXPECT_THAT (byte_string.Find (" " , 3 ), Optional (3 ));
761
+ EXPECT_THAT (byte_string.Find (" A string" , 1 ), Eq (absl::nullopt ));
762
+
763
+ // Find cord
764
+ EXPECT_THAT (byte_string.Find (absl::Cord (" A string" )), Optional (0 ));
765
+ EXPECT_THAT (
766
+ byte_string.Find (absl::Cord (" small string optimization!" )),
767
+ Optional (GetMediumStringView ().find (" small string optimization!" )));
768
+ EXPECT_THAT (
769
+ byte_string.Find (absl::MakeFragmentedCord (
770
+ {" A string" , " that is too large for the small string optimization!" ,
771
+ " extra" })),
772
+ Eq (absl::nullopt ));
773
+ EXPECT_THAT (byte_string.Find (GetMediumOrLargeFragmentedCord ()), Optional (0 ));
774
+ EXPECT_THAT (byte_string.Find (absl::Cord (" not found" )), Eq (absl::nullopt ));
775
+ EXPECT_THAT (byte_string.Find (absl::Cord (" " )), Optional (0 ));
776
+ EXPECT_THAT (byte_string.Find (absl::Cord (" " ), 3 ), Optional (3 ));
777
+ }
778
+
779
+ TEST_P (ByteStringTest, FindEdgeCases) {
780
+ ByteString empty_byte_string (GetAllocator (), " " );
781
+ EXPECT_THAT (empty_byte_string.Find (" a" ), Eq (absl::nullopt ));
782
+ EXPECT_THAT (empty_byte_string.Find (" " ), Optional (0 ));
783
+ ByteString cord_byte_string =
784
+ ByteString (GetAllocator (), GetMediumOrLargeCord ());
785
+ EXPECT_THAT (cord_byte_string.Find (" not found" ), Eq (absl::nullopt ));
786
+ ByteString byte_string = ByteString (GetAllocator (), GetMediumStringView ());
787
+
788
+ // Needle longer than haystack.
789
+ EXPECT_THAT (byte_string.Find (std::string (byte_string.size () + 1 , ' a' )),
790
+ Eq (absl::nullopt ));
791
+
792
+ // Needle at the end.
793
+ absl::string_view suffix = " optimization!" ;
794
+ EXPECT_THAT (byte_string.Find (suffix),
795
+ Optional (byte_string.size () - suffix.size ()));
796
+
797
+ // pos at the end.
798
+ EXPECT_THAT (byte_string.Find (" a" , byte_string.size ()), Eq (absl::nullopt ));
799
+ EXPECT_THAT (byte_string.Find (" " , byte_string.size ()),
800
+ Optional (byte_string.size ()));
801
+
802
+ // Search in a cord-backed ByteString with pos > 0.
803
+ EXPECT_THAT (cord_byte_string.Find (" string" , 1 ),
804
+ Optional (GetMediumStringView ().find (" string" , 1 )));
805
+
806
+ // Needle at the end of a cord-backed ByteString.
807
+ absl::string_view suffix_sv = " optimization!" ;
808
+ EXPECT_THAT (cord_byte_string.Find (suffix_sv),
809
+ Optional (cord_byte_string.size () - suffix_sv.size ()));
810
+ EXPECT_THAT (cord_byte_string.Find (absl::Cord (suffix_sv)),
811
+ Optional (cord_byte_string.size () - suffix_sv.size ()));
812
+
813
+ // Fragmented needle with empty first chunk.
814
+ absl::Cord fragmented_with_empty_chunk;
815
+ fragmented_with_empty_chunk.Append (" " );
816
+ fragmented_with_empty_chunk.Append (" A string" );
817
+ EXPECT_THAT (byte_string.Find (fragmented_with_empty_chunk), Optional (0 ));
818
+
819
+ // Search with fragmented cord needle on string_view backed ByteString with
820
+ // partial match.
821
+ ByteString partial_match_haystack (GetAllocator (), " abababac" );
822
+ absl::Cord partial_match_needle = absl::MakeFragmentedCord ({" aba" , " c" });
823
+ EXPECT_THAT (partial_match_haystack.Find (partial_match_needle), Optional (4 ));
824
+
825
+ // Search with fragmented cord needle where first chunk is found but not
826
+ // enough space for the rest.
827
+ ByteString short_haystack (GetAllocator (), " abcdefg" );
828
+ absl::Cord needle_too_long = absl::MakeFragmentedCord ({" ef" , " gh" });
829
+ EXPECT_THAT (short_haystack.Find (needle_too_long), Eq (absl::nullopt ));
830
+
831
+ // Search with a fragmented empty cord.
832
+ absl::Cord fragmented_empty_cord = absl::MakeFragmentedCord ({" " , " " });
833
+ EXPECT_THAT (byte_string.Find (fragmented_empty_cord), Optional (0 ));
834
+ EXPECT_THAT (byte_string.Find (fragmented_empty_cord, 3 ), Optional (3 ));
835
+
836
+ // Search for suffix in a fragmented cord.
837
+ ByteString fragmented_cord_byte_string (GetAllocator (),
838
+ GetMediumOrLargeFragmentedCord ());
839
+ EXPECT_THAT (fragmented_cord_byte_string.Find (suffix_sv),
840
+ Optional (fragmented_cord_byte_string.size () - suffix_sv.size ()));
841
+ EXPECT_THAT (fragmented_cord_byte_string.Find (absl::Cord (suffix_sv)),
842
+ Optional (fragmented_cord_byte_string.size () - suffix_sv.size ()));
843
+ }
844
+
845
+ #ifndef NDEBUG
846
+ TEST_P (ByteStringTest, FindOutOfBounds) {
847
+ ByteString byte_string = ByteString (GetAllocator (), " test" );
848
+ EXPECT_DEATH (byte_string.Find (" t" , 5 ), _);
849
+ }
850
+ #endif
851
+
852
+ TEST_P (ByteStringTest, Substring) {
853
+ // small byte_string substring
854
+ ByteString small_byte_string =
855
+ ByteString (GetAllocator (), GetSmallStringView ());
856
+ EXPECT_EQ (small_byte_string.Substring (1 , 5 ),
857
+ GetSmallStringView ().substr (1 , 4 ));
858
+ EXPECT_EQ (small_byte_string.Substring (0 , small_byte_string.size ()),
859
+ GetSmallStringView ());
860
+ EXPECT_EQ (small_byte_string.Substring (1 , 1 ), " " );
861
+ // medium byte_string substring
862
+ ByteString medium_byte_string =
863
+ ByteString (GetAllocator (), GetMediumStringView ());
864
+ EXPECT_EQ (medium_byte_string.Substring (2 , 12 ),
865
+ GetMediumStringView ().substr (2 , 10 ));
866
+ EXPECT_EQ (medium_byte_string.Substring (0 , medium_byte_string.size ()),
867
+ GetMediumStringView ());
868
+ // large byte_string substring
869
+ ByteString large_byte_string =
870
+ ByteString (GetAllocator (), GetMediumOrLargeCord ());
871
+ EXPECT_EQ (large_byte_string.Substring (3 , 15 ),
872
+ GetMediumOrLargeCord ().Subcord (3 , 12 ));
873
+ EXPECT_EQ (large_byte_string.Substring (0 , large_byte_string.size ()),
874
+ GetMediumOrLargeCord ());
875
+ // substring with one parameter
876
+ ByteString tacocat_byte_string = ByteString (GetAllocator (), " tacocat" );
877
+ EXPECT_EQ (tacocat_byte_string.Substring (4 ), " cat" );
878
+ }
879
+
880
+ TEST_P (ByteStringTest, SubstringEdgeCases) {
881
+ ByteString byte_string = ByteString (GetAllocator (), GetSmallStringView ());
882
+ EXPECT_EQ (byte_string.Substring (byte_string.size (), byte_string.size ()), " " );
883
+ EXPECT_EQ (byte_string.Substring (0 , 0 ), " " );
884
+ }
885
+
886
+ #ifndef NDEBUG
887
+ TEST_P (ByteStringTest, SubstringOutOfBounds) {
888
+ ByteString byte_string = ByteString (GetAllocator (), " test" );
889
+ EXPECT_DEATH (static_cast <void >(byte_string.Substring (5 , 5 )), _);
890
+ EXPECT_DEATH (static_cast <void >(byte_string.Substring (0 , 5 )), _);
891
+ EXPECT_DEATH (static_cast <void >(byte_string.Substring (3 , 2 )), _);
892
+ }
893
+ #endif
894
+
750
895
TEST_P (ByteStringTest, RemovePrefixSmall) {
751
896
ByteString byte_string = ByteString (GetAllocator (), GetSmallStringView ());
752
897
byte_string.RemovePrefix (1 );
0 commit comments