diff --git a/package.json b/package.json index 7646c4dbb6..b53fe3f26f 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "start:server:next-dev:docs": "yarn start:cli:build:docs && yarn && yarn workspace @lowdefy/server dev", "start:server-dev:next-dev:app": "yarn workspace lowdefy start build --config-directory ../../app --server-directory ../server-dev --output-directory ../ && yarn workspace @lowdefy/server-dev next dev", "test": "lerna run test", - "test:ci": "yarn test --ignore='@lowdefy/engine' --ignore='@lowdefy/format' --ignore='@lowdefy/blocks-*' --ignore='@lowdefy/plugin-aws'" + "test:ci": "yarn test --ignore='@lowdefy/format' --ignore='@lowdefy/blocks-*' --ignore='@lowdefy/plugin-aws'" }, "devDependencies": { "@yarnpkg/pnpify": "3.1.1-rc.13", diff --git a/packages/engine/src/actions/createCallMethod.test.js b/packages/engine/src/actions/createCallMethod.test.js index 4bceedf916..1ad8a251c3 100644 --- a/packages/engine/src/actions/createCallMethod.test.js +++ b/packages/engine/src/actions/createCallMethod.test.js @@ -17,20 +17,7 @@ import { jest } from '@jest/globals'; import testContext from '../../test/testContext.js'; -const lowdefy = { - _internal: { - actions: { - CallMethod: ({ methods: { callMethod }, params }) => { - return callMethod(params); - }, - }, - blockComponents: { - Button: { meta: { category: 'display' } }, - List: { meta: { category: 'list' } }, - TextInput: { meta: { category: 'input' } }, - }, - }, -}; +const lowdefy = {}; const RealDate = Date; const mockDate = jest.fn(() => ({ date: 0 })); @@ -91,7 +78,7 @@ test('CallMethod with no args, synchronous method', async () => { textInput.registerMethod('blockMethod', blockMethod); const res = await button.triggerEvent({ name: 'onClick' }); expect(res).toEqual({ - id: 'button', + blockId: 'button', bounced: false, event: undefined, eventName: 'onClick', @@ -166,7 +153,7 @@ test('CallMethod method return a promise', async () => { textInput.registerMethod('blockMethod', blockMethod); const res = await button.triggerEvent({ name: 'onClick' }); expect(res).toEqual({ - id: 'button', + blockId: 'button', bounced: false, event: undefined, eventName: 'onClick', @@ -229,7 +216,7 @@ test('CallMethod with args not an array', async () => { textInput.registerMethod('blockMethod', blockMethod); const res = await button.triggerEvent({ name: 'onClick' }); expect(res).toEqual({ - id: 'button', + blockId: 'button', bounced: false, event: undefined, eventName: 'onClick', @@ -238,7 +225,7 @@ test('CallMethod with args not an array', async () => { id: 'a', params: { args: 'arg', - blockId: 'block:root:textInput:0', + blockId: 'textInput', method: 'blockMethod', }, type: 'CallMethod', @@ -505,7 +492,7 @@ test('CallMethod with method does not exist', async () => { action: { id: 'a', params: { - blockId: 'block:root:textInput:0', + blockId: 'textInput', method: 'no-method', }, type: 'CallMethod', diff --git a/packages/engine/src/actions/createDisplayMessage.test.js b/packages/engine/src/actions/createDisplayMessage.test.js index c05af09cf0..33cc64cdd1 100644 --- a/packages/engine/src/actions/createDisplayMessage.test.js +++ b/packages/engine/src/actions/createDisplayMessage.test.js @@ -30,9 +30,6 @@ const lowdefy = { }); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, displayMessage: mockMessage, }, }; diff --git a/packages/engine/src/actions/createGetActions.test.js b/packages/engine/src/actions/createGetActions.test.js index 2c93519083..d9ead74de7 100644 --- a/packages/engine/src/actions/createGetActions.test.js +++ b/packages/engine/src/actions/createGetActions.test.js @@ -25,9 +25,6 @@ const lowdefy = { }, Custom: () => 'response', }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, }; diff --git a/packages/engine/src/actions/createGetBlockId.test.js b/packages/engine/src/actions/createGetBlockId.test.js index 2a8bdba46f..33a6c1c56b 100644 --- a/packages/engine/src/actions/createGetBlockId.test.js +++ b/packages/engine/src/actions/createGetBlockId.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getBlockId(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, }; diff --git a/packages/engine/src/actions/createGetEvent.test.js b/packages/engine/src/actions/createGetEvent.test.js index 972e429e48..b1baf66f0a 100644 --- a/packages/engine/src/actions/createGetEvent.test.js +++ b/packages/engine/src/actions/createGetEvent.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getEvent(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, }; diff --git a/packages/engine/src/actions/createGetGlobal.test.js b/packages/engine/src/actions/createGetGlobal.test.js index 12131965c9..1fd438969c 100644 --- a/packages/engine/src/actions/createGetGlobal.test.js +++ b/packages/engine/src/actions/createGetGlobal.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getGlobal(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, lowdefyGlobal: { some: 'data', @@ -52,7 +49,7 @@ afterAll(() => { test('getGlobal params is true', async () => { const pageConfig = { id: 'root', - tyoe: 'Box', + type: 'Box', blocks: [ { id: 'button', diff --git a/packages/engine/src/actions/createGetInput.test.js b/packages/engine/src/actions/createGetInput.test.js index dcb90900f9..57f21505b3 100644 --- a/packages/engine/src/actions/createGetInput.test.js +++ b/packages/engine/src/actions/createGetInput.test.js @@ -24,12 +24,9 @@ const lowdefy = { return getInput(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, inputs: { - test: { some: 'data' }, + 'page:root': { some: 'data' }, }, }; diff --git a/packages/engine/src/actions/createGetPageId.test.js b/packages/engine/src/actions/createGetPageId.test.js index bf710ac071..01a2759164 100644 --- a/packages/engine/src/actions/createGetPageId.test.js +++ b/packages/engine/src/actions/createGetPageId.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getPageId(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, }; diff --git a/packages/engine/src/actions/createGetRequestDetails.test.js b/packages/engine/src/actions/createGetRequestDetails.test.js index edfb99669f..11f857433c 100644 --- a/packages/engine/src/actions/createGetRequestDetails.test.js +++ b/packages/engine/src/actions/createGetRequestDetails.test.js @@ -43,12 +43,6 @@ const lowdefy = { Action: ({ methods: { getRequestDetails }, params }) => { return getRequestDetails(params); }, - Request: ({ methods: { request }, params }) => { - return request(params); - }, - }, - blockComponents: { - Button: { meta: { category: 'display' } }, }, callRequest: mockCallRequest, }, @@ -81,7 +75,8 @@ test('getRequestDetails params is true', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -142,7 +137,8 @@ test('getRequestDetails params is req_one', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -201,7 +197,8 @@ test('getRequestDetails params is none', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -267,7 +264,8 @@ test('getRequestDetails params.key is null', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -325,7 +323,8 @@ test('getRequestDetails params.all is true', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -388,7 +387,8 @@ test('getRequestDetails params.key is not string or int', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -463,7 +463,8 @@ test('getRequestDetails params.key is req_one', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ diff --git a/packages/engine/src/actions/createGetState.test.js b/packages/engine/src/actions/createGetState.test.js index edb22f9210..ea306d9cae 100644 --- a/packages/engine/src/actions/createGetState.test.js +++ b/packages/engine/src/actions/createGetState.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getState(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, }; @@ -55,7 +52,7 @@ test('getState params is true', async () => { { id: 'initState', type: 'SetState', - params: { textInput: 'init' }, + params: { some: 'data' }, }, ], }, diff --git a/packages/engine/src/actions/createGetUrlQuery.test.js b/packages/engine/src/actions/createGetUrlQuery.test.js index 857dee458d..bdf00e0a3d 100644 --- a/packages/engine/src/actions/createGetUrlQuery.test.js +++ b/packages/engine/src/actions/createGetUrlQuery.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getUrlQuery(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, urlQuery: { some: 'data', diff --git a/packages/engine/src/actions/createGetUser.test.js b/packages/engine/src/actions/createGetUser.test.js index 47d0f8876b..00879a9834 100644 --- a/packages/engine/src/actions/createGetUser.test.js +++ b/packages/engine/src/actions/createGetUser.test.js @@ -24,9 +24,6 @@ const lowdefy = { return getUser(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, }, user: { some: 'data', diff --git a/packages/engine/src/actions/createLink.test.js b/packages/engine/src/actions/createLink.test.js index 5179f8a536..d459bdcef6 100644 --- a/packages/engine/src/actions/createLink.test.js +++ b/packages/engine/src/actions/createLink.test.js @@ -34,11 +34,6 @@ const lowdefy = { } }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - List: { meta: { category: 'list' } }, - TextInput: { meta: { category: 'input' } }, - }, link: jest.fn(), }, }; diff --git a/packages/engine/src/actions/createLogin.test.js b/packages/engine/src/actions/createLogin.test.js index 5f4b1beb30..f8a647fdf5 100644 --- a/packages/engine/src/actions/createLogin.test.js +++ b/packages/engine/src/actions/createLogin.test.js @@ -24,9 +24,6 @@ const lowdefy = { return login(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, auth: { login: jest.fn(), }, diff --git a/packages/engine/src/actions/createLogout.test.js b/packages/engine/src/actions/createLogout.test.js index fe8229fcf9..ebf15edd6a 100644 --- a/packages/engine/src/actions/createLogout.test.js +++ b/packages/engine/src/actions/createLogout.test.js @@ -24,9 +24,6 @@ const lowdefy = { return logout(); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, auth: { logout: jest.fn(), }, diff --git a/packages/engine/src/actions/createRequest.test.js b/packages/engine/src/actions/createRequest.test.js index fa238d3451..f9b2c189b9 100644 --- a/packages/engine/src/actions/createRequest.test.js +++ b/packages/engine/src/actions/createRequest.test.js @@ -50,9 +50,6 @@ const lowdefy = { return request(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, callRequest: mockCallRequest, }, }; @@ -84,7 +81,8 @@ test('Request call one request', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, ], blocks: [ @@ -133,10 +131,12 @@ test('Request call all requests', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, { - requestId: 'req_two', + id: 'req_two', + type: 'Fetch', }, ], blocks: [ @@ -204,10 +204,12 @@ test('Request call array of requests', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, { - requestId: 'req_two', + id: 'req_two', + type: 'Fetch', }, ], blocks: [ @@ -275,10 +277,12 @@ test('Request pass if params are none', async () => { type: 'Box', requests: [ { - requestId: 'req_one', + id: 'req_one', + type: 'Fetch', }, { - requestId: 'req_two', + id: 'req_two', + type: 'Fetch', }, ], blocks: [ @@ -306,7 +310,8 @@ test('Request call request error', async () => { type: 'Box', requests: [ { - requestId: 'req_error', + id: 'req_error', + type: 'Fetch', }, ], blocks: [ diff --git a/packages/engine/src/actions/createReset.js b/packages/engine/src/actions/createReset.js index bb98da16c4..09653d96bf 100644 --- a/packages/engine/src/actions/createReset.js +++ b/packages/engine/src/actions/createReset.js @@ -22,7 +22,6 @@ function createReset({ context }) { context._internal.RootBlocks.reset( serializer.deserializeFromString(context._internal.State.frozenState) ); - context._internal.update(); }; } diff --git a/packages/engine/src/actions/createReset.test.js b/packages/engine/src/actions/createReset.test.js index c3767d6dd0..6f003d4b85 100644 --- a/packages/engine/src/actions/createReset.test.js +++ b/packages/engine/src/actions/createReset.test.js @@ -24,11 +24,6 @@ const lowdefy = { return reset(); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - List: { meta: { category: 'list', valueType: 'array' } }, - TextInput: { meta: { category: 'input', valueType: 'string' } }, - }, }, }; diff --git a/packages/engine/src/actions/createSetGlobal.test.js b/packages/engine/src/actions/createSetGlobal.test.js index 440badcc82..f37a9592a9 100644 --- a/packages/engine/src/actions/createSetGlobal.test.js +++ b/packages/engine/src/actions/createSetGlobal.test.js @@ -14,22 +14,22 @@ limitations under the License. */ +import { jest } from '@jest/globals'; + import testContext from '../../test/testContext.js'; -test('SetGlobal data to global', async () => { - const lowdefy = { - _internal: { - actions: { - SetGlobal: ({ methods: { setGlobal }, params }) => { - return setGlobal(params); - }, +const lowdefy = { + _internal: { + actions: { + SetGlobal: ({ methods: { setGlobal }, params }) => { + return setGlobal(params); }, - blockComponents: { - Button: { meta: { category: 'display' } }, - }, - lowdefyGlobal: { x: 'old', init: 'init' }, }, - }; + lowdefyGlobal: { x: 'old', init: 'init' }, + }, +}; + +test('SetGlobal data to global', async () => { const pageConfig = { id: 'root', type: 'Box', @@ -65,4 +65,35 @@ test('SetGlobal data to global', async () => { }); }); -test.todo('SetGlobal calls context update'); +// ?? CHECK: we call update before actions, when a action is completed, and again when all actions is completed?? So 3 calls. +test('SetGlobal calls context update', async () => { + const updateFunction = jest.fn(); + const pageConfig = { + id: 'root', + type: 'Box', + blocks: [ + { + id: 'button', + type: 'Button', + events: { + onClick: [ + { + id: 'a', + type: 'SetGlobal', + params: { str: 'hello', number: 13, arr: [1, 2, 3], x: 'new' }, + }, + ], + }, + }, + ], + }; + const context = await testContext({ + lowdefy, + pageConfig, + }); + context._internal.update = updateFunction; + expect(updateFunction).toHaveBeenCalledTimes(0); + const button = context._internal.RootBlocks.map['button']; + await button.triggerEvent({ name: 'onClick' }); + expect(updateFunction).toHaveBeenCalledTimes(3); +}); diff --git a/packages/engine/src/actions/createSetState.test.js b/packages/engine/src/actions/createSetState.test.js index eb56d5a9b6..188f02391d 100644 --- a/packages/engine/src/actions/createSetState.test.js +++ b/packages/engine/src/actions/createSetState.test.js @@ -23,15 +23,10 @@ const lowdefy = { return setState(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - List: { meta: { category: 'list', valueType: 'array' } }, - TextInput: { meta: { category: 'input', valueType: 'string' } }, - }, }, }; -test('SetState data to state', () => { +test('SetState data to state', async () => { const pageConfig = { id: 'root', type: 'Box', @@ -69,7 +64,7 @@ test('SetState data to state', () => { expect(context.state).toEqual({ textInput: 'init', x: [1, 2, 3] }); }); -test('SetState field to state and update block value', () => { +test('SetState field to state and update block value', async () => { const pageConfig = { id: 'root', type: 'Box', @@ -105,12 +100,12 @@ test('SetState field to state and update block value', () => { const textInput = context._internal.RootBlocks.map['textInput']; expect(context.state).toEqual({ textInput: 'init' }); - button.triggerEvent({ name: 'onClick' }); + await button.triggerEvent({ name: 'onClick' }); expect(context.state).toEqual({ textInput: 'new' }); expect(textInput.value).toEqual('new'); }); -test('SetState field to state with incorrect type - NOTE SetState IS NOT TYPE SAFE', () => { +test('SetState field to state with incorrect type - NOTE SetState IS NOT TYPE SAFE', async () => { const pageConfig = { id: 'root', type: 'Box', @@ -146,12 +141,12 @@ test('SetState field to state with incorrect type - NOTE SetState IS NOT TYPE SA const textInput = context._internal.RootBlocks.map['textInput']; expect(context.state).toEqual({ textInput: 'init' }); - button.triggerEvent({ name: 'onClick' }); + await button.triggerEvent({ name: 'onClick' }); expect(context.state).toEqual({ textInput: 1 }); expect(textInput.value).toEqual(1); }); -test('SetState value on array and create new Blocks for array items', () => { +test('SetState value on array and create new Blocks for array items', async () => { const pageConfig = { id: 'root', type: 'Box', @@ -172,7 +167,6 @@ test('SetState value on array and create new Blocks for array items', () => { { id: 'list.$.textInput', type: 'TextInput', - defaultValue: '123', }, ], }, @@ -199,7 +193,7 @@ test('SetState value on array and create new Blocks for array items', () => { expect(context.state).toEqual({ list: [{ textInput: 'init' }] }); - button.triggerEvent({ name: 'onClick' }); + await button.triggerEvent({ name: 'onClick' }); expect(context.state).toEqual({ list: [{ textInput: '0' }, { textInput: '1' }, { textInput: '2' }], }); diff --git a/packages/engine/src/actions/createValidate.test.js b/packages/engine/src/actions/createValidate.test.js index 60f2d3c207..99dd6967b0 100644 --- a/packages/engine/src/actions/createValidate.test.js +++ b/packages/engine/src/actions/createValidate.test.js @@ -15,8 +15,6 @@ */ import { jest } from '@jest/globals'; -import { get, type } from '@lowdefy/helpers'; - import testContext from '../../test/testContext.js'; const closeLoader = jest.fn(); @@ -28,101 +26,7 @@ const lowdefy = { return validate(params); }, }, - blockComponents: { - Button: { meta: { category: 'display' } }, - TextInput: { meta: { category: 'input', valueType: 'string' } }, - }, displayMessage, - operators: { - _not: ({ params }) => { - return !params; - }, - _type: ({ location, params, state }) => { - const typeName = type.isObject(params) ? params.type : params; - if (!type.isString(typeName)) { - throw new Error( - `Operator Error: _type.type must be a string. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - const on = Object.prototype.hasOwnProperty.call(params, 'on') - ? params.on - : get(state, get(params, 'key', { default: location })); - switch (typeName) { - case 'string': - return type.isString(on); - case 'array': - return type.isArray(on); - case 'date': - return type.isDate(on); // Testing for date is problematic due to stringify - case 'object': - return type.isObject(on); - case 'boolean': - return type.isBoolean(on); - case 'number': - return type.isNumber(on); - case 'integer': - return type.isInt(on); - case 'null': - return type.isNull(on); - case 'undefined': - return type.isUndefined(on); - case 'none': - return type.isNone(on); - case 'primitive': - return type.isPrimitive(on); - default: - throw new Error( - `Operator Error: "${typeName}" is not a valid _type test. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - }, - _regex: ({ location, params, state }) => { - const pattern = type.isObject(params) ? params.pattern : params; - if (!type.isString(pattern)) { - throw new Error( - `Operator Error: _regex.pattern must be a string. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - let on = !type.isUndefined(params.on) ? params.on : get(state, location); - if (!type.isUndefined(params.key)) { - if (!type.isString(params.key)) { - throw new Error( - `Operator Error: _regex.key must be a string. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - on = get(state, params.key); - } - if (type.isNone(on)) { - return false; - } - if (!type.isString(on)) { - throw new Error( - `Operator Error: _regex.on must be a string. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - try { - const re = new RegExp(pattern, params.flags || 'gm'); - return re.test(on); - } catch (e) { - // log e to LowdefyError - throw new Error( - `Operator Error: _regex failed to execute RegExp.test. Received: ${JSON.stringify( - params - )} at ${location}.` - ); - } - }, - }, }, }; diff --git a/packages/engine/test/Actions/Actions.test.js b/packages/engine/test/Actions.test.js similarity index 87% rename from packages/engine/test/Actions/Actions.test.js rename to packages/engine/test/Actions.test.js index b77d91dbc9..87dab06aa0 100644 --- a/packages/engine/test/Actions/Actions.test.js +++ b/packages/engine/test/Actions.test.js @@ -16,26 +16,9 @@ limitations under the License. */ -import testContext from '../testContext.js'; -import actions from '../../src/actions/index.js'; +import { jest } from '@jest/globals'; -jest.mock('../../src/actions/index.js', () => ({ - ActionSync: jest.fn(({ params }) => params), - ActionAsync: jest.fn(async ({ params }) => { - await timeout(params.ms || 1); - return params; - }), - ActionError: jest.fn(() => { - throw new Error('Test error'); - }), - CatchActionError: jest.fn(() => { - throw new Error('Test catch error'); - }), - ActionAsyncError: jest.fn(async ({ params }) => { - await timeout(params.ms || 1); - throw new Error('Test error'); - }), -})); +import testContext from './testContext.js'; const timeout = (ms) => { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -47,10 +30,32 @@ const RealDate = Date; const mockDate = jest.fn(() => ({ date: 0 })); mockDate.now = jest.fn(() => 0); +const getActions = () => { + return { + ActionSync: jest.fn(({ params }) => params), + ActionAsync: jest.fn(async ({ params }) => { + await timeout(params.ms || 1); + return params; + }), + ActionError: jest.fn(() => { + throw new Error('Test error'); + }), + CatchActionError: jest.fn(() => { + throw new Error('Test catch error'); + }), + ActionAsyncError: jest.fn(async ({ params }) => { + await timeout(params.ms || 1); + throw new Error('Test error'); + }), + }; +}; + const closeLoader = jest.fn(); const displayMessage = jest.fn(); const lowdefy = { - displayMessage, + _internal: { + displayMessage, + }, pageId, }; const arrayIndices = []; @@ -76,11 +81,13 @@ test('call a synchronous action', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'ActionSync', params: 'params' }], arrayIndices, @@ -113,11 +120,13 @@ test('call a asynchronous action', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'ActionAsync', params: 'params' }], arrayIndices, @@ -150,11 +159,13 @@ test('call 2 actions', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test1', type: 'ActionSync', params: 'params1' }, @@ -194,11 +205,13 @@ test('operators are evaluated in params, skip and messages', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -268,11 +281,13 @@ test('operators are evaluated in error messages after error', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -314,11 +329,13 @@ test('action error in error messages from same action id', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -368,11 +385,13 @@ test('action error in error parser', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { @@ -419,11 +438,13 @@ test('error with messages undefined', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -453,11 +474,13 @@ test('skip a action', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'ActionSync', skip: true }], arrayIndices, @@ -490,11 +513,13 @@ test('action throws a error', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'ActionError', params: 'params' }], arrayIndices, @@ -539,11 +564,13 @@ test('actions after a error are not called throws a error', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test', type: 'ActionError', params: 'params' }, @@ -592,11 +619,13 @@ test('Invalid action type', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'Invalid', params: 'params' }], arrayIndices, @@ -640,11 +669,13 @@ test('Parser error in action', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [{ id: 'test', type: 'ActionSync', params: { _state: [] } }], arrayIndices, @@ -694,11 +725,13 @@ test('Display default loading and success messages when value == true ', async ( id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -737,11 +770,13 @@ test('Display custom loading and success messages when value is a string ', asyn id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -780,11 +815,13 @@ test('Do not display loading and success messages by default', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -807,11 +844,13 @@ test('Display error message by default', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -841,11 +880,13 @@ test('Display custom error message', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -878,11 +919,13 @@ test('Do not display an error message if message === false', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; await Actions.callActions({ actions: [ { @@ -907,11 +950,13 @@ test('Call catchActions when actions throws error', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { @@ -981,11 +1026,13 @@ test('Call catchActions when actions throws error and catchActions throws error' id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { @@ -1082,11 +1129,13 @@ test('call 2 actions, first with async: true', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test1', type: 'ActionAsync', async: true, params: { ms: 100 } }, @@ -1143,11 +1192,13 @@ test('call async: true with error', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test1', type: 'ActionAsyncError', async: true, params: { ms: 100 } }, @@ -1204,11 +1255,13 @@ test('call 2 actions, first with async: false', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test1', type: 'ActionAsync', async: false, params: { ms: 100 } }, @@ -1248,11 +1301,13 @@ test('call 2 actions, first with async: null', async () => { id: 'root', type: 'Box', }; + const actions = getActions(); + lowdefy._internal.actions = actions; const context = await testContext({ lowdefy, pageConfig, }); - const Actions = context.Actions; + const Actions = context._internal.Actions; const res = await Actions.callActions({ actions: [ { id: 'test1', type: 'ActionAsync', async: null, params: { ms: 100 } }, diff --git a/packages/engine/test/Block/Blocks.test.js b/packages/engine/test/Block/Blocks.test.js index 83078147d9..31ee122ac6 100644 --- a/packages/engine/test/Block/Blocks.test.js +++ b/packages/engine/test/Block/Blocks.test.js @@ -22,7 +22,7 @@ import { serializer } from '@lowdefy/helpers'; import testContext from '../testContext.js'; const pageId = 'one'; -const lowdefy = { pageId }; +const lowdefy = { pageId, _internal: {} }; test('init blocks and SetState to set value to block', async () => { const pageConfig = { @@ -97,20 +97,20 @@ test('set block value to initValue in meta', async () => { }, ], }; - const context = await testContext({ - lowdefy, - pageConfig, - blocks: { - ObjectBlock: { - meta: { - category: 'input', - valueType: 'object', - initValue: { - a: 1, - }, + lowdefy._internal.blocks = { + ObjectBlock: { + meta: { + category: 'input', + valueType: 'object', + initValue: { + a: 1, }, }, }, + }; + const context = await testContext({ + lowdefy, + pageConfig, }); const { object_one } = context._internal.RootBlocks.map; expect(object_one.value).toEqual({ a: 1 }); diff --git a/packages/engine/test/Block/benchmark.test.js b/packages/engine/test/Block/benchmark.test.js index eeb590e176..ff6ca362b7 100644 --- a/packages/engine/test/Block/benchmark.test.js +++ b/packages/engine/test/Block/benchmark.test.js @@ -75,7 +75,7 @@ test(`parse nunjucks value 500 blocks`, async () => { const fn = (i) => { b0.setValue(i); - context.update(); + context._internal.update(); }; const results = runTests({ times: NUM_TIMES, fn }); const totalTime = results.reduce((sum, r) => sum + r, 0); @@ -118,7 +118,7 @@ test(`parse nunjucks value 100 blocks`, async () => { const fn = (i) => { b0.setValue(i); - context.update(); + context._internal.update(); }; const results = runTests({ times: NUM_TIMES, fn }); const totalTime = results.reduce((sum, r) => sum + r, 0); @@ -206,7 +206,7 @@ test(`parse state value 1000 blocks`, async () => { // console.log('-----------------------'); // console.log(`fn: ${i}`); // b0.setValue(i); -// context.update(); +// context._internal.update(); // }; // const results = runTests({ times: 3, fn }); // // const totalTime = results.reduce((sum, r) => sum + r, 0); diff --git a/packages/engine/test/Events.test.js b/packages/engine/test/Events.test.js index 816861fba6..f9657a0761 100644 --- a/packages/engine/test/Events.test.js +++ b/packages/engine/test/Events.test.js @@ -64,8 +64,8 @@ const timeout = (ms) => { }; // Comment out to use console -// console.log = () => {}; -// console.error = () => {}; +console.log = () => {}; +console.error = () => {}; beforeEach(() => { global.Date = mockDate; diff --git a/packages/engine/test/Requests.test.js b/packages/engine/test/Requests.test.js index 58d4c045e6..b82e28e0b2 100644 --- a/packages/engine/test/Requests.test.js +++ b/packages/engine/test/Requests.test.js @@ -14,6 +14,8 @@ limitations under the License. */ +import { jest } from '@jest/globals'; + import testContext from './testContext.js'; const mockReqResponses = { @@ -42,55 +44,55 @@ const mockCallRequestImp = ({ requestId }) => { }); }; -const pageConfig = { - id: 'page1', - type: 'Box', - events: { - onInit: [ - { - id: 'init', - type: 'SetState', - params: { state: true }; - }, - ], - }, - requests: [ - { - requestId: 'req_one', - payload: { - event: { - _event: true, - }, - action: { - _actions: 'action1', +const getPageConfig = () => { + return { + id: 'page1', + type: 'Box', + events: { + onInit: [ + { + id: 'init', + type: 'SetState', + params: { state: true }, }, - sum: { - _sum: [1, 1], - }, - arrayIndices: { - _global: 'array.$', + ], + }, + requests: [ + { + id: 'req_one', + type: 'Fetch', + payload: { + event: { + _event: true, + }, + action: { + _actions: 'action1', + }, + sum: { + _sum: [1, 1], + }, + arrayIndices: { + _global: 'array.$', + }, }, }, - }, - { - requestId: 'req_error', - }, - { - requestId: 'req_two', - }, - ], + { + id: 'req_error', + type: 'Fetch', + }, + { + id: 'req_two', + type: 'Fetch', + }, + ], + }; }; -const pageId = 'page1'; - const actions = {}; -const arrayIndices = []; const event = {}; - +const arrayIndices = []; const lowdefy = { - callRequest: mockCallRequest, lowdefyGlobal: { array: ['a', 'b', 'c'] }, - pageId, }; // Comment out to use console @@ -103,11 +105,13 @@ beforeEach(() => { }); test('callRequest', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); - await context.Requests.callRequest({ requestId: 'req_one' }); + context._internal.lowdefy._internal.callRequest = mockCallRequest; + await context._internal.Requests.callRequest({ requestId: 'req_one' }); expect(context.requests).toEqual({ req_one: { error: [], @@ -118,11 +122,14 @@ test('callRequest', async () => { }); test('callRequest, payload operators are evaluated', async () => { + const pageConfig = getPageConfig(); + const context = await testContext({ lowdefy, pageConfig, }); - await context.Requests.callRequest({ + context._internal.lowdefy._internal.callRequest = mockCallRequest; + await context._internal.Requests.callRequest({ requestId: 'req_one', event: { event: true }, actions: { action1: 'action1' }, @@ -141,11 +148,13 @@ test('callRequest, payload operators are evaluated', async () => { }); test('callRequests all requests', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); - const promise = context.Requests.callRequests({ + context._internal.lowdefy._internal.callRequest = mockCallRequest; + const promise = context._internal.Requests.callRequests({ actions, arrayIndices, event, @@ -194,11 +203,13 @@ test('callRequests all requests', async () => { }); test('callRequests', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); - const promise = context.Requests.callRequests({ + context._internal.lowdefy._internal.callRequest = mockCallRequest; + const promise = context._internal.Requests.callRequests({ actions, arrayIndices, event, @@ -223,11 +234,15 @@ test('callRequests', async () => { }); test('callRequest error', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); - await expect(context.Requests.callRequest({ requestId: 'req_error' })).rejects.toThrow(); + context._internal.lowdefy._internal.callRequest = mockCallRequest; + await expect( + context._internal.Requests.callRequest({ requestId: 'req_error' }) + ).rejects.toThrow(); expect(context.requests).toEqual({ req_error: { error: [new Error('mock error')], @@ -235,7 +250,9 @@ test('callRequest error', async () => { response: null, }, }); - await expect(context.Requests.callRequest({ requestId: 'req_error' })).rejects.toThrow(); + await expect( + context._internal.Requests.callRequest({ requestId: 'req_error' }) + ).rejects.toThrow(); expect(context.requests).toEqual({ req_error: { error: [new Error('mock error'), new Error('mock error')], @@ -246,13 +263,15 @@ test('callRequest error', async () => { }); test('callRequest request does not exist', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); - await expect(context.Requests.callRequest({ requestId: 'req_does_not_exist' })).rejects.toThrow( - 'Configuration Error: Request req_does_not_exist not defined on page.' - ); + context._internal.lowdefy._internal.callRequest = mockCallRequest; + await expect( + context._internal.Requests.callRequest({ requestId: 'req_does_not_exist' }) + ).rejects.toThrow('Configuration Error: Request req_does_not_exist not defined on page.'); expect(context.requests).toEqual({ req_does_not_exist: { error: [new Error('Configuration Error: Request req_does_not_exist not defined on page.')], @@ -263,25 +282,29 @@ test('callRequest request does not exist', async () => { }); test('update function should be called', async () => { + const pageConfig = getPageConfig(); const updateFunction = jest.fn(); const context = await testContext({ lowdefy, pageConfig, }); - context.update = updateFunction; - await context.Requests.callRequest({ requestId: 'req_one' }); + context._internal.lowdefy._internal.callRequest = mockCallRequest; + context._internal.update = updateFunction; + await context._internal.Requests.callRequest({ requestId: 'req_one' }); expect(updateFunction).toHaveBeenCalledTimes(1); }); test('update function should be called if error', async () => { + const pageConfig = getPageConfig(); const updateFunction = jest.fn(); const context = await testContext({ lowdefy, pageConfig, }); - context.update = updateFunction; + context._internal.lowdefy._internal.callRequest = mockCallRequest; + context._internal.update = updateFunction; try { - await context.Requests.callRequest({ requestId: 'req_error' }); + await context._internal.Requests.callRequest({ requestId: 'req_error' }); } catch (e) { // catch thrown errors console.log(e); @@ -290,15 +313,17 @@ test('update function should be called if error', async () => { }); test('fetch should set call query every time it is called', async () => { + const pageConfig = getPageConfig(); const context = await testContext({ lowdefy, pageConfig, }); + context._internal.lowdefy._internal.callRequest = mockCallRequest; context._internal.RootBlocks = { update: jest.fn(), }; - await context.Requests.callRequest({ requestId: 'req_one', onlyNew: true }); + await context._internal.Requests.callRequest({ requestId: 'req_one', onlyNew: true }); expect(mockCallRequest).toHaveBeenCalledTimes(1); - context.Requests.fetch({ requestId: 'req_one' }); + await context._internal.Requests.fetch({ requestId: 'req_one' }); expect(mockCallRequest).toHaveBeenCalledTimes(2); }); diff --git a/packages/engine/test/getContext.test.js b/packages/engine/test/getContext.test.js index bcf8e085bf..e3f974247e 100644 --- a/packages/engine/test/getContext.test.js +++ b/packages/engine/test/getContext.test.js @@ -14,124 +14,147 @@ limitations under the License. */ -import getContext from '../src/getContext.js'; +import { jest } from '@jest/globals'; -const updateBlock = () => jest.fn(); -const pageId = 'pageId'; -const client = {}; +import getContext from '../src/getContext.js'; +import buildTestPage from '@lowdefy/build/buildTestPage'; -test('page is required input', async () => { - const lowdefy = { - client, +const getLowdefy = () => { + const updateBlock = () => jest.fn(); + const testLowdefy = { contexts: {}, - inputs: {}, - pageId, - updateBlock, + inputs: { test: {} }, + urlQuery: {}, + _internal: { + displayMessage: () => () => {}, + updateBlock, + operators: {}, + actions: {}, + blockComponents: { + TextInput: { + meta: { + category: 'input', + valueType: 'string', + }, + }, + Box: { + meta: { + category: 'container', + }, + }, + Button: { + meta: { + category: 'display', + }, + }, + List: { + meta: { + category: 'list', + valueType: 'array', + }, + }, + Paragraph: { + meta: { + category: 'display', + }, + }, + Switch: { + meta: { + category: 'input', + valueType: 'boolean', + }, + }, + MultipleSelector: { + meta: { + category: 'input', + valueType: 'array', + }, + }, + NumberInput: { + meta: { + category: 'input', + valueType: 'number', + }, + }, + }, + }, }; - await expect(getContext({ lowdefy })).rejects.toThrow('A page must be provided to get context.'); + return testLowdefy; +}; + +test('page is required input', async () => { + const resetContext = { reset: true, setReset: () => {} }; + const lowdefy = getLowdefy(); + expect(() => getContext({ lowdefy, resetContext })).toThrow( + 'A page must be provided to get context.' + ); }); -test('memoize context', async () => { - const lowdefy = { - client, - contexts: {}, - inputs: {}, - pageId, - updateBlock, - }; +test('memoize context and reset', async () => { + const resetContext = { reset: true, setReset: () => {} }; + const lowdefy = getLowdefy(); const page = { - pageId: 'pageId', - blockId: 'pageId', - meta: { - type: 'container', - }, + id: 'pageId', + type: 'Box', }; - const c1 = await getContext({ page, lowdefy }); - const c2 = await getContext({ page, lowdefy }); + const config = buildTestPage({ pageConfig: page }); + const c1 = getContext({ config, lowdefy, resetContext: { reset: true, setReset: () => {} } }); + const c2 = getContext({ config, lowdefy, resetContext: { reset: false, setReset: () => {} } }); expect(c1).toBe(c2); + expect(c1._internal.RootBlocks.id).toEqual(c2._internal.RootBlocks.id); + const c3 = getContext({ config, lowdefy, resetContext: { reset: true, setReset: () => {} } }); + expect(c1._internal.RootBlocks.id).not.toEqual(c3._internal.RootBlocks.id); }); test('create context', () => { - const lowdefy = { - client: { client: true }, - contexts: {}, - document: { document: true }, - inputs: { pageId: { input: true } }, - lowdefyGlobal: { lowdefyGlobal: true }, - menus: [{ id: 'default' }], - pageId, - routeHistory: ['routeHistory'], - updateBlock, - urlQuery: { urlQuery: true }, - window: { window: true }, - }; + const resetContext = { reset: true, setReset: () => {} }; + const lowdefy = getLowdefy(); const page = { - pageId: 'pageId', - blockId: 'pageId', - meta: { - type: 'container', - }, + id: 'pageId', + type: 'Box', }; - const context = getContext({ page, lowdefy }); - expect(context.Actions).toBeDefined(); - expect(context.Requests).toBeDefined(); + const config = buildTestPage({ pageConfig: page }); + const context = getContext({ config, lowdefy, resetContext }); + expect(context._internal.Actions).toBeDefined(); + expect(context._internal.Requests).toBeDefined(); expect(context._internal.RootBlocks).toBeDefined(); - expect(context.State).toBeDefined(); - expect(context.lowdefy).toEqual(lowdefy); + expect(context._internal.State).toBeDefined(); + expect(context._internal.runOnInit).toBeDefined(); + expect(context._internal.runOnInitAsync).toBeDefined(); + expect(context._internal.lowdefy).toEqual(lowdefy); expect(context.eventLog).toEqual([]); - expect(context.id).toEqual('pageId'); - expect(context.lowdefy.pageId).toEqual('pageId'); - expect(context.parser).toBeDefined(); + expect(context.id).toEqual('page:pageId'); + expect(context.pageId).toEqual('pageId'); + expect(context._internal.parser).toBeDefined(); expect(context.requests).toEqual({}); expect(context.pageId).toEqual('pageId'); - expect(context.rootBlock).toBeDefined(); + expect(context._internal.rootBlock).toBeDefined(); expect(context.state).toEqual({}); - expect(context.update).toBeDefined(); + expect(context._internal.update).toBeDefined(); }); -test('create context, initialize input', () => { - const lowdefy = { - client: { client: true }, - contexts: {}, - document: { document: true }, - inputs: {}, - lowdefyGlobal: { lowdefyGlobal: true }, - menus: [{ id: 'default' }], - pageId, - routeHistory: ['routeHistory'], - updateBlock, - urlQuery: { urlQuery: true }, - window: { window: true }, - }; +test('create context, initialize input', async () => { + const resetContext = { reset: true, setReset: () => {} }; + const lowdefy = getLowdefy(); const page = { - pageId: 'pageId', - blockId: 'pageId', - meta: { - type: 'container', - }, + id: 'pageId', + type: 'Box', }; - const context = getContext({ page, lowdefy }); - expect(context.lowdefy.inputs.pageId).toEqual({}); + const config = buildTestPage({ pageConfig: page }); + const context = getContext({ config, lowdefy, resetContext }); + expect(context._internal.lowdefy.inputs['page:pageId']).toEqual({}); }); -test('update memoized context', () => { - const lowdefy = { - client, - contexts: {}, - inputs: {}, - pageId, - updateBlock, - }; +test('update memoized context', async () => { + const lowdefy = getLowdefy(); const page = { - pageId: 'pageId', - blockId: 'pageId', - meta: { - type: 'container', - }, + id: 'pageId', + type: 'Box', }; + const config = buildTestPage({ pageConfig: page }); const mockUpdate = jest.fn(); - const c1 = getContext({ page, lowdefy }); - c1.update = mockUpdate; - getContext({ page, lowdefy }); + const c1 = getContext({ config, lowdefy, resetContext: { reset: true, setReset: () => {} } }); + c1._internal.update = mockUpdate; + getContext({ config, lowdefy, resetContext: { reset: false, setReset: () => {} } }); expect(mockUpdate.mock.calls.length).toBe(1); }); diff --git a/packages/engine/test/testActions.js b/packages/engine/test/testActions.js index f3e64cafa9..e0f69935e9 100644 --- a/packages/engine/test/testActions.js +++ b/packages/engine/test/testActions.js @@ -1,9 +1,11 @@ import { CallMethod as CallMethod } from '@lowdefy/actions-core/actions'; import { Link as Link } from '@lowdefy/actions-core/actions'; +import { Request as Request } from '@lowdefy/actions-core/actions'; import { SetState as SetState } from '@lowdefy/actions-core/actions'; export default { CallMethod, Link, + Request, SetState, }; diff --git a/packages/engine/test/testContext.js b/packages/engine/test/testContext.js index 6a2a67d45e..50a24b3dec 100644 --- a/packages/engine/test/testContext.js +++ b/packages/engine/test/testContext.js @@ -20,18 +20,19 @@ import getContext from '../src/getContext.js'; import testOperators from './testOperators.js'; import testActions from './testActions.js'; -const testContext = async ({ lowdefy, pageConfig, blocks = {} }) => { +const testContext = async ({ lowdefy, pageConfig }) => { const testLowdefy = { contexts: {}, - inputs: { test: {} }, + inputs: {}, urlQuery: {}, ...lowdefy, _internal: { + callRequest: () => {}, displayMessage: () => () => {}, updateBlock: () => {}, - ...lowdefy._internal, + ...lowdefy?._internal, operators: testOperators, - actions: testActions, + actions: { ...testActions, ...lowdefy?._internal?.actions }, blockComponents: { TextInput: { meta: { @@ -78,7 +79,7 @@ const testContext = async ({ lowdefy, pageConfig, blocks = {} }) => { valueType: 'number', }, }, - ...blocks, + ...lowdefy?._internal?.blocks, }, }, }; diff --git a/packages/engine/test/testOperators.js b/packages/engine/test/testOperators.js index 1430b5a79e..858ebc51ed 100644 --- a/packages/engine/test/testOperators.js +++ b/packages/engine/test/testOperators.js @@ -1,14 +1,31 @@ -import { _not as _not } from '@lowdefy/operators-js/operators/client'; +import { _actions as _actions } from '@lowdefy/operators-js/operators/client'; +import { _divide as _divide } from '@lowdefy/operators-js/operators/client'; import { _eq as _eq } from '@lowdefy/operators-js/operators/client'; -import { _type as _type } from '@lowdefy/operators-js/operators/client'; -import { _state as _state } from '@lowdefy/operators-js/operators/client'; -import { _regex as _regex } from '@lowdefy/operators-js/operators/client'; +import { _event as _event } from '@lowdefy/operators-js/operators/client'; +import { _global as _global } from '@lowdefy/operators-js/operators/client'; +import { _if_none as _if_none } from '@lowdefy/operators-js/operators/client'; +import { _json as _json } from '@lowdefy/operators-js/operators/client'; import { _mql as _mql } from '@lowdefy/operators-mql/operators/client'; +import { _not as _not } from '@lowdefy/operators-js/operators/client'; +import { _regex as _regex } from '@lowdefy/operators-js/operators/client'; +import { _state as _state } from '@lowdefy/operators-js/operators/client'; +import { _string as _string } from '@lowdefy/operators-js/operators/client'; +import { _sum as _sum } from '@lowdefy/operators-js/operators/client'; +import { _type as _type } from '@lowdefy/operators-js/operators/client'; export default { + _actions, + _divide, _eq, + _event, + _global, + _if_none, + _json, + _mql, _not, - _type, - _state, _regex, + _state, + _string, + _sum, + _type, };