From ed6d29c5acf45712d5099c97a7ab0df96c3458a1 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Wed, 17 May 2023 14:51:38 +0200 Subject: [PATCH 1/2] Add tests to check negation operator --- e2e/html/negation-operator.html | 29 +++++++++++++++++++++++++++ e2e/js/negation-operator.js | 17 ++++++++++++++++ e2e/specs/negation-operator.spec.ts | 31 +++++++++++++++++++++++++++++ webpack.config.js | 1 + 4 files changed, 78 insertions(+) create mode 100644 e2e/html/negation-operator.html create mode 100644 e2e/js/negation-operator.js create mode 100644 e2e/specs/negation-operator.spec.ts diff --git a/e2e/html/negation-operator.html b/e2e/html/negation-operator.html new file mode 100644 index 00000000..79ae7ba2 --- /dev/null +++ b/e2e/html/negation-operator.html @@ -0,0 +1,29 @@ + + + + Negation Operator + + + + + +
+ +
+ + + + + + diff --git a/e2e/js/negation-operator.js b/e2e/js/negation-operator.js new file mode 100644 index 00000000..1a5f9d97 --- /dev/null +++ b/e2e/js/negation-operator.js @@ -0,0 +1,17 @@ +import { store } from '../../src/runtime/store'; + +store({ + selectors: { + active: ({ state }) => { + return state.active; + }, + }, + state: { + active: false, + }, + actions: { + toggle: ({ state }) => { + state.active = !state.active; + }, + }, +}); diff --git a/e2e/specs/negation-operator.spec.ts b/e2e/specs/negation-operator.spec.ts new file mode 100644 index 00000000..f0f67338 --- /dev/null +++ b/e2e/specs/negation-operator.spec.ts @@ -0,0 +1,31 @@ +import { test, expect } from '../tests'; + +test.describe('negation-operator', () => { + test.beforeEach(async ({ goToFile }) => { + await goToFile('negation-operator.html'); + }); + + test('add hidden attribute when !state.active', async ({ page }) => { + const el = page.getByTestId( + 'add hidden attribute if state is not active' + ); + + await expect(el).toHaveAttribute('hidden', ''); + page.getByTestId('toggle active value').click(); + await expect(el).not.toHaveAttribute('hidden', ''); + page.getByTestId('toggle active value').click(); + await expect(el).toHaveAttribute('hidden', ''); + }); + + test('add hidden attribute when !selectors.active', async ({ page }) => { + const el = page.getByTestId( + 'add hidden attribute if selector is not active' + ); + + await expect(el).toHaveAttribute('hidden', ''); + page.getByTestId('toggle active value').click(); + await expect(el).not.toHaveAttribute('hidden', ''); + page.getByTestId('toggle active value').click(); + await expect(el).toHaveAttribute('hidden', ''); + }); +}); diff --git a/webpack.config.js b/webpack.config.js index 1a9927db..c41e0ef0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,6 +12,7 @@ module.exports = [ 'e2e/page-2': './e2e/page-2', 'e2e/directive-bind': './e2e/js/directive-bind', 'e2e/directive-effect': './e2e/js/directive-effect', + 'e2e/negation-operator': './e2e/js/negation-operator', }, output: { filename: '[name].js', From e50ee7215d2bab1cbc62d1bcc264f8312d0dd410 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Wed, 17 May 2023 14:52:47 +0200 Subject: [PATCH 2/2] Move `hasNegationOperator` logic to `getEvaluate` --- src/runtime/hooks.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/runtime/hooks.js b/src/runtime/hooks.js index a7d764ea..8abf2c20 100644 --- a/src/runtime/hooks.js +++ b/src/runtime/hooks.js @@ -13,25 +13,27 @@ export const directive = (name, cb) => { // Resolve the path to some property of the store object. const resolve = (path, ctx) => { - // If path starts with !, remove it and save a flag. - const hasNegationOperator = path[0] === '!' && !!(path = path.slice(1)); let current = { ...store, context: ctx }; path.split('.').forEach((p) => (current = current[p])); - return hasNegationOperator ? !current : current; + return current; }; // Generate the evaluate function. const getEvaluate = ({ ref } = {}) => (path, extraArgs = {}) => { + // If path starts with !, remove it and save a flag. + const hasNegationOperator = path[0] === '!' && !!(path = path.slice(1)); const value = resolve(path, extraArgs.context); - return typeof value === 'function' - ? value({ - ref: ref.current, - ...store, - ...extraArgs, - }) - : value; + const returnValue = + typeof value === 'function' + ? value({ + ref: ref.current, + ...store, + ...extraArgs, + }) + : value; + return hasNegationOperator ? !returnValue : returnValue; }; // Directive wrapper.