mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] observer: protect observed state against changes
This commit is contained in:
+8
-5
@@ -18,6 +18,9 @@ const ModifiedArrayProto = Object.create(ArrayProto);
|
|||||||
for (let method of methodsToPatch) {
|
for (let method of methodsToPatch) {
|
||||||
const initialMethod = ArrayProto[method];
|
const initialMethod = ArrayProto[method];
|
||||||
ModifiedArrayProto[method] = function(...args) {
|
ModifiedArrayProto[method] = function(...args) {
|
||||||
|
if (!this.__observer__.allowMutations) {
|
||||||
|
throw new Error(`Array cannot be changed here")`);
|
||||||
|
}
|
||||||
this.__observer__.notifyChange();
|
this.__observer__.notifyChange();
|
||||||
this.__owl__.rev++;
|
this.__owl__.rev++;
|
||||||
let parent = this;
|
let parent = this;
|
||||||
@@ -122,12 +125,12 @@ export class Observer {
|
|||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
set(newVal) {
|
set(newVal) {
|
||||||
if (!self.allowMutations) {
|
|
||||||
throw new Error(
|
|
||||||
`State cannot be changed outside a mutation! (key: "${key}", val: "${newVal}")`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (newVal !== value) {
|
if (newVal !== value) {
|
||||||
|
if (!self.allowMutations) {
|
||||||
|
throw new Error(
|
||||||
|
`Observed state cannot be changed here! (key: "${key}", val: "${newVal}")`
|
||||||
|
);
|
||||||
|
}
|
||||||
self.unobserve(value);
|
self.unobserve(value);
|
||||||
value = newVal;
|
value = newVal;
|
||||||
self.observe(newVal, obj);
|
self.observe(newVal, obj);
|
||||||
|
|||||||
@@ -279,4 +279,26 @@ describe("observer", () => {
|
|||||||
await nextMicroTick();
|
await nextMicroTick();
|
||||||
expect(observer.notifyCB).toBeCalledTimes(4);
|
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");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user