diff --git a/src/Model/index.js b/src/Model/index.js index 29596fa00..c02bcabfd 100644 --- a/src/Model/index.js +++ b/src/Model/index.js @@ -123,6 +123,10 @@ export default class Model { * @see {Database#batch} */ prepareUpdate(recordUpdater: (this) => void = noop): this { + this.__debugInvariant( + !this._preparedState, + `Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`, + ) invariant( !this._preparedState, `Cannot update a record with pending changes (${this.__debugName})`, @@ -182,6 +186,7 @@ export default class Model { * @see {Database#batch} */ prepareMarkAsDeleted(): this { + this.__debugInvariant(!this._preparedState, `Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`) invariant( !this._preparedState, `Cannot mark a record with pending changes as deleted (${this.__debugName})`, @@ -217,6 +222,7 @@ export default class Model { * @see {Database#batch} */ prepareDestroyPermanently(): this { + this.__debugInvariant(!this._preparedState, `Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`) invariant( !this._preparedState, `Cannot destroy permanently record with pending changes (${this.__debugName})`, @@ -485,4 +491,10 @@ export default class Model { logger.debug(`${debugName}: ${this.__debugName}`) } } + + __debugInvariant(condition: boolean, errorMessage: string): void { + if (this.db.experimentalIsVerbose && !condition) { + logger.debug(errorMessage) + } + } } diff --git a/src/Model/test.js b/src/Model/test.js index 33c3d7525..1714a35aa 100644 --- a/src/Model/test.js +++ b/src/Model/test.js @@ -10,6 +10,7 @@ import { field, date, readonly } from '../decorators' import { noop } from '../utils/fp' import sortBy from '../utils/fp/sortBy' import { sanitizedRaw } from '../RawRecord' +import { logger } from '../utils/common' import Model from './index' import { fetchDescendants } from './helpers' @@ -419,6 +420,9 @@ describe('Safety features', () => { }) it('disallows operations on uncommited records', async () => { const db = makeDatabase() + const spy = jest.spyOn(logger, 'debug') + db.experimentalIsVerbose = true + db.adapter.batch = jest.fn() await db.write(async () => { const model = MockModel._prepareCreate(db.get('mock'), () => {}) @@ -428,8 +432,12 @@ describe('Safety features', () => { model.update(() => {}), 'with pending changes', ) + expect(spy).toHaveBeenCalledWith(expect.stringMatching('Model MockModel, Raw Data: {')) + await expectToRejectWithMessage(model.markAsDeleted(), 'with pending changes') + await expectToRejectWithMessage(model.destroyPermanently(), 'with pending changes') + expect(() => model.observe()).toThrow('uncommitted') await db.batch(model) })