Skip to content

Commit

Permalink
✅ test: Verified that arrays are diffed correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
joebobmiles committed Jul 9, 2021
1 parent f743b3c commit 543ed26
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 21 deletions.
3 changes: 0 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ const arrayToYarray = (array: Array<any>): Y.Array<any> =>
if (typeof value !== "function" && typeof value !== "undefined")
{
if (value instanceof Array)

yarray.push([ arrayToYarray(value) ]);

else if (value instanceof Object)

yarray.push([ stateToYmap(value) ]);

else

yarray.push([ value ]);

}
Expand Down
53 changes: 37 additions & 16 deletions src/patching.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,36 @@ describe("getChangeList", () =>
}
);

it(
"Should create an add entry when b contains a new item.",
() =>
it.each([
[
{},
{ "foo": 1, },
[ "add", "foo", 1 ]
],
[
[],
[ 1 ],
[ "add", 0, 1 ]
]
])(
"Should create an add entry when b contains a new item. (#%#)",
(a, b, change) =>
{
expect(getChangeList({}, { "foo": 1, })).toEqual([ [ "add", "foo", 1 ] ]);
expect(getChangeList(a, b)).toEqual([ change ]);
}
);

it(
"Should create an update entry when b contains a new value.",
() =>
{
expect(getChangeList({ "foo": 1, }, { "foo": 2, }))
.toEqual([ [ "update", "foo", 2 ] ]);
}
);
it("Should create an update entry when b contains a new value.", () =>
{
expect(getChangeList( { "foo": 1, }, { "foo": 2, }))
.toEqual([ [ "update", "foo", 2 ] ]);
});

it("Should create an add and delete entry when an array changes.", () =>
{
expect(getChangeList( [ 1 ], [ 2 ]))
.toEqual([ [ "delete", 0, undefined ], [ "add", 0, 2 ] ]);
});

it(
"Should create a delete entry when b is missing a value.",
Expand All @@ -39,18 +53,25 @@ describe("getChangeList", () =>
it.each([
[
{ "foo": { "bar": 1, }, },
{ "foo": { "bar": 2, }, }
{ "foo": { "bar": 2, }, },
[ "pending", "foo", undefined ]
],
[
{ "foo": [ 1 ], },
{ "foo": [ 1, 2 ], }
{ "foo": [ 1, 2 ], },
[ "pending", "foo", undefined ]
],
[
[ { "foo": 1, "bar": 3, } ],
[ { "foo": 2, "bar": 3, } ],
[ "pending", 0, undefined ]
]
])(
"Should create a pending entry when a and b have nested data. (#%#)",
(a, b) =>
(a, b, change) =>
{
expect(getChangeList(a, b))
.toEqual([ [ "pending", "foo", undefined ] ]);
.toEqual([ change ]);
}
);
});
38 changes: 36 additions & 2 deletions src/patching.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,46 @@
import { diff, } from "json-diff";

export type Change = [ "add" | "update" | "delete" | "pending", string, any ];
export type Change = [
"add" | "update" | "delete" | "pending",
string | number,
any
];

export const getChangeList = (a: any, b: any): Change[] =>
{
const delta = diff(a, b);

if (delta instanceof Object)
if (delta instanceof Array)
{
const patch: Change[] = [];

let offset = 0;

delta.forEach(([ type, value ], index) =>
{
switch (type)
{
case "+":
if (0 < patch.length && patch[patch.length-1][0] === "delete") offset--;
patch.push([ "add", index + offset, value ]);
break;

case "-":
patch.push([ "delete", index + offset, undefined ]);
break;

case "~":
patch.push([ "pending", index + offset, undefined ]);
break;

default:
break;
}
});

return patch;
}
else if (delta instanceof Object)
{
const patch: Change[] = [];

Expand Down

0 comments on commit 543ed26

Please sign in to comment.