diff --git a/package.json b/package.json index 6ce63148..75385bbe 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "scripts": { "doc": "rm -Rf docs && jsdoc -c .jsdoc.json --verbose && cp -R assets docs/", "lint": "npx eslint src", - "test": "mocha", + "test": "npx mocha", + "test:all": "npx mocha tests/*/*.spec.js", "toc": "markdown-toc -i README.md", "types": "rm -Rf types && tsc", "preversion": "npm run toc && git commit -am 'docs: build' --allow-empty", diff --git a/tests/Context.spec.js b/tests/contexts/Context.spec.js similarity index 99% rename from tests/Context.spec.js rename to tests/contexts/Context.spec.js index 904c8003..65efa0a1 100644 --- a/tests/Context.spec.js +++ b/tests/contexts/Context.spec.js @@ -1,9 +1,9 @@ import { assert } from 'chai'; -import { Server, Context as ServerContext } from '../src/server/index.js'; -import { Client, Context as ClientContext } from '../src/client/index.js'; +import { Server, Context as ServerContext } from '../../src/server/index.js'; +import { Client, Context as ClientContext } from '../../src/client/index.js'; -import config from './utils/config.js'; +import config from '../utils/config.js'; describe('# Context', () => { describe(`## contructor()`, () => { diff --git a/tests/Client.spec.js b/tests/essentials/Client.spec.js similarity index 97% rename from tests/Client.spec.js rename to tests/essentials/Client.spec.js index e89c0e7f..d4ae1fc1 100644 --- a/tests/Client.spec.js +++ b/tests/essentials/Client.spec.js @@ -1,10 +1,10 @@ import { assert } from 'chai'; -import { Server, Context as ServerContext } from '../src/server/index.js'; -import { Client, Context as ClientContext } from '../src/client/index.js'; +import { Server, Context as ServerContext } from '../../src/server/index.js'; +import { Client, Context as ClientContext } from '../../src/client/index.js'; -import pluginDelayClient from './utils/PluginDelayClient.js'; -import config from './utils/config.js'; +import pluginDelayClient from '../utils/PluginDelayClient.js'; +import config from '../utils/config.js'; describe('# client::Client', () => { describe(`## new Client(config)`, () => { diff --git a/tests/Server.spec.js b/tests/essentials/Server.spec.js similarity index 99% rename from tests/Server.spec.js rename to tests/essentials/Server.spec.js index 42049184..91b4cce4 100644 --- a/tests/Server.spec.js +++ b/tests/essentials/Server.spec.js @@ -7,10 +7,10 @@ import dotenv from 'dotenv'; import merge from 'lodash.merge'; import tcpp from 'tcp-ping'; -import { Server, Context as ServerContext } from '../src/server/index.js'; -import { Client } from '../src/client/index.js'; +import { Server, Context as ServerContext } from '../../src/server/index.js'; +import { Client } from '../../src/client/index.js'; -import config from './utils/config.js'; +import config from '../utils/config.js'; const __filename = url.fileURLToPath(import.meta.url); const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); diff --git a/tests/plugins/Plugin.spec.js b/tests/plugins/Plugin.spec.js index c03c66ab..6f1b08d6 100644 --- a/tests/plugins/Plugin.spec.js +++ b/tests/plugins/Plugin.spec.js @@ -22,8 +22,8 @@ const config = { }, }; -describe('Plugin', () => { - describe(`# new Plugin(server|client, options)`, () => { +describe('# Plugin', () => { + describe(`## constructor(server|client, options)`, () => { it(`id and type should be readonly`, async () => { const server = new Server(config); server.pluginManager.register('delay', pluginDelayServer, { @@ -59,7 +59,7 @@ describe('Plugin', () => { }); }); - describe(`# [client] Plugin.state propagation`, () => { + describe(`## [client] Plugin.state propagation`, () => { it(`should propagate its inner state`, async () => { const server = new Server(config); server.pluginManager.register('stateful', (ServerPlugin) => class StatefulPlugin extends ServerPlugin {}); @@ -135,7 +135,7 @@ describe('Plugin', () => { }); }); - describe(`# [client|server] Require plugin within plugin`, () => { + describe(`## [client|server] Require plugin within plugin`, () => { it(`should work`, async function() { this.timeout(2000); @@ -214,7 +214,7 @@ describe('Plugin', () => { }); }); - describe(`# [server] Plugin.state propagation`, () => { + describe(`## [server] Plugin.state propagation`, () => { it('PluginManager should properly propagate plugin state', async () => { const server = new Server(config); server.pluginManager.register('stateful', (ClientPlugin) => { diff --git a/tests/plugins/client.PluginManager.spec.js b/tests/plugins/client.PluginManager.spec.js index 08bd75d6..2fe821a7 100644 --- a/tests/plugins/client.PluginManager.spec.js +++ b/tests/plugins/client.PluginManager.spec.js @@ -9,7 +9,7 @@ import pluginDelayServer from '../utils/PluginDelayServer.js'; import pluginDelayClient from '../utils/PluginDelayClient.js'; import config from '../utils/config.js'; -describe(`client::PluginManager`, () => { +describe(`# PluginManagerClient`, () => { let server = null; before(async function() { @@ -29,7 +29,7 @@ describe(`client::PluginManager`, () => { await server.stop(); }); - describe(`# (protected) new PluginManager(client)`, () => { + describe(`## [private] constructor(client)`, () => { it(`should throw if argument is not instance of Client`, () => { let errored = false; try { @@ -42,7 +42,7 @@ describe(`client::PluginManager`, () => { }); }); - describe(`# register(id, pluginFactory)`, () => { + describe(`## register(id, pluginFactory)`, () => { let client; beforeEach(() => { @@ -140,7 +140,7 @@ describe(`client::PluginManager`, () => { }); }); - describe(`# (protected) await pluginManager.init()`, () => { + describe(`## [private] async init()`, () => { it(`should throw if started twice`, async () => { const client = new Client({ role: 'test', ...config }); await client.init(); // run pluginManager.init() @@ -156,7 +156,7 @@ describe(`client::PluginManager`, () => { }); }); - describe(`# await pluginManager.get(id)`, () => { + describe(`## async get(id)`, () => { it(`should throw if called before server.init()`, async () => { const client = new Client({ role: 'test', ...config }); client.pluginManager.register('delay', pluginDelayClient, { delayTime: 100 }); @@ -246,7 +246,7 @@ describe(`client::PluginManager`, () => { // }); }); - describe(`# pluginManager.onStateChange((states, updatedPlugin) => {})`, () => { + describe(`## onStateChange((states, updatedPlugin) => {})`, () => { it(`should properly propagate statuses`, async function() { this.timeout(3 * 1000); @@ -302,7 +302,18 @@ describe(`client::PluginManager`, () => { }); }); - describe(`# plugin initialization lifecycle`, () => { + describe(`## getRegisteredPlugins()`, () => { + it(`should return the list of registered plugins`, () => { + const client = new Client({ role: 'test', ...config }); + client.pluginManager.register('delay-1', pluginDelayClient, { delayTime: 0 }); + client.pluginManager.register('delay-2', pluginDelayClient, { delayTime: 0 }); + + const registeredPlugins = client.pluginManager.getRegisteredPlugins(); + assert.deepEqual(['delay-1', 'delay-2'], registeredPlugins) + }); + }); + + describe(`## [lifecyle] plugin initialization`, () => { it(`client should start if no plugins registered`, async function() { const client = new Client({ role: 'test', ...config }); await client.init(); @@ -502,15 +513,4 @@ describe(`client::PluginManager`, () => { } }); }); - - describe(`# pluginManager.getRegisteredPlugins()`, () => { - it(`should return the list of registered plugins`, () => { - const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('delay-1', pluginDelayClient, { delayTime: 0 }); - client.pluginManager.register('delay-2', pluginDelayClient, { delayTime: 0 }); - - const registeredPlugins = client.pluginManager.getRegisteredPlugins(); - assert.deepEqual(['delay-1', 'delay-2'], registeredPlugins) - }); - }); }); diff --git a/tests/plugins/server.PluginManager.spec.js b/tests/plugins/server.PluginManager.spec.js index 4c862c5d..357f2bff 100644 --- a/tests/plugins/server.PluginManager.spec.js +++ b/tests/plugins/server.PluginManager.spec.js @@ -8,8 +8,8 @@ import PluginManager from '../../src/server/PluginManager.js'; import pluginDelayServer from '../utils/PluginDelayServer.js'; import config from '../utils/config.js'; -describe(`server::PluginManager`, () => { - describe(`# (protected) new PluginManager(server)`, () => { +describe(`# PluginManagerServer`, () => { + describe(`## [private] constructor(server)`, () => { it(`should throw if argument is not instance of Server`, () => { let errored = false; try { @@ -22,7 +22,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# register(id, pluginFactory)`, () => { + describe(`## register(id, pluginFactory)`, () => { let server; beforeEach(() => { @@ -121,7 +121,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# [protected] await pluginManager.init()`, () => { + describe(`## [private] async init()`, () => { it(`should throw if started twice`, async () => { const server = new Server(config); await server.init(); // run pluginManager.start() @@ -137,7 +137,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# await pluginManager.get(id)`, () => { + describe(`## async get(id)`, () => { it(`should throw if called before server.init()`, async () => { const server = new Server(config); server.pluginManager.register('delay', pluginDelayServer, { delayTime: 100 }); @@ -229,7 +229,7 @@ describe(`server::PluginManager`, () => { // }); }); - describe(`# pluginManager.onStateChange((plugins, updatedPlugin) => {})`, () => { + describe(`## onStateChange((plugins, updatedPlugin) => {})`, () => { it(`should properly propagate statuses`, async function() { this.timeout(3 * 1000); @@ -287,7 +287,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# [protected] pluginManager.addClient(client)`, () => { + describe(`## [private] addClient(client)`, () => { it(`should properly add clients to Plugin`, async () => { let addClientCalled = false; @@ -360,7 +360,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# [protected] pluginManager.removeClient(client)`, () => { + describe(`## [private] removeClient(client)`, () => { it(`should be called on client.stop()`, async () => { let removeClientCalled = false; @@ -467,7 +467,7 @@ describe(`server::PluginManager`, () => { }); }); - describe(`# plugin initialization lifecycle`, () => { + describe(`## [lifecycle] plugin initialization`, () => { it(`server should start if no plugins registered`, async function() { const server = new Server(config); await server.init(); diff --git a/tests/states/SharedStateCollection.spec.js b/tests/states/SharedStateCollection.spec.js index 06d0737d..8b73b184 100644 --- a/tests/states/SharedStateCollection.spec.js +++ b/tests/states/SharedStateCollection.spec.js @@ -7,7 +7,7 @@ import { Client } from '../../src/client/index.js'; import config from '../utils/config.js'; import { a, b } from '../utils/schemas.js'; -describe(`await getCollection()`, () => { +describe(`# SharedStateCollection`, () => { let server; let clients = []; diff --git a/tests/states/schema-options.spec.js b/tests/states/schema-options.spec.js index bb199ef0..2a3b1f46 100644 --- a/tests/states/schema-options.spec.js +++ b/tests/states/schema-options.spec.js @@ -11,7 +11,7 @@ import { import config from '../utils/config.js'; import { a } from '../utils/schemas.js'; -describe('# schema options', () => { +describe('# SharedState - schema options', () => { let server; let client1; let client2; @@ -40,418 +40,420 @@ describe('# schema options', () => { server.stop(); }); - it('default options [event=false, filterChange=true, immediate=false] should behave correctly', async () => { - const a = await server.stateManager.create('a'); - let counter = 0; - - a.onUpdate(updates => { - try { - assert.deepEqual(updates, { bool: true }); - counter += 1; - } catch(err) { - reject(err); - } - }); - - await a.set({ bool: true }); - await a.set({ bool: true }); - await a.set({ bool: true }); - - await new Promise(resolve => setTimeout(resolve, 200)); - assert.equal(counter, 1); - - await a.delete(); - }); - - it('[event=true] should behave correctly', async () => { - return new Promise(async (resolve, reject) => { - server.stateManager.registerSchema('event-test', { - value: { - type: 'boolean', - event: true, - } - }); - const state = await server.stateManager.create('event-test'); - const numEvents = 5; + describe('## Behavioral options', () => { + it('default options [event=false, filterChange=true, immediate=false] should behave correctly', async () => { + const a = await server.stateManager.create('a'); let counter = 0; - assert.equal(state.get('value'), null); - - // should be able to read if called from a subscription - function readInSubscribe() { - assert.equal(state.get('value'), true); - } - - state.onUpdate(updates => { + a.onUpdate(updates => { try { - assert.deepEqual(updates, { value: true }); - readInSubscribe(); + assert.deepEqual(updates, { bool: true }); counter += 1; } catch(err) { reject(err); } }); - let updates; - for (let i = 0; i < numEvents; i++) { - updates = await state.set({ value: true }); - // returned updates object has the proper value - assert.deepEqual(updates, { value: true }); - // but value is null if read from state - assert.equal(state.get('value'), null); - updates = null; - } + await a.set({ bool: true }); + await a.set({ bool: true }); + await a.set({ bool: true }); - // client-side - const clientState = await client1.stateManager.attach('event-test'); - assert.equal(clientState.get('value'), null); + await new Promise(resolve => setTimeout(resolve, 200)); + assert.equal(counter, 1); - setTimeout(() => { - assert.equal(counter, numEvents); - resolve(); - }, 100); + await a.delete(); }); - }); - it('[filterChange=false] should behave correctly', async () => { - return new Promise(async (resolve, reject) => { - server.stateManager.registerSchema('filter-change-test', { - value: { - type: 'boolean', - default: true, - filterChange: false, + it('[event=true] should behave correctly', async () => { + return new Promise(async (resolve, reject) => { + server.stateManager.registerSchema('event-test', { + value: { + type: 'boolean', + event: true, + } + }); + const state = await server.stateManager.create('event-test'); + const numEvents = 5; + let counter = 0; + + assert.equal(state.get('value'), null); + + // should be able to read if called from a subscription + function readInSubscribe() { + assert.equal(state.get('value'), true); } - }); - const state = await server.stateManager.create('filter-change-test'); - const numCalls = 5; - let counter = 0; - state.onUpdate(updates => { - try { + state.onUpdate(updates => { + try { + assert.deepEqual(updates, { value: true }); + readInSubscribe(); + counter += 1; + } catch(err) { + reject(err); + } + }); + + let updates; + for (let i = 0; i < numEvents; i++) { + updates = await state.set({ value: true }); + // returned updates object has the proper value assert.deepEqual(updates, { value: true }); - counter += 1; - } catch(err) { - reject(err); + // but value is null if read from state + assert.equal(state.get('value'), null); + updates = null; } - }); - - for (let i = 0; i < numCalls; i++) { - await state.set({ value: true }); - // contrary to `event` the value is still stored into the state - assert.equal(state.get('value'), true); - } + // client-side + const clientState = await client1.stateManager.attach('event-test'); + assert.equal(clientState.get('value'), null); - setTimeout(() => { - // try { - assert.equal(counter, numCalls); + setTimeout(() => { + assert.equal(counter, numEvents); resolve(); - // } catch(err) { - // reject(err); - // } - }, 100); + }, 100); + }); }); - }); - it('[immediate=true] (w/ [event=false, filterChange=true]) should behave correctly', async () => { - return new Promise(async (resolve, reject) => { - server.stateManager.registerSchema('immediate-test', { - immediateValue: { - type: 'integer', - default: 0, - immediate: true, - }, - normalValue: { - type: 'integer', - default: 0, - } - }); + it('[filterChange=false] should behave correctly', async () => { + return new Promise(async (resolve, reject) => { + server.stateManager.registerSchema('filter-change-test', { + value: { + type: 'boolean', + default: true, + filterChange: false, + } + }); + const state = await server.stateManager.create('filter-change-test'); + const numCalls = 5; + let counter = 0; - let subscribeCalledBeforeHook = false; + state.onUpdate(updates => { + try { + assert.deepEqual(updates, { value: true }); + counter += 1; + } catch(err) { + reject(err); + } + }); - server.stateManager.registerUpdateHook('immediate-test', (updates, currentValues) => { - try { - // assert.fail(); - assert.isTrue(subscribeCalledBeforeHook, 'subscribe should be called before hook'); - } catch(err) { - reject(err); + for (let i = 0; i < numCalls; i++) { + await state.set({ value: true }); + // contrary to `event` the value is still stored into the state + assert.equal(state.get('value'), true); } - if (updates.immediateValue === 2) { - return { - ...updates, - immediateValue: 3, - } - } - return updates; + setTimeout(() => { + // try { + assert.equal(counter, numCalls); + resolve(); + // } catch(err) { + // reject(err); + // } + }, 100); }); + }); - const state = await client1.stateManager.create('immediate-test'); - const attached = await client2.stateManager.attach('immediate-test'); + it('[immediate=true] (w/ [event=false, filterChange=true]) should behave correctly', async () => { + return new Promise(async (resolve, reject) => { + server.stateManager.registerSchema('immediate-test', { + immediateValue: { + type: 'integer', + default: 0, + immediate: true, + }, + normalValue: { + type: 'integer', + default: 0, + } + }); - const statePromise = new Promise((resolve) => { - let call = 0; + let subscribeCalledBeforeHook = false; - state.onUpdate(updates => { - if (call === 0) { - subscribeCalledBeforeHook = true; + server.stateManager.registerUpdateHook('immediate-test', (updates, currentValues) => { + try { + // assert.fail(); + assert.isTrue(subscribeCalledBeforeHook, 'subscribe should be called before hook'); + } catch(err) { + reject(err); + } - try { - assert.deepEqual(updates, { immediateValue: 1 }); - } catch(err) { - reject(err); - } - } else if (call === 1) { - try { - assert.deepEqual(updates, { normalValue: 10 }); - resolve(); - } catch(err) { - reject(err); - } - } else if (call === 2) { - // call from immedaite - try { - assert.deepEqual(updates, { immediateValue: 2 }); - resolve(); - } catch(err) { - reject(err); - } - } else if (call === 3) { - // call from server override - try { - assert.deepEqual(updates, { immediateValue: 3 }); - resolve(); - } catch(err) { - reject(err); + if (updates.immediateValue === 2) { + return { + ...updates, + immediateValue: 3, } - } else { - reject('creator: something went wrong'); } - call += 1; + return updates; }); - }); - // should be notified normally if not initiator of the update - const attachedPromise = new Promise((resolve) => { - let call = 0; - - attached.onUpdate(updates => { - if (call === 0) { - try { - assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); - resolve(); - } catch(err) { - reject(err); - } - } else if (call === 1) { - try { - assert.deepEqual(updates, { immediateValue: 3 }); - resolve(); - } catch(err) { - reject(err); + const state = await client1.stateManager.create('immediate-test'); + const attached = await client2.stateManager.attach('immediate-test'); + + const statePromise = new Promise((resolve) => { + let call = 0; + + state.onUpdate(updates => { + if (call === 0) { + subscribeCalledBeforeHook = true; + + try { + assert.deepEqual(updates, { immediateValue: 1 }); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { normalValue: 10 }); + resolve(); + } catch(err) { + reject(err); + } + } else if (call === 2) { + // call from immedaite + try { + assert.deepEqual(updates, { immediateValue: 2 }); + resolve(); + } catch(err) { + reject(err); + } + } else if (call === 3) { + // call from server override + try { + assert.deepEqual(updates, { immediateValue: 3 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('creator: something went wrong'); } - } else { - reject('attached: something went wrong'); - } - call += 1; + call += 1; + }); }); - }); - // invalid value - try { - await state.set({ immediateValue: 1, normalValue: 10 }); - // this should not trigger anything - await state.set({ immediateValue: 1, normalValue: 10 }); - // if the value is overriden server-side, initiator should be called twice - // while attached should be called once with final value - await state.set({ immediateValue: 2 }); - } catch(err) { - reject(err); - } + // should be notified normally if not initiator of the update + const attachedPromise = new Promise((resolve) => { + let call = 0; + + attached.onUpdate(updates => { + if (call === 0) { + try { + assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); + resolve(); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { immediateValue: 3 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('attached: something went wrong'); + } - Promise.all([statePromise, attachedPromise]).then(() => resolve()); - }); - }); + call += 1; + }); + }); - it('[immediate=true, event=true] should behave correctly', async () => { - return new Promise(async (resolve, reject) => { - server.stateManager.registerSchema('immediate-test-2', { - immediateValue: { - type: 'integer', - default: 0, - immediate: true, - event: true, - }, - normalValue: { - type: 'integer', - default: 0, + // invalid value + try { + await state.set({ immediateValue: 1, normalValue: 10 }); + // this should not trigger anything + await state.set({ immediateValue: 1, normalValue: 10 }); + // if the value is overriden server-side, initiator should be called twice + // while attached should be called once with final value + await state.set({ immediateValue: 2 }); + } catch(err) { + reject(err); } - }); - const state = await client1.stateManager.create('immediate-test-2'); - const attached = await client2.stateManager.attach('immediate-test-2'); - - const statePromise = new Promise((resolve) => { - let call = 0; + Promise.all([statePromise, attachedPromise]).then(() => resolve()); + }); + }); - state.onUpdate(updates => { - if (call === 0) { - try { - assert.deepEqual(updates, { immediateValue: 1 }); - } catch(err) { - reject(err); - } - } else if (call === 1) { - try { - assert.deepEqual(updates, { normalValue: 10 }); - } catch(err) { - reject(err); - } - } else if (call === 2) { - // as it's an event it should be retriggered - try { - assert.deepEqual(updates, { immediateValue: 1 }); - resolve(); - } catch(err) { - reject(err); - } - } else { - reject('creator: something wrong happened'); + it('[immediate=true, event=true] should behave correctly', async () => { + return new Promise(async (resolve, reject) => { + server.stateManager.registerSchema('immediate-test-2', { + immediateValue: { + type: 'integer', + default: 0, + immediate: true, + event: true, + }, + normalValue: { + type: 'integer', + default: 0, } - - call += 1; }); - }); - // should be notified normally if not initiator of the update - const attachedPromise = new Promise((resolve) => { - let call = 0; - - attached.onUpdate(updates => { - if (call === 0) { - try { - assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); - resolve(); - } catch(err) { - reject(err); - } - } else if (call === 1) { - try { - assert.deepEqual(updates, { immediateValue: 1 }); - resolve(); - } catch(err) { - reject(err); + const state = await client1.stateManager.create('immediate-test-2'); + const attached = await client2.stateManager.attach('immediate-test-2'); + + const statePromise = new Promise((resolve) => { + let call = 0; + + state.onUpdate(updates => { + if (call === 0) { + try { + assert.deepEqual(updates, { immediateValue: 1 }); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { normalValue: 10 }); + } catch(err) { + reject(err); + } + } else if (call === 2) { + // as it's an event it should be retriggered + try { + assert.deepEqual(updates, { immediateValue: 1 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('creator: something wrong happened'); } - } else { - reject('attached: something wrong happened'); - } - call += 1; + call += 1; + }); }); - }); - // invalid value - try { - await state.set({ immediateValue: 1, normalValue: 10 }); - // this should not trigger anything - await state.set({ immediateValue: 1, normalValue: 10 }); - } catch(err) { - reject(err); - } + // should be notified normally if not initiator of the update + const attachedPromise = new Promise((resolve) => { + let call = 0; + + attached.onUpdate(updates => { + if (call === 0) { + try { + assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); + resolve(); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { immediateValue: 1 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('attached: something wrong happened'); + } - Promise.all([statePromise, attachedPromise]).then(() => resolve()); - }); - }); + call += 1; + }); + }); - it('[immediate=true, filterChange=false] should behave correctly', async () => { - return new Promise(async (resolve, reject) => { - server.stateManager.registerSchema('immediate-test-3', { - immediateValue: { - type: 'integer', - default: 0, - immediate: true, - filterChange: false, - }, - normalValue: { - type: 'integer', - default: 0, + // invalid value + try { + await state.set({ immediateValue: 1, normalValue: 10 }); + // this should not trigger anything + await state.set({ immediateValue: 1, normalValue: 10 }); + } catch(err) { + reject(err); } - }); - const state = await client1.stateManager.create('immediate-test-3'); - const attached = await client2.stateManager.attach('immediate-test-3'); + Promise.all([statePromise, attachedPromise]).then(() => resolve()); + }); + }); - const statePromise = new Promise((resolve) => { - let call = 0; + it('[immediate=true, filterChange=false] should behave correctly', async () => { + return new Promise(async (resolve, reject) => { + server.stateManager.registerSchema('immediate-test-3', { + immediateValue: { + type: 'integer', + default: 0, + immediate: true, + filterChange: false, + }, + normalValue: { + type: 'integer', + default: 0, + } + }); - state.onUpdate(updates => { - if (call === 0) { - try { - assert.deepEqual(updates, { immediateValue: 1 }); - } catch(err) { - reject(err); - } - } else if (call === 1) { - try { - assert.deepEqual(updates, { normalValue: 10 }); - } catch(err) { - reject(err); - } - } else if (call === 2) { - // as it's an event it should be retriggered - try { - assert.deepEqual(updates, { immediateValue: 1 }); - resolve(); - } catch(err) { - reject(err); + const state = await client1.stateManager.create('immediate-test-3'); + const attached = await client2.stateManager.attach('immediate-test-3'); + + const statePromise = new Promise((resolve) => { + let call = 0; + + state.onUpdate(updates => { + if (call === 0) { + try { + assert.deepEqual(updates, { immediateValue: 1 }); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { normalValue: 10 }); + } catch(err) { + reject(err); + } + } else if (call === 2) { + // as it's an event it should be retriggered + try { + assert.deepEqual(updates, { immediateValue: 1 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('creator: something wrong happened'); } - } else { - reject('creator: something wrong happened'); - } - call += 1; + call += 1; + }); }); - }); - // should be notified normally if not initiator of the update - const attachedPromise = new Promise((resolve) => { - let call = 0; - attached.onUpdate(updates => { - if (call === 0) { - try { - assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); - resolve(); - } catch(err) { - reject(err); + // should be notified normally if not initiator of the update + const attachedPromise = new Promise((resolve) => { + let call = 0; + attached.onUpdate(updates => { + if (call === 0) { + try { + assert.deepEqual(updates, { immediateValue: 1, normalValue: 10 }); + resolve(); + } catch(err) { + reject(err); + } + } else if (call === 1) { + try { + assert.deepEqual(updates, { immediateValue: 1 }); + resolve(); + } catch(err) { + reject(err); + } + } else { + reject('attached: something wrong happened'); } - } else if (call === 1) { - try { - assert.deepEqual(updates, { immediateValue: 1 }); - resolve(); - } catch(err) { - reject(err); - } - } else { - reject('attached: something wrong happened'); - } - call += 1; + call += 1; + }); }); - }); - // invalid value - try { - await state.set({ immediateValue: 1, normalValue: 10 }); - // this should not trigger anything - await state.set({ immediateValue: 1, normalValue: 10 }); - } catch(err) { - reject(err); - } + // invalid value + try { + await state.set({ immediateValue: 1, normalValue: 10 }); + // this should not trigger anything + await state.set({ immediateValue: 1, normalValue: 10 }); + } catch(err) { + reject(err); + } - Promise.all([statePromise, attachedPromise]).then(() => resolve()); + Promise.all([statePromise, attachedPromise]).then(() => resolve()); + }); }); });