diff --git a/__tests__/__snapshots__/base.js.snap b/__tests__/__snapshots__/base.js.snap index c47baf80..a2a4268c 100644 --- a/__tests__/__snapshots__/base.js.snap +++ b/__tests__/__snapshots__/base.js.snap @@ -22,6 +22,8 @@ exports[`base functionality - es5 (autofreeze) set drafts revokes sets 1`] = `"[ exports[`base functionality - es5 (autofreeze) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - es5 (autofreeze) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - es5 (autofreeze) throws when the draft is modified and another object is returned 1`] = `"[Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."`; exports[`base functionality - es5 (autofreeze)(patch listener) async recipe function works with rejected promises 1`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {\\"a\\":0,\\"b\\":1}"`; @@ -46,6 +48,8 @@ exports[`base functionality - es5 (autofreeze)(patch listener) set drafts revoke exports[`base functionality - es5 (autofreeze)(patch listener) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - es5 (autofreeze)(patch listener) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - es5 (autofreeze)(patch listener) throws when the draft is modified and another object is returned 1`] = `"[Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."`; exports[`base functionality - es5 (no freeze) async recipe function works with rejected promises 1`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {\\"a\\":0,\\"b\\":1}"`; @@ -70,6 +74,8 @@ exports[`base functionality - es5 (no freeze) set drafts revokes sets 1`] = `"[I exports[`base functionality - es5 (no freeze) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - es5 (no freeze) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - es5 (no freeze) throws when the draft is modified and another object is returned 1`] = `"[Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."`; exports[`base functionality - es5 (patch listener) async recipe function works with rejected promises 1`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {\\"a\\":0,\\"b\\":1}"`; @@ -94,6 +100,8 @@ exports[`base functionality - es5 (patch listener) set drafts revokes sets 1`] = exports[`base functionality - es5 (patch listener) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - es5 (patch listener) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - es5 (patch listener) throws when the draft is modified and another object is returned 1`] = `"[Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."`; exports[`base functionality - proxy (autofreeze) array drafts throws when a non-numeric property is added 1`] = `"[Immer] Immer only supports setting array indices and the 'length' property"`; @@ -130,6 +138,8 @@ exports[`base functionality - proxy (autofreeze) set drafts revokes sets 1`] = ` exports[`base functionality - proxy (autofreeze) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - proxy (autofreeze) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - proxy (autofreeze) throws when Object.defineProperty() is used on drafts 1`] = `"[Immer] Object.defineProperty() cannot be used on an Immer draft"`; exports[`base functionality - proxy (autofreeze) throws when Object.setPrototypeOf() is used on a draft 1`] = `"[Immer] Object.setPrototypeOf() cannot be used on an Immer draft"`; @@ -170,6 +180,8 @@ exports[`base functionality - proxy (autofreeze)(patch listener) set drafts revo exports[`base functionality - proxy (autofreeze)(patch listener) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - proxy (autofreeze)(patch listener) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - proxy (autofreeze)(patch listener) throws when Object.defineProperty() is used on drafts 1`] = `"[Immer] Object.defineProperty() cannot be used on an Immer draft"`; exports[`base functionality - proxy (autofreeze)(patch listener) throws when Object.setPrototypeOf() is used on a draft 1`] = `"[Immer] Object.setPrototypeOf() cannot be used on an Immer draft"`; @@ -210,6 +222,8 @@ exports[`base functionality - proxy (no freeze) set drafts revokes sets 1`] = `" exports[`base functionality - proxy (no freeze) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - proxy (no freeze) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - proxy (no freeze) throws when Object.defineProperty() is used on drafts 1`] = `"[Immer] Object.defineProperty() cannot be used on an Immer draft"`; exports[`base functionality - proxy (no freeze) throws when Object.setPrototypeOf() is used on a draft 1`] = `"[Immer] Object.setPrototypeOf() cannot be used on an Immer draft"`; @@ -250,6 +264,8 @@ exports[`base functionality - proxy (patch listener) set drafts revokes sets 1`] exports[`base functionality - proxy (patch listener) set drafts revokes sets 2`] = `"[Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}"`; +exports[`base functionality - proxy (patch listener) throws on non-immerable instance 1`] = `"[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'"`; + exports[`base functionality - proxy (patch listener) throws when Object.defineProperty() is used on drafts 1`] = `"[Immer] Object.defineProperty() cannot be used on an Immer draft"`; exports[`base functionality - proxy (patch listener) throws when Object.setPrototypeOf() is used on a draft 1`] = `"[Immer] Object.setPrototypeOf() cannot be used on an Immer draft"`; diff --git a/__tests__/base.js b/__tests__/base.js index 3382ffa5..acce0871 100644 --- a/__tests__/base.js +++ b/__tests__/base.js @@ -883,6 +883,34 @@ function runBaseTest(name, useProxies, autoFreeze, useListener) { }) }) + it("throws on non-immerable instance", () => { + const Pet = class { + constructor(name) { + this.name = name + } + } + const baseState = new Pet("Rover") + expect(() => { + produce(baseState, draft => { + draft.name = "Rex" + }) + }).toThrowErrorMatchingSnapshot() + }) + + it("throws on non-immerable class-instance property of plain object", () => { + const Pet = class { + constructor(name) { + this.name = name + } + } + const baseState = {pet: new Pet("Rover")} + expect(() => { + produce(baseState, draft => { + draft.pet.name = "Rex" + }) + }).toThrowErrorMatchingSnapshot() + }) + it("supports `immerable` symbol on constructor", () => { class One {} One[immerable] = true