From 9d04dbcff8da4a1fbc37c6a1ac4904d82836de22 Mon Sep 17 00:00:00 2001 From: b-ma Date: Fri, 15 Dec 2023 12:50:46 +0100 Subject: [PATCH] feat: add utilities to state collection --- src/common/BaseSharedState.js | 8 ++-- src/common/BaseSharedStateCollection.js | 55 ++++++++++++++++++---- tests/states/StateCollection.spec.js | 61 +++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/src/common/BaseSharedState.js b/src/common/BaseSharedState.js index 5ff643ad..0dbef22a 100644 --- a/src/common/BaseSharedState.js +++ b/src/common/BaseSharedState.js @@ -437,12 +437,12 @@ ${JSON.stringify(initValues, null, 2)}`); } /** - * Get the schema from which the state has been created. + * Definition of schema from which the state has been created. * - * @param {string} [name=null] - If given, returns only the definition corresponding - * to the given param name. + * @param {string} [name=null] - If given, returns only the definition + * corresponding to the given param name. * @throws Throws if `name` does not correspond to an existing field - * of the state. + * of the schema. * @return {object} * @example * const schema = state.getSchema(); diff --git a/src/common/BaseSharedStateCollection.js b/src/common/BaseSharedStateCollection.js index 812bd2ca..cdaf64d6 100644 --- a/src/common/BaseSharedStateCollection.js +++ b/src/common/BaseSharedStateCollection.js @@ -62,19 +62,38 @@ class BaseSharedStateCollection { } /** - * Detach from the collection, i.e. detach all underlying shared states. - * @type {number} + * Name of the schema from which the collection has been created. + * @type {String} + * @readonly */ - async detach() { - this._unobserve(); - this._onUpdateCallbacks.clear(); - - await this._controller.delete(); + get schemaName() { + return this._controller.schemaName; + } - const promises = this._states.map(state => state.detach()); - await Promise.all(promises); + /** + * Definition of schema from which the collection has been created. + * + * @param {string} [name=null] - If given, returns only the definition + * corresponding to the given param name. + * @throws Throws if `name` does not correspond to an existing field + * of the schema. + * @return {object} + * @example + * const schema = collection.getSchema(); + */ + getSchema(name = null) { + return this._controller.getSchema(name); + } - this._onDetachCallbacks.clear(); + /** + * Get the default values as declared in the schema. + * + * @return {object} + * @example + * const defaults = state.getDefaults(); + */ + getDefaults() { + return this._controller.getDefaults(); } /** @@ -169,6 +188,22 @@ class BaseSharedStateCollection { return () => this._onDetachCallbacks.delete(callback); } + /** + * Detach from the collection, i.e. detach all underlying shared states. + * @type {number} + */ + async detach() { + this._unobserve(); + this._onUpdateCallbacks.clear(); + + await this._controller.delete(); + + const promises = this._states.map(state => state.detach()); + await Promise.all(promises); + + this._onDetachCallbacks.clear(); + } + /** * Execute the given function once for each states of the collection (see `Array.forEach`). * diff --git a/tests/states/StateCollection.spec.js b/tests/states/StateCollection.spec.js index d520faee..78be1f06 100644 --- a/tests/states/StateCollection.spec.js +++ b/tests/states/StateCollection.spec.js @@ -156,6 +156,67 @@ describe(`# SharedStateCollection`, () => { }); }); + describe(`## schemaName`, () => { + it(`should return the schema name`, async () => { + const collection = await clients[0].stateManager.getCollection('a'); + const schemaName = collection.schemaName; + assert.equal(schemaName, 'a') + + await collection.detach(); + }); + }); + + describe(`## getSchema()`, () => { + it(`should return the schema name`, async () => { + const collection = await clients[0].stateManager.getCollection('a'); + const schema = collection.getSchema(); + const expected = { + "bool": { + "default": false, + "event": false, + "filterChange": true, + "immediate": false, + "initValue": false, + "metas": {}, + "nullable": false, + "type": "boolean", + }, + "int": { + "default": 0, + "event": false, + "filterChange": true, + "immediate": false, + "initValue": 0, + "max": 100, + "metas": {}, + "min": 0, + "nullable": false, + "step": 1, + "type": "integer", + }, + }; + + assert.deepEqual(schema, expected); + + await collection.detach(); + }); + }); + + describe(`## getDefaults()`, () => { + it(`should return the schema name`, async () => { + const collection = await clients[0].stateManager.getCollection('a'); + const defaults = collection.getDefaults(); + const expected = { + bool: false, + int: 0, + }; + + assert.deepEqual(defaults, expected); + + await collection.detach(); + }); + }); + describe(`## set(updates, context = null)`, () => { it(`should properly progate updates`, async () => { const state0 = await clients[0].stateManager.create('a');