From 66208350e3f9dff24c7a55c508942525e69a43a6 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Fri, 2 Aug 2019 16:14:14 +0200 Subject: [PATCH] Fix: If a property is added, then deleted, don't produce a patch --- __tests__/patch.js | 75 ++++++++++++++++++++++++++++++++++++++++++++-- src/proxy.js | 3 ++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/__tests__/patch.js b/__tests__/patch.js index fa38724a..d50db90a 100644 --- a/__tests__/patch.js +++ b/__tests__/patch.js @@ -4,6 +4,8 @@ import produce, {setUseProxies, applyPatches} from "../src/index" jest.setTimeout(1000) function runPatchTest(base, producer, patches, inversePathes) { + let resultProxies, resultEs5 + function runPatchTestHelper() { let recordedPatches let recordedInversePatches @@ -24,17 +26,24 @@ function runPatchTest(base, producer, patches, inversePathes) { test("patches can be reversed", () => { expect(applyPatches(res, recordedInversePatches)).toEqual(base) }) + + return res } describe(`proxy`, () => { setUseProxies(true) - runPatchTestHelper() + resultProxies = runPatchTestHelper() }) describe(`es5`, () => { setUseProxies(false) - runPatchTestHelper() + resultEs5 = runPatchTestHelper() + test("ES5 and Proxy implementation yield same result", () => { + expect(resultEs5).toEqual(resultProxies) + }) }) + + return resultProxies } describe("applyPatches", () => { @@ -414,3 +423,65 @@ describe("simple delete", () => { ] ) }) + +describe("patch compressions yields correct results", () => { + let p1, p2 + runPatchTest( + {}, + d => { + d.x = {test: true} + }, + (p1 = [ + { + op: "add", + path: ["x"], + value: { + test: true + } + } + ]) + ) + runPatchTest( + {x: {test: true}}, + d => { + delete d.x + }, + (p2 = [ + { + op: "remove", + path: ["x"] + } + ]) + ) + const res = runPatchTest( + {}, + d => { + debugger + applyPatches(d, [...p1, ...p2]) + }, + [] + ) + + expect(res).toEqual({}) +}) + +describe("change then delete property", () => { + const res = runPatchTest( + { + x: 1 + }, + d => { + d.x = 2 + delete d.x + }, + [ + { + op: "remove", + path: ["x"] + } + ] + ) + test("valid result", () => { + expect(res).toEqual({}) + }) +}) diff --git a/src/proxy.js b/src/proxy.js index f4caefde..33d7ed40 100644 --- a/src/proxy.js +++ b/src/proxy.js @@ -156,6 +156,9 @@ function deleteProperty(state, prop) { if (peek(state.base, prop) !== undefined || prop in state.base) { state.assigned[prop] = false markChanged(state) + } else if (state.assigned[prop]) { + // if an originally not assigned property was deleted + delete state.assigned[prop] } if (state.copy) delete state.copy[prop] return true