Commit fbad0279dd4439c8eb8da96d385e27acd5755c74
init
Signed-off-by: Clemens Burger <clemo@cbcode.at>Clemens Burger committed on 10/22/2016, 7:25:45 PM
Files changed
.babelrc | added |
.gitignore | added |
.gitlab-ci.yml | added |
Dockerfile.test | added |
README.md | added |
index.js | added |
lib/config.js | added |
lib/express.js | added |
lib/express/moduleLoader.js | added |
lib/form.js | added |
lib/lib.js | added |
lib/math.js | added |
package.json | added |
test/units/assets.config/config.default.js | added |
test/units/assets.config/config.js | added |
test/units/configTEST.js | added |
test/units/expressTEST.js | added |
test/units/formTEST.js | added |
test/units/libTEST.js | added |
test/units/mathTEST.js | added |
.gitlab-ci.yml | ||
---|---|---|
@@ -1,0 +1,10 @@ | ||
1 … | +before_script: | |
2 … | + - docker info | |
3 … | +stages: | |
4 … | + - test | |
5 … | + | |
6 … | +test: | |
7 … | + stage: test | |
8 … | + script: | |
9 … | + - docker build -f ./Dockerfile.test -t helperjs:test . | |
10 … | + - docker run helperjs:test |
Dockerfile.test | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 … | +FROM node:6 | |
2 … | +RUN apt-get update | |
3 … | +RUN mkdir /app | |
4 … | +WORKDIR /app | |
5 … | +COPY package.json /app/package.json | |
6 … | +RUN npm install --silent | |
7 … | +COPY . /app | |
8 … | +CMD ["npm","run", "cover"] |
README.md | ||
---|---|---|
@@ -1,0 +1,115 @@ | ||
1 … | +# devcontrol-helper | |
2 … | + | |
3 … | +## how does it work? | |
4 … | + | |
5 … | +> the best code of devcontrol in one module | |
6 … | + | |
7 … | +add it to your `package.json` file | |
8 … | + | |
9 … | +``` | |
10 … | +'dependencies':{ | |
11 … | + ... | |
12 … | +'devcontrol-helper':'git+https://git.devcontrol.org/team/helperjs.git#stable-v1' | |
13 … | +} | |
14 … | +``` | |
15 … | + | |
16 … | +## todo: | |
17 … | + | |
18 … | + - [x] tests [see reports](https://deploy.cbcode.at/deployserver/team/helperjs/stable-v1/) | |
19 … | + - [ ] express helper module | |
20 … | + | |
21 … | +## Debug | |
22 … | + | |
23 … | +see [npm package debug](https://www.npmjs.com/package/debug) | |
24 … | + | |
25 … | +`DEBUG=helper:* node app.js` | |
26 … | + | |
27 … | +or to only log 1 lib: | |
28 … | + | |
29 … | +`DEBUG=helper:form node app.js` | |
30 … | + | |
31 … | +## what can it do? | |
32 … | + | |
33 … | +- lib | |
34 … | + | |
35 … | +``` | |
36 … | +const player = new Lib('player'); | |
37 … | +player.setHook('beforeAdd',(x) => {x.name = x.name.toUpperCase();return x;}); | |
38 … | +let p1 = player.add({name:"Max Muster"}); | |
39 … | +console.log(player.getById(p1.id)); //{id:uuid,name:'Max Muster'} | |
40 … | +console.log(player.getArray()) //[p1] | |
41 … | +player.remove(p1.id); | |
42 … | +``` | |
43 … | + | |
44 … | +- form | |
45 … | + | |
46 … | +> vaitation.validator can be [validator](https://www.npmjs.com/package/validator) string or a boolean function | |
47 … | + | |
48 … | +``` | |
49 … | +let validation = {name:{type:'text',element:'input',validator:'isLength',options:{max:20,min:10},required:true}} | |
50 … | +//or | |
51 … | +let validation = {name:{type:'text',element:'input',convert:(x){return x.toUpperCase()},validator(val){return val.length > 3}} | |
52 … | +let sample = Form(validation); | |
53 … | +sample.fill(post,false); | |
54 … | +if(sample.isValid()){ | |
55 … | + pug.renderfile('form.pug',sample); | |
56 … | +}else{ | |
57 … | + pug.renderfile('success.pug',sample); | |
58 … | +} | |
59 … | +//full pug and valitation file will follow soon | |
60 … | +``` | |
61 … | + | |
62 … | +- math | |
63 … | + | |
64 … | +``` | |
65 … | +let m = new Math(); | |
66 … | +let u = m.uuid(); //unique id xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx | |
67 … | +console.log(m.checkUuid(u)) //true | |
68 … | +console.log(m.random(0,5)); //int between 0 and 5 | |
69 … | +console.log(uniqueRandomArray(10,0,30)); //[10 unique values] | |
70 … | +``` | |
71 … | + | |
72 … | +- config | |
73 … | + | |
74 … | +``` | |
75 … | +import {config} from 'devcontrol-helper'; | |
76 … | +console.log(config); //object cointaining of config.default.js, config.js, APP_ENV | |
77 … | +or | |
78 … | +import {Config} from 'devcontrol-helper'; | |
79 … | +const config = new Config(env.PWD,'APP'); //directory, env-prefix | |
80 … | +``` | |
81 … | + | |
82 … | +config.js and config.default.js can look like this | |
83 … | + | |
84 … | +``` | |
85 … | +module.exports.development = { | |
86 … | + title:'hello developer' | |
87 … | +} | |
88 … | +module.exports.test = { | |
89 … | + title:'hello test-world' | |
90 … | +} | |
91 … | +module.exports.production = { | |
92 … | + title:'hello world' | |
93 … | +} | |
94 … | +``` | |
95 … | + | |
96 … | +to overwrite an config property on execution: | |
97 … | + | |
98 … | +`APP_TITLE="meeeh" npm run start` | |
99 … | + | |
100 … | + | |
101 … | +- debug | |
102 … | + | |
103 … | + > see [npm package debug](https://www.npmjs.com/package/debug) | |
104 … | + | |
105 … | + - output 1 app: `DEBUG=helper:*` | |
106 … | + - output all debug: `DEBUG=*:error,*:info,*:debug` | |
107 … | + | |
108 … | +- express | |
109 … | + | |
110 … | +> express module is awesome, more doku and examples are comming with stable-v2 | |
111 … | + | |
112 … | +``` | |
113 … | +import * as helper from 'devcontrol-helper'; | |
114 … | +helper.express.moduleLoader(app, config, passport); | |
115 … | +``` |
index.js | ||
---|---|---|
@@ -1,0 +1,19 @@ | ||
1 … | +import Math from './lib/math.js'; | |
2 … | +import Lib from './lib/lib.js'; | |
3 … | +import Form from './lib/form.js'; | |
4 … | +import * as config from './lib/config.js'; | |
5 … | +import * as express from './lib/express.js'; | |
6 … | +import debug from 'debug'; | |
7 … | +const log = debug('helper:index:info'); | |
8 … | +const error = debug('helper:index:error'); | |
9 … | +exports.debug = debug; | |
10 … | +exports.Math = Math; | |
11 … | +exports.Lib = Lib; | |
12 … | +exports.Form = Form; | |
13 … | +exports.config = config.default; | |
14 … | +exports.Config = config.Config; | |
15 … | +exports.express = express; | |
16 … | +exports.export = function uuid(x) { | |
17 … | + error('helper.uuid() will be removed soon, use new helper.Math().uuid()'); | |
18 … | + return new Math().uuid(x); | |
19 … | +} |
lib/config.js | ||
---|---|---|
@@ -1,0 +1,33 @@ | ||
1 … | +import fs from 'fs'; | |
2 … | +import debug from 'debug'; | |
3 … | +import path from 'path'; | |
4 … | +import env2obj from 'env2obj'; | |
5 … | +import _ from 'lodash'; | |
6 … | +const log = debug('helper:config:info'); | |
7 … | +const error = debug('helper:config:error'); | |
8 … | +const debg = debug('helper:config:debug'); | |
9 … | +export class Config { | |
10 … | + constructor(basedir = process.env.PWD, prefix = 'APP') { | |
11 … | + let env = process.env.NODE_ENV || 'development'; | |
12 … | + process.env.NODE_ENV = env; | |
13 … | + this.file = {}; | |
14 … | + if (fs.existsSync(path.join(basedir, 'config.js'))) { | |
15 … | + this.file = require(path.join(basedir, 'config.js'), 'utf-8')[env]; | |
16 … | + } else { | |
17 … | + debg('file', 'did not use ', path.join(basedir, 'config.js')) | |
18 … | + } | |
19 … | + this.fileDefault = {}; | |
20 … | + if (fs.existsSync(path.join(basedir, 'config.default.js'))) { | |
21 … | + this.fileDefault = | |
22 … | + require(path.join(basedir, 'config.default.js'), 'utf-8')[env] | |
23 … | + } else { | |
24 … | + debg('file', 'did not use ', path.join(basedir, 'config.default.js')) | |
25 … | + } | |
26 … | + this.env = env2obj(prefix); | |
27 … | + this.config = _.merge(this.fileDefault, this.file, this.env); | |
28 … | + debg('used config', this.config) | |
29 … | + } | |
30 … | +} | |
31 … | +const config = new Config(); | |
32 … | + | |
33 … | +exports.default = config.config; |
lib/express.js | ||
---|---|---|
@@ -1,0 +1,2 @@ | ||
1 … | +import moduleLoader from './express/moduleLoader'; | |
2 … | +exports.moduleLoader = moduleLoader; |
lib/express/moduleLoader.js | ||
---|---|---|
@@ -1,0 +1,73 @@ | ||
1 … | +import url from 'url'; | |
2 … | +import debug from 'debug'; | |
3 … | + | |
4 … | +import path from 'path'; | |
5 … | +import mkdirp from 'mkdirp'; | |
6 … | +import express from 'express'; | |
7 … | + | |
8 … | +const log = debug('helper:express:module:info'); | |
9 … | +const error = debug('helper:express:module:error'); | |
10 … | +const dbug = debug('helper:express:module:debug'); | |
11 … | +const routes = {}; | |
12 … | + | |
13 … | +export const moduleLoader = function(app, config, ...args) { | |
14 … | + if ('undefined' !== typeof config.url.prependurl) { | |
15 … | + for (let m in config.url.modules[m]) { | |
16 … | + config.url.modules[m] = config.url.prependurl + config.url.modules[m]; | |
17 … | + } | |
18 … | + } | |
19 … | + for (let m in config.modules) { | |
20 … | + routes[m] = | |
21 … | + require(process.env.PWD + '/modules/' + m + '/route.js').default; | |
22 … | + } | |
23 … | + app.use((req, res, next) => { | |
24 … | + log(req.method, req.url); | |
25 … | + if ('undefined' === typeof res.locals) { | |
26 … | + res.locals = {}; | |
27 … | + } | |
28 … | + | |
29 … | + // res.locals.baseHost = url.parse(config.url.baseurl); | |
30 … | + if ("undefined" !== typeof config.locals) { // todo merge deep | |
31 … | + dbug("set view vars", JSON.stringify(config.locals, null, 2)); | |
32 … | + res.locals = config.locals; | |
33 … | + } | |
34 … | + res.locals.url = config.url; | |
35 … | + res.locals.user = req.user; | |
36 … | + | |
37 … | + next(); | |
38 … | + }); | |
39 … | + app.get('/', (req, res) => { res.redirect(config.url.home); }); | |
40 … | + | |
41 … | + // devcontrol middleware | |
42 … | + /* | |
43 … | + view | |
44 … | + */ | |
45 … | + function setConfig(config, m) { | |
46 … | + return function(req, res, next) { | |
47 … | + req.config = config.modules[m]; | |
48 … | + if ('undefined' === typeof res.locals) { | |
49 … | + res.locals = {}; // todo merge modules locals | |
50 … | + } | |
51 … | + next(); | |
52 … | + } | |
53 … | + } | |
54 … | + app.set('view engine', 'pug'); | |
55 … | + let views = [ path.join(process.env.PWD, './views') ]; | |
56 … | + for (let m in config.modules) { | |
57 … | + views.push(path.join(__dirname, m, 'views')); | |
58 … | + let moduleconfig = Object.assign({url : config.url}, config.modules[m], | |
59 … | + {baseurl : config.url.modules[m]}); | |
60 … | + let rout = routes[m](moduleconfig, ...args); | |
61 … | + rout.use(setConfig(config, m)); | |
62 … | + if (moduleconfig.use) { | |
63 … | + app.use(moduleconfig.baseurl, moduleconfig.use, rout); | |
64 … | + } else { | |
65 … | + app.use(moduleconfig.baseurl, rout); | |
66 … | + } | |
67 … | + rout.use('/static', | |
68 … | + express.static(process.env.PWD + '/modules/' + m + '/static')); | |
69 … | + } | |
70 … | + app.set('views', views); | |
71 … | + | |
72 … | +}; | |
73 … | +exports.default = moduleLoader; |
lib/form.js | |||
---|---|---|---|
@@ -1,0 +1,111 @@ | |||
1 … | +import debug from 'debug'; | ||
2 … | +import validator from 'validator'; | ||
3 … | +import faker from 'faker'; | ||
4 … | + | ||
5 … | +const log = debug('helper:form:info'); | ||
6 … | + | ||
7 … | +export class Form { | ||
8 … | + constructor(validation) { this.validation = validation; } | ||
9 … | + fill(object, check = true) { | ||
10 … | + for (let element in this.validation) { | ||
11 … | + if ('undefined' !== typeof object && object[element]) { | ||
12 … | + this.validation[element].value = object[element]; | ||
13 … | + } | ||
14 … | + if (check) { | ||
15 … | + this.validation[element].error = !this.isValid(element); | ||
16 … | + } | ||
17 … | + } | ||
18 … | + return this.validation; | ||
19 … | + } // end fill | ||
20 … | + isValid(element) { | ||
21 … | + if ("undefined" !== typeof element) { // check 1 element | ||
22 … | + if ("function" === typeof this.validation[element].convert) { // convert | ||
23 … | + this.validation[element].checkValue = | ||
24 … | + this.validation[element].convert(this.validation[element].value); | ||
25 … | + log("convert", element, this.validation[element].value, 'to', | ||
26 … | + this.validation[element].checkValue); | ||
27 … | + } else if ("string" === typeof this.validation[element].convert) { | ||
28 … | + log("convert", element, this.validation[element].value, 'to', | ||
29 … | + this.validation[element].checkValue); | ||
30 … | + this.validation[element].checkValue = | ||
31 … | + validator[this.validation[element].convert]( | ||
32 … | + this.validation[element].value); | ||
33 … | + } else { | ||
34 … | + this.validation[element].checkValue = this.validation[element].value; | ||
35 … | + } | ||
36 … | + // validate | ||
37 … | + log(typeof this.validation[element].validator, | ||
38 … | + typeof validator[this.validation[element].validator], | ||
39 … | + typeof this.validation[element].checkValue); | ||
40 … | + | ||
41 … | + if ("string" === typeof this.validation[element].validator && | ||
42 … | + "function" === typeof validator[this.validation[element].validator] && | ||
43 … | + "string" === | ||
44 … | + typeof this.validation[element] | ||
45 … | + .checkValue) { // validation function | ||
46 … | + log("validat by validator string", element); | ||
47 … | + return validator[this.validation[element].validator]( | ||
48 … | + this.validation[element].checkValue, | ||
49 … | + this.validation[element].options); | ||
50 … | + } else if ("function" === typeof this.validation[element].validator && | ||
51 … | + "string" === | ||
52 … | + typeof this.validation[element] | ||
53 … | + .checkValue) { // own validation function | ||
54 … | + log("validat by validator function", element); | ||
55 … | + return this.validation[element].validator( | ||
56 … | + this.validation[element].checkValue); | ||
57 … | + } else if (this.validation[element].required && | ||
58 … | + ("undefined" === typeof this.validation[element].checkValue || | ||
59 … | + "" === | ||
60 … | + this.validation[element] | ||
61 … | + .checkValue)) { // validation but no value | ||
62 … | + log("validat required but no value", element); | ||
63 … | + return false; | ||
64 … | + } else if ("undefined" === typeof this.validation[element].validator || | ||
65 … | + !this.validation[element] | ||
66 … | + .required) { // no validation or not required | ||
67 … | + log("validat no validator (true)", element); | ||
68 … | + return true; // no validation, so valid | ||
69 … | + } | ||
70 … | + return false; | ||
71 … | + | ||
72 … | + } else { // check everything | ||
73 … | + let valid = true; | ||
74 … | + for (let e in this.validation) { | ||
75 … | + if (!this.isValid(e)) { | ||
76 … | + valid = false; | ||
77 … | + } | ||
78 … | + } | ||
79 … | + return valid; | ||
80 … | + } | ||
81 … | + } // end isValid | ||
82 … | + | ||
83 … | + fakeFill(element) { | ||
84 … | + | ||
85 … | + if (element) { | ||
86 … | + if ('string' === typeof this.validation[element].fake) { | ||
87 … | + this.validation[element].value = | ||
88 … | + faker.fake(this.validation[element].fake); | ||
89 … | + log('fake fill', element, this.validation[element].value); | ||
90 … | + return true; | ||
91 … | + } else if ('function' === typeof this.validation[element].fake) { | ||
92 … | + let fake = this.validation[element].fake(); | ||
93 … | + | ||
94 … | + this.validation[element].value = faker.fake(fake); | ||
95 … | + | ||
96 … | + return true; | ||
97 … | + } | ||
98 … | + return false; | ||
99 … | + } else { | ||
100 … | + let filled = true; | ||
101 … | + for (let e in this.validation) { | ||
102 … | + if (!this.fakeFill(e)) { | ||
103 … | + filled = false; | ||
104 … | + } | ||
105 … | + } | ||
106 … | + return filled; | ||
107 … | + } | ||
108 … | + } | ||
109 … | +} | ||
110 … | + | ||
111 … | +exports.default = Form; |
lib/lib.js | ||
---|---|---|
@@ -1,0 +1,54 @@ | ||
1 … | +import debug from 'debug'; | |
2 … | +import Math from './math.js'; | |
3 … | +const log = debug('helper:lib:info'); | |
4 … | +const error = debug('helper:lib:error'); | |
5 … | +export class Lib { | |
6 … | + constructor() { | |
7 … | + this.items = []; | |
8 … | + this._hooks = {}; | |
9 … | + } | |
10 … | + getById(id) { return this.getArray().filter((item) => (item.id === id))[0]; } | |
11 … | + getArray() { return this.items.filter((item) => (!item._remove)); } | |
12 … | + add(item, overwrite = false) { | |
13 … | + log("add item", item); | |
14 … | + if ("function" === typeof this._hooks['beforeAdd']) { | |
15 … | + item = this._hooks['beforeAdd'](item); | |
16 … | + } | |
17 … | + if ('undefined' === typeof item.id) { | |
18 … | + item.id = new Math().uuid(); | |
19 … | + } | |
20 … | + let existingItem = this.getById(item.id); | |
21 … | + if ("undefined" !== typeof existingItem) { | |
22 … | + if (overwrite) { | |
23 … | + existingItem = item; | |
24 … | + return existingItem; | |
25 … | + } else { | |
26 … | + return log('add duplicate', | |
27 … | + 'item with this id already exist overwrite != true'); | |
28 … | + } | |
29 … | + } else { | |
30 … | + this.items.push(item); | |
31 … | + return item; | |
32 … | + } | |
33 … | + } | |
34 … | + | |
35 … | + setHook(type, fn) { | |
36 … | + log('setHook', type, fn); | |
37 … | + this._hooks[type] = fn; | |
38 … | + } | |
39 … | + | |
40 … | + remove(id) { | |
41 … | + log('remove item', id); | |
42 … | + this.getById(id)._remove = true; | |
43 … | + } | |
44 … | + | |
45 … | + each(cb) { | |
46 … | + let items = this.getArray(); | |
47 … | + for (let i = items.length; i >= 0; i--) { | |
48 … | + if (items[i] && items[i].id !== null) { | |
49 … | + cb(items[i]); | |
50 … | + } | |
51 … | + } | |
52 … | + } | |
53 … | +} | |
54 … | +export default Lib; |
lib/math.js | ||
---|---|---|
@@ -1,0 +1,37 @@ | ||
1 … | +import crypto from 'crypto'; | |
2 … | +export class Math { | |
3 … | + constructor() {} | |
4 … | + uuid() { | |
5 … | + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' | |
6 … | + .replace(/[xy]/g, | |
7 … | + (c) => { | |
8 … | + let r = global.Math.random() * 16 | 0, | |
9 … | + v = c == 'x' ? r : (r & 0x3 | 0x8); | |
10 … | + return v.toString(16); | |
11 … | + }) | |
12 … | + .toUpperCase(); | |
13 … | + } | |
14 … | + checkUuid(uuid) { | |
15 … | + return uuid.search( | |
16 … | + /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i) !== | |
17 … | + -1 | |
18 … | + } | |
19 … | + random(min, max) { | |
20 … | + return global.Math.floor(min + (global.Math.random() * (max + 1 - min))); | |
21 … | + // return min + offset; | |
22 … | + } | |
23 … | + uniqueRandomArray(amount, from, to) { | |
24 … | + if (amount > to - from) { | |
25 … | + return []; | |
26 … | + } | |
27 … | + let found = []; | |
28 … | + while (found.length < amount) { | |
29 … | + let r = this.random(from, to); | |
30 … | + if (found.indexOf(r) === -1) { | |
31 … | + found.push(r); | |
32 … | + } | |
33 … | + } | |
34 … | + return found; | |
35 … | + } | |
36 … | +} | |
37 … | +exports.default = Math; |
package.json | ||
---|---|---|
@@ -1,0 +1,37 @@ | ||
1 … | +{ | |
2 … | + "name": "devcontrol-helper", | |
3 … | + "version": "1.0.0", | |
4 … | + "description": "helper functions", | |
5 … | + "main": "build/index.js", | |
6 … | + "scripts": { | |
7 … | + "postinstall": "npm run build", | |
8 … | + "test": "mocha --renderer --compilers js:babel-core/register test/**/*TEST.js", | |
9 … | + "cover": "node_modules/.bin/babel-node node_modules/.bin/babel-istanbul cover node_modules/.bin/_mocha -- --recursive", | |
10 … | + "build": "babel ./index.js ./lib/*.js ./lib/**/*.js --presets babel-preset-es2015 --out-dir build/", | |
11 … | + "start-dev": "./node_modules/.bin/nodemon --ignore build/ --exec npm run build" | |
12 … | + }, | |
13 … | + "keywords": [ | |
14 … | + "helper", | |
15 … | + "functions", | |
16 … | + "included", | |
17 … | + "everywhere" | |
18 … | + ], | |
19 … | + "author": "Clemens Burger", | |
20 … | + "license": "WTFPL", | |
21 … | + "devDependencies": { | |
22 … | + "babel-istanbul": "^0.11.0", | |
23 … | + "chai": "^3.5.0", | |
24 … | + "mocha": "^3.0.2", | |
25 … | + "nodemon": "^1.10.2" | |
26 … | + }, | |
27 … | + "dependencies": { | |
28 … | + "babel-cli": "^6.9.0", | |
29 … | + "babel-preset-es2015": "^6.9.0", | |
30 … | + "debug": "^2.2.0", | |
31 … | + "env2obj": "^1.0.0", | |
32 … | + "express": "^4.14.0", | |
33 … | + "faker": "^3.1.0", | |
34 … | + "lodash": "^4.16.2", | |
35 … | + "validator": "^5.6.0" | |
36 … | + } | |
37 … | +} |
test/units/assets.config/config.default.js | ||
---|---|---|
@@ -1,0 +1,20 @@ | ||
1 … | +module.exports.test = { | |
2 … | + db:'test.db.default', | |
3 … | + deep:{ | |
4 … | + one:1, | |
5 … | + zero:2 | |
6 … | + } | |
7 … | +}; | |
8 … | +module.exports.development = { | |
9 … | + db:'dev.db.default', | |
10 … | + deep:{ | |
11 … | + one:1 | |
12 … | + } | |
13 … | +}; | |
14 … | +module.exports.production = { | |
15 … | + db:'pro.db.default', | |
16 … | + deep:{ | |
17 … | + one:1, | |
18 … | + zero:0 | |
19 … | + } | |
20 … | +}; |
test/units/assets.config/config.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 … | +module.exports.test = { | |
2 … | + db:'test.db', | |
3 … | +}; | |
4 … | +module.exports.development = { | |
5 … | + db:'dev.db', | |
6 … | + deep:{ | |
7 … | + zero:0 | |
8 … | + } | |
9 … | +}; | |
10 … | +module.exports.production = { | |
11 … | + db:'pro.db', | |
12 … | + deep:{ | |
13 … | + zero:0 | |
14 … | + } | |
15 … | +}; |
test/units/configTEST.js | ||
---|---|---|
@@ -1,0 +1,51 @@ | ||
1 … | +import * as c from '../../lib/config.js'; | |
2 … | +import {expect} from 'chai'; | |
3 … | +let defaultConfig = c.config; | |
4 … | +/*globals describe,it*/ | |
5 … | + | |
6 … | +describe('lib::CONFIG', () => { | |
7 … | + 'use strict'; | |
8 … | + describe('constructor', () => { | |
9 … | + it('should get config from file', (done) => { | |
10 … | + process.env.NODE_ENV = 'test'; | |
11 … | + let config = new c.Config(__dirname + '/assets.config/', 'TEST').config; | |
12 … | + expect(config).property('db').to.be.a('string').to.equal('test.db'); | |
13 … | + done(); | |
14 … | + }); | |
15 … | + | |
16 … | + it('should get config from env', (done) => { | |
17 … | + process.env.NODE_ENV = 'test'; | |
18 … | + process.env.TEST_DB = 'env.db'; | |
19 … | + let config = new c.Config(__dirname + '/assets.config/', 'TEST').config; | |
20 … | + expect(config).property('db').to.be.a('string').to.equal('env.db'); | |
21 … | + delete process.env.TEST_DB; | |
22 … | + done(); | |
23 … | + }); | |
24 … | + it('should merge file & env', (done) => { | |
25 … | + process.env.NODE_ENV = 'test'; | |
26 … | + process.env.TEST_SESSION = 'env.db'; | |
27 … | + let config = new c.Config(__dirname + '/assets.config/', 'TEST').config; | |
28 … | + expect(config).property('db').to.be.a('string').to.equal('test.db'); | |
29 … | + expect(config).property('session').to.be.a('string').to.equal('env.db'); | |
30 … | + done(); | |
31 … | + }); | |
32 … | + it('should merge deep', (done) => { | |
33 … | + { | |
34 … | + process.env.NODE_ENV = 'test'; | |
35 … | + let config = | |
36 … | + new c.Config(__dirname + '/assets.config/', 'DEEP').config; | |
37 … | + console.log(config); | |
38 … | + expect(config).property('deep').property('one').equal(1); | |
39 … | + expect(config).property('deep').property('zero').equal(2); | |
40 … | + } | |
41 … | + { | |
42 … | + process.env.NODE_ENV = 'production'; | |
43 … | + let config = new c.Config(__dirname + '/assets.config/', 'DEEPTEST').config; | |
44 … | + console.log(config); | |
45 … | + expect(config).property('deep').property('one').equal(1); | |
46 … | + expect(config).property('deep').property('zero').equal(0); | |
47 … | + done(); | |
48 … | + } | |
49 … | +}); | |
50 … | +}) | |
51 … | +}); |
test/units/expressTEST.js | ||
---|---|---|
@@ -1,0 +1,14 @@ | ||
1 … | +import helperExpress from '../../lib/express.js'; | |
2 … | +import {expect} from 'chai'; | |
3 … | +/*globals describe,it*/ | |
4 … | + | |
5 … | +describe('lib::EXPRESS', () => { | |
6 … | + 'use strict'; | |
7 … | + describe('constructor', () => { | |
8 … | + it('should get have moduleLoader', (done) => { | |
9 … | + expect(helperExpress).ownProperty('moduleLoader'); | |
10 … | + done(); | |
11 … | + }); | |
12 … | + | |
13 … | + }); | |
14 … | +}); |
test/units/formTEST.js | ||
---|---|---|
@@ -1,0 +1,74 @@ | ||
1 … | +import Form from '../../lib/form.js'; | |
2 … | +import Math from '../../lib/math'; | |
3 … | +import {expect} from 'chai'; | |
4 … | +describe('lib::FORM', () => { | |
5 … | + 'use strict'; | |
6 … | + describe('constructor', () => { | |
7 … | + let basicForm = { | |
8 … | + name : { | |
9 … | + required : true, | |
10 … | + validator : 'isLength', | |
11 … | + options : {min : 3, max : 70}, | |
12 … | + fake : '{{name.lastName}}' | |
13 … | + }, | |
14 … | + id : { | |
15 … | + validator : 'isInt', | |
16 … | + required : true, | |
17 … | + options : {min : 0, max : 20}, fake() { return '1' } | |
18 … | + }, | |
19 … | + sample : { | |
20 … | + required : false, | |
21 … | + validator(x) { return new Math().checkUuid(x); }, | |
22 … | + convert(x) { | |
23 … | + return x; // fake convert a=a | |
24 … | + }, | |
25 … | + fake() { return new Math().uuid(); } | |
26 … | + }, | |
27 … | + email : { | |
28 … | + convert : 'normalizeEmail', | |
29 … | + type : 'email', | |
30 … | + validator : 'isEmail', | |
31 … | + fake : '{{internet.email}}' | |
32 … | + } | |
33 … | + | |
34 … | + }; | |
35 … | + it('should fakefill to valid', (done) => { | |
36 … | + let form = new Form(basicForm); | |
37 … | + | |
38 … | + form.fakeFill(); | |
39 … | + form.fill({}, false); | |
40 … | + | |
41 … | + let valid = form.isValid(); | |
42 … | + expect(valid).equal(true); | |
43 … | + done(); | |
44 … | + }); | |
45 … | + it('should fill to valid', (done) => { | |
46 … | + let form = new Form(basicForm); | |
47 … | + form.fill({name : 'max', id : '5'}); | |
48 … | + expect(form.isValid()).equal(true); | |
49 … | + done(); | |
50 … | + }); | |
51 … | + it('should put error', (done) => { | |
52 … | + let localForm = { | |
53 … | + e1 : {validator : 'isEmail', required : true, fake : 'notamail'}, | |
54 … | + e2 : {required : false, validator(x) { return false; }}, | |
55 … | + e3 : {required : true, validator(x) { return false; }}, | |
56 … | + e4 : { | |
57 … | + required : true, | |
58 … | + convert(x) { return x; }, | |
59 … | + validator(x) { return false; } | |
60 … | + } | |
61 … | + }; | |
62 … | + Object.assign(localForm, basicForm); | |
63 … | + let form = new Form(localForm); | |
64 … | + form.fakeFill(); | |
65 … | + let res = form.fill({e4 : ''}); | |
66 … | + form.isValid(); | |
67 … | + expect(res.e1.error).equal(true, 'should mark error'); | |
68 … | + expect(res.e2.error).equal(false, 'should not mark error'); | |
69 … | + expect(res.e3.error).equal(true, 'should mark error'); | |
70 … | + expect(res.e4.error).equal(true, 'should mark error'); | |
71 … | + done(); | |
72 … | + }); | |
73 … | + }); | |
74 … | +}); |
test/units/libTEST.js | ||
---|---|---|
@@ -1,0 +1,116 @@ | ||
1 … | +import Lib from '../../lib/lib.js'; | |
2 … | +import Math from '../../lib/math.js'; | |
3 … | +import {expect} from 'chai'; | |
4 … | +/*globals describe,it*/ | |
5 … | +let lib1; | |
6 … | +describe('lib::LIB', () => { | |
7 … | + 'use strict'; | |
8 … | + describe('constructor', () => { | |
9 … | + | |
10 … | + let count = 0; | |
11 … | + // let l = Date.now(); | |
12 … | + const maxMs = 1000 / 60; | |
13 … | + let loop; | |
14 … | + it('should store in lib', (done) => { | |
15 … | + lib1 = new Lib(); | |
16 … | + let bob = lib1.add({name : 'bob'}); | |
17 … | + expect(bob).to.have.ownProperty('id', 'should have property id'); | |
18 … | + expect(bob).property('id').to.be.a('string', 'obj.id should be a string'); | |
19 … | + expect(new Math().checkUuid(bob.id)) | |
20 … | + .to.equal(true, 'obj.id should be a uuid'); | |
21 … | + expect(bob) | |
22 … | + .to.have.ownProperty('name', 'should have property id') | |
23 … | + .property('name') | |
24 … | + .to.be.a('string', 'should be a string') | |
25 … | + .equal('bob', 'should equal bob'); | |
26 … | + | |
27 … | + let max = lib1.add({name : 'max'}); | |
28 … | + expect(max) | |
29 … | + .to.have.ownProperty('id', 'should have property id') | |
30 … | + .to.have.ownProperty('name', 'should have property id') | |
31 … | + .property('id') | |
32 … | + .to.be.a('string', 'obj.id should be a string'); | |
33 … | + expect(max) | |
34 … | + .property('name') | |
35 … | + .to.be.a('string', 'should be a string') | |
36 … | + .equal('max', 'should equal max'); | |
37 … | + expect(new Math().checkUuid(bob.id)) | |
38 … | + .to.equal(true, 'obj.id should be a uuid'); | |
39 … | + done(); | |
40 … | + }); | |
41 … | + it('should remove from lib', (done) => { | |
42 … | + let found = 0; | |
43 … | + lib1.each((obj) => { | |
44 … | + found++; | |
45 … | + expect(obj) | |
46 … | + .to.have.ownProperty('id', 'should have property id') | |
47 … | + .to.have.ownProperty('name', 'should have property id') | |
48 … | + .property('name') | |
49 … | + .to.be.a('string', 'should be a string'); | |
50 … | + if (obj.name === 'bob') { | |
51 … | + lib1.remove(obj.id); | |
52 … | + } | |
53 … | + | |
54 … | + }); | |
55 … | + expect(found).equal(2, 'should contain 2 records (bob,max)'); // bob,max | |
56 … | + expect(lib1.getArray().length) | |
57 … | + .to.equal(1, 'should contain only max'); // max | |
58 … | + done(); | |
59 … | + | |
60 … | + }); | |
61 … | + it('should store element by existing id', (done) => { | |
62 … | + const lib = new Lib(); | |
63 … | + lib.add({id : 'one', name : 'max'}); | |
64 … | + lib.add({id : 'two', name : 'max2'}); | |
65 … | + expect(lib.getById('one')) | |
66 … | + .to.have.ownProperty('id', 'getById should return item with id') | |
67 … | + .to.have.ownProperty('name', 'item should have property name') | |
68 … | + .property('name') | |
69 … | + .to.be.a('string', 'name should be a string') | |
70 … | + .equal('max', 'should be expacted value - should use added id'); | |
71 … | + expect(lib.getById('two')) | |
72 … | + .to.have.ownProperty('id', 'getById should return item with id') | |
73 … | + .to.have.ownProperty('name', 'item should have property name') | |
74 … | + .property('name') | |
75 … | + .to.be.a('string', 'name should be a string') | |
76 … | + .equal('max2', 'should be expacted value - should use added id'); | |
77 … | + done(); | |
78 … | + }); | |
79 … | + it('should undefined or overwrite by adding double id', (done) => { | |
80 … | + let doublet = JSON.parse(JSON.stringify(lib1.getArray()[0])); | |
81 … | + let saveddoublet = JSON.parse(JSON.stringify(doublet)); | |
82 … | + delete doublet.name; | |
83 … | + doublet.name2 = 'franz'; | |
84 … | + // let overwrite = lib1.add(doublet, true); | |
85 … | + expect(lib1.add(doublet)).to.be.an('undefined'); | |
86 … | + | |
87 … | + let dbrecord = lib1.getById(doublet.id); | |
88 … | + expect(dbrecord) | |
89 … | + .to.have.ownProperty('id', 'getById should return item with id') | |
90 … | + .to.have.ownProperty('name', 'item should have property name') | |
91 … | + .property('name') | |
92 … | + .equal(saveddoublet.name); | |
93 … | + let addedRecord = lib1.add(doublet, true); | |
94 … | + expect(addedRecord) | |
95 … | + .to.have.ownProperty('id', 'getById should return item with id') | |
96 … | + .to.have.ownProperty('name2', 'item should have property name') | |
97 … | + .property('name2') | |
98 … | + .to.be.a('string', 'name should be a string') | |
99 … | + .equal('franz'); | |
100 … | + expect(addedRecord).to.not.ownProperty('name', 'name should not existis'); | |
101 … | + | |
102 … | + done(); | |
103 … | + | |
104 … | + }); | |
105 … | + it('should call hook beforeAdd', (done) => { | |
106 … | + lib1.setHook('beforeAdd', (x) => { | |
107 … | + x.hooked = true; | |
108 … | + return x; | |
109 … | + }); | |
110 … | + let item = lib1.add({id : 'hooktest'}); | |
111 … | + expect(item).to.have.ownProperty('hooked').property('hooked').equal(true); | |
112 … | + done(); | |
113 … | + }); | |
114 … | + | |
115 … | + }); | |
116 … | +}); |
test/units/mathTEST.js | ||
---|---|---|
@@ -1,0 +1,42 @@ | ||
1 … | +import Lib from '../../lib/lib.js'; | |
2 … | +import Math from '../../lib/math.js'; | |
3 … | +import {expect} from 'chai'; | |
4 … | +/*globals describe,it*/ | |
5 … | + | |
6 … | +describe('lib::MATH', () => { | |
7 … | + 'use strict'; | |
8 … | + let lib = new Lib(); | |
9 … | + let m = new Math(); | |
10 … | + describe('constructor', () => { | |
11 … | + it('should get 500 unique uuids', (done) => { | |
12 … | + for (let i = 0; i < 500; i++) { | |
13 … | + lib.add({id : m.uuid()}); | |
14 … | + } | |
15 … | + expect(lib.getArray()).property('length').to.be.a('number').equal(500); | |
16 … | + done(); | |
17 … | + }); | |
18 … | + it('should veryfy 500 uuid', (done) => { | |
19 … | + lib.each((x) => { expect(m.checkUuid(x.id)).equal(true); }); | |
20 … | + done(); | |
21 … | + }); | |
22 … | + it('should get 10 random nr between 5 and 10', (done) => { | |
23 … | + for (let i = 0; i < 10; i++) { | |
24 … | + let i = m.random(5, 10); | |
25 … | + expect(i).to.be.a('number'); | |
26 … | + expect(i).to.satisfy((num) => { return num >= 5 && num <= 10; }); | |
27 … | + } | |
28 … | + done(); | |
29 … | + }); | |
30 … | + it('should get a array with unique random values', (done) => { | |
31 … | + let u = m.uniqueRandomArray(10, 0, 30); | |
32 … | + expect(u).property('length').equal(10); | |
33 … | + | |
34 … | + done(); | |
35 … | + }); | |
36 … | + it('should throw on limited random array', (done) => { | |
37 … | + expect(m.uniqueRandomArray(10, 0, 5)).property('length').equal(0); | |
38 … | + done(); | |
39 … | + }); | |
40 … | + | |
41 … | + }); | |
42 … | +}); |
Built with git-ssb-web