From c271c5e0e65385c7a5b9f4f22071e439605d11c8 Mon Sep 17 00:00:00 2001 From: geowarin Date: Thu, 17 Sep 2015 12:26:26 +0200 Subject: [PATCH 1/3] Use destroy lifecycle bean method instead of shutdown hook --- .../react/config/webpack/WebpackLauncher.groovy | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/backend/src/main/groovy/react/config/webpack/WebpackLauncher.groovy b/backend/src/main/groovy/react/config/webpack/WebpackLauncher.groovy index a04124f..d2dafa8 100644 --- a/backend/src/main/groovy/react/config/webpack/WebpackLauncher.groovy +++ b/backend/src/main/groovy/react/config/webpack/WebpackLauncher.groovy @@ -1,5 +1,6 @@ package react.config.webpack +import org.springframework.beans.factory.DisposableBean import org.springframework.beans.factory.InitializingBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -14,8 +15,9 @@ class WebpackLauncher { new WebpackRunner() } - class WebpackRunner implements InitializingBean { + class WebpackRunner implements InitializingBean, DisposableBean { static final String WEBPACK_SERVER_PROPERTY = 'webpack-server-loaded' + private process static boolean isWindows() { System.getProperty('os.name').toLowerCase().contains('windows') @@ -30,11 +32,16 @@ class WebpackLauncher { private void startWebpackDevServer() { String cmd = isWindows() ? 'cmd /c gradlew.bat frontend:start' : './gradlew frontend:start' - def process = cmd.execute() + process = cmd.execute() process.consumeProcessOutput(System.out, System.err) System.setProperty(WEBPACK_SERVER_PROPERTY, 'true') - System.addShutdownHook { - process.destroy() + } + + @Override + void destroy() throws Exception { + if (process) { + process.destroyForcibly() + process.waitFor() } } } From 66df7bf3f7ddfe671514318e41f1a61a727871f7 Mon Sep 17 00:00:00 2001 From: geowarin Date: Thu, 17 Sep 2015 12:26:40 +0200 Subject: [PATCH 2/3] Update node version --- frontend/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/build.gradle b/frontend/build.gradle index 78d06e8..28c603b 100644 --- a/frontend/build.gradle +++ b/frontend/build.gradle @@ -9,10 +9,10 @@ buildDir = 'dist' node { // Version of node to use. - version = '4.0.0' + version = '4.1.0' // Version of npm to use. - npmVersion = '2.14.2' + npmVersion = '2.14.3' download = true } From 16dc5566a374c9c46a9eca33616ef30621dcdc8b Mon Sep 17 00:00:00 2001 From: geowarin Date: Fri, 18 Sep 2015 11:47:34 +0200 Subject: [PATCH 3/3] Refactor tests with legit-tests --- frontend/build.gradle | 14 +++--- frontend/package.json | 6 +-- frontend/test/actions/fetchResource.spec.js | 5 ++ frontend/test/components/LoginPage.spec.js | 33 +++++++++++++ frontend/test/components/MyComponent.spec.js | 48 ++++++------------- frontend/test/components/MyComponent.spec3.js | 46 ------------------ frontend/test/utils/jsdomReact.js | 7 --- 7 files changed, 62 insertions(+), 97 deletions(-) create mode 100644 frontend/test/components/LoginPage.spec.js delete mode 100644 frontend/test/components/MyComponent.spec3.js delete mode 100644 frontend/test/utils/jsdomReact.js diff --git a/frontend/build.gradle b/frontend/build.gradle index 28c603b..38bbe75 100644 --- a/frontend/build.gradle +++ b/frontend/build.gradle @@ -17,17 +17,15 @@ node { download = true } -task bundle(type: NpmTask) { - args = ['run', 'bundle'] +task bundle(type: NpmTask, dependsOn: ['npm_install']) { + args = ['run', 'bundle'] } -task start(type: NpmTask) { - args = ['start'] +task start(type: NpmTask, dependsOn: ['npm_install']) { + args = ['start'] } -task test(type: NpmTask) { - args = ['test'] +task test(type: NpmTask, dependsOn: ['npm_install']) { + args = ['test'] } check.dependsOn(test) -start.dependsOn(npm_install) -bundle.dependsOn(npm_install) assemble.dependsOn(bundle) diff --git a/frontend/package.json b/frontend/package.json index caa79b2..366ba80 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,11 +20,10 @@ "babel": "^5.8.23", "babel-loader": "^5.3.2", "babel-plugin-module-alias": "^0.1.2", + "es6-promise": "^3.0.2", "expect": "^1.10.0", "html-webpack-plugin": "^1.6.1", - "jsdom": "^6.3.0", "mocha": "^2.3.2", - "mocha-jsdom": "^1.0.0", "nock": "^2.10.0", "react-hot-loader": "^1.3.0", "redux-devtools": "^2.1.0", @@ -32,8 +31,9 @@ "webpack-dev-server": "^1.10.1" }, "dependencies": { - "axios": "^0.5.4", + "axios": "mzabriskie/axios", "history": "^1.8.5", + "legit-tests": "^0.3.3", "react": "^0.13.3", "react-redux": "^2.1.1", "react-router": "^1.0.0-rc1", diff --git a/frontend/test/actions/fetchResource.spec.js b/frontend/test/actions/fetchResource.spec.js index ac22166..303071f 100644 --- a/frontend/test/actions/fetchResource.spec.js +++ b/frontend/test/actions/fetchResource.spec.js @@ -4,6 +4,11 @@ import { ON_FETCH } from 'actions/fetchResource'; import nock from 'nock'; describe('actions', () => { + + before(() => { + global.XMLHttpRequest = undefined; + }); + it('fetchResource must call an ON_FETCH action', (done) => { nock('http://localhost') .get('/api/simple') diff --git a/frontend/test/components/LoginPage.spec.js b/frontend/test/components/LoginPage.spec.js new file mode 100644 index 0000000..e2fb5e6 --- /dev/null +++ b/frontend/test/components/LoginPage.spec.js @@ -0,0 +1,33 @@ +import Test from 'legit-tests'; +import expect from 'expect'; +import { Promise } from 'es6-promise'; +import { LoginPage } from 'ui/LoginPage'; + +function ChangeValues(data) { + let elements = this.helpers.elements[data.elements]; + elements.forEach((element, index) => { + element.getDOMNode().value = data.values[index]; + }); +} + +describe('components', () => { + + describe('LoginPage', () => { + + it('should call login', () => { + + let props = { + login: expect.createSpy().andCall(() => Promise.resolve()) + }; + + Test() + .find('input') + .use(ChangeValues, {elements: 'input', values: ['username', 'password']}) + .find('form') + .simulate({element: 'form', method: 'submit'}) + .test(() => { + expect(props.login).toHaveBeenCalledWith('username', 'password'); + }); + }); + }); +}); diff --git a/frontend/test/components/MyComponent.spec.js b/frontend/test/components/MyComponent.spec.js index fdf6b2b..0dbfa05 100644 --- a/frontend/test/components/MyComponent.spec.js +++ b/frontend/test/components/MyComponent.spec.js @@ -1,43 +1,25 @@ +import Test from 'legit-tests'; import expect from 'expect'; -import jsdomReact from '../utils/jsdomReact'; -import React from 'react/addons'; -import MyComponent from 'ui/Component'; -import { createStore } from 'redux'; -import reducers from 'reducers/index'; - -const { TestUtils } = React.addons; - -function setup() { - const items = ['one', 'two', 'three']; - const store = createStore(reducers, { - simple: { - items: items - } - }); - - let props = { - fetch: expect.createSpy(), - store: store - }; - - const component = TestUtils.renderIntoDocument(); - - return { - output: component, - ul: TestUtils.findRenderedDOMComponentWithTag(component, 'ul').getDOMNode() - }; -} +import { MyComponent } from 'ui/Component'; describe('components', () => { - jsdomReact(); describe('MyComponent', () => { - it('should render correctly', () => { - const { ul } = setup(); + it('should render correctly using shallow renderer', () => { + + const items = ['one', 'two']; + let props = { + fetchResource: expect.createSpy(), + items: items + }; - expect(ul.children.length).toBe(3); - expect(ul.children[0].textContent).toBe('one'); + Test() + .find('button') + .simulate({method: 'click', element: 'button'}) + .test(() => { + expect(props.fetchResource).toHaveBeenCalled(); + }); }); }); }); diff --git a/frontend/test/components/MyComponent.spec3.js b/frontend/test/components/MyComponent.spec3.js deleted file mode 100644 index 3c54dae..0000000 --- a/frontend/test/components/MyComponent.spec3.js +++ /dev/null @@ -1,46 +0,0 @@ -import expect from 'expect'; -import jsdomReact from '../utils/jsdomReact'; -import React from 'react/addons'; -import { MyComponent } from 'ui/Component'; -import { createStore } from 'redux'; -import reducers from 'reducers/index'; - -const { TestUtils } = React.addons; - -function setup() { - const items = ['one', 'two']; - - let props = { - dispatch: expect.createSpy(), - items: items - }; - - let renderer = TestUtils.createRenderer(); - renderer.render(); - - let output = renderer.getRenderOutput(); - - return { - props: props, - output: output, - renderer: renderer - }; -} - -describe('components', () => { - - describe('MyComponent', () => { - - it('should render correctly using shallow renderer', () => { - const { output } = setup(); - - expect(output.type).toBe('div'); - - const ul = output.props.children.find(item => item.type === 'ul'); - expect(ul).toNotEqual(null); - - const li = ul.props.children.filter(item => item.type === 'li'); - expect(li.length).toEqual(2); - }); - }); -}); diff --git a/frontend/test/utils/jsdomReact.js b/frontend/test/utils/jsdomReact.js deleted file mode 100644 index 0083824..0000000 --- a/frontend/test/utils/jsdomReact.js +++ /dev/null @@ -1,7 +0,0 @@ -import ExecutionEnvironment from 'react/lib/ExecutionEnvironment'; -import jsdom from 'mocha-jsdom'; - -export default function jsdomReact() { - jsdom(); - ExecutionEnvironment.canUseDOM = true; -} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy