@ -206,7 +206,32 @@ class CordTestPeer {
ABSL_NAMESPACE_END
} // namespace absl
TEST ( Cord , AllFlatSizes ) {
// The CordTest fixture runs all tests with and without Cord Btree enabled.
class CordTest : public testing : : TestWithParam < bool > {
public :
CordTest ( ) : was_btree_ ( absl : : cord_internal : : cord_btree_enabled . load ( ) ) {
absl : : cord_internal : : cord_btree_enabled . store ( UseBtree ( ) ) ;
}
~ CordTest ( ) override {
absl : : cord_internal : : cord_btree_enabled . store ( was_btree_ ) ;
}
// Returns true if test is running with btree enabled.
bool UseBtree ( ) const { return GetParam ( ) ; }
// Returns human readable string representation of the test parameter.
static std : : string ToString ( testing : : TestParamInfo < bool > param ) {
return param . param ? " Btree " : " Concat " ;
}
private :
const bool was_btree_ ;
} ;
INSTANTIATE_TEST_SUITE_P ( WithParam , CordTest , testing : : Bool ( ) ,
CordTest : : ToString ) ;
TEST_P ( CordTest , AllFlatSizes ) {
using absl : : strings_internal : : CordTestAccess ;
for ( size_t s = 0 ; s < CordTestAccess : : MaxFlatLength ( ) ; s + + ) {
@ -224,7 +249,7 @@ TEST(Cord, AllFlatSizes) {
// We create a Cord at least 128GB in size using the fact that Cords can
// internally reference-count; thus the Cord is enormous without actually
// consuming very much memory.
TEST ( Gigabyte Cord, FromExternal ) {
TEST_P ( CordTest , GigabyteCord FromExternal) {
const size_t one_gig = 1024U * 1024U * 1024U ;
size_t max_size = 2 * one_gig ;
if ( sizeof ( max_size ) > 4 ) max_size = 128 * one_gig ;
@ -273,7 +298,7 @@ static absl::Cord MakeExternalCord(int size) {
extern bool my_unique_true_boolean ;
bool my_unique_true_boolean = true ;
TEST ( Cord , Assignment ) {
TEST_P ( CordTest , Assignment ) {
absl : : Cord x ( absl : : string_view ( " hi there " ) ) ;
absl : : Cord y ( x ) ;
ASSERT_EQ ( std : : string ( x ) , " hi there " ) ;
@ -327,7 +352,7 @@ TEST(Cord, Assignment) {
}
}
TEST ( Cord , StartsEndsWith ) {
TEST_P ( CordTest , StartsEndsWith ) {
absl : : Cord x ( absl : : string_view ( " abcde " ) ) ;
absl : : Cord empty ( " " ) ;
@ -360,7 +385,7 @@ TEST(Cord, StartsEndsWith) {
ASSERT_TRUE ( ! empty . EndsWith ( " xyz " ) ) ;
}
TEST ( Cord , Subcord ) {
TEST_P ( CordTest , Subcord ) {
RandomEngine rng ( GTEST_FLAG_GET ( random_seed ) ) ;
const std : : string s = RandomLowercaseString ( & rng , 1024 ) ;
@ -421,7 +446,7 @@ TEST(Cord, Subcord) {
EXPECT_TRUE ( sa . empty ( ) ) ;
}
TEST ( Cord , Swap ) {
TEST_P ( CordTest , Swap ) {
absl : : string_view a ( " Dexter " ) ;
absl : : string_view b ( " Mandark " ) ;
absl : : Cord x ( a ) ;
@ -453,7 +478,7 @@ static void VerifyCopyToString(const absl::Cord& cord) {
}
}
TEST ( Cord , CopyToString ) {
TEST_P ( CordTest , CopyToString ) {
VerifyCopyToString ( absl : : Cord ( ) ) ;
VerifyCopyToString ( absl : : Cord ( " small cord " ) ) ;
VerifyCopyToString (
@ -461,45 +486,45 @@ TEST(Cord, CopyToString) {
" copying " , " to " , " a " , " string. " } ) ) ;
}
TEST ( TryFlat , Empty ) {
TEST_P ( CordTest , TryFlat Empty ) {
absl : : Cord c ;
EXPECT_EQ ( c . TryFlat ( ) , " " ) ;
}
TEST ( TryFlat , Flat ) {
TEST_P ( CordTest , TryFlat Flat ) {
absl : : Cord c ( " hello " ) ;
EXPECT_EQ ( c . TryFlat ( ) , " hello " ) ;
}
TEST ( TryFlat , SubstrInlined ) {
TEST_P ( CordTest , TryFlat SubstrInlined ) {
absl : : Cord c ( " hello " ) ;
c . RemovePrefix ( 1 ) ;
EXPECT_EQ ( c . TryFlat ( ) , " ello " ) ;
}
TEST ( TryFlat , SubstrFlat ) {
TEST_P ( CordTest , TryFlat SubstrFlat ) {
absl : : Cord c ( " longer than 15 bytes " ) ;
absl : : Cord sub = absl : : CordTestPeer : : MakeSubstring ( c , 1 , c . size ( ) - 1 ) ;
EXPECT_EQ ( sub . TryFlat ( ) , " onger than 15 bytes " ) ;
}
TEST ( TryFlat , Concat ) {
TEST_P ( CordTest , TryFlat Concat ) {
absl : : Cord c = absl : : MakeFragmentedCord ( { " hel " , " lo " } ) ;
EXPECT_EQ ( c . TryFlat ( ) , absl : : nullopt ) ;
}
TEST ( TryFlat , External ) {
TEST_P ( CordTest , TryFlat External ) {
absl : : Cord c = absl : : MakeCordFromExternal ( " hell " , [ ] ( absl : : string_view ) { } ) ;
EXPECT_EQ ( c . TryFlat ( ) , " hell " ) ;
}
TEST ( TryFlat , SubstrExternal ) {
TEST_P ( CordTest , TryFlat SubstrExternal ) {
absl : : Cord c = absl : : MakeCordFromExternal ( " hell " , [ ] ( absl : : string_view ) { } ) ;
absl : : Cord sub = absl : : CordTestPeer : : MakeSubstring ( c , 1 , c . size ( ) - 1 ) ;
EXPECT_EQ ( sub . TryFlat ( ) , " ell " ) ;
}
TEST ( TryFlat , SubstrConcat ) {
TEST_P ( CordTest , TryFlat SubstrConcat ) {
absl : : Cord c = absl : : MakeFragmentedCord ( { " hello " , " world " } ) ;
absl : : Cord sub = absl : : CordTestPeer : : MakeSubstring ( c , 1 , c . size ( ) - 1 ) ;
EXPECT_EQ ( sub . TryFlat ( ) , absl : : nullopt ) ;
@ -507,7 +532,7 @@ TEST(TryFlat, SubstrConcat) {
EXPECT_EQ ( c . TryFlat ( ) , absl : : nullopt ) ;
}
TEST ( TryFlat , CommonlyAssumedInvariants ) {
TEST_P ( CordTest , TryFlat CommonlyAssumedInvariants ) {
// The behavior tested below is not part of the API contract of Cord, but it's
// something we intend to be true in our current implementation. This test
// exists to detect and prevent accidental breakage of the implementation.
@ -563,7 +588,7 @@ static void VerifyFlatten(absl::Cord c) {
EXPECT_TRUE ( IsFlat ( c ) ) ;
}
TEST ( Cord , Flatten ) {
TEST_P ( CordTest , Flatten ) {
VerifyFlatten ( absl : : Cord ( ) ) ;
VerifyFlatten ( absl : : Cord ( " small cord " ) ) ;
VerifyFlatten ( absl : : Cord ( " larger than small buffer optimization " ) ) ;
@ -617,7 +642,7 @@ class TestData {
} ;
} // namespace
TEST ( Cord , MultipleLengths ) {
TEST_P ( CordTest , MultipleLengths ) {
TestData d ;
for ( size_t i = 0 ; i < d . size ( ) ; i + + ) {
std : : string a = d . data ( i ) ;
@ -693,7 +718,7 @@ TEST(Cord, MultipleLengths) {
namespace {
TEST ( Cord , RemoveSuffixWithExternalOrSubstring ) {
TEST_P ( CordTest , RemoveSuffixWithExternalOrSubstring ) {
absl : : Cord cord = absl : : MakeCordFromExternal (
" foo bar baz " , [ ] ( absl : : string_view s ) { DoNothing ( s , nullptr ) ; } ) ;
@ -708,7 +733,7 @@ TEST(Cord, RemoveSuffixWithExternalOrSubstring) {
EXPECT_EQ ( " foo " , std : : string ( cord ) ) ;
}
TEST ( Cord , RemoveSuffixMakesZeroLengthNode ) {
TEST_P ( CordTest , RemoveSuffixMakesZeroLengthNode ) {
absl : : Cord c ;
c . Append ( absl : : Cord ( std : : string ( 100 , ' x ' ) ) ) ;
absl : : Cord other_ref = c ; // Prevent inplace appends
@ -735,7 +760,7 @@ absl::Cord CordWithZedBlock(size_t size) {
}
// Establish that ZedBlock does what we think it does.
TEST ( CordSplice Test , ZedBlock ) {
TEST_P ( CordTest , CordSpliceTest ZedBlock) {
absl : : Cord blob = CordWithZedBlock ( 10 ) ;
EXPECT_EQ ( 10 , blob . size ( ) ) ;
std : : string s ;
@ -743,7 +768,7 @@ TEST(CordSpliceTest, ZedBlock) {
EXPECT_EQ ( " zzzzzzzzzz " , s ) ;
}
TEST ( CordSplice Test , ZedBlock0 ) {
TEST_P ( CordTest , CordSpliceTest ZedBlock0) {
absl : : Cord blob = CordWithZedBlock ( 0 ) ;
EXPECT_EQ ( 0 , blob . size ( ) ) ;
std : : string s ;
@ -751,7 +776,7 @@ TEST(CordSpliceTest, ZedBlock0) {
EXPECT_EQ ( " " , s ) ;
}
TEST ( CordSplice Test , ZedBlockSuffix1 ) {
TEST_P ( CordTest , CordSpliceTest ZedBlockSuffix1) {
absl : : Cord blob = CordWithZedBlock ( 10 ) ;
EXPECT_EQ ( 10 , blob . size ( ) ) ;
absl : : Cord suffix ( blob ) ;
@ -763,7 +788,7 @@ TEST(CordSpliceTest, ZedBlockSuffix1) {
}
// Remove all of a prefix block
TEST ( CordSplice Test , ZedBlockSuffix0 ) {
TEST_P ( CordTest , CordSpliceTest ZedBlockSuffix0) {
absl : : Cord blob = CordWithZedBlock ( 10 ) ;
EXPECT_EQ ( 10 , blob . size ( ) ) ;
absl : : Cord suffix ( blob ) ;
@ -795,7 +820,7 @@ absl::Cord SpliceCord(const absl::Cord& blob, int64_t offset,
}
// Taking an empty suffix of a block breaks appending.
TEST ( CordSplice Test , RemoveEntireBlock1 ) {
TEST_P ( CordTest , CordSpliceTest RemoveEntireBlock1) {
absl : : Cord zero = CordWithZedBlock ( 10 ) ;
absl : : Cord suffix ( zero ) ;
suffix . RemovePrefix ( 10 ) ;
@ -803,7 +828,7 @@ TEST(CordSpliceTest, RemoveEntireBlock1) {
result . Append ( suffix ) ;
}
TEST ( CordSplice Test , RemoveEntireBlock2 ) {
TEST_P ( CordTest , CordSpliceTest RemoveEntireBlock2) {
absl : : Cord zero = CordWithZedBlock ( 10 ) ;
absl : : Cord prefix ( zero ) ;
prefix . RemoveSuffix ( 10 ) ;
@ -813,7 +838,7 @@ TEST(CordSpliceTest, RemoveEntireBlock2) {
result . Append ( suffix ) ;
}
TEST ( CordSplice Test , RemoveEntireBlock3 ) {
TEST_P ( CordTest , CordSpliceTest RemoveEntireBlock3) {
absl : : Cord blob = CordWithZedBlock ( 10 ) ;
absl : : Cord block = BigCord ( 10 , ' b ' ) ;
blob = SpliceCord ( blob , 0 , block ) ;
@ -844,7 +869,7 @@ void VerifyComparison(const CordCompareTestCase& test_case) {
< < " LHS= " < < rhs_string < < " ; RHS= " < < lhs_string ;
}
TEST ( Cord , Compare ) {
TEST_P ( CordTest , Compare ) {
absl : : Cord subcord ( " aaaaaBBBBBcccccDDDDD " ) ;
subcord = subcord . Subcord ( 3 , 10 ) ;
@ -907,7 +932,7 @@ TEST(Cord, Compare) {
}
}
TEST ( Cord , CompareAfterAssign ) {
TEST_P ( CordTest , CompareAfterAssign ) {
absl : : Cord a ( " aaaaaa1111111 " ) ;
absl : : Cord b ( " aaaaaa2222222 " ) ;
a = " cccccc " ;
@ -936,7 +961,7 @@ static void TestCompare(const absl::Cord& c, const absl::Cord& d,
EXPECT_EQ ( expected , sign ( c . Compare ( d ) ) ) < < c < < " , " < < d ;
}
TEST ( Compa re , ComparisonIsUnsigned ) {
TEST_P ( CordT est , Compare ComparisonIsUnsigned) {
RandomEngine rng ( GTEST_FLAG_GET ( random_seed ) ) ;
std : : uniform_int_distribution < uint32_t > uniform_uint8 ( 0 , 255 ) ;
char x = static_cast < char > ( uniform_uint8 ( rng ) ) ;
@ -945,7 +970,7 @@ TEST(Compare, ComparisonIsUnsigned) {
absl : : Cord ( std : : string ( GetUniformRandomUpTo ( & rng , 100 ) , x ^ 0x80 ) ) , & rng ) ;
}
TEST ( Compa re , RandomComparisons ) {
TEST_P ( CordT est , Compare RandomComparisons) {
const int kIters = 5000 ;
RandomEngine rng ( GTEST_FLAG_GET ( random_seed ) ) ;
@ -1003,43 +1028,43 @@ void CompareOperators() {
EXPECT_FALSE ( b < = a ) ;
}
TEST ( ComparisonOperators , Cord_Cord ) {
TEST_P ( CordTest , ComparisonOperators_ Cord_Cord ) {
CompareOperators < absl : : Cord , absl : : Cord > ( ) ;
}
TEST ( ComparisonOperators , Cord_StringPiece ) {
TEST_P ( CordTest , ComparisonOperators_ Cord_StringPiece ) {
CompareOperators < absl : : Cord , absl : : string_view > ( ) ;
}
TEST ( ComparisonOperators , StringPiece_Cord ) {
TEST_P ( CordTest , ComparisonOperators_ StringPiece_Cord ) {
CompareOperators < absl : : string_view , absl : : Cord > ( ) ;
}
TEST ( ComparisonOperators , Cord_string ) {
TEST_P ( CordTest , ComparisonOperators_ Cord_string ) {
CompareOperators < absl : : Cord , std : : string > ( ) ;
}
TEST ( ComparisonOperators , string_Cord ) {
TEST_P ( CordTest , ComparisonOperators_ string_Cord ) {
CompareOperators < std : : string , absl : : Cord > ( ) ;
}
TEST ( ComparisonOperators , stdstring_Cord ) {
TEST_P ( CordTest , ComparisonOperators_ stdstring_Cord ) {
CompareOperators < std : : string , absl : : Cord > ( ) ;
}
TEST ( ComparisonOperators , Cord_stdstring ) {
TEST_P ( CordTest , ComparisonOperators_ Cord_stdstring ) {
CompareOperators < absl : : Cord , std : : string > ( ) ;
}
TEST ( ComparisonOperators , charstar_Cord ) {
TEST_P ( CordTest , ComparisonOperators_ charstar_Cord ) {
CompareOperators < const char * , absl : : Cord > ( ) ;
}
TEST ( ComparisonOperators , Cord_charstar ) {
TEST_P ( CordTest , ComparisonOperators_ Cord_charstar ) {
CompareOperators < absl : : Cord , const char * > ( ) ;
}
TEST ( ConstructFromExternal , ReleaserInvoked ) {
TEST_P ( CordTest , ConstructFromExternal ReleaserInvoked ) {
// Empty external memory means the releaser should be called immediately.
{
bool invoked = false ;
@ -1081,7 +1106,7 @@ TEST(ConstructFromExternal, ReleaserInvoked) {
}
}
TEST ( ConstructFromExternal , CompareContents ) {
TEST_P ( CordTest , ConstructFromExternal CompareContents ) {
RandomEngine rng ( GTEST_FLAG_GET ( random_seed ) ) ;
for ( int length = 1 ; length < = 2048 ; length * = 2 ) {
@ -1097,7 +1122,7 @@ TEST(ConstructFromExternal, CompareContents) {
}
}
TEST ( ConstructFromExternal , LargeReleaser ) {
TEST_P ( CordTest , ConstructFromExternal LargeReleaser ) {
RandomEngine rng ( GTEST_FLAG_GET ( random_seed ) ) ;
constexpr size_t kLength = 256 ;
std : : string data = RandomLowercaseString ( & rng , kLength ) ;
@ -1112,7 +1137,7 @@ TEST(ConstructFromExternal, LargeReleaser) {
EXPECT_TRUE ( invoked ) ;
}
TEST ( ConstructFromExternal , FunctionPointerReleaser ) {
TEST_P ( CordTest , ConstructFromExternal FunctionPointerReleaser ) {
static absl : : string_view data ( " hello world " ) ;
static bool invoked ;
auto * releaser =
@ -1129,7 +1154,7 @@ TEST(ConstructFromExternal, FunctionPointerReleaser) {
EXPECT_TRUE ( invoked ) ;
}
TEST ( ConstructFromExternal , MoveOnlyReleaser ) {
TEST_P ( CordTest , ConstructFromExternal MoveOnlyReleaser ) {
struct Releaser {
explicit Releaser ( bool * invoked ) : invoked ( invoked ) { }
Releaser ( Releaser & & other ) noexcept : invoked ( other . invoked ) { }
@ -1143,20 +1168,20 @@ TEST(ConstructFromExternal, MoveOnlyReleaser) {
EXPECT_TRUE ( invoked ) ;
}
TEST ( ConstructFromExternal , NoArgLambda ) {
TEST_P ( CordTest , ConstructFromExternal NoArgLambda ) {
bool invoked = false ;
( void ) absl : : MakeCordFromExternal ( " dummy " , [ & invoked ] ( ) { invoked = true ; } ) ;
EXPECT_TRUE ( invoked ) ;
}
TEST ( ConstructFromExternal , StringViewArgLambda ) {
TEST_P ( CordTest , ConstructFromExternal StringViewArgLambda ) {
bool invoked = false ;
( void ) absl : : MakeCordFromExternal (
" dummy " , [ & invoked ] ( absl : : string_view ) { invoked = true ; } ) ;
EXPECT_TRUE ( invoked ) ;
}
TEST ( ConstructFromExternal , NonTrivialReleaserDestructor ) {
TEST_P ( CordTest , ConstructFromExternal NonTrivialReleaserDestructor ) {
struct Releaser {
explicit Releaser ( bool * destroyed ) : destroyed ( destroyed ) { }
~ Releaser ( ) { * destroyed = true ; }
@ -1171,7 +1196,7 @@ TEST(ConstructFromExternal, NonTrivialReleaserDestructor) {
EXPECT_TRUE ( destroyed ) ;
}
TEST ( ConstructFromExternal , ReferenceQualifierOverloads ) {
TEST_P ( CordTest , ConstructFromExternal ReferenceQualifierOverloads ) {
struct Releaser {
void operator ( ) ( absl : : string_view ) & { * lvalue_invoked = true ; }
void operator ( ) ( absl : : string_view ) & & { * rvalue_invoked = true ; }
@ -1199,7 +1224,7 @@ TEST(ConstructFromExternal, ReferenceQualifierOverloads) {
EXPECT_TRUE ( rvalue_invoked ) ;
}
TEST ( ExternalMemory , BasicUsage ) {
TEST_P ( CordTest , ExternalMemory BasicUsage ) {
static const char * strings [ ] = { " " , " hello " , " there " } ;
for ( const char * str : strings ) {
absl : : Cord dst ( " (prefix) " ) ;
@ -1210,7 +1235,7 @@ TEST(ExternalMemory, BasicUsage) {
}
}
TEST ( ExternalMemory , RemovePrefixSuffix ) {
TEST_P ( CordTest , ExternalMemory RemovePrefixSuffix ) {
// Exhaustively try all sub-strings.
absl : : Cord cord = MakeComposite ( ) ;
std : : string s = std : : string ( cord ) ;
@ -1225,7 +1250,7 @@ TEST(ExternalMemory, RemovePrefixSuffix) {
}
}
TEST ( ExternalMemory , Get ) {
TEST_P ( CordTest , ExternalMemory Get ) {
absl : : Cord cord ( " hello " ) ;
AddExternalMemory ( " world! " , & cord ) ;
AddExternalMemory ( " how are " , & cord ) ;
@ -1244,16 +1269,16 @@ TEST(ExternalMemory, Get) {
// Additionally we have some whiteboxed expectations based on our knowledge of
// the layout and size of empty and inlined cords, and flat nodes.
TEST ( CordMemoryUsage , Empty ) {
TEST_P ( CordTest , CordMemoryUsage Empty ) {
EXPECT_EQ ( sizeof ( absl : : Cord ) , absl : : Cord ( ) . EstimatedMemoryUsage ( ) ) ;
}
TEST ( CordMemoryUsage , Embedded ) {
TEST_P ( CordTest , CordMemoryUsage Embedded ) {
absl : : Cord a ( " hello " ) ;
EXPECT_EQ ( a . EstimatedMemoryUsage ( ) , sizeof ( absl : : Cord ) ) ;
}
TEST ( CordMemoryUsage , EmbeddedAppend ) {
TEST_P ( CordTest , CordMemoryUsage EmbeddedAppend ) {
absl : : Cord a ( " a " ) ;
absl : : Cord b ( " bcd " ) ;
EXPECT_EQ ( b . EstimatedMemoryUsage ( ) , sizeof ( absl : : Cord ) ) ;
@ -1261,7 +1286,7 @@ TEST(CordMemoryUsage, EmbeddedAppend) {
EXPECT_EQ ( a . EstimatedMemoryUsage ( ) , sizeof ( absl : : Cord ) ) ;
}
TEST ( CordMemoryUsage , ExternalMemory ) {
TEST_P ( CordTest , CordMemoryUsage ExternalMemory ) {
static const int kLength = 1000 ;
absl : : Cord cord ;
AddExternalMemory ( std : : string ( kLength , ' x ' ) , & cord ) ;
@ -1269,14 +1294,14 @@ TEST(CordMemoryUsage, ExternalMemory) {
EXPECT_LE ( cord . EstimatedMemoryUsage ( ) , kLength * 1.5 ) ;
}
TEST ( CordMemoryUsage , Flat ) {
TEST_P ( CordTest , CordMemoryUsage Flat ) {
static const int kLength = 125 ;
absl : : Cord a ( std : : string ( kLength , ' a ' ) ) ;
EXPECT_GT ( a . EstimatedMemoryUsage ( ) , kLength ) ;
EXPECT_LE ( a . EstimatedMemoryUsage ( ) , kLength * 1.5 ) ;
}
TEST ( CordMemoryUsage , AppendFlat ) {
TEST_P ( CordTest , CordMemoryUsage AppendFlat ) {
using absl : : strings_internal : : CordTestAccess ;
absl : : Cord a ( std : : string ( CordTestAccess : : MaxFlatLength ( ) , ' a ' ) ) ;
size_t length = a . EstimatedMemoryUsage ( ) ;
@ -1286,9 +1311,32 @@ TEST(CordMemoryUsage, AppendFlat) {
EXPECT_LE ( delta , CordTestAccess : : MaxFlatLength ( ) * 1.5 ) ;
}
TEST_P ( CordTest , CordMemoryUsageAppendExternal ) {
static const int kLength = 1000 ;
using absl : : strings_internal : : CordTestAccess ;
absl : : Cord a ( std : : string ( CordTestAccess : : MaxFlatLength ( ) , ' a ' ) ) ;
size_t length = a . EstimatedMemoryUsage ( ) ;
AddExternalMemory ( std : : string ( kLength , ' b ' ) , & a ) ;
size_t delta = a . EstimatedMemoryUsage ( ) - length ;
EXPECT_GT ( delta , kLength ) ;
EXPECT_LE ( delta , kLength * 1.5 ) ;
}
TEST_P ( CordTest , CordMemoryUsageSubString ) {
static const int kLength = 2000 ;
using absl : : strings_internal : : CordTestAccess ;
absl : : Cord a ( std : : string ( kLength , ' a ' ) ) ;
size_t length = a . EstimatedMemoryUsage ( ) ;
AddExternalMemory ( std : : string ( kLength , ' b ' ) , & a ) ;
absl : : Cord b = a . Subcord ( 0 , kLength + kLength / 2 ) ;
size_t delta = b . EstimatedMemoryUsage ( ) - length ;
EXPECT_GT ( delta , kLength ) ;
EXPECT_LE ( delta , kLength * 1.5 ) ;
}
// Regtest for a change that had to be rolled back because it expanded out
// of the InlineRep too soon, which was observable through MemoryUsage().
TEST ( CordMemoryUsage , InlineRep ) {
TEST_P ( CordTest , CordMemoryUsage InlineRep ) {
constexpr size_t kMaxInline = 15 ; // Cord::InlineRep::N
const std : : string small_string ( kMaxInline , ' x ' ) ;
absl : : Cord c1 ( small_string ) ;
@ -1302,7 +1350,7 @@ TEST(CordMemoryUsage, InlineRep) {
} // namespace
// Regtest for 7510292 (fix a bug introduced by 7465150)
TEST ( Cord , Concat_Append ) {
TEST_P ( CordTest , Concat_Append ) {
// Create a rep of type CONCAT
absl : : Cord s1 ( " foobarbarbarbarbar " ) ;
s1 . Append ( " abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg " ) ;
@ -1317,7 +1365,7 @@ TEST(Cord, Concat_Append) {
EXPECT_EQ ( s2 . size ( ) , size + 1 ) ;
}
TEST ( Cord , DiabolicalGrowth ) {
TEST_P ( CordTest , DiabolicalGrowth ) {
// This test exercises a diabolical Append(<one char>) on a cord, making the
// cord shared before each Append call resulting in a terribly fragmented
// resulting cord.
@ -1337,7 +1385,7 @@ TEST(Cord, DiabolicalGrowth) {
cord . EstimatedMemoryUsage ( ) ) ;
}
TEST ( MakeFragmented Cord, MakeFragmentedCordFromInitializerList ) {
TEST_P ( CordTest , MakeFragmentedCordFromInitializerList ) {
absl : : Cord fragmented =
absl : : MakeFragmentedCord ( { " A " , " fragmented " , " Cord " } ) ;
@ -1357,7 +1405,7 @@ TEST(MakeFragmentedCord, MakeFragmentedCordFromInitializerList) {
ASSERT_TRUE ( + + chunk_it = = fragmented . chunk_end ( ) ) ;
}
TEST ( MakeFragmented Cord, MakeFragmentedCordFromVector ) {
TEST_P ( CordTest , MakeFragmentedCordFromVector ) {
std : : vector < absl : : string_view > chunks = { " A " , " fragmented " , " Cord " } ;
absl : : Cord fragmented = absl : : MakeFragmentedCord ( chunks ) ;
@ -1377,7 +1425,7 @@ TEST(MakeFragmentedCord, MakeFragmentedCordFromVector) {
ASSERT_TRUE ( + + chunk_it = = fragmented . chunk_end ( ) ) ;
}
TEST ( CordChunkIterator , Traits ) {
TEST_P ( CordTest , CordChunkIterator Traits ) {
static_assert ( std : : is_copy_constructible < absl : : Cord : : ChunkIterator > : : value ,
" " ) ;
static_assert ( std : : is_copy_assignable < absl : : Cord : : ChunkIterator > : : value , " " ) ;
@ -1458,7 +1506,7 @@ static void VerifyChunkIterator(const absl::Cord& cord,
EXPECT_TRUE ( post_iter = = cord . chunk_end ( ) ) ; // NOLINT
}
TEST ( CordChunkIterator , Operations ) {
TEST_P ( CordTest , CordChunkIterator Operations ) {
absl : : Cord empty_cord ;
VerifyChunkIterator ( empty_cord , 0 ) ;
@ -1628,7 +1676,7 @@ TEST(CordCharIterator, Operations) {
VerifyCharIterator ( subcords ) ;
}
TEST ( Cord , StreamingOutput ) {
TEST_P ( CordTest , StreamingOutput ) {
absl : : Cord c =
absl : : MakeFragmentedCord ( { " A " , " small " , " fragmented " , " Cord " , " . " } ) ;
std : : stringstream output ;
@ -1636,7 +1684,7 @@ TEST(Cord, StreamingOutput) {
EXPECT_EQ ( " A small fragmented Cord. " , output . str ( ) ) ;
}
TEST ( Cord , ForEachChunk ) {
TEST_P ( CordTest , ForEachChunk ) {
for ( int num_elements : { 1 , 10 , 200 } ) {
SCOPED_TRACE ( num_elements ) ;
std : : vector < std : : string > cord_chunks ;
@ -1654,7 +1702,7 @@ TEST(Cord, ForEachChunk) {
}
}
TEST ( Cord , SmallBufferAssignFromOwnData ) {
TEST_P ( CordTest , SmallBufferAssignFromOwnData ) {
constexpr size_t kMaxInline = 15 ;
std : : string contents = " small buff cord " ;
EXPECT_EQ ( contents . size ( ) , kMaxInline ) ;
@ -1669,7 +1717,7 @@ TEST(Cord, SmallBufferAssignFromOwnData) {
}
}
TEST ( Cord , Format ) {
TEST_P ( CordTest , Format ) {
absl : : Cord c ;
absl : : Format ( & c , " There were %04d little %s. " , 3 , " pigs " ) ;
EXPECT_EQ ( c , " There were 0003 little pigs. " ) ;
@ -1770,7 +1818,7 @@ struct LongView {
} ;
TEST ( Cord , ConstinitConstructor ) {
TEST_P ( CordTest , ConstinitConstructor ) {
TestConstinitConstructor (
absl : : strings_internal : : MakeStringConstant ( ShortView { } ) ) ;
TestConstinitConstructor (