Skip to content

Commit

Permalink
Add a clean option to patch
Browse files Browse the repository at this point in the history
  • Loading branch information
Swizz committed Nov 11, 2017
1 parent df0e418 commit 1d00365
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 60 deletions.
14 changes: 10 additions & 4 deletions README.md
Expand Up @@ -56,7 +56,7 @@ const prevCar = {
- [API](#api)
- [interface patch](#interface-patch--do-object-undo-object-)
- [function diff](#function-diff-from-object-array-to-object-array--patch)
- [function patch](#function-patch-from-object-array-diff-patch--object)
- [function patch](#function-patch-from-object-array-diff-patch-array-boolean-clean-boolean--object-array)
- [Recipes](#recipes)
- [Operation type](#operation-type)
- [Array time traveling](#array-time-traveling)
Expand Down Expand Up @@ -126,6 +126,9 @@ T(a)rdis provide you a patch function, ready to counter all the T(a)rdis diff
function features. This function is aligned with the diff signature to allow you
to take all benefits of T(a)rdis with a sanitized experience.

The patch function provide an option to automatically return well structured arrays ;
and another one to remove undefined/deleted properties.

```js
let past = patch(future, present.undo)
let future = patch(past, present.do)
Expand Down Expand Up @@ -189,11 +192,14 @@ This is the patch object, it will hold two properties :
The diff function will return the patch object by comparing the second object to
the first one. The patch will help to undo the changes or to redo them later.
#### function patch: (from: object | array, diff: patch) => object
#### function patch: (from: object | array, diff: patch, array: boolean, clean: boolean) => object | array
The patch function is an helpful function to merge the from object with the given
diff patch. Object will be merge into a new object. The patch function return
an object with all the keys, the deleted properties will appear as undefined.
diff patch. Object will be merge into a new object.
If the array paramter is set to true, arrays will be automatically returned.
The patch function return an object with all the keys, the deleted properties will
appear as undefined, unless you set the clean parameter to true.
## Recipes
Expand Down
12 changes: 9 additions & 3 deletions src/index.js
Expand Up @@ -31,13 +31,19 @@ export function diff(from, to) {
return patch
}

export function patch(from, diff, array) {
export function patch(from, diff, array, clean) {
var to = {}
for (var key in from) {
to[key] = from[key]
if (!(clean && from[key] === undefined)) {
to[key] = from[key]
}
}
for (var key in diff) {
to[key] = diff[key]
if (!(clean && diff[key] === undefined)) {
to[key] = diff[key]
} else {
delete to[key]
}
}
return array && "length" in to ? Array.from(to) : to
}
146 changes: 93 additions & 53 deletions tests/patch.test.js
Expand Up @@ -6,47 +6,47 @@ describe("flat", () => {

const to = { a: 1, b: 2, c: 3 }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch deleted", () => {
const from = { a: 1, b: 2 }

const to = { a: 1 }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch updated", () => {
const from = { a: 1, b: 2 }

const to = { a: 1, b: 1 }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch kept", () => {
const from = { a: 1, b: 2 }

const to = { a: 1, b: 2 }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})
})

Expand All @@ -56,47 +56,47 @@ describe("nested", () => {

const to = { a: 1, b: { a: 1, b: 2, c: 3 } }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch deleted", () => {
const from = { a: 1, b: { a: 1, b: 2 } }

const to = { a: 1, b: { a: 1 } }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch updated", () => {
const from = { a: 1, b: { a: 1, b: 2 } }

const to = { a: 1, b: { a: 1, b: 1 } }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})

test("patch kept", () => {
const from = { a: 1, b: { a: 1, b: 2 } }

const to = { a: 1, b: { a: 1, b: 2 } }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, future.do)).toEqual(to)
expect(patch(from, present.do)).toEqual(to)

expect(patch(to, future.undo)).toEqual(from)
expect(patch(to, present.undo)).toEqual(from)
})
})

Expand All @@ -106,74 +106,114 @@ describe("array", () => {

const to = [1, 2, 3]

const future = diff(from, to)
const present = diff(from, to)

expect(Array.from(patch(from, future.do))).toEqual(to)
expect(Array.from(patch(from, present.do))).toEqual(to)

expect(Array.from(patch(to, future.undo))).toEqual(from)

expect(patch(from, future.do, true)).toEqual(to)

expect(patch(to, future.undo, true)).toEqual(from)
expect(Array.from(patch(to, present.undo))).toEqual(from)
})

test("patch deleted", () => {
const from = [1, 2]

const to = [1]

const future = diff(from, to)

expect(Array.from(patch(from, future.do))).toEqual(to)
const present = diff(from, to)

expect(Array.from(patch(to, future.undo))).toEqual(from)
expect(Array.from(patch(from, present.do))).toEqual(to)

expect(patch(from, future.do, true)).toEqual(to)

expect(patch(to, future.undo, true)).toEqual(from)
expect(Array.from(patch(to, present.undo))).toEqual(from)
})

test("patch updated", () => {
const from = [1, 2]

const to = [1, 1]

const future = diff(from, to)

expect(Array.from(patch(from, future.do))).toEqual(to)
const present = diff(from, to)

expect(Array.from(patch(to, future.undo))).toEqual(from)
expect(Array.from(patch(from, present.do))).toEqual(to)

expect(patch(from, future.do, true)).toEqual(to)

expect(patch(to, future.undo, true)).toEqual(from)
expect(Array.from(patch(to, present.undo))).toEqual(from)
})

test("patch kept", () => {
const from = [1, 2]

const to = [1, 2]

const future = diff(from, to)
const present = diff(from, to)

expect(Array.from(patch(from, future.do))).toEqual(to)
expect(Array.from(patch(from, present.do))).toEqual(to)

expect(Array.from(patch(to, future.undo))).toEqual(from)
expect(Array.from(patch(to, present.undo))).toEqual(from)
})
})

expect(patch(from, future.do, true)).toEqual(to)

expect(patch(to, future.undo, true)).toEqual(from)
describe("array option", () => {
test("transform array", () => {
const from = [1, 2]

const to = [1, 2, 3]

const present = diff(from, to)

expect(patch(from, present.do, true)).toEqual(to)

expect(patch(to, present.undo, true)).toEqual(from)
})

test("do not transform object", () => {
const from = { a: 1, b: 1 }

const to = { a: 1, b: 2, c: 3 }

const future = diff(from, to)
const present = diff(from, to)

expect(patch(from, present.do, true)).toEqual(to)

expect(patch(to, present.undo, true)).toEqual(from)
})
})


describe("clean option", () => {
test("deleted properties", () => {
const from = { a: 1, b: 1 }

const to = { a: 1, c: 3 }

const present = diff(from, to)

const past = patch(to, present.undo)
const past_clean = patch(to, present.undo, undefined, true)

const future = patch(from, present.do)
const future_clean = patch(from, present.do, undefined, true)

expect(future).toEqual(to)
expect(future_clean).toEqual(to)

expect('b' in future).toBe(true)
expect('b' in future_clean).toBe(false)

expect(past).toEqual(from)
expect(past_clean).toEqual(from)

expect('c' in past).toBe(true)
expect('c' in past_clean).toBe(false)
})

test("array intact", () => {
const from = [1, 2]

const to = [1, undefined, 3]

const present = diff(from, to)

expect(patch(from, future.do, true)).toEqual(to)
expect(patch(from, present.do, true, true)).toEqual(to)

expect(patch(to, future.undo, true)).toEqual(from)
expect(patch(to, present.undo, true, true)).toEqual(from)
})
})

0 comments on commit 1d00365

Please sign in to comment.