mirror of
https://github.com/BoostIO/BoostNote-App.git
synced 2024-10-05 00:27:56 +03:00
Prepare Webpack HMR test
This commit is contained in:
parent
d7202e65a8
commit
7170fdf89a
16
.babelrc
Normal file
16
.babelrc
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"es2015",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
],
|
||||
"stage-2",
|
||||
"react"
|
||||
],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel",
|
||||
"transform-class-properties"
|
||||
]
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Drafter</title>
|
||||
<title>Inpad</title>
|
||||
<style>
|
||||
#content {
|
||||
position: absolute;
|
||||
@ -16,6 +16,7 @@
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="../node_modules/octicons/build/octicons.css">
|
||||
<link rel="stylesheet" type="text/css" href="../node_modules/codemirror/lib/codemirror.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
|
36
docs/testing.md
Normal file
36
docs/testing.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Testing
|
||||
|
||||
We use custom runner for testing.
|
||||
|
||||
## How to
|
||||
|
||||
Run webpack dev server
|
||||
|
||||
```
|
||||
npm test:serve
|
||||
```
|
||||
|
||||
Open another terminal and Run test runner
|
||||
|
||||
```
|
||||
npm test:run
|
||||
```
|
||||
|
||||
Then, runner will track changes from `**.spec.js` files in `src` directory and its dependencies and run the needed test.
|
||||
|
||||
## `**.spec.js`
|
||||
|
||||
Spec file should export test method to `default`.
|
||||
|
||||
```
|
||||
import assert from 'assert'
|
||||
import StorageManager from './StorageManager'
|
||||
|
||||
export default t => {
|
||||
assert.ok(true)
|
||||
}
|
||||
```
|
||||
|
||||
## Mocking
|
||||
|
||||
This feature is not implemented yet. But, it would be easily solved by using `import-loader`.
|
28
package.json
28
package.json
@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "Inpad",
|
||||
"name": "inpad",
|
||||
"version": "0.1.0",
|
||||
"description": "A simple note app for developer",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "NODE_ENV=development electron app/index.js",
|
||||
"pack": "build --dir",
|
||||
"dist": "build",
|
||||
"lint": "standard",
|
||||
"webpack": "NODE_ENV=development webpack-dev-server --config webpack.config.js",
|
||||
"test:run": "NODE_ENV=test electron ./tools/webpack-test.js",
|
||||
"test:serve": "NODE_ENV=test webpack-dev-server --config webpack.config.js",
|
||||
"rebuild": "electron-rebuild"
|
||||
},
|
||||
"keywords": [
|
||||
@ -33,6 +34,7 @@
|
||||
"electron-devtools-installer": "^2.0.1",
|
||||
"electron-rebuild": "^1.3.0",
|
||||
"file-loader": "^0.9.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"react-desktop": "^0.2.14",
|
||||
"react-hot-loader": "^3.0.0-beta.6",
|
||||
"react-router": "^3.0.0",
|
||||
@ -45,37 +47,27 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"codemirror": "^5.20.2",
|
||||
"color": "^0.11.4",
|
||||
"filenamify": "^1.2.1",
|
||||
"github-markdown-css": "^2.4.1",
|
||||
"immutable": "^3.8.1",
|
||||
"leveldown": "^1.5.0",
|
||||
"lodash": "^4.16.6",
|
||||
"moment": "^2.17.0",
|
||||
"octicons": "^5.0.1",
|
||||
"pouchdb": "^6.0.7",
|
||||
"react": "^15.3.2",
|
||||
"react-dom": "^15.3.2",
|
||||
"react-redux": "^4.4.5",
|
||||
"redux": "^3.6.0",
|
||||
"remark": "^6.2.0",
|
||||
"remark-emoji": "^1.1.1",
|
||||
"remark-html": "^5.1.0",
|
||||
"remark-lint": "^5.2.0",
|
||||
"sander": "^0.5.1",
|
||||
"styled-components": "^1.0.10"
|
||||
},
|
||||
"standard": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
[
|
||||
"es2015",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
],
|
||||
"stage-2",
|
||||
"react"
|
||||
],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel",
|
||||
"transform-class-properties"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,14 @@ const sander = require('sander')
|
||||
const path = require('path')
|
||||
const PouchDB = require('pouchdb')
|
||||
const { OrderedMap, Map, Set } = require('immutable')
|
||||
const util = require('../util')
|
||||
const util = require('lib/util')
|
||||
|
||||
const electron = require('electron')
|
||||
const { remote } = electron
|
||||
|
||||
const storagesPath = path.join(remote.app.getPath('userData'), 'storages')
|
||||
const storagesPath = process.env.NODE_ENV !== 'test'
|
||||
? path.join(remote.app.getPath('userData'), 'storages')
|
||||
: path.join(remote.app.getPath('userData'), 'test-storages')
|
||||
|
||||
let dbs
|
||||
|
||||
@ -34,7 +36,7 @@ export function init () {
|
||||
}
|
||||
// If `storages/notebook` doesn't exist, create it.
|
||||
if (!dirNames.some((dirName) => dirName === 'notebook')) {
|
||||
dirNames.unshift(path.join(storagesPath, 'notebook'))
|
||||
dirNames.unshift('notebook')
|
||||
}
|
||||
|
||||
dbs = dirNames.reduce(function (map, name) {
|
||||
@ -188,13 +190,14 @@ export function updateNote (name, noteId, payload) {
|
||||
const db = dbs.get(name)
|
||||
if (db == null) return Promise.reject(new Error('DB doesn\'t exist.'))
|
||||
|
||||
return db.get(noteId)
|
||||
return db.get('note:' + noteId)
|
||||
.then((doc) => {
|
||||
return db
|
||||
.put({}, doc, payload, {
|
||||
.put(Object.assign({}, doc, payload, {
|
||||
_id: doc._id,
|
||||
_rev: doc._rev
|
||||
})
|
||||
_rev: doc._rev,
|
||||
updatedAt: new Date()
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
23
src/main/lib/StorageManager.spec.js
Normal file
23
src/main/lib/StorageManager.spec.js
Normal file
@ -0,0 +1,23 @@
|
||||
import assert from 'assert'
|
||||
import StorageManager from './StorageManager'
|
||||
// import _ from 'lodash'
|
||||
|
||||
export default t => {
|
||||
let listTest = StorageManager.list()
|
||||
.then((map) => {
|
||||
assert.ok(map.size > 0, 'At least, one db should exist')
|
||||
assert.ok(map.has('notebook'), 'Default DB, notebook, should exist.')
|
||||
})
|
||||
|
||||
let loadAllTest = StorageManager.loadAll()
|
||||
.then(storageListMap => {
|
||||
assert.ok(storageListMap.size > 0)
|
||||
assert.ok(storageListMap.get('notebook').has('notes'))
|
||||
assert.ok(storageListMap.get('notebook').has('folders'))
|
||||
})
|
||||
|
||||
return Promise.all([
|
||||
listTest,
|
||||
loadAllTest
|
||||
])
|
||||
}
|
58
tools/webpack-test-entry.js
Normal file
58
tools/webpack-test-entry.js
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* # Test entry
|
||||
*
|
||||
* Grab `*.spec.js` files
|
||||
*
|
||||
* ## TODO
|
||||
*
|
||||
* - [ ] Render result as a react
|
||||
* - [ ] Before/After hook
|
||||
*
|
||||
*/
|
||||
|
||||
const _ = require('lodash')
|
||||
|
||||
function runTest (key, spec, isReloaded) {
|
||||
if (!_.isFunction(spec.default)) return Promise.reject(new Error('It cannot be excuted. : ' + key))
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
return spec.default()
|
||||
})
|
||||
.then(v => {
|
||||
console.info(`%c${key} ${(isReloaded ? 're-' : '')}tested successfully.`, 'color: green;')
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn('Test failed: ' + key)
|
||||
throw e
|
||||
})
|
||||
}
|
||||
|
||||
function loadContext () {
|
||||
return require.context('../src', true, /\.spec\.js$/)
|
||||
}
|
||||
|
||||
let specContext = loadContext()
|
||||
|
||||
let modules = {}
|
||||
specContext.keys().forEach(function (key) {
|
||||
let spec = specContext(key)
|
||||
modules[key] = spec
|
||||
runTest(key, spec, false)
|
||||
})
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept(specContext.id, function () {
|
||||
let reloadedContext = loadContext()
|
||||
let changedModules = reloadedContext.keys()
|
||||
.map(function (key) {
|
||||
return [key, reloadedContext(key)]
|
||||
})
|
||||
.filter(function (reloadedModule) {
|
||||
return modules[reloadedModule[0]] !== reloadedModule[1]
|
||||
})
|
||||
changedModules.forEach(function (specTuple) {
|
||||
modules[specTuple[0]] = specTuple[1]
|
||||
runTest(specTuple[0], specTuple[1], true)
|
||||
})
|
||||
})
|
||||
}
|
40
tools/webpack-test.html
Normal file
40
tools/webpack-test.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
<style>
|
||||
#content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="../node_modules/octicons/build/octicons.css">
|
||||
<link rel="stylesheet" type="text/css" href="../node_modules/codemirror/lib/codemirror.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/lib/codemirror.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/mode/meta.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/addon/mode/overlay.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/keymap/sublime.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/codemirror/addon/edit/continuelist.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../node_modules/react/dist/react.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/react-dom/dist/react-dom.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/redux/dist/redux.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/react-redux/dist/react-redux.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/immutable/dist/immutable.js"></script>
|
||||
|
||||
<script type="text/javascript" src="http://localhost:8081/assets/test.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
21
tools/webpack-test.js
Normal file
21
tools/webpack-test.js
Normal file
@ -0,0 +1,21 @@
|
||||
'use strict'
|
||||
|
||||
const electron = require('electron')
|
||||
const { app, BrowserWindow } = electron
|
||||
const path = require('path')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('ready', () => {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
mainWindow.loadURL('file://' + path.join(__dirname, '/webpack-test.html'))
|
||||
})
|
@ -4,26 +4,44 @@ const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin')
|
||||
|
||||
const config = {
|
||||
entry: {
|
||||
const port = process.env.NODE_ENV !== 'test'
|
||||
? 8080
|
||||
: 8081
|
||||
|
||||
const entry = process.env.NODE_ENV !== 'test'
|
||||
? {
|
||||
main: [
|
||||
'react-hot-loader/patch',
|
||||
'webpack-dev-server/client?http://localhost:8080',
|
||||
'webpack-dev-server/client?http://localhost:' + port,
|
||||
'webpack/hot/only-dev-server',
|
||||
'./src/main/index.js'
|
||||
]
|
||||
},
|
||||
}
|
||||
: {
|
||||
test: [
|
||||
'webpack-dev-server/client?http://localhost:' + port,
|
||||
'webpack/hot/only-dev-server',
|
||||
'./tools/webpack-test-entry.js'
|
||||
]
|
||||
}
|
||||
|
||||
const config = {
|
||||
entry,
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx'],
|
||||
alias: {
|
||||
'components': path.join(__dirname, 'src/components'),
|
||||
'lib': path.join(__dirname, 'src/lib'),
|
||||
'main': path.join(__dirname, 'src/main')
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(),
|
||||
new NodeTargetPlugin()
|
||||
new NodeTargetPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': `"${process.env.NODE_ENV}"`
|
||||
})
|
||||
],
|
||||
externals: [
|
||||
'electron',
|
||||
@ -33,12 +51,20 @@ const config = {
|
||||
'electron-devtools-installer',
|
||||
'octicons',
|
||||
'filenamify',
|
||||
'color',
|
||||
'moment',
|
||||
'remark',
|
||||
'remark-lint',
|
||||
'remark-html',
|
||||
'remark-emoji',
|
||||
'lodash',
|
||||
{
|
||||
react: 'var React',
|
||||
'react-dom': 'var ReactDOM',
|
||||
'react-redux': 'var ReactRedux',
|
||||
'redux': 'var Redux',
|
||||
'immutable': 'var Immutable'
|
||||
'immutable': 'var Immutable',
|
||||
'codemirror': 'var CodeMirror'
|
||||
}
|
||||
],
|
||||
module: {
|
||||
@ -50,7 +76,15 @@ const config = {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
],
|
||||
include: path.join(__dirname, 'src')
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
},
|
||||
{
|
||||
test: /\.json?$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'json-loader'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -59,11 +93,12 @@ const config = {
|
||||
filename: '[name].js',
|
||||
sourceMapFilename: '[name].map',
|
||||
libraryTarget: 'commonjs2',
|
||||
publicPath: 'http://localhost:8080/assets/'
|
||||
publicPath: 'http://localhost:' + port + '/assets/'
|
||||
},
|
||||
devtool: 'eval',
|
||||
devServer: {
|
||||
hot: true
|
||||
hot: true,
|
||||
port
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user