Skip to content

Commit

Permalink
🐛 No-op left transforms where the inserted objects are identical
Browse files Browse the repository at this point in the history
At the moment if you transform two identical `oi` ops by one another,
you get a no-op in the `right` case, but the `left` case results in a
"silly" op whose `od` value is identical to its `oi` value.

`left` vs `right` should simply determine which op wins in a tie. Since
the two ops are identical, the `right` scenario and `left` scenario
should also be identical.

This change updates the transform behaviour to check this case, and
results in a no-op regardless of `left` or `right` if the two ops are
performing identical `oi`.
  • Loading branch information
alecgibson committed Oct 4, 2024
1 parent c391d9a commit 5ed2ca1
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/json0.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ json.transformComponent = function(dest, c, otherC, type) {
}
else if (otherC.oi !== void 0 && otherC.od !== void 0) {
if (c.p[common] === otherC.p[common]) {
if (c.oi !== void 0 && commonOperand) {
if (c.oi !== void 0 && commonOperand && !deepEqual(otherC.oi, c.oi)) {
// we inserted where someone else replaced
if (type === 'right') {
// left wins
Expand All @@ -669,7 +669,7 @@ json.transformComponent = function(dest, c, otherC, type) {
} else if (otherC.oi !== void 0) {
if (c.oi !== void 0 && c.p[common] === otherC.p[common]) {
// left wins if we try to insert at the same place
if (type === 'left') {
if (type === 'left' && !deepEqual(otherC.oi, c.oi)) {
json.append(dest,{p: c.p, od:otherC.oi});
} else {
return dest;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@reedsy/ot-json0",
"version": "1.1.0-reedsy.1.2.5",
"version": "1.1.0-reedsy.1.2.6",
"description": "JSON OT type",
"main": "lib/index.js",
"directories": {
Expand Down
20 changes: 20 additions & 0 deletions test/json0.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,26 @@ genTests = (type) ->
assert.deepEqual [], type.transform [{p:['k'], od:'x'}], [{p:['k'], od:'x'}], 'left'
assert.deepEqual [], type.transform [{p:['k'], od:'x'}], [{p:['k'], od:'x'}], 'right'

it 'An attempt to re-add a key with an identical string becomes a no-op', ->
assert.deepEqual [], type.transform [{p:['k'], oi:'x'}], [{p:['k'], oi:'x'}], 'left'
assert.deepEqual [], type.transform [{p:['k'], oi:'x'}], [{p:['k'], oi:'x'}], 'right'

it 'An attempt to re-replace a key with an identical string becomes a no-op', ->
assert.deepEqual [], type.transform [{p:['k'], oi:'x', od: 'a'}], [{p:['k'], oi:'x', od: 'a'}], 'left'
assert.deepEqual [], type.transform [{p:['k'], oi:'x', od: 'a'}], [{p:['k'], oi:'x', od: 'a'}], 'right'

it 'An attempt to re-replace a key with an identical string becomes a no-op', ->
assert.deepEqual [], type.transform [{p:['k'], oi:'x', od: 'a'}], [{p:['k'], oi:'x', od: 'b'}], 'left'
assert.deepEqual [], type.transform [{p:['k'], oi:'x', od: 'a'}], [{p:['k'], oi:'x', od: 'b'}], 'right'

it 'An attempt to re-add a key with an identical object becomes a no-op', ->
assert.deepEqual [], type.transform [{p:['k'], oi:{}}], [{p:['k'], oi:{}}], 'left'
assert.deepEqual [], type.transform [{p:['k'], oi:{}}], [{p:['k'], oi:{}}], 'right'

it 'An attempt to re-replace a key with an identical object becomes a no-op', ->
assert.deepEqual [], type.transform [{p:['k'], oi:{}, od: 'a'}], [{p:['k'], oi:{}, od: 'a'}], 'left'
assert.deepEqual [], type.transform [{p:['k'], oi:{}, od: 'a'}], [{p:['k'], oi:{}, od: 'a'}], 'right'

it 'throws when the deletion target does not match', ->
assert.throws -> type.apply {x:'a'}, [{p:['x'], od: 'b'}]
assert.throws -> type.apply {x:'a'}, [{p:['x'], oi: 'c', od: 'b'}]
Expand Down

0 comments on commit 5ed2ca1

Please sign in to comment.