summaryrefslogtreecommitdiff
path: root/absl/strings/cord_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/cord_test.cc')
-rw-r--r--absl/strings/cord_test.cc50
1 files changed, 46 insertions, 4 deletions
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index f9982428..fb673411 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -187,6 +187,18 @@ class CordTestPeer {
static cord_internal::CordzInfo* GetCordzInfo(const Cord& c) {
return c.contents_.cordz_info();
}
+
+ static Cord MakeSubstring(Cord src, size_t offset, size_t length) {
+ Cord cord = src;
+ ABSL_RAW_CHECK(cord.contents_.is_tree(), "Can not be inlined");
+ auto* rep = new cord_internal::CordRepSubstring;
+ rep->tag = cord_internal::SUBSTRING;
+ rep->child = cord.contents_.tree();
+ rep->start = offset;
+ rep->length = length;
+ cord.contents_.replace_tree(rep);
+ return cord;
+ }
};
ABSL_NAMESPACE_END
@@ -466,8 +478,8 @@ TEST(TryFlat, SubstrInlined) {
TEST(TryFlat, SubstrFlat) {
absl::Cord c("longer than 15 bytes");
- c.RemovePrefix(1);
- EXPECT_EQ(c.TryFlat(), "onger 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) {
@@ -482,16 +494,46 @@ TEST(TryFlat, External) {
TEST(TryFlat, SubstrExternal) {
absl::Cord c = absl::MakeCordFromExternal("hell", [](absl::string_view) {});
- c.RemovePrefix(1);
- EXPECT_EQ(c.TryFlat(), "ell");
+ absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
+ EXPECT_EQ(sub.TryFlat(), "ell");
}
TEST(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);
c.RemovePrefix(1);
EXPECT_EQ(c.TryFlat(), absl::nullopt);
}
+TEST(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.
+ absl::string_view fragments[] = {"A fragmented test",
+ " cord",
+ " to test subcords",
+ " of ",
+ "a",
+ " cord for",
+ " each chunk "
+ "returned by the ",
+ "iterator"};
+ absl::Cord c = absl::MakeFragmentedCord(fragments);
+ int fragment = 0;
+ int offset = 0;
+ absl::Cord::CharIterator itc = c.char_begin();
+ for (absl::string_view sv : c.Chunks()) {
+ absl::string_view expected = fragments[fragment];
+ absl::Cord subcord1 = c.Subcord(offset, sv.length());
+ absl::Cord subcord2 = absl::Cord::AdvanceAndRead(&itc, sv.size());
+ EXPECT_EQ(subcord1.TryFlat(), expected);
+ EXPECT_EQ(subcord2.TryFlat(), expected);
+ ++fragment;
+ offset += sv.length();
+ }
+}
+
static bool IsFlat(const absl::Cord& c) {
return c.chunk_begin() == c.chunk_end() || ++c.chunk_begin() == c.chunk_end();
}