Skip to content

Commit 728ba67

Browse files
committed
Add more UpdateIfNeeded tests
1 parent 916881b commit 728ba67

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

src/realm/collection.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,11 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
564564
m_content_version = 0;
565565
}
566566

567+
CollectionParent* get_owner() const noexcept
568+
{
569+
return m_parent;
570+
}
571+
567572
void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;
568573

569574
using Interface::get_owner_key;

test/test_list.cpp

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ TEST(List_UpdateIfNeeded)
10981098
auto table = tr->add_table("table");
10991099
auto col = table->add_column(type_Mixed, "mixed");
11001100
auto col2 = table->add_column(type_Mixed, "col2");
1101-
table->create_object();
1101+
auto leading_obj = table->create_object();
11021102
Obj obj = table->create_object();
11031103
obj.set_collection(col, CollectionType::List);
11041104

@@ -1123,9 +1123,24 @@ TEST(List_UpdateIfNeeded)
11231123
// The list is now non-empty, so a new accessor can initialize
11241124
auto list_3 = obj.get_list<Mixed>(col);
11251125
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::Updated);
1126+
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::NoChange);
1127+
1128+
// A copy of a list is lazily initialized, so it's updated on first call
1129+
// even if the source was up-to-date
1130+
auto list_4 = std::make_shared<Lst<Mixed>>(list_3);
1131+
CHECK_EQUAL(list_4->update_if_needed(), UpdateStatus::Updated);
1132+
1133+
// Nested lists work the same way as top-level ones
1134+
list_4->insert_collection(1, CollectionType::List);
1135+
auto list_4_1 = list_4->get_list(1);
1136+
auto list_4_2 = list_4->get_list(1);
1137+
list_4_1->add(Mixed());
1138+
// FIXME: this should be NoChange
1139+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::Updated);
1140+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::Updated);
11261141

11271142
// Update the row index of the parent object, forcing it to update
1128-
table->remove_object(table->begin());
1143+
leading_obj.remove();
11291144

11301145
// Updating the base object directly first doesn't change the result of
11311146
// updating the list
@@ -1135,6 +1150,12 @@ TEST(List_UpdateIfNeeded)
11351150
CHECK_EQUAL(list_2.update_if_needed(), UpdateStatus::Updated);
11361151
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::Updated);
11371152

1153+
// These two lists share the same parent, so the first updates due to the
1154+
// parent returning Updated, and the second updates due to seeing that the
1155+
// parent version has changed
1156+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::Updated);
1157+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::Updated);
1158+
11381159
tr->commit_and_continue_as_read();
11391160

11401161
// Committing the write transaction changes the obj's ref, so everything
@@ -1143,6 +1164,8 @@ TEST(List_UpdateIfNeeded)
11431164
CHECK_EQUAL(list_1.update_if_needed(), UpdateStatus::Updated);
11441165
CHECK_EQUAL(list_2.update_if_needed(), UpdateStatus::Updated);
11451166
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::Updated);
1167+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::Updated);
1168+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::Updated);
11461169

11471170
// Perform a write which does not result in obj changing
11481171
{
@@ -1157,6 +1180,8 @@ TEST(List_UpdateIfNeeded)
11571180
CHECK_EQUAL(list_1.update_if_needed(), UpdateStatus::NoChange);
11581181
CHECK_EQUAL(list_2.update_if_needed(), UpdateStatus::NoChange);
11591182
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::NoChange);
1183+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::NoChange);
1184+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::NoChange);
11601185

11611186
// Perform a write which does modify obj
11621187
{
@@ -1171,6 +1196,8 @@ TEST(List_UpdateIfNeeded)
11711196
CHECK_EQUAL(list_1.update_if_needed(), UpdateStatus::Updated);
11721197
CHECK_EQUAL(list_2.update_if_needed(), UpdateStatus::Updated);
11731198
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::Updated);
1199+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::Updated);
1200+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::Updated);
11741201

11751202
// Everything updates to detached when the object is removed
11761203
tr->promote_to_write();
@@ -1180,4 +1207,41 @@ TEST(List_UpdateIfNeeded)
11801207
CHECK_EQUAL(list_1.update_if_needed(), UpdateStatus::Detached);
11811208
CHECK_EQUAL(list_2.update_if_needed(), UpdateStatus::Detached);
11821209
CHECK_EQUAL(list_3.update_if_needed(), UpdateStatus::Detached);
1210+
CHECK_EQUAL(list_4_1->update_if_needed(), UpdateStatus::Detached);
1211+
CHECK_EQUAL(list_4_2->update_if_needed(), UpdateStatus::Detached);
1212+
}
1213+
1214+
TEST(List_AsCollectionParent)
1215+
{
1216+
Group g;
1217+
auto table = g.add_table("table");
1218+
auto col = table->add_column(type_Mixed, "mixed");
1219+
1220+
Obj obj = table->create_object();
1221+
obj.set_collection(col, CollectionType::List);
1222+
auto list_1 = obj.get_list<Mixed>(col);
1223+
list_1.insert_collection(0, CollectionType::List);
1224+
1225+
// list_1 is stack allocated, so we have to create a new object which can
1226+
// serve as the owner. This object is not reused for multiple calls.
1227+
auto list_1_1 = list_1.get_list(0);
1228+
auto list_1_2 = list_1.get_list(0);
1229+
CHECK_NOT_EQUAL(list_1_1->get_owner(), &list_1);
1230+
CHECK_NOT_EQUAL(list_1_1->get_owner(), list_1_2->get_owner());
1231+
1232+
// list_2 is heap allocated but not owned by a shared_ptr, so we have to
1233+
// create a new object which can serve as the owner. This object is not
1234+
// reused for multiple calls.
1235+
auto list_2 = obj.get_list_ptr<Mixed>(col);
1236+
auto list_2_1 = list_2->get_list(0);
1237+
auto list_2_2 = list_2->get_list(0);
1238+
CHECK_NOT_EQUAL(list_2_1->get_owner(), list_2.get());
1239+
CHECK_NOT_EQUAL(list_2_1->get_owner(), list_2_2->get_owner());
1240+
1241+
// list_3 is owned by a shared_ptr, so we can just use it as the owner directly
1242+
auto list_3 = std::shared_ptr{std::move(list_2)};
1243+
auto list_3_1 = list_3->get_list(0);
1244+
auto list_3_2 = list_3->get_list(0);
1245+
CHECK_EQUAL(list_3_1->get_owner(), list_3.get());
1246+
CHECK_EQUAL(list_3_1->get_owner(), list_3_2->get_owner());
11831247
}

0 commit comments

Comments
 (0)