12 changed files with 138 additions and 160 deletions
@ -1,36 +0,0 @@ |
|||
language: node_js |
|||
|
|||
node_js: |
|||
- "8" |
|||
|
|||
env: |
|||
matrix: |
|||
- TEST_TYPE=lint |
|||
- TEST_TYPE=build |
|||
- TEST_TYPE=test-all |
|||
- TEST_TYPE=test-dist |
|||
|
|||
addons: |
|||
apt: |
|||
packages: |
|||
- xvfb |
|||
|
|||
install: |
|||
- export DISPLAY=':99.0' |
|||
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & |
|||
- npm install |
|||
|
|||
script: |
|||
- | |
|||
if [ "$TEST_TYPE" = lint ]; then |
|||
npm run lint |
|||
elif [ "$TEST_TYPE" = build ]; then |
|||
npm run build |
|||
elif [ "$TEST_TYPE" = test-all ]; then |
|||
npm run test:all |
|||
elif [ "$TEST_TYPE" = test-dist ]; then |
|||
npm run site |
|||
mv dist/* ./ |
|||
php -S localhost:8000 & |
|||
DEBUG=* npm test .e2e.js |
|||
fi |
|||
@ -1,26 +0,0 @@ |
|||
# Test against the latest version of this Node.js version |
|||
environment: |
|||
nodejs_version: "8" |
|||
|
|||
# this is how to allow failing jobs in the matrix |
|||
matrix: |
|||
fast_finish: true # set this flag to immediately finish build once one of the jobs fails. |
|||
|
|||
# Install scripts. (runs after repo cloning) |
|||
install: |
|||
# Get the latest stable version of Node.js or io.js |
|||
- ps: Install-Product node $env:nodejs_version |
|||
# install modules |
|||
- npm install |
|||
# Output useful info for debugging. |
|||
- node --version |
|||
- npm --version |
|||
|
|||
# Post-install test scripts. |
|||
test_script: |
|||
- npm run lint |
|||
- npm run test:all |
|||
- npm run build |
|||
|
|||
# Don't actually build. |
|||
build: off |
|||
@ -1,44 +1,9 @@ |
|||
// [START functionsimport]
|
|||
const functions = require('firebase-functions'); |
|||
const express = require('express'); |
|||
const mock = require('./mock/index'); |
|||
|
|||
const matchMock = require('./matchMock'); |
|||
const app = express(); |
|||
const sendData = (body, req, res) => { |
|||
if (!body) { |
|||
res.send('test'); |
|||
return ''; |
|||
} |
|||
if (typeof body === 'function') { |
|||
body(req, res); |
|||
} |
|||
res.send(body); |
|||
}; |
|||
app.get('/api', (req, res) => { |
|||
const html = Object.keys(mock).map(url => { |
|||
const href = url.split(' /')[1]; |
|||
return `<li><a href="${href}"><code>${url}</code></a></li>`; |
|||
}); |
|||
res.send(`<ul>${html.join('')}</ul>`); |
|||
}); |
|||
app.get('/', (req, res) => { |
|||
res.send(`<ul><li><a href="api/api"><code>/api</code></a></li></ul>`); |
|||
}); |
|||
|
|||
Object.keys(mock).forEach(url => { |
|||
const body = mock[url]; |
|||
const urlParams = url.split(' '); |
|||
|
|||
const path = urlParams[1]; |
|||
const send = (req, res) => { |
|||
sendData(body, req, res); |
|||
}; |
|||
if (urlParams[0] === 'GET') { |
|||
app.get(path, send); |
|||
} |
|||
if (urlParams[0] === 'POST') { |
|||
app.post(path, send); |
|||
} |
|||
}); |
|||
app.use(matchMock); |
|||
|
|||
exports.api = functions.https.onRequest(app); |
|||
|
|||
@ -0,0 +1,117 @@ |
|||
const mockFile = require('./mock/index'); |
|||
const pathToRegexp = require('path-to-regexp'); |
|||
const debug = console.log; |
|||
const bodyParser = require('body-parser'); |
|||
|
|||
const BODY_PARSED_METHODS = ['post', 'put', 'patch']; |
|||
|
|||
function parseKey(key) { |
|||
let method = 'get'; |
|||
let path = key; |
|||
if (key.indexOf(' ') > -1) { |
|||
const splited = key.split(' '); |
|||
method = splited[0].toLowerCase(); |
|||
path = splited[1]; // eslint-disable-line
|
|||
} |
|||
return { |
|||
method, |
|||
path, |
|||
}; |
|||
} |
|||
|
|||
function createHandler(method, path, handler) { |
|||
return function(req, res, next) { |
|||
if (BODY_PARSED_METHODS.includes(method)) { |
|||
bodyParser.json({ limit: '5mb', strict: false })(req, res, () => { |
|||
bodyParser.urlencoded({ limit: '5mb', extended: true })(req, res, () => { |
|||
sendData(); |
|||
}); |
|||
}); |
|||
} else { |
|||
sendData(); |
|||
} |
|||
|
|||
function sendData() { |
|||
if (typeof handler === 'function') { |
|||
handler(req, res, next); |
|||
} else { |
|||
res.json(handler); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function normalizeConfig(config) { |
|||
return Object.keys(config).reduce((memo, key) => { |
|||
const handler = config[key]; |
|||
const { method, path } = parseKey(key); |
|||
const keys = []; |
|||
const re = pathToRegexp(path, keys); |
|||
memo.push({ |
|||
method, |
|||
path, |
|||
re, |
|||
keys, |
|||
handler: createHandler(method, path, handler), |
|||
}); |
|||
return memo; |
|||
}, []); |
|||
} |
|||
|
|||
const mockData = normalizeConfig(mockFile); |
|||
|
|||
function matchMock(req) { |
|||
const { path: exceptPath } = req; |
|||
const exceptMethod = req.method.toLowerCase(); |
|||
for (const mock of mockData) { |
|||
const { method, re, keys } = mock; |
|||
if (method === exceptMethod) { |
|||
const match = re.exec(req.path); |
|||
if (match) { |
|||
const params = {}; |
|||
|
|||
for (let i = 1; i < match.length; i = i + 1) { |
|||
const key = keys[i - 1]; |
|||
const prop = key.name; |
|||
const val = decodeParam(match[i]); |
|||
|
|||
if (val !== undefined || !hasOwnProperty.call(params, prop)) { |
|||
params[prop] = val; |
|||
} |
|||
} |
|||
req.params = params; |
|||
return mock; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function decodeParam(val) { |
|||
if (typeof val !== 'string' || val.length === 0) { |
|||
return val; |
|||
} |
|||
|
|||
try { |
|||
return decodeURIComponent(val); |
|||
} catch (err) { |
|||
if (err instanceof URIError) { |
|||
err.message = `Failed to decode param ' ${val} '`; |
|||
err.status = err.statusCode = 400; |
|||
} |
|||
|
|||
throw err; |
|||
} |
|||
} |
|||
|
|||
return mockData.filter(({ method, re }) => { |
|||
return method === exceptMethod && re.test(exceptPath); |
|||
})[0]; |
|||
} |
|||
module.exports = (req, res, next) => { |
|||
const match = matchMock(req); |
|||
if (match) { |
|||
debug(`mock matched: [${match.method}] ${match.path}`); |
|||
return match.handler(req, res, next); |
|||
} else { |
|||
return next(); |
|||
} |
|||
}; |
|||
@ -1,33 +0,0 @@ |
|||
import api from '../mock/api'; |
|||
import chart from '../mock/chart'; |
|||
import geographic from '../mock/geographic'; |
|||
import notices from '../mock/notices'; |
|||
import profile from '../mock/profile'; |
|||
import rule from '../mock/rule'; |
|||
import user from '../mock/user'; |
|||
|
|||
const data = {}; |
|||
Object.keys(api).forEach(key => { |
|||
data[key] = api[key]; |
|||
}); |
|||
Object.keys(chart).forEach(key => { |
|||
data[key] = chart[key]; |
|||
}); |
|||
|
|||
Object.keys(geographic).forEach(key => { |
|||
data[key] = geographic[key]; |
|||
}); |
|||
Object.keys(notices).forEach(key => { |
|||
data[key] = notices[key]; |
|||
}); |
|||
Object.keys(profile).forEach(key => { |
|||
data[key] = profile[key]; |
|||
}); |
|||
Object.keys(rule).forEach(key => { |
|||
data[key] = rule[key]; |
|||
}); |
|||
Object.keys(user).forEach(key => { |
|||
data[key] = user[key]; |
|||
}); |
|||
|
|||
export default data; |
|||
@ -0,0 +1,3 @@ |
|||
const generateMock = require('merge-umi-mock-data'); |
|||
const path = require('path'); |
|||
generateMock(path.join(__dirname, '../mock'), path.join(__dirname, '../functions/mock/index.js')); |
|||
@ -1,16 +0,0 @@ |
|||
import json from 'rollup-plugin-json'; |
|||
// rollup.config.js
|
|||
export default { |
|||
input: './all_mock.js', |
|||
output: { |
|||
file: '../functions/mock/index.js', |
|||
format: 'umd', |
|||
name: 'mock', |
|||
}, |
|||
plugins: [ |
|||
json({ |
|||
preferConst: true, // Default: false
|
|||
indent: ' ', |
|||
}), |
|||
], |
|||
}; |
|||
Loading…
Reference in new issue