Skip to content

Commit

Permalink
Merge pull request #31 from creately/feat-merge-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chandika committed Jun 9, 2021
2 parents 4826dad + b96b6c3 commit 0cc13b0
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 34 deletions.
6 changes: 6 additions & 0 deletions changelog.md
@@ -1,3 +1,9 @@
# 2021-05-14 - v2.4.4

- added `mergeChanges` and `unwrap` method to sakota
- replace `deepEqual` with `lodash.isequal`
- added `hasSakota` a public static method

# 2021-03-16 - v2.4.3

- improved change tracking. now if the value of a property is updated with the same value it will not track as a change.
Expand Down
36 changes: 35 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@creately/sakota",
"version": "2.4.3",
"version": "2.4.4",
"description": "Proxies js objects and records all changes made on an object without modifying the object.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand All @@ -15,6 +15,8 @@
"license": "MIT",
"devDependencies": {
"@types/jasmine": "^3.3.9",
"@types/lodash.isequal": "^4.5.5",
"@types/lodash.set": "^4.3.6",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.3.0",
"karma": "^3.1.4",
Expand All @@ -27,5 +29,9 @@
"ts-loader": "^5.3.3",
"typescript": "^3.3.3333",
"webpack": "^4.29.6"
},
"dependencies": {
"lodash.isequal": "^4.5.0",
"lodash.set": "^4.3.2"
}
}
213 changes: 213 additions & 0 deletions src/__tests__/index.spec.ts
Expand Up @@ -623,4 +623,217 @@ describe('Sakota', () => {
expect(console.warn).toHaveBeenCalledTimes(1);
});
});

// Test for mergeChanges
// -----------------------

describe('mergeChanges', () => {
it('should merge given changes into the sakota model', () => {
const source = {
a: 123,
a1: 23,
b: {
x: 234,
y: 345,
},
b1: {
x: 234,
y: 345,
},
c: [{ a: 123 }],
d: [1, 2, 3],
e: [{ a: 123 }],
};

const target = {
a: 234,
a2: 23,
b: {
x: 234,
z: 234,
},
b1: {
x: 234,
},
c: [{ b: 123 }, { a: 234 }],
d: [1, 3],
e: [{ a: 234 }],
};

const wrapped: any = Sakota.create(source);
wrapped.a = 234;
delete wrapped.a1;
wrapped.a2 = 23;
wrapped.b.x = 234;
delete wrapped.b.y;
wrapped.c = [{ b: 123 }, { a: 234 }];
wrapped.b.z = 234;
wrapped.d = [1, 3];
wrapped.e[0].a = 234;
delete wrapped.b1.y;

const wrapped1: any = Sakota.create(source);
wrapped1.__sakota__.mergeChanges(wrapped.__sakota__.getChanges());
expect(wrapped1).toEqual(target as any);
});

it('should merge given changes into the existing sakota changes', () => {
const source = {
a: 123,
a1: 23,
b: {
x: 234,
y: 345,
},
c: [{ a: 123 }],
d: [1, 2, 3],
e: [{ a: 123 }, { b: 123 }],
};

const target = {
a: 234,
a2: 23,
b: {
x: 234,
z: 234,
},
c: [{ b: 123 }, { a: 234 }],
d: [1, 3],
e: [{ a: 234 }, { b: 345 }],
};

const wrapped: any = Sakota.create(source);
wrapped.a = 234;
delete wrapped.a1;
wrapped.a2 = 23;
wrapped.b.x = 234;
delete wrapped.b.y;
wrapped.c = [{ b: 123 }, { a: 234 }];

const wrapped1: any = Sakota.create(source);
wrapped1.b.z = 234;
wrapped1.d = [1, 3];
wrapped1.e[0].a = 234;
wrapped1.e[1].b = 345;

wrapped.__sakota__.mergeChanges(wrapped1.__sakota__.getChanges());
expect(wrapped).toEqual(target as any);
});
});

// Test for unwrap
// -----------------------
describe('unwrap', () => {
it('should create a copy of the object removing sakota', () => {
const obj: any = {
a: 123,
b: {
c: 234,
},
};
const wrapped = Sakota.create(freeze(obj));
wrapped.a = 345;
wrapped.a1 = 234;
wrapped.b.c = 2345;

const expected = {
a: 345,
a1: 234,
b: {
c: 2345,
},
};

const unwrapped = wrapped.__sakota__.unwrap();
expect(unwrapped).toEqual(expected);
expect(unwrapped === obj).toBeFalsy();
expect(Sakota.hasSakota(unwrapped)).toBeFalsy();
});

it('should apply the changes to the target object if unwrapped in place', () => {
const obj: any = {
a: 123,
b: {
c: 234,
},
};
const wrapped = Sakota.create(obj);
wrapped.a = 345;
wrapped.a1 = 234;
wrapped.b.c = 2345;

const expected = {
a: 345,
a1: 234,
b: {
c: 2345,
},
};

const unwrapped = wrapped.__sakota__.unwrap(true);
expect(unwrapped === obj).toBeTruthy();
expect(obj).toEqual(expected);
expect(Sakota.hasSakota(unwrapped)).toBeFalsy();
});

it('should remove Sakota wrapper around array props', () => {
const obj: any = {
a: [{ b: 234 }],
};
const wrapped = Sakota.create(freeze(obj));
wrapped.a[0].b = 345;
const expected = {
a: [{ b: 345 }],
};

const unwrapped = wrapped.__sakota__.unwrap();
expect(unwrapped).toEqual(expected);
expect(unwrapped === obj).toBeFalsy();
expect(Sakota.hasSakota(unwrapped)).toBeFalsy();
});

it('should return the same object as target', () => {
const obj: any = {
a: [{ b: 234 }],
};
const wrapped = Sakota.create(obj);
delete obj.a[0].b;

const unwrapped = wrapped.__sakota__.unwrap(true);
expect(unwrapped === obj).toBeTruthy();
expect(unwrapped).toEqual({ a: [{}] });
expect(Sakota.hasSakota(unwrapped)).toBeFalsy();
});
});

describe('mergeChanges + unwrap', () => {
it('should handle multiple changes properly', () => {
const source = {
a: 123,
};
const target = {
a: 234,
b: {
c: 345,
},
c: {
d: 456,
},
};
const sakotaWrapped: any = Sakota.create(source);
sakotaWrapped.a = 234;
sakotaWrapped.b = {
c: 234,
d: 345,
};
const sakotaWrapped1 = Sakota.create(sakotaWrapped.__sakota__.unwrap());
sakotaWrapped1.b.c = 345;
delete sakotaWrapped1.b.d;
sakotaWrapped1.c = { d: 234 };
sakotaWrapped1.c.d = 456;
sakotaWrapped.__sakota__.mergeChanges(sakotaWrapped1.__sakota__.getChanges());
expect(sakotaWrapped.__sakota__.unwrap()).toEqual(sakotaWrapped);
expect(sakotaWrapped).toEqual(target);
});
});
});
26 changes: 0 additions & 26 deletions src/deep-equal.ts

This file was deleted.

0 comments on commit 0cc13b0

Please sign in to comment.