diff --git a/internals/flow/CSSModule.js.flow b/internals/flow/CSSModule.js.flow
deleted file mode 100644
index 6bd2a54f..00000000
--- a/internals/flow/CSSModule.js.flow
+++ /dev/null
@@ -1,3 +0,0 @@
-// @flow
-
-declare export default { [key: string]: string }
\ No newline at end of file
diff --git a/internals/flow/WebpackAsset.js.flow b/internals/flow/WebpackAsset.js.flow
deleted file mode 100644
index 37d49d3e..00000000
--- a/internals/flow/WebpackAsset.js.flow
+++ /dev/null
@@ -1,2 +0,0 @@
-// @flow
-declare export default string
diff --git a/internals/img/eslint-padded-90.png b/internals/img/eslint-padded-90.png
deleted file mode 100644
index d3c59cba..00000000
Binary files a/internals/img/eslint-padded-90.png and /dev/null differ
diff --git a/internals/img/eslint-padded.png b/internals/img/eslint-padded.png
deleted file mode 100644
index d6f9a1af..00000000
Binary files a/internals/img/eslint-padded.png and /dev/null differ
diff --git a/internals/img/eslint.png b/internals/img/eslint.png
deleted file mode 100755
index 7fc0e980..00000000
Binary files a/internals/img/eslint.png and /dev/null differ
diff --git a/internals/img/flow-padded-90.png b/internals/img/flow-padded-90.png
deleted file mode 100644
index 3ee97f0c..00000000
Binary files a/internals/img/flow-padded-90.png and /dev/null differ
diff --git a/internals/img/flow-padded.png b/internals/img/flow-padded.png
deleted file mode 100644
index 35ebd029..00000000
Binary files a/internals/img/flow-padded.png and /dev/null differ
diff --git a/internals/img/flow.png b/internals/img/flow.png
deleted file mode 100755
index f4c4bed7..00000000
Binary files a/internals/img/flow.png and /dev/null differ
diff --git a/internals/img/jest-padded-90.png b/internals/img/jest-padded-90.png
deleted file mode 100644
index 1f942a87..00000000
Binary files a/internals/img/jest-padded-90.png and /dev/null differ
diff --git a/internals/img/jest-padded.png b/internals/img/jest-padded.png
deleted file mode 100644
index ff62dd02..00000000
Binary files a/internals/img/jest-padded.png and /dev/null differ
diff --git a/internals/img/jest.png b/internals/img/jest.png
deleted file mode 100644
index 3923b0bc..00000000
Binary files a/internals/img/jest.png and /dev/null differ
diff --git a/internals/img/js-padded.png b/internals/img/js-padded.png
deleted file mode 100644
index d1f0ba60..00000000
Binary files a/internals/img/js-padded.png and /dev/null differ
diff --git a/internals/img/js.png b/internals/img/js.png
deleted file mode 100755
index 7f492390..00000000
Binary files a/internals/img/js.png and /dev/null differ
diff --git a/internals/img/npm.png b/internals/img/npm.png
deleted file mode 100755
index 06c649a8..00000000
Binary files a/internals/img/npm.png and /dev/null differ
diff --git a/internals/img/react-padded-90.png b/internals/img/react-padded-90.png
deleted file mode 100644
index d10d9f28..00000000
Binary files a/internals/img/react-padded-90.png and /dev/null differ
diff --git a/internals/img/react-padded.png b/internals/img/react-padded.png
deleted file mode 100644
index a5f24293..00000000
Binary files a/internals/img/react-padded.png and /dev/null differ
diff --git a/internals/img/react-router-padded-90.png b/internals/img/react-router-padded-90.png
deleted file mode 100644
index 711d7412..00000000
Binary files a/internals/img/react-router-padded-90.png and /dev/null differ
diff --git a/internals/img/react-router-padded.png b/internals/img/react-router-padded.png
deleted file mode 100644
index a0c4ac95..00000000
Binary files a/internals/img/react-router-padded.png and /dev/null differ
diff --git a/internals/img/react-router.png b/internals/img/react-router.png
deleted file mode 100644
index a926678b..00000000
Binary files a/internals/img/react-router.png and /dev/null differ
diff --git a/internals/img/react.png b/internals/img/react.png
deleted file mode 100755
index b82579d5..00000000
Binary files a/internals/img/react.png and /dev/null differ
diff --git a/internals/img/redux-padded-90.png b/internals/img/redux-padded-90.png
deleted file mode 100644
index 7d96a6a6..00000000
Binary files a/internals/img/redux-padded-90.png and /dev/null differ
diff --git a/internals/img/redux-padded.png b/internals/img/redux-padded.png
deleted file mode 100644
index fd23430b..00000000
Binary files a/internals/img/redux-padded.png and /dev/null differ
diff --git a/internals/img/redux.png b/internals/img/redux.png
deleted file mode 100755
index cda220de..00000000
Binary files a/internals/img/redux.png and /dev/null differ
diff --git a/internals/img/webpack-padded-90.png b/internals/img/webpack-padded-90.png
deleted file mode 100644
index 4076d5bd..00000000
Binary files a/internals/img/webpack-padded-90.png and /dev/null differ
diff --git a/internals/img/webpack-padded.png b/internals/img/webpack-padded.png
deleted file mode 100644
index cc1d1a22..00000000
Binary files a/internals/img/webpack-padded.png and /dev/null differ
diff --git a/internals/img/webpack.png b/internals/img/webpack.png
deleted file mode 100755
index bc437f0b..00000000
Binary files a/internals/img/webpack.png and /dev/null differ
diff --git a/internals/img/yarn-padded-90.png b/internals/img/yarn-padded-90.png
deleted file mode 100644
index a08b53ba..00000000
Binary files a/internals/img/yarn-padded-90.png and /dev/null differ
diff --git a/internals/img/yarn-padded.png b/internals/img/yarn-padded.png
deleted file mode 100644
index ca85ee2f..00000000
Binary files a/internals/img/yarn-padded.png and /dev/null differ
diff --git a/internals/img/yarn.png b/internals/img/yarn.png
deleted file mode 100644
index f406a471..00000000
Binary files a/internals/img/yarn.png and /dev/null differ
diff --git a/internals/scripts/.eslintrc b/internals/scripts/.eslintrc
new file mode 100644
index 00000000..35dc618d
--- /dev/null
+++ b/internals/scripts/.eslintrc
@@ -0,0 +1,8 @@
+{
+ "rules": {
+ "no-console": "off",
+ "global-require": "off",
+ "import/no-dynamic-require": "off",
+ "import/no-extraneous-dependencies": "off"
+ }
+}
diff --git a/internals/scripts/BabelRegister.js b/internals/scripts/BabelRegister.js
index bf41c5af..9608e76e 100644
--- a/internals/scripts/BabelRegister.js
+++ b/internals/scripts/BabelRegister.js
@@ -2,5 +2,5 @@ const path = require('path');
require('@babel/register')({
extensions: ['.es6', '.es', '.jsx', '.js', '.mjs', '.ts', '.tsx'],
- cwd: path.join(__dirname, '..', '..'),
+ cwd: path.join(__dirname, '..', '..')
});
diff --git a/internals/scripts/CheckBuildsExist.js b/internals/scripts/CheckBuildsExist.js
new file mode 100644
index 00000000..802394c0
--- /dev/null
+++ b/internals/scripts/CheckBuildsExist.js
@@ -0,0 +1,30 @@
+// Check if the renderer and main bundles are built
+import path from 'path';
+import chalk from 'chalk';
+import fs from 'fs';
+
+const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js');
+const rendererPath = path.join(
+ __dirname,
+ '..',
+ '..',
+ 'app',
+ 'dist',
+ 'renderer.prod.js'
+);
+
+if (!fs.existsSync(mainPath)) {
+ throw new Error(
+ chalk.whiteBright.bgRed.bold(
+ 'The main process is not built yet. Build it by running "yarn build-main"'
+ )
+ );
+}
+
+if (!fs.existsSync(rendererPath)) {
+ throw new Error(
+ chalk.whiteBright.bgRed.bold(
+ 'The renderer process is not built yet. Build it by running "yarn build-renderer"'
+ )
+ );
+}
diff --git a/internals/scripts/CheckBuiltsExist.js b/internals/scripts/CheckBuiltsExist.js
deleted file mode 100644
index 91510811..00000000
--- a/internals/scripts/CheckBuiltsExist.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// @flow
-// Check if the renderer and main bundles are built
-import path from 'path';
-import chalk from 'chalk';
-import fs from 'fs';
-
-function CheckBuildsExist() {
- const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js');
- const rendererPath = path.join(__dirname, '..', '..', 'app', 'dist', 'renderer.prod.js');
-
- if (!fs.existsSync(mainPath)) {
- throw new Error(
- chalk.whiteBright.bgRed.bold(
- 'The main process is not built yet. Build it by running "npm run build-main"'
- )
- );
- }
-
- if (!fs.existsSync(rendererPath)) {
- throw new Error(
- chalk.whiteBright.bgRed.bold(
- 'The renderer process is not built yet. Build it by running "npm run build-renderer"'
- )
- );
- }
-}
-
-CheckBuildsExist();
diff --git a/internals/scripts/CheckNativeDep.js b/internals/scripts/CheckNativeDep.js
index 578b6bed..1acf39ec 100644
--- a/internals/scripts/CheckNativeDep.js
+++ b/internals/scripts/CheckNativeDep.js
@@ -1,60 +1,49 @@
-// @flow
import fs from 'fs';
import chalk from 'chalk';
import { execSync } from 'child_process';
import { dependencies } from '../../package.json';
-(() => {
- if (!dependencies) return;
-
+if (dependencies) {
const dependenciesKeys = Object.keys(dependencies);
const nativeDeps = fs
.readdirSync('node_modules')
- .filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
-
+ .filter(folder => fs.existsSync(`node_modules/${folder}/binding.gyp`));
try {
// Find the reason for why the dependency is installed. If it is installed
// because of a devDependency then that is okay. Warn when it is installed
// because of a dependency
- const dependenciesObject = JSON.parse(
+ const { dependencies: dependenciesObject } = JSON.parse(
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
);
- const rootDependencies = Object.keys(dependenciesObject.dependencies);
- const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
+ const rootDependencies = Object.keys(dependenciesObject);
+ const filteredRootDependencies = rootDependencies.filter(rootDependency =>
dependenciesKeys.includes(rootDependency)
);
-
if (filteredRootDependencies.length > 0) {
const plural = filteredRootDependencies.length > 1;
console.log(`
-
-${chalk.whiteBright.bgYellow.bold('Webpack does not work with native dependencies.')}
+ ${chalk.whiteBright.bgYellow.bold(
+ 'Webpack does not work with native dependencies.'
+ )}
${chalk.bold(filteredRootDependencies.join(', '))} ${
plural ? 'are native dependencies' : 'is a native dependency'
} and should be installed inside of the "./app" folder.
-
-
-First uninstall the packages from "./package.json":
-${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
-
-${chalk.bold('Then, instead of installing the package to the root "./package.json":')}
-${chalk.whiteBright.bgRed.bold('npm install your-package --save')}
-
-${chalk.bold('Install the package to "./app/package.json"')}
-${chalk.whiteBright.bgGreen.bold('cd ./app && npm install your-package --save')}
-
-
-Read more about native dependencies at:
+ First, uninstall the packages from "./package.json":
+${chalk.whiteBright.bgGreen.bold('yarn remove your-package')}
+ ${chalk.bold(
+ 'Then, instead of installing the package to the root "./package.json":'
+ )}
+${chalk.whiteBright.bgRed.bold('yarn add your-package')}
+ ${chalk.bold('Install the package to "./app/package.json"')}
+${chalk.whiteBright.bgGreen.bold('cd ./app && yarn add your-package')}
+ Read more about native dependencies at:
${chalk.bold(
- 'https://github.com/chentsulin/electron-react-boilerplate/wiki/Module-Structure----Two-package.json-Structure'
+ 'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
)}
-
-
-`);
-
+ `);
process.exit(1);
}
} catch (e) {
console.log('Native dependencies could not be checked');
}
-})();
+}
diff --git a/internals/scripts/CheckNodeEnv.js b/internals/scripts/CheckNodeEnv.js
index b2f50bcf..8acca0a2 100644
--- a/internals/scripts/CheckNodeEnv.js
+++ b/internals/scripts/CheckNodeEnv.js
@@ -1,7 +1,6 @@
-// @flow
import chalk from 'chalk';
-export default function CheckNodeEnv(expectedEnv: string) {
+export default function CheckNodeEnv(expectedEnv) {
if (!expectedEnv) {
throw new Error('"expectedEnv" not set');
}
diff --git a/internals/scripts/CheckPortInUse.js b/internals/scripts/CheckPortInUse.js
index a61be941..982ca49e 100644
--- a/internals/scripts/CheckPortInUse.js
+++ b/internals/scripts/CheckPortInUse.js
@@ -1,19 +1,16 @@
-// @flow
import chalk from 'chalk';
import detectPort from 'detect-port';
-(function CheckPortInUse() {
- const port: string = process.env.PORT || '1212';
+const port = process.env.PORT || '1212';
- detectPort(port, (err: ?Error, availablePort: number) => {
- if (port !== String(availablePort)) {
- throw new Error(
- chalk.whiteBright.bgRed.bold(
- `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm run dev`
- )
- );
- } else {
- process.exit(0);
- }
- });
-})();
+detectPort(port, (err, availablePort) => {
+ if (port !== String(availablePort)) {
+ throw new Error(
+ chalk.whiteBright.bgRed.bold(
+ `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 yarn dev`
+ )
+ );
+ } else {
+ process.exit(0);
+ }
+});
diff --git a/internals/scripts/CheckYarn.js b/internals/scripts/CheckYarn.js
new file mode 100644
index 00000000..aa5be8d1
--- /dev/null
+++ b/internals/scripts/CheckYarn.js
@@ -0,0 +1,5 @@
+if (!/yarn\.js$/.test(process.env.npm_execpath || '')) {
+ console.warn(
+ "\u001b[33mYou don't seem to be using yarn. This could produce unexpected results.\u001b[39m"
+ );
+}
diff --git a/internals/scripts/DeleteSourceMaps.js b/internals/scripts/DeleteSourceMaps.js
new file mode 100644
index 00000000..91bbb3a1
--- /dev/null
+++ b/internals/scripts/DeleteSourceMaps.js
@@ -0,0 +1,7 @@
+import path from 'path';
+import rimraf from 'rimraf';
+
+export default function deleteSourceMaps() {
+ rimraf.sync(path.join(__dirname, '../../app/dist/*.js.map'));
+ rimraf.sync(path.join(__dirname, '../../app/*.js.map'));
+}
diff --git a/internals/scripts/ElectronRebuild.js b/internals/scripts/ElectronRebuild.js
index adb858af..2bff677c 100644
--- a/internals/scripts/ElectronRebuild.js
+++ b/internals/scripts/ElectronRebuild.js
@@ -1,19 +1,22 @@
-// @flow
import path from 'path';
import { execSync } from 'child_process';
import fs from 'fs';
-import dependencies from '../../app/package.json';
+import { dependencies } from '../../app/package.json';
const nodeModulesPath = path.join(__dirname, '..', '..', 'app', 'node_modules');
-if (Object.keys(dependencies || {}).length > 0 && fs.existsSync(nodeModulesPath)) {
+if (
+ Object.keys(dependencies || {}).length > 0 &&
+ fs.existsSync(nodeModulesPath)
+) {
const electronRebuildCmd =
'../node_modules/.bin/electron-rebuild --parallel --force --types prod,dev,optional --module-dir .';
-
const cmd =
- process.platform === 'win32' ? electronRebuildCmd.replace(/\//g, '\\') : electronRebuildCmd;
-
+ process.platform === 'win32'
+ ? electronRebuildCmd.replace(/\//g, '\\')
+ : electronRebuildCmd;
execSync(cmd, {
cwd: path.join(__dirname, '..', '..', 'app'),
+ stdio: 'inherit'
});
}
diff --git a/internals/scripts/RunTests.js b/internals/scripts/RunTests.js
deleted file mode 100644
index 45e0cd28..00000000
--- a/internals/scripts/RunTests.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import spawn from 'cross-spawn';
-import path from 'path';
-
-const pattern =
- process.argv[2] === 'e2e' ? 'test/e2e/.+\\.spec\\.js' : 'test/(?!e2e/)[^/]+/.+\\.spec\\.js$';
-
-const result = spawn.sync(
- path.normalize('./node_modules/.bin/jest'),
- [pattern, ...process.argv.slice(2)],
- { stdio: 'inherit' }
-);
-
-process.exit(result.status);
diff --git a/test/.eslintrc.json b/test/.eslintrc.json
new file mode 100644
index 00000000..9adaad74
--- /dev/null
+++ b/test/.eslintrc.json
@@ -0,0 +1,13 @@
+{
+ "extends": "plugin:testcafe/recommended",
+ "env": {
+ "jest/globals": true
+ },
+ "plugins": ["jest", "testcafe"],
+ "rules": {
+ "jest/no-disabled-tests": "warn",
+ "jest/no-focused-tests": "error",
+ "jest/no-identical-title": "error",
+ "no-console": "off"
+ }
+}
diff --git a/test/actions/__snapshots__/counter.spec.ts.snap b/test/actions/__snapshots__/counter.spec.ts.snap
new file mode 100644
index 00000000..dc692275
--- /dev/null
+++ b/test/actions/__snapshots__/counter.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`actions should decrement should create decrement action 1`] = `
+Object {
+ "type": "DECREMENT_COUNTER",
+}
+`;
+
+exports[`actions should increment should create increment action 1`] = `
+Object {
+ "type": "INCREMENT_COUNTER",
+}
+`;
diff --git a/test/actions/counter.spec.ts b/test/actions/counter.spec.ts
new file mode 100644
index 00000000..0bdd6ea5
--- /dev/null
+++ b/test/actions/counter.spec.ts
@@ -0,0 +1,45 @@
+import { spy } from 'sinon';
+import * as actions from '../../app/actions/counter';
+
+describe('actions', () => {
+ it('should increment should create increment action', () => {
+ expect(actions.increment()).toMatchSnapshot();
+ });
+
+ it('should decrement should create decrement action', () => {
+ expect(actions.decrement()).toMatchSnapshot();
+ });
+
+ it('should incrementIfOdd should create increment action', () => {
+ const fn = actions.incrementIfOdd();
+ expect(fn).toBeInstanceOf(Function);
+ const dispatch = spy();
+ const getState = () => ({ counter: 1 });
+ fn(dispatch, getState);
+ expect(dispatch.calledWith({ type: actions.INCREMENT_COUNTER })).toBe(true);
+ });
+
+ it('should incrementIfOdd shouldnt create increment action if counter is even', () => {
+ const fn = actions.incrementIfOdd();
+ const dispatch = spy();
+ const getState = () => ({ counter: 2 });
+ fn(dispatch, getState);
+ expect(dispatch.called).toBe(false);
+ });
+
+ // There's no nice way to test this at the moment...
+ it('should incrementAsync', () => {
+ return new Promise(resolve => {
+ const fn = actions.incrementAsync(1);
+ expect(fn).toBeInstanceOf(Function);
+ const dispatch = spy();
+ fn(dispatch);
+ setTimeout(() => {
+ expect(dispatch.calledWith({ type: actions.INCREMENT_COUNTER })).toBe(
+ true
+ );
+ resolve();
+ }, 5);
+ });
+ });
+});
diff --git a/test/components/Counter.spec.tsx b/test/components/Counter.spec.tsx
new file mode 100644
index 00000000..05fda86a
--- /dev/null
+++ b/test/components/Counter.spec.tsx
@@ -0,0 +1,71 @@
+/* eslint react/jsx-props-no-spreading: off */
+import { spy } from 'sinon';
+import React from 'react';
+import Enzyme, { shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { BrowserRouter as Router } from 'react-router-dom';
+import renderer from 'react-test-renderer';
+import Counter from '../../app/components/Counter';
+
+Enzyme.configure({ adapter: new Adapter() });
+
+function setup() {
+ const actions = {
+ increment: spy(),
+ incrementIfOdd: spy(),
+ incrementAsync: spy(),
+ decrement: spy()
+ };
+ const component = shallow(