From dea2e987025f90bab2ce784bb4eb0fff82e1a28c Mon Sep 17 00:00:00 2001 From: Andrey Gubanov Date: Fri, 14 Apr 2017 23:14:24 +0300 Subject: [PATCH] feat(calc): Allow to use promises via promiseCalc flag --- .babelrc | 21 ++++++---- .eslintrc.js | 1 + package.json | 9 +++-- src/calc/_createcalchandler.js | 18 ++++++++- test/browser-test/SpecRunner.html | 1 + test/spec/bindings/existence_binder_spec.js | 1 - test/spec/calc_spec.js | 43 +++++++++++++++++++++ yarn.lock | 22 +++++++++++ 8 files changed, 101 insertions(+), 15 deletions(-) diff --git a/.babelrc b/.babelrc index d7228595..0f4d5fa6 100644 --- a/.babelrc +++ b/.babelrc @@ -11,12 +11,17 @@ ["transform-es2015-template-literals", { "loose": true }], ["transform-es2015-destructuring", { "loose": true }], ["transform-es2015-computed-properties", { "loose": true }], - - // the following plugins are used at tests - "transform-es2015-classes", - "transform-es2015-for-of", - ["transform-es2015-spread", { - "loose": true - }] - ] + ], + "env": { + "test": { + "plugins": [ + "transform-es2015-classes", + "transform-es2015-for-of", + "babel-plugin-transform-async-to-generator", + ["transform-es2015-spread", { + "loose": true + }] + ] + } + } } diff --git a/.eslintrc.js b/.eslintrc.js index cebdda00..e009f3c1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,6 +6,7 @@ module.exports = { rules: { indent: ['error', 4, { 'SwitchCase': 1 }], 'no-var': 'error', + 'no-console': 'error', 'prefer-rest-params': 0, // arguments work faster 'no-param-reassign': ["error", { "props": false }], 'no-underscore-dangle': 0, // for some hacks and array methods underscore prefix/suffix is required diff --git a/package.json b/package.json index eafd6fc6..8d450e3e 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,11 @@ "main": "matreshka.js", "scripts": { "test": "npm run node-cover && npm run check-coverage && npm run lint", - "node-test": "babel-node test/node-test/jasmine.js", - "node-cover": "babel-node node_modules/.bin/babel-istanbul cover test/node-test/jasmine.js && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", + "node-test": "BABEL_ENV=test babel-node test/node-test/jasmine.js", + "node-cover": "BABEL_ENV=test babel-node node_modules/.bin/babel-istanbul cover test/node-test/jasmine.js && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", "check-coverage": "babel-istanbul check-coverage --lines 95", "develop": "CHROME_BIN=chromium-browser karma start test/karma-test/karma.conf.js", - "karma-test": "CHROME_BIN=chromium-browser karma start test/karma-test/karma.conf.js --single-run --no-auto-watch", + "karma-test": "BABEL_ENV=test CHROME_BIN=chromium-browser karma start test/karma-test/karma.conf.js --single-run --no-auto-watch", "karma-libraries-test": "npm run karma-test && npm run karma-test -- --dom-library=jquery-1 && npm run karma-test -- --dom-library=jquery-2 && npm run karma-test -- --dom-library=jquery-3 && npm run karma-test -- --dom-library=zepto", "watch": "webpack --config ./webpack.config.js --watch", "watch-browser-test": "webpack --config test/webpack-test.config.js --watch", @@ -25,7 +25,7 @@ "npm-deploy": "npm run npm-compile && npm run npm-deploy-setup && npm run npm-publish", "bundle": "webpack --config ./webpack.config.js", "deploy-to-git": "shx rm -rf bundle && deploy-to-git", - "bundle-browser-test": "webpack --config test/webpack-test.config.js", + "bundle-browser-test": "BABEL_ENV=test webpack --config test/webpack-test.config.js", "bundle-deploy-script": "npm run bundle && npm run bundle-browser-test", "upgrade": "ncu -u -a && yarn install" }, @@ -83,6 +83,7 @@ "babel-loader": "^6.4.1", "babel-plugin-check-es2015-constants": "^6.22.0", "babel-plugin-nofn": "0.0.3", + "babel-plugin-transform-async-to-generator": "^6.24.1", "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", "babel-plugin-transform-es2015-block-scoping": "^6.24.1", "babel-plugin-transform-es2015-classes": "^6.24.1", diff --git a/src/calc/_createcalchandler.js b/src/calc/_createcalchandler.js index 71f61432..2960d1f1 100644 --- a/src/calc/_createcalchandler.js +++ b/src/calc/_createcalchandler.js @@ -15,6 +15,7 @@ export default function createCalcHandler({ const values = []; const { protector = {} } = changeEvent; const protectKey = target + def.id; + const { promiseCalc } = eventOptions; const setEventOptions = { protector, ...eventOptions, @@ -36,7 +37,20 @@ export default function createCalcHandler({ values.push(value); }); - const targetValue = apply(handler, object, values); - set(object, target, targetValue, setEventOptions); + let targetValue = apply(handler, object, values); + + if (promiseCalc) { + if (!(targetValue instanceof Promise)) { + targetValue = Promise.resolve(targetValue); + } + + targetValue + .then(promiseResult => set(object, target, promiseResult, setEventOptions)) + .catch((e) => { + throw Error(e); + }); + } else { + set(object, target, targetValue, setEventOptions); + } }; } diff --git a/test/browser-test/SpecRunner.html b/test/browser-test/SpecRunner.html index 75858201..b83e35c0 100644 --- a/test/browser-test/SpecRunner.html +++ b/test/browser-test/SpecRunner.html @@ -10,6 +10,7 @@ + diff --git a/test/spec/bindings/existence_binder_spec.js b/test/spec/bindings/existence_binder_spec.js index 5628083c..e2d60fd5 100644 --- a/test/spec/bindings/existence_binder_spec.js +++ b/test/spec/bindings/existence_binder_spec.js @@ -110,7 +110,6 @@ describe('Existence binder', () => { for (const item of arr) { bindNode(item, 'exists', ':sandbox', existence(), noDebounceFlag); - console.log(select(item, ':sandbox').__matreshkaReplacedByNode); } expect( diff --git a/test/spec/calc_spec.js b/test/spec/calc_spec.js index 7787825e..d469f715 100644 --- a/test/spec/calc_spec.js +++ b/test/spec/calc_spec.js @@ -5,6 +5,7 @@ import makeObject from '../helpers/makeobject'; import createSpy from '../helpers/createspy'; const noDebounceFlag = { debounceCalc: false }; +const delay = duration => new Promise(resolve => setTimeout(resolve, duration)); describe('calc', () => { it('adds simple dependency', () => { @@ -254,4 +255,46 @@ describe('calc', () => { expect(handler).not.toHaveBeenCalled(); }); + + it('allows to use promises via promiseCalc', async (done) => { + const obj = { + a: 1, + b: 2 + }; + + calc(obj, 'c', ['a', 'b'], (a, b) => new Promise(resolve => setTimeout(() => resolve(a + b), 10)), { + promiseCalc: true + }); + + expect(obj.c).toEqual(undefined); + obj.a = 3; + await delay(50); + expect(obj.c).toEqual(5); + obj.b = 3; + await delay(50); + expect(obj.c).toEqual(6); + + done(); + }); + + it('allows to use non-promises when promiseCalc=true', async (done) => { + const obj = { + a: 1, + b: 2 + }; + + calc(obj, 'c', ['a', 'b'], (a, b) => a + b, { + promiseCalc: true + }); + + expect(obj.c).toEqual(undefined); + obj.a = 3; + await delay(50); + expect(obj.c).toEqual(5); + obj.b = 3; + await delay(50); + expect(obj.c).toEqual(6); + + done(); + }); }); diff --git a/yarn.lock b/yarn.lock index c1c2fe45..77721ad6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -422,6 +422,16 @@ babel-helper-optimise-call-expression@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" @@ -531,10 +541,22 @@ babel-plugin-nofn@0.0.3: babel-template "^6.3.13" better-log "^1.3.1" +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" +babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"