[FIX] observer: protect observed state against changes

This commit is contained in:
Géry Debongnie
2019-04-17 16:55:57 +02:00
parent d07f396578
commit 4b30d0b412
2 changed files with 30 additions and 5 deletions
+8 -5
View File
@@ -18,6 +18,9 @@ const ModifiedArrayProto = Object.create(ArrayProto);
for (let method of methodsToPatch) {
const initialMethod = ArrayProto[method];
ModifiedArrayProto[method] = function(...args) {
if (!this.__observer__.allowMutations) {
throw new Error(`Array cannot be changed here")`);
}
this.__observer__.notifyChange();
this.__owl__.rev++;
let parent = this;
@@ -122,12 +125,12 @@ export class Observer {
return value;
},
set(newVal) {
if (!self.allowMutations) {
throw new Error(
`State cannot be changed outside a mutation! (key: "${key}", val: "${newVal}")`
);
}
if (newVal !== value) {
if (!self.allowMutations) {
throw new Error(
`Observed state cannot be changed here! (key: "${key}", val: "${newVal}")`
);
}
self.unobserve(value);
value = newVal;
self.observe(newVal, obj);
+22
View File
@@ -279,4 +279,26 @@ describe("observer", () => {
await nextMicroTick();
expect(observer.notifyCB).toBeCalledTimes(4);
});
test("throw error when state is mutated in object if allowMutation=false", async () => {
const observer = new Observer();
observer.allowMutations = false;
const obj: any = { a: 1 };
observer.observe(obj);
expect(() => {
obj.a = 2;
}).toThrow('Observed state cannot be changed here! (key: "a", val: "2")');
});
test("throw error when state is mutated in array if allowMutation=false", async () => {
const observer = new Observer();
observer.allowMutations = false;
const obj: any = { a: [1] };
observer.observe(obj);
expect(() => {
obj.a.push(2);
}).toThrow("Array cannot be changed here");
});
});