From 08efd9c179a86fe60c4fe5f9d91a7fbfc8b3ea52 Mon Sep 17 00:00:00 2001 From: Yourim Cha Date: Mon, 6 Nov 2023 23:28:58 +0900 Subject: [PATCH] Fix test to use disableGC option --- src/document/crdt/element_rht.ts | 11 +++++++++++ src/document/crdt/object.ts | 8 ++++++++ src/document/operation/remove_operation.ts | 4 ++-- test/integration/object_test.ts | 14 ++++++++------ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/document/crdt/element_rht.ts b/src/document/crdt/element_rht.ts index efcce5e8d..6865c790b 100644 --- a/src/document/crdt/element_rht.ts +++ b/src/document/crdt/element_rht.ts @@ -184,6 +184,17 @@ export class ElementRHT { return !node.isRemoved(); } + /** + * `hasByCreatedAt` returns whether the element exists of the given createdAt or not. + */ + public hasByCreatedAt(createdAt: TimeTicket): boolean { + const node = this.nodeMapByCreatedAt.get(createdAt.toIDString()); + if (node == null) { + return false; + } + return !node.isRemoved(); + } + /** * `get` returns the value of the given key. */ diff --git a/src/document/crdt/object.ts b/src/document/crdt/object.ts index d642ffc0d..82af95fed 100644 --- a/src/document/crdt/object.ts +++ b/src/document/crdt/object.ts @@ -98,6 +98,14 @@ export class CRDTObject extends CRDTContainer { return this.memberNodes.has(key); } + /** + * `hasByCreatedAt` returns whether the element exists of the given + * createdAt or not. + */ + public hasByCreatedAt(createdAt: TimeTicket): boolean { + return this.memberNodes.hasByCreatedAt(createdAt); + } + /** * `toJSON` returns the JSON encoding of this object. */ diff --git a/src/document/operation/remove_operation.ts b/src/document/operation/remove_operation.ts index 98c06f661..f7297ab17 100644 --- a/src/document/operation/remove_operation.ts +++ b/src/document/operation/remove_operation.ts @@ -69,16 +69,16 @@ export class RemoveOperation extends Operation { logger.fatal(`only object and array can execute remove: ${parentObject}`); } const obj = parentObject as CRDTContainer; - const key = obj.subPathOf(this.createdAt); // NOTE(chacha912): Handle cases where operation cannot be executed during undo and redo. if ( source === OpSource.UndoRedo && (obj.getRemovedAt() || - (obj instanceof CRDTObject && !obj.has(key!)) || + (obj instanceof CRDTObject && !obj.hasByCreatedAt(this.createdAt)) || (obj instanceof CRDTArray && !obj.get(this.createdAt))) ) { return; } + const key = obj.subPathOf(this.createdAt); const reverseOp = this.getReverseOperation(obj); const elem = obj.delete(this.createdAt, this.getExecutedAt()); diff --git a/test/integration/object_test.ts b/test/integration/object_test.ts index 3598426f3..9ac3e309c 100644 --- a/test/integration/object_test.ts +++ b/test/integration/object_test.ts @@ -587,15 +587,16 @@ describe('Object', function () { assert.equal(doc2.toSortedJSON(), '{"color":"red"}'); }); - it.skip(`Should handle case of reverse operations referencing already garbage-collected elements`, async function ({ + it(`Should handle case of reverse operations referencing already garbage-collected elements`, async function ({ task, }) { interface TestDoc { shape: { color: string }; } const docKey = toDocKey(`${task.name}-${new Date().getTime()}`); - const doc1 = new Document(docKey); - const doc2 = new Document(docKey); + // TODO(chacha912): Remove the disableGC option + const doc1 = new Document(docKey, { disableGC: true }); + const doc2 = new Document(docKey, { disableGC: true }); const client1 = new Client(testRPCAddr); const client2 = new Client(testRPCAddr); @@ -626,12 +627,13 @@ describe('Object', function () { assert.equal(doc1.toSortedJSON(), '{"shape":{"color":"red"}}'); assert.equal(doc2.toSortedJSON(), '{"shape":{"color":"red"}}'); - // TODO(chacha912): fix error that occurs when undoing and make the test pass doc1.history.undo(); - assert.equal(doc1.toSortedJSON(), '{}'); + assert.equal(doc1.toSortedJSON(), '{"shape":{"color":"red"}}'); + assert.equal(doc1.getRedoStackForTest().length, 0); + assert.equal(doc1.history.canRedo(), false); await client1.sync(); await client2.sync(); - assert.equal(doc2.toSortedJSON(), '{}'); + assert.equal(doc2.toSortedJSON(), '{"shape":{"color":"red"}}'); }); }); });