From 238dcaa72a0af2d69d65155f5d018868bf6c3ac2 Mon Sep 17 00:00:00 2001 From: Sylvain Pollet-Villard Date: Sun, 13 Jun 2021 22:14:43 +0200 Subject: [PATCH] add CHECK_ONCE mode on object models constructors --- src/object-model.js | 4 +++- test/array-model.spec.cjs | 1 - test/object-model.spec.cjs | 20 ++++++++++++++++++++ test/umd.html | 16 ++++++++-------- types/index.d.ts | 1 + 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/object-model.js b/src/object-model.js index 11cf697..effc2ec 100644 --- a/src/object-model.js +++ b/src/object-model.js @@ -8,6 +8,7 @@ export const _check = Symbol(), _checked = Symbol(), // used to skip validation at instanciation for perf _original = Symbol(), // used to bypass proxy + CHECK_ONCE = Symbol(), initModel = (def, constructor, parent, init, getTraps, useNew) => { const model = function (val = model.default, mode) { @@ -15,7 +16,7 @@ export const if (init) val = init(val, model, this) if (mode === _checked || check(model, val)) - return getTraps ? proxify(val, getTraps(model)) : val + return getTraps && mode !== CHECK_ONCE ? proxify(val, getTraps(model)) : val } if (parent) extend(model, parent) @@ -387,6 +388,7 @@ Object.assign(Model.prototype, { } }) +Model.CHECK_ONCE = CHECK_ONCE export function BasicModel(def) { return initModel(def, BasicModel) diff --git a/test/array-model.spec.cjs b/test/array-model.spec.cjs index 84eba9e..61bf47e 100644 --- a/test/array-model.spec.cjs +++ b/test/array-model.spec.cjs @@ -16,7 +16,6 @@ QUnit.test("constructor && proto", function (assert) { assert.ok(Arr.definition === Number, "test Array model prop definition"); assert.ok(typeof Arr.assertions === "object", "test Array model prop assertions"); - assert.ok(ArrayModel(undefined) instanceof ArrayModel, "ArrayModel can receive undefined as argument"); }); diff --git a/test/object-model.spec.cjs b/test/object-model.spec.cjs index 727a8bd..cfdf422 100644 --- a/test/object-model.spec.cjs +++ b/test/object-model.spec.cjs @@ -1305,4 +1305,24 @@ QUnit.test("Null-safe object traversal", function (assert) { assert.strictEqual(config.local.time.format, undefined, "null-safe object traversal getter") config.local.time.format = "12h"; assert.strictEqual(config.local.time.format, "12h", "null-safe object traversal setter") +}) + +QUnit.test("Check once mode", function(assert){ + const Address = Model({ city: String, street: { name: String, number: Number }}) + assert.throws(function () { + Address({ city: "Paris", street: { name: null, number: 12 }}, Model.CHECK_ONCE) + }, /TypeError.*expecting street.name to be String/, "check once mode still checks at instanciation") + const a = new Address({ city: "Paris", street: { name: "Champs-Elysees", number: 12 }}, Model.CHECK_ONCE) + a.street.name = null; + assert.strictEqual(a.street.name, null, "check once mode does not check future mutations") + + class Person extends Model({ name: String, age: Number }) { + constructor({ name, age }) { + super({ name, age }, Model.CHECK_ONCE) + } + } + + const john = new Person({ name: "John", age: 32 }) + john.age = "twelve"; + assert.strictEqual(john.age, "twelve", "check once mode does not check future mutations for extended class-based models") }) \ No newline at end of file diff --git a/test/umd.html b/test/umd.html index 9892c7b..ff13c10 100644 --- a/test/umd.html +++ b/test/umd.html @@ -8,14 +8,14 @@ - - - - - - - - + + + + + + + + diff --git a/types/index.d.ts b/types/index.d.ts index 2bdf623..2f6daf6 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -28,6 +28,7 @@ export interface Model { export interface ModelConstructor { (definition: any): ObjectModel; new(definition: any): ObjectModel; + CHECK_ONCE: symbol; } export interface BasicModel extends Model {