├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .husky └── pre-commit ├── .npmignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── _dist ├── LICENSE.md ├── README.md └── lib │ ├── picodb.js │ ├── picodb.min.js │ ├── picodb.min.mjs │ └── picodb.mjs ├── index.js ├── lib ├── picodb.js └── picodb.mjs ├── package-lock.json ├── package.json ├── rmdstore.sh ├── scripts ├── build.js.dev.js ├── build.js.prod.js ├── build.skeleton.prod.js └── config.js ├── src ├── lib │ ├── _.js │ └── plugin.js ├── picodb.js └── private │ ├── count.js │ ├── delete.js │ ├── find.js │ ├── geo.js │ ├── insert.js │ ├── projection.js │ ├── query.js │ └── update.js └── test ├── int ├── lib.js └── private │ ├── _.js │ ├── count.js │ ├── count │ ├── count_1.js │ ├── count_2.js │ └── count_3.js │ ├── delete.js │ ├── delete │ ├── delete_1.js │ ├── delete_2.js │ └── delete_3.js │ ├── event.js │ ├── event │ ├── event_1.js │ └── event_2.js │ ├── find.js │ ├── find │ ├── find_1.js │ ├── find_2.js │ └── find_3.js │ ├── geo.js │ ├── geo │ ├── geo_1.js │ ├── geo_2.js │ ├── geo_3.js │ ├── geodb.js │ └── usa.js │ ├── insert.js │ ├── insert │ ├── insert_1.js │ ├── insertmany.js │ └── insertone.js │ ├── plugin.js │ ├── plugin │ ├── plugin_1.js │ └── plugin_2.js │ ├── query.js │ ├── query │ ├── query_1.js │ ├── query_2.js │ ├── query_3.js │ ├── query_4.js │ └── query_5.js │ ├── update.js │ └── update │ ├── update_1.js │ ├── update_2.js │ ├── update_3.js │ ├── update_4.js │ ├── update_5.js │ └── update_6.js └── main.js /.eslintignore: -------------------------------------------------------------------------------- 1 | _dist/lib/picodb.min.* 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | * Set JavaScript language options 4 | */ 5 | "parserOptions": { 6 | "sourceType": "module" 7 | }, 8 | /** 9 | * Set Environnement 10 | */ 11 | "env": { 12 | "browser": true 13 | }, 14 | /** 15 | * Set globals 16 | */ 17 | "globals": { 18 | }, 19 | /** 20 | * Set rules 21 | */ 22 | "extends": "airbnb-base", 23 | // Overwritten airbnb's rules: 24 | "rules": { 25 | "strict": ["error", "global"], 26 | "func-names": ["error", "never"], 27 | "space-before-function-paren": ["error", { "anonymous": "never", "named": "never", "asyncArrow": "always" }], 28 | "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }], 29 | "no-multi-spaces": [2, { "exceptions": { "VariableDeclarator": true } }], 30 | "comma-style": ["error", "first", { "exceptions": { "ArrayExpression": true, "ObjectExpression": true } }], 31 | "indent": ["error", 2, { "VariableDeclarator": { "const": 2 }, "SwitchCase": 1 }], 32 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 0 }] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node. 2 | name: CI pipeline 3 | 4 | on: 5 | push: 6 | branches: [ master, main ] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: 18 16 | - run: npm install 17 | - run: npm run build:dev 18 | - run: npm test 19 | - run: npm run check:coverage 20 | 21 | - name: Coveralls 22 | uses: coverallsapp/github-action@v2 23 | # -- oOo -- 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _old_* 3 | 4 | coverage 5 | node_modules 6 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run build:dev 5 | npm run build:prod 6 | npm test 7 | npm run check:coverage 8 | npm run report 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !_dist/**/* 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### HEAD 2 | 3 | 4 | ### 1.0.6 (February 1, 2024) 5 | 6 | * Updated the project with ES6Kadoo v2.1 (no Gulp, Github Actions), 7 | * Release. 8 | 9 | 10 | ### 1.0.5 (May 18, 2023) 11 | 12 | * Updated the project dependencies, 13 | * Fixed versioning, 14 | * Updated .travis.yml, 15 | * Release. 16 | 17 | 18 | ### 1.0.4 (January 27, 2022) 19 | 20 | * Updated the project dependencies, 21 | * Updated the copyright, 22 | * Release. 23 | 24 | 25 | ### 1.0.3 (November 14, 2021) 26 | 27 | * Fixed a typo in the README that prevented badges to be displayed properly, 28 | * Release. 29 | 30 | 31 | ### 1.0.2 (November 13, 2021) 32 | 33 | * Updated the project dependencies, 34 | * Release. 35 | 36 | 37 | ### 1.0.1 (January 29, 2021) 38 | 39 | * Updated the project dependencies, 40 | * Release. 41 | 42 | 43 | ### 1.0.0 (November 7, 2020) 44 | 45 | * Reshuffled the project from ES6Kadoo boilerplate, 46 | * Updated the code to comply with ES6 standard only, 47 | * Added promises, 48 | * Added the logical operator $and for explicit AND (before AND was implicit only), 49 | * Updated README.md, 50 | * Added MongoDB dot notation capability to query fields, 51 | * Added the support of the query { $and: [{ $or: [...] }, { $or: [...] }]}, 52 | * First release candidate, 53 | * Removed the "_db._silent" option (testing purpose only), 54 | * Second release candidate, 55 | * Release. 56 | 57 | 58 | ### 0.12.2 (August 20, 2020) 59 | 60 | * Updated the project dependencies, 61 | * Fixed and closed issue #8, 62 | * Release. 63 | 64 | 65 | ### 0.12.1 (December 16, 2019) 66 | 67 | * Updated the dependencies, 68 | * Release. 69 | 70 | 71 | ### 0.12.0 (April 1, 2019) 72 | 73 | * Reshuffled the library, 74 | * Closed issue #2 as we intend to keep PicoDB free of dependencies, 75 | * Closed issue #3 as implicit $and is already implemented, 76 | * Release. 77 | 78 | 79 | ### 0.11.0 (March 30, 2019) 80 | 81 | * Updated the project to comply with Gulp 4 and ESLint 5, 82 | * Release. 83 | 84 | 85 | ### 0.10.1 (November 7, 2017) 86 | 87 | * Fixed a timeout issue on a find request when the database is not initialized, 88 | * Release. 89 | 90 | 91 | ### 0.10.0 (August 19, 2017) 92 | 93 | * Simplified the creation of the object PicoDB with the pattern Prototypal Instantiation, 94 | * Release. 95 | 96 | 97 | ### 0.9.0 (August 17, 2017) 98 | 99 | * Reworked the build to make it more modular, 100 | * Modified the test files to comply with ES6 standard, 101 | * Release. 102 | 103 | 104 | ### 0.8.5 (April 28, 2017) 105 | 106 | * Updated the dependencies, 107 | * Release 0.8.5. 108 | 109 | 110 | ### 0.8.4 (February 3, 2017) 111 | 112 | * Updated the dependencies and the product description, 113 | * Release 0.8.4. 114 | 115 | 116 | ### 0.8.3 (January 14, 2017) 117 | 118 | * Fixed a mismatch between the version number of the library and the package, 119 | * Release 0.8.3. 120 | 121 | 122 | ### 0.8.2 (January 12, 2017) 123 | 124 | * Fixed a regression for the method 'update' when a doc. is replaced by a new one (no operator), 125 | * Release 0.8.2. 126 | 127 | 128 | ### 0.8.1 (December 27, 2016) 129 | 130 | * Updated the dependencies and replaced the deprecated ghooks module by Husky, 131 | * Updated .travis.yml to run the tests with the latest stable version of Node.js, 132 | * Release 0.8.1. 133 | 134 | 135 | ### 0.8.0 (October 11, 2016) 136 | 137 | * Updated the module to comply with Airbnb's ESLint rules, 138 | * Release 0.8.0. 139 | 140 | 141 | ### 0.7.1 (June 20, 2016) 142 | 143 | * Removed unused files, 144 | * Release 0.7.1. 145 | 146 | 147 | ### 0.7.0 (June 11, 2016) 148 | 149 | * Added a basic projection (without operators), 150 | * Release 0.7.0. 151 | 152 | 153 | ### 0.6.0 (June 9, 2016) 154 | 155 | * Added the GeoSpatial Query Operators $geoWithin and $geoIntersects, 156 | * Extended $geoWithin/$geometry with LineString, MultiPoint, MultiLineString and Polygon geometries, 157 | * Added the GeoSpatial Operator $near, 158 | * Release 0.6.0. 159 | 160 | 161 | ### 0.5.0 (June 2, 2016) 162 | 163 | * Added the Update Operator $pullAll, 164 | * Increased the test coverage, 165 | * Added the usage of multiple query operators in the same condition (ex: { $gt: 1, $lt: 5 }), 166 | * Release 0.5.0. 167 | 168 | 169 | ### 0.4.0 (May 27, 2016) 170 | 171 | * Added the Update Operator $pull, 172 | * Release 0.4.0. 173 | 174 | 175 | ### 0.3.0 (May 26, 2016) 176 | 177 | * Added the Update Operators $push and $pop, 178 | * Release 0.3.0. 179 | 180 | 181 | ### 0.2.0 (May 24, 2016) 182 | 183 | * Added the Update Operators $inc, $mul, $rename, $min, $max and $currentDate, 184 | * Release 0.2.0. 185 | 186 | 187 | ### 0.1.0 (May 18, 2016) 188 | 189 | * First release. 190 | 191 | 192 | ### 0.0.0 (May 10, 2016) 193 | 194 | * Initial build. 195 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Mobilabs (http://www.mobilabs.fr) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /_dist/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Mobilabs (http://www.mobilabs.fr) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/picodb'); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "picodb", 3 | "version": "1.0.6", 4 | "description": "A tiny in-memory database (MongoDB like) that stores JSON documents", 5 | "main": "_dist/lib/picodb.js", 6 | "minified": "_dist/lib/picodb.min.js", 7 | "unpkg": "_dist/lib/picodb.mjs", 8 | "module": "_dist/lib/picodb.min.mjs", 9 | "bin": {}, 10 | "scripts": { 11 | "general": " --- GENERAL ---", 12 | 13 | "build:js": " --- JAVASCRIPT --- ", 14 | "build:js:dev": "node scripts/build.js.dev.js $1", 15 | "build:js:prod": "node scripts/build.js.prod.js $1", 16 | 17 | "build:css": " --- CSS --- ", 18 | 19 | "build:generic": " --- BUILD (GENERIC) --- ", 20 | 21 | "build:development": " --- BUILD (DEVELOPMENT) --- ", 22 | "build:dev": "npm run build:js:dev", 23 | 24 | "build:production": " --- BUILD (PRODUCTION) --- ", 25 | "build:skeleton:prod": "node scripts/build.skeleton.prod.js $1", 26 | "prebuild:prod": "npm run build:dev && npm run build:skeleton:prod", 27 | "build:prod": "npm run build:js:prod", 28 | 29 | "testing": " --- TESTING --- ", 30 | "test": "cross-env NODE_ENV=test c8 --reporter=lcov mocha --require esm ./test/main.js", 31 | "display:coverage": "open -a safari ./coverage/lcov-report/index.html", 32 | "check:coverage": "c8 check-coverage --statements 90 --branches 90 --functions 90 --lines 90", 33 | "report": "c8 report", 34 | 35 | "serving": " --- SERVING --- ", 36 | "server:dev": "http-server --port 8080", 37 | "server:prod": "http-server --port 8090", 38 | 39 | "watch:js:css": " --- WATCHING --- ", 40 | "watch:js": "nodemon --watch './src/**/*.js' --exec npm run build:dev", 41 | "watch": "npm run watch:js", 42 | 43 | "deployment": " --- DEPLOYMENT --- ", 44 | "dep:prod": "rm -rf _dist-$npm_package_version && npm run build:prod && cp -r _dist _dist-$npm_package_version", 45 | 46 | "others": " --- OTHERS ---", 47 | "prepare": "husky install", 48 | "doc": "" 49 | }, 50 | "repository": { 51 | "type": "git", 52 | "url": "https://github.com/jclo/picodb.git" 53 | }, 54 | "keywords": [ 55 | "mongodb", 56 | "mongodb-like", 57 | "in-memory", 58 | "database", 59 | "db", 60 | "nosql", 61 | "json" 62 | ], 63 | "author": { 64 | "name": "Mobilabs", 65 | "email": "contact@mobilabs.fr", 66 | "url": "http://www.mobilabs.fr" 67 | }, 68 | "license": "MIT", 69 | "bugs": { 70 | "url": "https://github.com/jclo/picodb/issues" 71 | }, 72 | "homepage": "https://github.com/jclo/picodb", 73 | "dependencies": {}, 74 | "devDependencies": { 75 | "@mobilabs/messenger": "^1.0.4", 76 | "c8": "^9.0.0", 77 | "chai": "4.3.10", 78 | "cross-env": "^7.0.3", 79 | "eslint": "^8.56.0", 80 | "eslint-config-airbnb-base": "^15.0.0", 81 | "eslint-plugin-import": "^2.29.1", 82 | "esm": "^3.2.25", 83 | "http-server": "^14.1.1", 84 | "husky": "^8.0.3", 85 | "kadoo": "^1.2.0", 86 | "mocha": "^8.4.0", 87 | "nodemon": "^3.0.2", 88 | "terser": "^5.26.0", 89 | "@mobilabs/es6kadoo": "2.1.0" 90 | }, 91 | "c8": { 92 | "include": [ 93 | "src/**/*.js" 94 | ], 95 | "exclude": [], 96 | "all": false 97 | }, 98 | "publishConfig": { 99 | "access": "public" 100 | }, 101 | "private": false 102 | } 103 | -------------------------------------------------------------------------------- /rmdstore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Find '.DS_Store' 4 | find . -type f -name '.DS_Store' 5 | find . -type f -name '._.DS_Store' 6 | 7 | if [[ $1 = '-del' ]]; then 8 | echo 'Deleting ...' 9 | find . -type f -name '.DS_Store' -delete 10 | find . -type f -name '._.DS_Store' -delete 11 | fi 12 | -------------------------------------------------------------------------------- /scripts/build.js.dev.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* ***************************************************************************** 3 | * 4 | * Creates the JS bundle. 5 | * 6 | * build:js.dev script creates the JS bundle from ./public/src/main.js by importing 7 | * all the linked src files; 8 | * 9 | * Private Functions: 10 | * . _help displays the help message, 11 | * . _clean removes the previous build, 12 | * . _dogenericlib creates the generic library, 13 | * . _doumdlib creates the UMD Module, 14 | * . _domodule creates the ES6 module, 15 | * . _delgeneric removes the temp file(s), 16 | * 17 | * 18 | * Public Static Methods: 19 | * . run executes the script, 20 | * 21 | * 22 | * @namespace - 23 | * @dependencies none 24 | * @exports - 25 | * @author - 26 | * @since 0.0.0 27 | * @version - 28 | * ************************************************************************** */ 29 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0, 30 | import/no-extraneous-dependencies: 0 */ 31 | 32 | 33 | // -- Vendor Modules 34 | const fs = require('fs') 35 | , nopt = require('nopt') 36 | , Kadoo = require('kadoo') 37 | ; 38 | 39 | 40 | // -- Local Modules 41 | const pack = require('../package.json') 42 | , config = require('./config') 43 | ; 44 | 45 | 46 | // -- Local Constants 47 | const VERSION = '0.0.0-alpha.0' 48 | , opts = { 49 | help: [Boolean, false], 50 | version: [String, null], 51 | } 52 | , shortOpts = { 53 | h: ['--help'], 54 | v: ['--version', VERSION], 55 | } 56 | , parsed = nopt(opts, shortOpts, process.argv, 2) 57 | , destination = config.libdir 58 | , { ES6GLOB } = config 59 | , { source } = config 60 | , { libname } = config 61 | , { name } = config 62 | , { version } = pack 63 | ; 64 | 65 | 66 | // -- Local Variables 67 | 68 | 69 | // -- Private Functions -------------------------------------------------------- 70 | 71 | /** 72 | * Dispays the help message. 73 | * 74 | * @function () 75 | * @private 76 | * @param {} -, 77 | * @returns {} -, 78 | * @since 0.0.0 79 | */ 80 | function _help() { 81 | const message = ['', 82 | 'Usage: command [options]', 83 | '', 84 | ' creates the js bundle(s) from ./public/src/main.js', 85 | '', 86 | 'Options:', 87 | '', 88 | '-h, --help output usage information', 89 | '-v, --version output the version number', 90 | '', 91 | ].join('\n'); 92 | 93 | process.stdout.write(`${message}\n`); 94 | } 95 | 96 | /** 97 | * Removes the previous build. 98 | * 99 | * @function () 100 | * @private 101 | * @param {} -, 102 | * @returns {} -, 103 | * @since 0.0.0 104 | */ 105 | function _clean() { 106 | const d1 = new Date(); 107 | process.stdout.write('Starting \'\x1b[36mclean\x1b[89m\x1b[0m\'...\n'); 108 | 109 | return new Promise((resolve) => { 110 | fs.rm(destination, { force: true, recursive: true }, (err1) => { 111 | if (err1) throw new Error(err1); 112 | 113 | fs.mkdir(destination, { recursive: true }, (err2) => { 114 | if (err2) throw new Error(err2); 115 | 116 | const d2 = new Date() - d1; 117 | process.stdout.write(`Finished '\x1b[36mclean\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 118 | resolve(); 119 | }); 120 | }); 121 | }); 122 | } 123 | 124 | /** 125 | * Creates the generic library. 126 | * 127 | * @function () 128 | * @private 129 | * @param {} -, 130 | * @returns {Object} returns a promise, 131 | * @since 0.0.0 132 | */ 133 | function _dogeneric() { 134 | const d1 = new Date(); 135 | process.stdout.write('Starting \'\x1b[36mdogenericlib\x1b[89m\x1b[0m\'...\n'); 136 | 137 | return new Promise((resolve) => { 138 | const kadoo = Kadoo(source, { export: 'generic', type: 'generic' }); 139 | kadoo.get((data) => { 140 | const content = data 141 | .replace(/{{lib:name}}/g, libname) 142 | .replace(/{{lib:version}}/g, version) 143 | // Remove extra global. 144 | // (keep the first global only) 145 | .replace(/\/\* global/, '/* gloobal') 146 | .replace(/\/\* global[\w$_\s,]+\*\//g, '/* - */') 147 | .replace(/\/\* gloobal/, '/* global') 148 | // Remove extra 'use strict'. 149 | // (keep the two first only) 150 | .replace(/use strict/, 'use_strict') 151 | .replace(/use strict/, 'use_strict') 152 | .replace(/'use strict';/g, '/* - */') 153 | .replace(/use_strict/g, 'use strict') 154 | ; 155 | 156 | fs.writeFile(`${destination}/generic.js`, content, { encoding: 'utf8' }, (err) => { 157 | if (err) throw new Error(err); 158 | 159 | const d2 = new Date() - d1; 160 | process.stdout.write(`Finished '\x1b[36mdogenericlib\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 161 | resolve(); 162 | }); 163 | }); 164 | }); 165 | } 166 | 167 | /** 168 | * Creates the UMD Module. 169 | * 170 | * @function (arg1) 171 | * @private 172 | * @param {Function} the function to call at the completion, 173 | * @returns {} -, 174 | * @since 0.0.0 175 | */ 176 | function _doumdlib(done) { 177 | const d1 = new Date(); 178 | process.stdout.write('Starting \'\x1b[36mdoumdlib\x1b[89m\x1b[0m\'...\n'); 179 | 180 | fs.readFile(`${destination}/${'generic'}.js`, 'utf8', (err1, data) => { 181 | if (err1) throw new Error(err1); 182 | 183 | const content = data 184 | .replace('{{lib:es6:define}}\n', '') 185 | .replace('{{lib:es6:link}}', 'this') 186 | .replace('{{lib:es6:export}}\n', '') 187 | ; 188 | 189 | fs.writeFile(`${destination}/${name}.js`, content, { encoding: 'utf8' }, (err2) => { 190 | if (err2) throw new Error(err2); 191 | 192 | const d2 = new Date() - d1; 193 | process.stdout.write(`Finished '\x1b[36mdoumdlib\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 194 | done(); 195 | }); 196 | }); 197 | } 198 | 199 | /** 200 | * Creates the ES6 module. 201 | * 202 | * @function (arg1) 203 | * @private 204 | * @param {Function} the function to call at the completion, 205 | * @returns {} -, 206 | * @since 0.0.0 207 | */ 208 | function _domodule(done) { 209 | const d1 = new Date(); 210 | process.stdout.write('Starting \'\x1b[36mdomodule\x1b[89m\x1b[0m\'...\n'); 211 | 212 | fs.readFile(`${destination}/${'generic'}.js`, 'utf8', (err1, data) => { 213 | if (err1) throw new Error(err1); 214 | 215 | let exportM = '\n// -- Export\n'; 216 | exportM += `export default ${ES6GLOB}.${libname};`; 217 | 218 | const content = data 219 | .replace('{{lib:es6:define}}', `const ${ES6GLOB} = {};`) 220 | .replace('{{lib:es6:link}}', ES6GLOB) 221 | .replace('{{lib:es6:export}}', exportM) 222 | ; 223 | 224 | fs.writeFile(`${destination}/${name}.mjs`, content, { encoding: 'utf8' }, (err2) => { 225 | if (err2) throw new Error(err2); 226 | 227 | const d2 = new Date() - d1; 228 | process.stdout.write(`Finished '\x1b[36mdomodule\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 229 | done(); 230 | }); 231 | }); 232 | } 233 | 234 | /** 235 | * Removes the temp file(s). 236 | * 237 | * @function (arg1) 238 | * @private 239 | * @param {Function} the function to call at the completion, 240 | * @returns {} -, 241 | * @since 0.0.0 242 | */ 243 | function _delgeneric(done) { 244 | const d1 = new Date(); 245 | process.stdout.write('Starting \'\x1b[36mdelgeneric\x1b[89m\x1b[0m\'...\n'); 246 | 247 | fs.unlink(`${destination}/generic.js`, (err) => { 248 | if (err) throw new Error(err); 249 | 250 | const d2 = new Date() - d1; 251 | process.stdout.write(`Finished '\x1b[36mdelgeneric\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 252 | done(); 253 | }); 254 | } 255 | 256 | 257 | // -- Main --------------------------------------------------------------------- 258 | 259 | /** 260 | * Executes the script. 261 | * 262 | * @function () 263 | * @public 264 | * @param {} -, 265 | * @returns {} -, 266 | * @since 0.0.0 267 | */ 268 | async function run() { 269 | const PENDING = 2; 270 | 271 | if (parsed.help) { 272 | _help(); 273 | return; 274 | } 275 | 276 | if (parsed.version) { 277 | process.stdout.write(`version: ${parsed.version}\n`); 278 | return; 279 | } 280 | 281 | const d1 = new Date(); 282 | process.stdout.write('Starting \'\x1b[36mbuild:js:dev\x1b[89m\x1b[0m\'...\n'); 283 | 284 | let pending = PENDING; 285 | /** 286 | * Executes done until completion. 287 | */ 288 | function done() { 289 | pending -= 1; 290 | if (!pending) { 291 | _delgeneric(() => { 292 | const d2 = new Date() - d1; 293 | process.stdout.write(`Finished '\x1b[36mbuild:js:dev\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 294 | }); 295 | } 296 | } 297 | 298 | await _clean(); 299 | await _dogeneric(); 300 | _doumdlib(done); 301 | _domodule(done); 302 | } 303 | 304 | 305 | // Start script. 306 | run(); 307 | 308 | 309 | // -- oOo -- 310 | -------------------------------------------------------------------------------- /scripts/build.js.prod.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* ***************************************************************************** 3 | * 4 | * Creates the production JS files. 5 | * 6 | * build:js:prod.js script minifies JS files and copies them in the 7 | * production folder. 8 | * 9 | * Private Functions: 10 | * . _help displays the help message, 11 | * . _clean removes the previous js production files, 12 | * . _copydev builds the js production file, 13 | * . _copydevm builds the ES6 module production file, 14 | * . _makeminified builds and minifies the js production file, 15 | * . _makeminifiedm builds and minifies the ES6 module production file, 16 | * 17 | * 18 | * Public Static Methods: 19 | * . run executes the script, 20 | * 21 | * 22 | * @namespace - 23 | * @dependencies none 24 | * @exports - 25 | * @author - 26 | * @since 0.0.0 27 | * @version - 28 | * ************************************************************************** */ 29 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0, 30 | import/no-extraneous-dependencies: 0 */ 31 | 32 | 33 | // -- Vendor Modules 34 | const fs = require('fs') 35 | , nopt = require('nopt') 36 | , { minify } = require('terser') 37 | ; 38 | 39 | 40 | // -- Local Modules 41 | const config = require('./config') 42 | ; 43 | 44 | 45 | // -- Local Constants 46 | const VERSION = '0.0.0-alpha.0' 47 | , opts = { 48 | help: [Boolean, false], 49 | version: [String, null], 50 | } 51 | , shortOpts = { 52 | h: ['--help'], 53 | v: ['--version', VERSION], 54 | } 55 | , parsed = nopt(opts, shortOpts, process.argv, 2) 56 | , { dist } = config 57 | , { libdir } = config 58 | , { name } = config 59 | , { license } = config 60 | ; 61 | 62 | 63 | // -- Local Variables 64 | 65 | 66 | // -- Private Functions -------------------------------------------------------- 67 | 68 | /** 69 | * Dispays the help message. 70 | * 71 | * @function () 72 | * @private 73 | * @param {} -, 74 | * @returns {} -, 75 | * @since 0.0.0 76 | */ 77 | function _help() { 78 | const message = ['', 79 | 'Usage: command [options]', 80 | '', 81 | ' creates the js production files', 82 | '', 83 | 'Options:', 84 | '', 85 | '-h, --help output usage information', 86 | '-v, --version output the version number', 87 | '', 88 | ].join('\n'); 89 | 90 | process.stdout.write(`${message}\n`); 91 | } 92 | 93 | /** 94 | * Removes the previous js production build. 95 | * 96 | * @function () 97 | * @private 98 | * @param {} -, 99 | * @returns {} -, 100 | * @since 0.0.0 101 | */ 102 | function _clean() { 103 | const d1 = new Date(); 104 | process.stdout.write('Starting \'\x1b[36mclean\x1b[89m\x1b[0m\'...\n'); 105 | 106 | return new Promise((resolve) => { 107 | fs.rm(`${dist}/lib`, { force: true, recursive: true }, (err1) => { 108 | if (err1) throw new Error(err1); 109 | 110 | fs.mkdir(`${dist}/lib`, { recursive: true }, (err2) => { 111 | if (err2) throw new Error(err2); 112 | 113 | const d2 = new Date() - d1; 114 | process.stdout.write(`Finished '\x1b[36mclean\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 115 | resolve(); 116 | }); 117 | }); 118 | }); 119 | } 120 | 121 | /** 122 | * Builds the js production file. 123 | * 124 | * @function (arg1) 125 | * @private 126 | * @param {Function} the function to call at the completion, 127 | * @returns {} -, 128 | * @since 0.0.0 129 | */ 130 | function _copydev(done) { 131 | const d1 = new Date(); 132 | process.stdout.write('Starting \'\x1b[36mcopydev\x1b[89m\x1b[0m\'...\n'); 133 | 134 | fs.readFile(`${libdir}/${name}.js`, 'utf8', (err1, data) => { 135 | if (err1) throw new Error(err1); 136 | 137 | let content = license; 138 | content += data; 139 | fs.writeFile(`${dist}/lib/${name}.js`, content, { encoding: 'utf8' }, (err2) => { 140 | if (err2) throw new Error(err2); 141 | 142 | const d2 = new Date() - d1; 143 | process.stdout.write(`Finished '\x1b[36mcopydev\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 144 | done(); 145 | }); 146 | }); 147 | } 148 | 149 | /** 150 | * Builds the ES6 module production file. 151 | * 152 | * @function (arg1) 153 | * @private 154 | * @param {Function} the function to call at the completion, 155 | * @returns {} -, 156 | * @since 0.0.0 157 | */ 158 | function _copydevm(done) { 159 | const d1 = new Date(); 160 | process.stdout.write('Starting \'\x1b[36mcopydevm\x1b[89m\x1b[0m\'...\n'); 161 | 162 | fs.readFile(`${libdir}/${name}.mjs`, 'utf8', (err1, data) => { 163 | if (err1) throw new Error(err1); 164 | 165 | let content = license; 166 | content += data; 167 | fs.writeFile(`${dist}/lib/${name}.mjs`, content, { encoding: 'utf8' }, (err2) => { 168 | if (err2) throw new Error(err2); 169 | 170 | const d2 = new Date() - d1; 171 | process.stdout.write(`Finished '\x1b[36mcopydevm\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 172 | done(); 173 | }); 174 | }); 175 | } 176 | 177 | /** 178 | * Builds and minifies the js production file. 179 | * 180 | * @function (arg1) 181 | * @private 182 | * @param {Function} the function to call at the completion, 183 | * @returns {} -, 184 | * @since 0.0.0 185 | */ 186 | function _makeminified(done) { 187 | const d1 = new Date(); 188 | process.stdout.write('Starting \'\x1b[36mmakeminified\x1b[89m\x1b[0m\'...\n'); 189 | 190 | fs.readFile(`${libdir}/${name}.js`, 'utf8', (err1, data) => { 191 | if (err1) throw new Error(err1); 192 | 193 | let content = license; 194 | content += data.replace(/\/\*! \*\*\*/g, '/** ***'); 195 | 196 | minify(content, {}) 197 | .then((result) => { 198 | fs.writeFile(`${dist}/lib/${name}.min.js`, result.code, { encoding: 'utf8' }, (err2) => { 199 | if (err2) throw new Error(err2); 200 | 201 | const d2 = new Date() - d1; 202 | process.stdout.write(`Finished '\x1b[36mmakeminified\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 203 | done(); 204 | }); 205 | }); 206 | }); 207 | } 208 | 209 | /** 210 | * Builds and minifies the ES6 module production file. 211 | * 212 | * @function (arg1) 213 | * @private 214 | * @param {Function} the function to call at the completion, 215 | * @returns {} -, 216 | * @since 0.0.0 217 | */ 218 | function _makeminifiedm(done) { 219 | const d1 = new Date(); 220 | process.stdout.write('Starting \'\x1b[36mmakeminifiedm\x1b[89m\x1b[0m\'...\n'); 221 | 222 | fs.readFile(`${libdir}/${name}.mjs`, 'utf8', (err1, data) => { 223 | if (err1) throw new Error(err1); 224 | 225 | let content = license; 226 | content += data.replace(/\/\*! \*\*\*/g, '/** ***'); 227 | 228 | minify(content, {}) 229 | .then((result) => { 230 | fs.writeFile(`${dist}/lib/${name}.min.mjs`, result.code, { encoding: 'utf8' }, (err2) => { 231 | if (err2) throw new Error(err2); 232 | 233 | const d2 = new Date() - d1; 234 | process.stdout.write(`Finished '\x1b[36mmakeminifiedm\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 235 | done(); 236 | }); 237 | }); 238 | }); 239 | } 240 | 241 | 242 | // -- Main --------------------------------------------------------------------- 243 | 244 | /** 245 | * Executes the script. 246 | * 247 | * @function () 248 | * @public 249 | * @param {} -, 250 | * @returns {} -, 251 | * @since 0.0.0 252 | */ 253 | async function run() { 254 | const PENDING = 4; 255 | 256 | if (parsed.help) { 257 | _help(); 258 | return; 259 | } 260 | 261 | if (parsed.version) { 262 | process.stdout.write(`version: ${parsed.version}\n`); 263 | return; 264 | } 265 | 266 | const d1 = new Date(); 267 | process.stdout.write('Starting \'\x1b[36mbuild:js:prod\x1b[89m\x1b[0m\'...\n'); 268 | 269 | let pending = PENDING; 270 | /** 271 | * Executes done until completion. 272 | */ 273 | function done() { 274 | pending -= 1; 275 | if (!pending) { 276 | const d2 = new Date() - d1; 277 | process.stdout.write(`Finished '\x1b[36mbuild:js:prod\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 278 | } 279 | } 280 | 281 | await _clean(); 282 | _copydev(done); 283 | _copydevm(done); 284 | _makeminified(done); 285 | _makeminifiedm(done); 286 | } 287 | 288 | 289 | // Start script. 290 | run(); 291 | 292 | 293 | // -- oOo -- 294 | -------------------------------------------------------------------------------- /scripts/build.skeleton.prod.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* ***************************************************************************** 3 | * 4 | * Creates the production folder. 5 | * 6 | * build:skeleton:prod.js script creates the productiion folder and copies the 7 | * files defined in config.js. 8 | * 9 | * Private Functions: 10 | * . _help displays the help message, 11 | * . _clean removes the previous production folder, 12 | * . _doskeleton creates the production folder and copies files, 13 | * 14 | * 15 | * Public Static Methods: 16 | * . run executes the script, 17 | * 18 | * 19 | * @namespace - 20 | * @dependencies none 21 | * @exports - 22 | * @author - 23 | * @since 0.0.0 24 | * @version - 25 | * ************************************************************************** */ 26 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 27 | 28 | 29 | // -- Vendor Modules 30 | const fs = require('fs') 31 | , path = require('path') 32 | , nopt = require('nopt') 33 | ; 34 | 35 | 36 | // -- Local Modules 37 | const config = require('./config') 38 | ; 39 | 40 | 41 | // -- Local Constants 42 | const VERSION = '0.0.0-alpha.0' 43 | , opts = { 44 | help: [Boolean, false], 45 | version: [String, null], 46 | } 47 | , shortOpts = { 48 | h: ['--help'], 49 | v: ['--version', VERSION], 50 | } 51 | , parsed = nopt(opts, shortOpts, process.argv, 2) 52 | , { dist } = config 53 | , { webfiles } = config 54 | ; 55 | 56 | 57 | // -- Local Variables 58 | 59 | 60 | // -- Private Functions -------------------------------------------------------- 61 | 62 | /** 63 | * Dispays the help message. 64 | * 65 | * @function () 66 | * @private 67 | * @param {} -, 68 | * @returns {} -, 69 | * @since 0.0.0 70 | */ 71 | function _help() { 72 | const message = ['', 73 | 'Usage: command [options]', 74 | '', 75 | ' creates the production folder and copies the files defined in config.js', 76 | '', 77 | 'Options:', 78 | '', 79 | '-h, --help output usage information', 80 | '-v, --version output the version number', 81 | '', 82 | ].join('\n'); 83 | 84 | process.stdout.write(`${message}\n`); 85 | } 86 | 87 | /** 88 | * Removes the previous production folder, 89 | * 90 | * @function () 91 | * @private 92 | * @param {} -, 93 | * @returns {Object} returns a promise, 94 | * @since 0.0.0 95 | */ 96 | function _clean() { 97 | const d1 = new Date(); 98 | process.stdout.write('Starting \'\x1b[36mclean\x1b[89m\x1b[0m\'...\n'); 99 | 100 | return new Promise((resolve) => { 101 | fs.rm(dist, { force: true, recursive: true }, (err) => { 102 | if (err) throw new Error(err); 103 | 104 | const d2 = new Date() - d1; 105 | process.stdout.write(`Finished '\x1b[36mclean\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 106 | resolve(); 107 | }); 108 | }); 109 | } 110 | 111 | /** 112 | * Creates the production folder and copies files. 113 | * 114 | * @function (arg1) 115 | * @private 116 | * @param {Function} the function to call at the completion, 117 | * @returns {} -, 118 | * @since 0.0.0 119 | */ 120 | function _doskeleton(done) { 121 | const d1 = new Date(); 122 | process.stdout.write('Starting \'\x1b[36mdoskeleton\x1b[89m\x1b[0m\'...\n'); 123 | 124 | /** 125 | * Wait all processes completed; 126 | */ 127 | let pending = webfiles.length; 128 | function _next() { 129 | pending -= 1; 130 | if (!pending) { 131 | const d2 = new Date() - d1; 132 | process.stdout.write(`Finished '\x1b[36mdoskeleton\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 133 | done(); 134 | } 135 | } 136 | 137 | let filename; 138 | for (let i = 0; i < webfiles.length; i++) { 139 | filename = path.basename(webfiles[i]); 140 | fs.cp(webfiles[i], `${dist}/${filename}`, (err) => { 141 | if (err) throw new Error(err); 142 | _next(); 143 | }); 144 | } 145 | } 146 | 147 | 148 | // -- Main --------------------------------------------------------------------- 149 | 150 | /** 151 | * Executes the script. 152 | * 153 | * @function () 154 | * @public 155 | * @param {} -, 156 | * @returns {} -, 157 | * @since 0.0.0 158 | */ 159 | async function run() { 160 | const PENDING = 1; 161 | 162 | if (parsed.help) { 163 | _help(); 164 | return; 165 | } 166 | 167 | if (parsed.version) { 168 | process.stdout.write(`version: ${parsed.version}\n`); 169 | return; 170 | } 171 | 172 | const d1 = new Date(); 173 | process.stdout.write('Starting \'\x1b[36mbuild:skeleton:prod\x1b[89m\x1b[0m\'...\n'); 174 | 175 | let pending = PENDING; 176 | /** 177 | * Executes done until completion. 178 | */ 179 | function done() { 180 | pending -= 1; 181 | if (!pending) { 182 | const d2 = new Date() - d1; 183 | process.stdout.write(`Finished '\x1b[36mbuild:skeleton:prod\x1b[89m\x1b[0m' after \x1b[35m${d2} ms\x1b[89m\x1b[0m\n`); 184 | } 185 | } 186 | 187 | await _clean(); 188 | _doskeleton(done); 189 | } 190 | 191 | 192 | // Start script. 193 | run(); 194 | 195 | 196 | // -- oOo -- 197 | -------------------------------------------------------------------------------- /scripts/config.js: -------------------------------------------------------------------------------- 1 | /* eslint one-var: 0, semi-style: 0 */ 2 | 3 | 4 | // -- Vendor Modules 5 | 6 | 7 | // -- Local Modules 8 | const pack = require('../package.json'); 9 | 10 | 11 | // -- Local Constants 12 | const libname = 'PicoDB' 13 | , name = libname.replace(/\s+/g, '').toLowerCase() 14 | , source = './src/picodb.js' 15 | ; 16 | 17 | 18 | // -- Local Variables 19 | 20 | 21 | // -- Main 22 | 23 | module.exports = { 24 | ES6GLOB: '$__ES6GLOB', 25 | dist: './_dist', 26 | libdir: './lib', 27 | libname, 28 | name, 29 | index: './index.js', 30 | distlink: `./_dist/lib/${name}.js`, 31 | 32 | // This is the entry javascript file of your library. Choose one 33 | // pattern among the proposed ones in src. The files 'basic.js', 34 | // 'functional.js', 'functional-shared.js', 'prototypal.js', 35 | // 'pseudoclassical.js' and pseudoclassical-auto.js' are mutually exclusives. 36 | source, 37 | 38 | webfiles: [ 39 | // These are the files to copy to the root path of the web app, 40 | './README.md', 41 | './LICENSE.md', 42 | ], 43 | 44 | get license() { 45 | return ['/*! ****************************************************************************', 46 | ` * ${libname} v${pack.version}`, 47 | ' *', 48 | ` * ${pack.description}.`, 49 | ' * (you can download it from npm or github repositories)', 50 | ` * Copyright (c) ${(new Date()).getFullYear()} ${pack.author.name} <${pack.author.email}> (${pack.author.url}).`, 51 | ' * Released under the MIT license. You may obtain a copy of the License', 52 | ' * at: http://www.opensource.org/licenses/mit-license.php).', 53 | ' * Built from ES6Kadoo v2.1.0.', 54 | ' * ************************************************************************** */', 55 | ''].join('\n'); 56 | }, 57 | }; 58 | -------------------------------------------------------------------------------- /src/lib/plugin.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * Manages the plugin. 4 | * 5 | * plugin.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . none, 10 | * 11 | * 12 | * Public Static Methods: 13 | * . 14 | * 15 | * 16 | * 17 | * @namespace - 18 | * @dependencies none 19 | * @exports - 20 | * @author - 21 | * @since 0.0.0 22 | * @version - 23 | * ********************************************************************** */ 24 | /* global */ 25 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 26 | 27 | 28 | // -- Vendor Modules 29 | import _ from './_'; 30 | 31 | 32 | // -- Local Modules 33 | 34 | 35 | // -- Local Constants 36 | 37 | 38 | // -- Local Variables 39 | 40 | 41 | // -- Private Functions ---------------------------------------------------- 42 | 43 | /** 44 | * Attaches a valid plugin. 45 | * 46 | * @function (arg1, arg2) 47 | * @private 48 | * @param {Object} the plugin db, 49 | * @param {Function} the plugin library, 50 | * @returns {Boolean} returns true if it succeeds, 51 | * @since 0.0.0 52 | */ 53 | function _plugin(db, plug) { 54 | if (_.isLiteralObject(plug) 55 | && plug.messenger && plug.messenger.NAME === 'Messenger') { 56 | /* eslint-disable-next-line no-param-reassign */ 57 | db.messenger = plug.messenger; 58 | return true; 59 | } 60 | return false; 61 | } 62 | 63 | 64 | // -- Public Static Methods ------------------------------------------------ 65 | 66 | const Plugin = { 67 | 68 | /** 69 | * The plugin db 70 | */ 71 | _db: { 72 | messenger: null, 73 | }, 74 | 75 | /** 76 | * Attaches a valid plugin. 77 | * 78 | * @method (arg1) 79 | * @public 80 | * @param {Object} the plugin library, 81 | * @returns {Boolean} returns true if it succeeds, 82 | * @since 0.0.0 83 | */ 84 | plugin(plug) { 85 | return _plugin(this._db, plug); 86 | }, 87 | 88 | /** 89 | * Returns the requested plugin. 90 | * 91 | * @method (arg1) 92 | * @public 93 | * @param {String} the plugin name, 94 | * @returns {Function} returns the requested plugin, 95 | * @since 0.0.0 96 | */ 97 | get(plugin) { 98 | return _.isString(plugin) && this._db[plugin] ? this._db[plugin] : null; 99 | }, 100 | }; 101 | 102 | 103 | // -- Export 104 | export default Plugin; 105 | 106 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 107 | -------------------------------------------------------------------------------- /src/picodb.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * A tiny in-memory database (MongoDB like) that stores JSON documents. 4 | * 5 | * This is the entry point of the library where is defined the constructor 6 | * and the attached methods. 7 | * 8 | * picodb.js is built upon the Prototypal Instantiation pattern. It 9 | * returns an object by calling its constructor. It doesn't use the new 10 | * keyword. 11 | * 12 | * Private Functions: 13 | * . none, 14 | * 15 | * 16 | * Constructor: 17 | * . PicoDB creates and returns the PicoDB object, 18 | * 19 | * 20 | * Private Static Methods: 21 | * . _setTestMode returns internal objects for testing purpose, 22 | * 23 | * 24 | * Public Static Methods: 25 | * . noConflict returns a reference to this PicoDB object, 26 | * . plug attaches a plugin library, 27 | * 28 | * 29 | * Public Methods: 30 | * . whoami returns the library name and version, 31 | * . insertOne inserts a single document, 32 | * . insertMany inserts an array of documents, 33 | * . find finds the searched documents, 34 | * . toArray returns the found documents in an array, 35 | * . count counts the documents into the db that match, 36 | * . updateOne updates one document, 37 | * . updateMany updates many documents, 38 | * . deleteOne deletes the first (the oldest) doc. that matches, 39 | * . deleteMany deletes the documents into the db that match, 40 | * . addEventListener registers the specified listener, 41 | * . addOneTimeEventListener registers the specified listener for once, 42 | * . removeEventListener removes the event registered listener, 43 | * . on alias on addEventListener, 44 | * . one alias on addOneTimeEventListener, 45 | * . off alias on removeEventListener, 46 | * 47 | * 48 | * 49 | * @namespace - 50 | * @dependencies none 51 | * @exports - 52 | * @author - 53 | * @since 0.0.0 54 | * @version - 55 | * ********************************************************************** */ 56 | /* global root */ 57 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 58 | 59 | 60 | // -- Vendor Modules 61 | 62 | 63 | // -- Local Modules 64 | import _ from './lib/_'; 65 | import C from './private/count'; 66 | import D from './private/delete'; 67 | import F from './private/find'; 68 | import I from './private/insert'; 69 | import U from './private/update'; 70 | import P from './lib/plugin'; 71 | import G from './private/geo'; 72 | 73 | 74 | // -- Local Constants 75 | 76 | 77 | // -- Local Variables 78 | let methods 79 | ; 80 | 81 | 82 | // -- Public --------------------------------------------------------------- 83 | 84 | /** 85 | * Returns the PicoDB object. 86 | * (Prototypal Instantiation Pattern) 87 | * 88 | * @constructor () 89 | * @public 90 | * @param {} -, 91 | * @returns {Object} returns the PicoDB object, 92 | * @since 0.0.0 93 | */ 94 | const PicoDB = function() { 95 | const obj = Object.create(methods); 96 | obj._library = { 97 | name: '{{lib:name}}', 98 | version: '{{lib:version}}', 99 | }; 100 | 101 | // Creates a cursor. 102 | obj._cursor = F.initCursor(); 103 | 104 | // Creates the database container and attaches to it a schema. 105 | obj._db = I.schema(); 106 | 107 | // Creates a messenger object. 108 | const M = P.get('messenger'); 109 | obj._mess = M ? M() : null; 110 | return obj; 111 | }; 112 | 113 | // Attaches constants to PicoDB that provide name and version of the lib. 114 | PicoDB.NAME = '{{lib:name}}'; 115 | PicoDB.VERSION = '{{lib:version}}'; 116 | 117 | // Saves the previous value of the library variable, so that it can be 118 | // restored later on, if noConflict is used. 119 | const previousPicoDB = root.PicoDB; 120 | 121 | 122 | // -- Private Static Methods ----------------------------------------------- 123 | 124 | /** 125 | * Returns the internal objects for testing purpose. 126 | * (must not be deleted) 127 | * 128 | * @method () 129 | * @private 130 | * @param {} -, 131 | * @returns {Object} returns a list of internal objects, 132 | * @since 0.0.0 133 | */ 134 | PicoDB._setTestMode = function() { 135 | return [G, P, _]; 136 | }; 137 | 138 | 139 | // -- Public Static Methods ------------------------------------------------ 140 | 141 | /** 142 | * Returns a reference to this PicoDB object. 143 | * (must not be deleted) 144 | * 145 | * Nota: 146 | * Running PicoDB in noConflict mode, returns the PicoDB variable to 147 | * its previous owner. 148 | * 149 | * @method () 150 | * @public 151 | * @param {} -, 152 | * @returns {Object} returns the PicoDB object, 153 | * @since 0.0.0 154 | */ 155 | PicoDB.noConflict = function() { 156 | /* eslint-disable-next-line no-param-reassign */ 157 | root.PicoDB = previousPicoDB; 158 | return this; 159 | }; 160 | 161 | /** 162 | * Attaches a plugin library. 163 | * 164 | * @method (arg1) 165 | * @public 166 | * @param {Object} the plugin library, 167 | * @returns {Boolean} returns true if it succeeds, 168 | * @since 0.0.0 169 | */ 170 | PicoDB.plugin = function(plug) { 171 | return P.plugin(plug); 172 | }; 173 | 174 | 175 | // -- Public Methods ------------------------------------------------------- 176 | 177 | methods = { 178 | 179 | /** 180 | * Returns the library name and version. 181 | * (must not be deleted) 182 | * 183 | * @method () 184 | * @public 185 | * @param {} -, 186 | * @returns {Object} returns the library name and version, 187 | * @since 0.0.0 188 | */ 189 | whoami() { 190 | return this._library; 191 | }, 192 | 193 | /** 194 | * Inserts a single document into the db. 195 | * 196 | * @method (arg1, [arg2], [arg3]) 197 | * @public 198 | * @param {Object} the document to insert, 199 | * @param {Object} the optional settings, 200 | * @param {Function} the function to call at the completion, 201 | * @returns {Object} returns a promise, 202 | * @since 0.0.0 203 | */ 204 | insertOne(...args) { 205 | return I.insert(this._db, this._mess, false, ...args); 206 | }, 207 | 208 | /** 209 | * Inserts an array of documents into the db. 210 | * 211 | * @method (arg1, [arg2], [arg3]) 212 | * @public 213 | * @param {Array} the documents to insert, 214 | * @param {Object} the optional settings, 215 | * @param {Function} the function to call at the completion, 216 | * @returns {Object} returns a promise, 217 | * @since 0.0.0 218 | */ 219 | insertMany(...args) { 220 | return I.insert(this._db, this._mess, true, ...args); 221 | }, 222 | 223 | /** 224 | * Finds the searched documents. 225 | * 226 | * @method (arg1, arg2) 227 | * @public 228 | * @param {Object} the query object, 229 | * @param {Object} the projection object, 230 | * @returns {Object} returns this, 231 | * @since 0.0.0 232 | */ 233 | find(...args) { 234 | F.find(this._cursor, ...args); 235 | return this; 236 | }, 237 | 238 | /** 239 | * Returns the found documents in an array. 240 | * 241 | * @method (arg1) 242 | * @public 243 | * @param {Object} the function to call at the completion, 244 | * @returns {Object} returns a promise, 245 | * @since 0.0.0 246 | */ 247 | toArray(callback) { 248 | return F.toArray(this._db, this._cursor, callback); 249 | }, 250 | 251 | /** 252 | * Counts the documents into the db that match. 253 | * 254 | * @method (arg1, [arg2], [arg3]) 255 | * @public 256 | * @param {Object} the query object, 257 | * @param {Options} the optional settings, 258 | * @param {Function} the function to call at the completion, 259 | * @returns {Object} returns a promise, 260 | * @since 0.0.0 261 | */ 262 | count(...args) { 263 | return C.count(this._db, ...args); 264 | }, 265 | 266 | /** 267 | * Updates many documents into the db. 268 | * 269 | * @method (arg1, arg2, [arg3], [arg4]) 270 | * @public 271 | * @param {Object} the query object, 272 | * @param {object} the items to update, 273 | * @param {Object} the optional settings, 274 | * @param {Function} the function to call at the completion, 275 | * @returns {Object} returns a promise, 276 | * @since 0.0.0 277 | */ 278 | updateOne(...args) { 279 | return U.update(this._db, this._mess, false, ...args); 280 | }, 281 | 282 | /** 283 | * Updates many documents into the db. 284 | * 285 | * @method (arg1, arg2, arg3, arg4) 286 | * @public 287 | * @param {Object} the query object, 288 | * @param {object} the items to update, 289 | * @param {Object} the optional settings, 290 | * @param {Function} the function to call at the completion, 291 | * @returns {Object} returns a promise, 292 | * @since 0.0.0 293 | */ 294 | updateMany(...args) { 295 | return U.update(this._db, this._mess, true, ...args); 296 | }, 297 | 298 | /** 299 | * Deletes the first (the oldest) document into the db that matches. 300 | * 301 | * @method (arg1, [arg2], [arg3]) 302 | * @public 303 | * @param {Object} the object to found, 304 | * @param {Options} the optional settings, 305 | * @param {Function} the function to call at the completion, 306 | * @returns {Object} returns this, 307 | * @since 0.0.0 308 | */ 309 | deleteOne(...args) { 310 | return D.delete(this._db, this._mess, false, ...args); 311 | }, 312 | 313 | /** 314 | * Deletes the documents into the db that match. 315 | * 316 | * @method (arg1, [arg2], [arg3]) 317 | * @public 318 | * @param {Object} the object to found, 319 | * @param {Options} the optional settings, 320 | * @param {Function} the function to call at the completion, 321 | * @returns {Object} returns a promise, 322 | * @since 0.0.0 323 | */ 324 | deleteMany(...args) { 325 | return D.delete(this._db, this._mess, true, ...args); 326 | }, 327 | 328 | /** 329 | * Registers the specified listener on the event it's called on. 330 | * 331 | * @method (arg1, arg2) 332 | * @public 333 | * @param {String} the name of the event, 334 | * @param {function} the event listener, 335 | * @returns {Object} returns this, 336 | * @since 0.0.0 337 | */ 338 | addEventListener(ename, listener) { 339 | if (this._mess) { 340 | this._mess.subscribe(ename, listener); 341 | return this; 342 | } 343 | /* eslint-disable-next-line no-console */ 344 | console.log('warning: the plugin @mobilabs/messenger isn\'t installed!'); 345 | return this; 346 | }, 347 | 348 | /** 349 | * Registers the specified listener on the event for once. 350 | * 351 | * @method (arg1, arg2) 352 | * @public 353 | * @param {String} the name of the event, 354 | * @param {function} the event listener, 355 | * @returns {Object} returns this, 356 | * @since 0.0.0 357 | */ 358 | addOneTimeEventListener(ename, listener) { 359 | if (this._mess) { 360 | this._mess.subscribeOnce(ename, listener); 361 | return this; 362 | } 363 | /* eslint-disable-next-line no-console */ 364 | console.log('warning: the plugin @mobilabs/messenger isn\'t installed!'); 365 | return this; 366 | }, 367 | 368 | /** 369 | * Removes the event listener previously registered with addEventListener. 370 | * 371 | * @method (arg1, arg2) 372 | * @public 373 | * @param {String} the name of the event, 374 | * @param {function} the event listener, 375 | * @returns {Object} returns this, 376 | * @since 0.0.0 377 | */ 378 | removeEventListener(ename, listener) { 379 | if (this._mess) { 380 | this._mess.unsubscribe(ename, listener); 381 | } 382 | return this; 383 | }, 384 | 385 | /** 386 | * Registers the specified listener on the event it's called on. 387 | * 388 | * @method (arg1, arg2) 389 | * @public 390 | * @param {String} the name of the event, 391 | * @param {function} the event listener, 392 | * @returns {Object} returns this, 393 | * @since 0.0.0 394 | */ 395 | on(ename, listener) { 396 | return this.addEventListener(ename, listener); 397 | }, 398 | 399 | /** 400 | * Registers the specified listener on the event for once. 401 | * 402 | * @method (arg1, arg2) 403 | * @public 404 | * @param {String} the name of the event, 405 | * @param {function} the event listener, 406 | * @returns {Object} returns this, 407 | * @since 0.0.0 408 | */ 409 | one(ename, listener) { 410 | return this.addOneTimeEventListener(ename, listener); 411 | }, 412 | 413 | /** 414 | * Removes the event listener previously registered with addEventListener. 415 | * 416 | * @method (arg1, arg2) 417 | * @public 418 | * @param {String} the name of the event, 419 | * @param {function} the event listener, 420 | * @returns {Object} returns this, 421 | * @since 0.0.0 422 | */ 423 | off(ename, listener) { 424 | return this.removeEventListener(ename, listener); 425 | }, 426 | }; 427 | 428 | 429 | // -- Export 430 | export default PicoDB; 431 | 432 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 433 | -------------------------------------------------------------------------------- /src/private/count.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * Counts the number of documents into the db w.r.t. the filter. 4 | * 5 | * count.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . _getArgs returns the filtered arguments, 10 | * . _count counts the number of the documents in the db, 11 | * 12 | * 13 | * Public Static Methods: 14 | * . _count counts the number of the documents in the db, 15 | * 16 | * 17 | * 18 | * @namespace - 19 | * @dependencies none 20 | * @exports - 21 | * @author - 22 | * @since 0.0.0 23 | * @version - 24 | * ********************************************************************** */ 25 | /* global */ 26 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 27 | 28 | 29 | // -- Vendor Modules 30 | 31 | 32 | // -- Local Modules 33 | import _ from '../lib/_'; 34 | import Q from './query'; 35 | 36 | 37 | // -- Local Constants 38 | 39 | 40 | // -- Local Variables 41 | 42 | 43 | // -- Private Functions ---------------------------------------------------- 44 | 45 | /** 46 | * Returns the filtered arguments. 47 | * 48 | * @function (arg1, [arg2], [arg3]) 49 | * @private 50 | * @param {object} the query filter, 51 | * @param {object} the passed-in options, 52 | * @param {Function} the function to call at the completion, 53 | * @returns {Array} returns an array with the filtered arguments, 54 | * @since 0.0.0 55 | */ 56 | function _getArgs(...args) { 57 | // query, options, callback 58 | switch (args.length) { 59 | case 1: 60 | // must be query 61 | if (_.isLiteralObject(args[0])) { 62 | return [args[0], {}, null]; 63 | } 64 | if (_.isFunction(args[0])) { 65 | return [null, {}, args[0]]; 66 | } 67 | return [null, {}, args[0]]; 68 | 69 | case 2: 70 | // must be query, options or query, callback 71 | if (_.isLiteralObject(args[0])) { 72 | if (_.isLiteralObject(args[1])) { 73 | return [args[0], args[1], null]; 74 | } 75 | if (_.isFunction(args[1])) { 76 | return [args[0], {}, args[1]]; 77 | } 78 | return [args[0], {}, null]; 79 | } 80 | if (_.isFunction(args[1])) { 81 | return [null, {}, args[1]]; 82 | } 83 | return [null, {}, null]; 84 | 85 | case 3: 86 | // must be query, options, callback 87 | if (_.isLiteralObject(args[0])) { 88 | if (_.isLiteralObject(args[1])) { 89 | if (_.isFunction(args[2])) { 90 | return [args[0], args[1], args[2]]; 91 | } 92 | return [args[0], args[1], null]; 93 | } 94 | if (_.isFunction(args[2])) { 95 | return [args[0], {}, args[2]]; 96 | } 97 | return [args[0], {}, null]; 98 | } 99 | if (_.isFunction(args[2])) { 100 | return [null, {}, args[2]]; 101 | } 102 | return [null, {}, args[2]]; 103 | 104 | default: 105 | return [null, {}, null]; 106 | } 107 | } 108 | 109 | /** 110 | * Counts the number of the documents contained in the db. 111 | * 112 | * @function (arg1, arg2, arg3, arg4) 113 | * @private 114 | * @param {Object} the db, 115 | * @param {Object} the query filter, 116 | * @param {Object} the options, 117 | * @param {Function} the function to call at the completion, 118 | * @returns {} -, 119 | * @since 0.0.0 120 | */ 121 | function _count(db, query, options, callback) { 122 | if (!query) { 123 | callback(null, 0); 124 | return; 125 | } 126 | 127 | const sop = Q.isHavingSpecialOperator(query); 128 | let count = 0; 129 | for (let i = 0; i < db.data.length; i++) { 130 | if (Q.isMatch(db.data[i], query, sop)) { 131 | count += 1; 132 | } 133 | } 134 | callback(null, count); 135 | } 136 | 137 | 138 | // -- Public Static Methods ------------------------------------------------ 139 | 140 | const Count = { 141 | 142 | /** 143 | * Counts the number of the documents contained in the db 144 | * 145 | * @method (arg1, arg2, arg3, [arg4]) 146 | * @public 147 | * @param {Object} the database object, 148 | * @param {Object} the query filter object, 149 | * @param {Object} the optional settings, 150 | * @param {Function} the function to call at the completion, 151 | * @returns {Object} returns a promise, 152 | * @since 0.0.0 153 | */ 154 | count(db, ...args) { 155 | const [query, options, callback] = _getArgs(...args); 156 | 157 | return new Promise((resolve, reject) => { 158 | _count(db, query, options, (err, resp) => { 159 | if (err) { 160 | reject(err); 161 | if (callback) callback(err); 162 | } else { 163 | resolve(resp); 164 | if (callback) callback(null, resp); 165 | } 166 | }); 167 | }); 168 | }, 169 | }; 170 | 171 | 172 | // -- Export 173 | export default Count; 174 | 175 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 176 | -------------------------------------------------------------------------------- /src/private/delete.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * Deletes the requested documents from the database. 4 | * 5 | * delete.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . _getArgs returns the filtered arguments, 10 | * . _delete deletes the requested documents from the db, 11 | * 12 | * 13 | * Public Static Methods: 14 | * . _delete deletes the requested documents from the db, 15 | * 16 | * 17 | * 18 | * @namespace - 19 | * @dependencies none 20 | * @exports - 21 | * @author - 22 | * @since 0.0.0 23 | * @version - 24 | * ********************************************************************** */ 25 | /* global */ 26 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 27 | 28 | 29 | // -- Vendor Modules 30 | 31 | 32 | // -- Local Modules 33 | import _ from '../lib/_'; 34 | import Q from './query'; 35 | 36 | 37 | // -- Local Constants 38 | 39 | 40 | // -- Local Variables 41 | 42 | 43 | // -- Private Functions ---------------------------------------------------- 44 | 45 | /** 46 | * Returns the filtered arguments. 47 | * 48 | * @function (arg1, [arg2], [arg3]) 49 | * @private 50 | * @param {object} the query filter, 51 | * @param {object} the passed-in options, 52 | * @param {Function} the function to call at the completion, 53 | * @returns {Array} returns an array with the filtered arguments, 54 | * @since 0.0.0 55 | */ 56 | function _getArgs(...args) { 57 | // filter, options, callback 58 | switch (args.length) { 59 | case 1: 60 | // must be filter or callback 61 | if (_.isLiteralObject(args[0])) { 62 | return [args[0], {}, null]; 63 | } 64 | if (_.isFunction(args[0])) { 65 | return [null, {}, args[0]]; 66 | } 67 | return [null, {}, null]; 68 | 69 | case 2: 70 | // must be filter, options or filter, callback 71 | if (_.isLiteralObject(args[0])) { 72 | if (_.isLiteralObject(args[1])) { 73 | return [args[0], args[1], null]; 74 | } 75 | if (_.isFunction(args[1])) { 76 | return [args[0], {}, args[1]]; 77 | } 78 | return [args[0], {}, null]; 79 | } 80 | if (_.isFunction(args[1])) { 81 | return [null, null, args[1]]; 82 | } 83 | return [null, null, null]; 84 | 85 | case 3: 86 | // must be filter, options, callback 87 | if (_.isLiteralObject(args[0])) { 88 | if (_.isLiteralObject(args[1])) { 89 | if (_.isFunction(args[2])) { 90 | return [args[0], args[1], args[2]]; 91 | } 92 | return [args[0], args[1], null]; 93 | } 94 | if (_.isFunction(args[2])) { 95 | return [args[0], {}, args[2]]; 96 | } 97 | return [args[0], {}, null]; 98 | } 99 | if (_.isFunction(args[2])) { 100 | return [null, null, args[2]]; 101 | } 102 | return [null, null, null]; 103 | 104 | default: 105 | return [null, null, null]; 106 | } 107 | } 108 | 109 | /** 110 | * Deletes the requested documents from the db. 111 | * 112 | * @function (arg1, arg2, arg3, arg4, arg5, arg6) 113 | * @private 114 | * @param {object} the db object, 115 | * @param {object} the messenger object, 116 | * @param {Boolean} deletes one or many, 117 | * @param {Object} the query filter, 118 | * @param {object} the passed-in options, 119 | * @param {Function} the function to call at the completion, 120 | * @returns {} -, 121 | * @since 0.0.0 122 | */ 123 | function _delete(db, mess, many, filter, options, callback) { 124 | if (!filter) { 125 | callback(null, 0); 126 | return; 127 | } 128 | 129 | let docOut = [] 130 | , removed 131 | , dblength 132 | ; 133 | 134 | // Parse the documents into the db one by one and check if the keys match: 135 | // (each time a document is deleted, the counter and the length size must 136 | // be reajusted. It could have been easier to parse the db from the last 137 | // to the first but in case of deleteOne it deletes the most recent 138 | // instead of the oldest) 139 | const sop = Q.isHavingSpecialOperator(filter); 140 | docOut = []; 141 | removed = 0; 142 | dblength = db.data.length; 143 | // for (i = db.data.length - 1; i >= 0; i--) { 144 | for (let i = 0; i < dblength; i++) { 145 | if (Q.isMatch(db.data[i], filter, sop)) { 146 | // Remove the document that matches: 147 | docOut.push(db.data.splice(i, 1)[0]); 148 | removed += 1; 149 | // Readjust db length after one item has been removed & reposition i: 150 | i -= 1; 151 | dblength -= 1; 152 | if (!many) { 153 | // Remove one document only! 154 | break; 155 | } 156 | } 157 | } 158 | 159 | // Fire an event and execute the callback: 160 | if (mess) { 161 | mess.publish('delete', docOut); 162 | mess.publish('change', docOut); 163 | } 164 | callback(null, removed); 165 | } 166 | 167 | 168 | // -- Public Static Methods ------------------------------------------------ 169 | 170 | const Delete = { 171 | 172 | /** 173 | * Deletes the requested documents from the db. 174 | * 175 | * @method (arg1, arg2, arg3, arg4, arg5, arg6) 176 | * @public 177 | * @param {object} the db object, 178 | * @param {object} the messenger object, 179 | * @param {Boolean} deletes one or many, 180 | * @param {Object} the query filter, 181 | * @param {object} the passed-in options, 182 | * @param {Function} the function to call at the completion, 183 | * @returns {Object} returns a promise, 184 | * @since 0.0.0 185 | */ 186 | delete(db, mess, many, ...args) { 187 | const [filter, options, callback] = _getArgs(...args); 188 | 189 | return new Promise((resolve, reject) => { 190 | _delete(db, mess, many, filter, options, (err, resp) => { 191 | if (err) { 192 | reject(err); 193 | if (callback) callback(err); 194 | } else { 195 | resolve(resp); 196 | if (callback) callback(null, resp); 197 | } 198 | }); 199 | }); 200 | }, 201 | }; 202 | 203 | 204 | // -- Export 205 | export default Delete; 206 | 207 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 208 | -------------------------------------------------------------------------------- /src/private/find.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * Extracts the requested document(s) from the database. 4 | * 5 | * find.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . _initCursor returns the default cursor object, 10 | * . _getArgs returns the filtered arguments, 11 | * . _toArray returns the found documents, 12 | * . _find creates the cursor w.r.t to the query & proj, 13 | * 14 | * 15 | * Public Static Methods: 16 | * . initCursor returns the default cursor object, 17 | * . find creates the cursor w.r.t to the query & proj, 18 | * . toArray returns the found documents, 19 | * 20 | * 21 | * 22 | * @namespace - 23 | * @dependencies none 24 | * @exports - 25 | * @author - 26 | * @since 0.0.0 27 | * @version - 28 | * ********************************************************************** */ 29 | /* global */ 30 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 31 | 32 | 33 | // -- Vendor Modules 34 | 35 | 36 | // -- Local Modules 37 | import _ from '../lib/_'; 38 | import P from './projection'; 39 | import Q from './query'; 40 | 41 | 42 | // -- Local Constants 43 | 44 | 45 | // -- Local Variables 46 | 47 | 48 | // -- Private Functions ---------------------------------------------------- 49 | 50 | /** 51 | * Returns the default cursor object. 52 | * 53 | * @function () 54 | * @private 55 | * @param {} -, 56 | * @returns {Object} returns the default cursor object, 57 | * @since 0.0.0 58 | */ 59 | function _initCursor() { 60 | return { 61 | query: {}, 62 | projection: { 63 | type: null, 64 | value: null, 65 | }, 66 | }; 67 | } 68 | 69 | /** 70 | * Returns the filtered arguments. 71 | * 72 | * @function (arg1, [arg2]) 73 | * @private 74 | * @param {object} the query filter, 75 | * @param {object} the passed-in options, 76 | * @returns {Array} returns an array with the filtered arguments, 77 | * @since 0.0.0 78 | */ 79 | function _getArgs(...args) { 80 | return [ 81 | _.isLiteralObject(args[0]) ? args[0] : {}, 82 | _.isLiteralObject(args[1]) ? args[1] : {}, 83 | ]; 84 | } 85 | 86 | /** 87 | * Returns the found documents. 88 | * 89 | * @function (arg1, arg2, arg3) 90 | * @private 91 | * @param {Object} the db object, 92 | * @param {Object} the cursor object, 93 | * @param {Function} the function to call at the completion, 94 | * @returns {} -, 95 | * @since 0.0.0 96 | */ 97 | function _toArray(db, cursor, callback) { 98 | /* istanbul ignore next */ 99 | if (!cursor.query) { 100 | callback('This query isn\'t a valid Cursor query object'); 101 | return; 102 | } 103 | 104 | // Parse the database: 105 | const sop = Q.isHavingSpecialOperator(cursor.query); 106 | const docs = []; 107 | for (let i = 0; i < db.data.length; i++) { 108 | if (Q.isMatch(db.data[i], cursor.query, sop)) { 109 | P.add(docs, db.data[i], cursor.projection); 110 | } 111 | } 112 | callback(null, docs); 113 | } 114 | 115 | /** 116 | * Creates the cursor w.r.t to the query filter and the projection. 117 | * 118 | * @function (arg1, arg2, [arg3]) 119 | * @private 120 | * @param {Object} the cursor object, 121 | * @param {Object} the query filter, 122 | * @param {Object} the projection, 123 | * @returns {} -, 124 | * @since 0.0.0 125 | */ 126 | /* eslint-disable no-param-reassign */ 127 | function _find(cursor, query, projection) { 128 | cursor.query = query; 129 | cursor.projection.type = P.isProjectionTypeInclude(projection); 130 | cursor.projection.value = P.setProjection(projection, cursor.projection.type); 131 | } 132 | /* eslint-enable no-param-reassign */ 133 | 134 | 135 | // -- Public Static Methods ------------------------------------------------ 136 | 137 | const FA = { 138 | 139 | /** 140 | * Returns the default cursor. 141 | * 142 | * @method () 143 | * @public 144 | * @param {} -, 145 | * @returns {Object} returns the default cursor, 146 | * @since 0.0.0 147 | */ 148 | initCursor() { 149 | return _initCursor(); 150 | }, 151 | 152 | /** 153 | * Creates the cursor w.r.t to the query filter and the projection. 154 | * 155 | * @method (arg1, arg2, [arg3]) 156 | * @public 157 | * @param {Object} the cursor object, 158 | * @param {Object} the query filter, 159 | * @param {Object} the projection, 160 | * @returns {Object} returns this, 161 | * @since 0.0.0 162 | */ 163 | find(cursor, ...args) { 164 | const [query, projection] = _getArgs(...args); 165 | _find(cursor, query, projection); 166 | return this; 167 | }, 168 | 169 | /** 170 | * Returns the found documents. 171 | * 172 | * @method (arg1, arg2, [arg3]) 173 | * @public 174 | * @param {Object} the cursor object, 175 | * @param {Object} the query filter, 176 | * @param {Object} the projection, 177 | * @returns {Object} returns a promise, 178 | * @since 0.0.0 179 | */ 180 | toArray(db, cursor, cb) { 181 | const callback = _.isFunction(cb) ? cb : null; 182 | 183 | return new Promise((resolve, reject) => { 184 | _toArray(db, cursor, (err, resp) => { 185 | if (err) { 186 | reject(err); 187 | if (callback) callback(err); 188 | } else { 189 | resolve(resp); 190 | if (callback) callback(null, resp); 191 | } 192 | }); 193 | }); 194 | }, 195 | }; 196 | 197 | 198 | // -- Export 199 | export default FA; 200 | 201 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 202 | -------------------------------------------------------------------------------- /src/private/insert.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * A set of functions to insert new documents into the db. 4 | * 5 | * insert.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . _getArgs returns the filtered arguments, 10 | * . _schema returns the db model, 11 | * . _isNewId checks that this 'id' is new, 12 | * . _process inserts the new documents into the db, 13 | * . _insert inserts the new documents into the db, 14 | * 15 | * 16 | * Public Static Methods: 17 | * . schema returns the db model, 18 | * . insert inserts the new documents into the db, 19 | * 20 | * 21 | * 22 | * @namespace - 23 | * @dependencies none 24 | * @exports - 25 | * @author - 26 | * @since 0.0.0 27 | * @version - 28 | * ********************************************************************** */ 29 | /* global */ 30 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 31 | 32 | 33 | // -- Vendor Modules 34 | 35 | 36 | // -- Local Modules 37 | import _ from '../lib/_'; 38 | 39 | 40 | // -- Local Constants 41 | 42 | 43 | // -- Local Variables 44 | 45 | 46 | // -- Private Functions ---------------------------------------------------- 47 | 48 | /** 49 | * Returns the filtered arguments. 50 | * 51 | * @function (arg1, [arg2], arg3) 52 | * @private 53 | * @param {Array/Object} the new document(s), 54 | * @param {Object} the settings, 55 | * @param {Function} the function to call at the completion, 56 | * @returns {Array} returns the filtered arguments, 57 | * @since 0.0.0 58 | */ 59 | function _getArgs(...args) { 60 | // docs, options, callback 61 | switch (args.length) { 62 | case 1: 63 | // must be docs or fn 64 | if (_.isArray(args[0]) || _.isLiteralObject(args[0])) { 65 | return [args[0], {}, null]; 66 | } 67 | if (_.isFunction(args[0])) { 68 | return [[], {}, args[0]]; 69 | } 70 | return [[], {}, null]; 71 | 72 | case 2: 73 | // must be docs, options or docs, callback 74 | if (_.isArray(args[0]) || _.isLiteralObject(args[0])) { 75 | if (_.isLiteralObject(args[1])) { 76 | return [args[0], args[1], null]; 77 | } 78 | if (_.isFunction(args[1])) { 79 | return [args[0], {}, args[1]]; 80 | } 81 | return [args[0], {}, null]; 82 | } 83 | if (_.isFunction(args[1])) { 84 | return [[], {}, args[1]]; 85 | } 86 | return [[], {}, null]; 87 | 88 | case 3: 89 | // must be docs, options, callback 90 | if (_.isArray(args[0]) || _.isLiteralObject(args[0])) { 91 | if (_.isLiteralObject(args[1])) { 92 | if (_.isFunction(args[2])) { 93 | return [args[0], args[1], args[2]]; 94 | } 95 | return [args[0], args[1], null]; 96 | } 97 | if (_.isFunction(args[2])) { 98 | return [args[0], {}, args[2]]; 99 | } 100 | return [args[0], {}, null]; 101 | } 102 | if (_.isFunction(args[2])) { 103 | return [[], {}, args[2]]; 104 | } 105 | return [[], {}, null]; 106 | 107 | default: 108 | return [[], {}, null]; 109 | } 110 | } 111 | 112 | /** 113 | * Returns the db model. 114 | * 115 | * @function () 116 | * @private 117 | * @param {} -, 118 | * @returns {Object} returns the db object model, 119 | * @since 0.0.0 120 | */ 121 | function _schema() { 122 | return { 123 | data: [], 124 | }; 125 | } 126 | 127 | /** 128 | * Checks that this 'id' is new. 129 | * 130 | * @function (arg1, arg2) 131 | * @private 132 | * @param {Object} the database object, 133 | * @param {String} the new id, 134 | * @returns {Boolean} returns true if the id is new, false otherwise, 135 | * @since 0.0.0 136 | */ 137 | function _isNewId(db, id) { 138 | let status = true; 139 | for (let i = 0; i < db.data.length; i++) { 140 | if (db.data[i]._id === id) { 141 | status = false; 142 | break; 143 | } 144 | } 145 | return status; 146 | } 147 | 148 | /** 149 | * Inserts the new documents into the db. 150 | * 151 | * @function (arg1, arg2, arg3, arg4, arg5) 152 | * @private 153 | * @param {Object} the database object, 154 | * @param {Object} the messenger object, 155 | * @param {Array/Object} the new document(s), 156 | * @param {Object} the settings, 157 | * @param {Function} the function to call at the completion, 158 | * @returns {} -, 159 | * @since 0.0.0 160 | */ 161 | function _process(db, mess, docs, options, callback) { 162 | // Embed a single document in an array to get a generic process. 163 | let arr = []; 164 | if (_.isLiteralObject(docs)) { 165 | arr.push(docs); 166 | } else { 167 | arr = docs; 168 | } 169 | 170 | // Parse all the documents: 171 | const docOut = []; 172 | for (let i = 0; i < arr.length; i++) { 173 | if (_.isLiteralObject(arr[i])) { 174 | if (arr[i]._id) { 175 | // Do not duplicate doc! 176 | if (_isNewId(db, arr[i]._id)) { 177 | // Do not copy the references. Create new objects! 178 | db.data.push(_.extend({}, arr[i])); 179 | // Do not pass references to the db. Provide a copy instead! 180 | docOut.push(_.extend({}, arr[i])); 181 | if (!options.many) { 182 | break; 183 | } 184 | } 185 | } else { 186 | const id = _.token(); 187 | db.data.push(_.extend({ _id: id }, arr[i])); 188 | docOut.push(_.extend({ _id: id }, arr[i])); 189 | if (!options.many) { 190 | // insert only the first document if many is false! 191 | break; 192 | } 193 | } 194 | } 195 | } 196 | 197 | // Fire an event and execute the callback: 198 | if (mess) { 199 | mess.publish('change', docOut); 200 | mess.publish('insert', docOut); 201 | } 202 | callback(null, docOut); 203 | } 204 | 205 | /** 206 | * Inserts the new documents into the db. 207 | * 208 | * @function (arg1, arg2, arg3, arg4, arg5) 209 | * @private 210 | * @param {Object} the database object, 211 | * @param {Object} the messenger object, 212 | * @param {Boolean} true if many, false if one, 213 | * @param {Array/Object} the new document(s), 214 | * @param {Object} the settings, 215 | * @param {Function} the function to call at the completion, 216 | * @returns {} -, 217 | * @since 0.0.0 218 | */ 219 | /* eslint-disable no-param-reassign */ 220 | function _insert(db, mess, many, docs, options, callback) { 221 | // Insert if it is a valid document: 222 | options.many = many; 223 | if (many && _.isArray(docs)) { 224 | _process(db, mess, docs, options, callback); 225 | return; 226 | } 227 | if (!many && (_.isArray(docs) || _.isLiteralObject(docs))) { 228 | _process(db, mess, docs, options, callback); 229 | return; 230 | } 231 | callback(null, []); 232 | } 233 | /* eslint-enable no-param-reassign */ 234 | 235 | 236 | // -- Public Static Methods ------------------------------------------------ 237 | 238 | const Insert = { 239 | 240 | /** 241 | * Returns the db model. 242 | * 243 | * @method () 244 | * @public 245 | * @param {} -, 246 | * @returns {Object} returns the db object model, 247 | * @since 0.0.0 248 | */ 249 | schema() { 250 | return _schema(); 251 | }, 252 | 253 | /** 254 | * Inserts the new documents into the db. 255 | * 256 | * @method (arg1, arg2, arg3, arg4, [arg5]) 257 | * @public 258 | * @param {Object} the database object, 259 | * @param {Object} the messenger object, 260 | * @param {Boolean} true if many, false if one, 261 | * @param {Array/Object} the new document(s), 262 | * @param {Object} the settings, 263 | * @param {Function} the function to call at the completion, 264 | * @returns {Object} returns a promise, 265 | * @since 0.0.0 266 | */ 267 | insert(db, mess, many, ...args) { 268 | const [docs, options, callback] = _getArgs(...args); 269 | 270 | return new Promise((resolve, reject) => { 271 | _insert(db, mess, many, docs, options, (err, resp) => { 272 | if (err) { 273 | reject(err); 274 | if (callback) callback(err); 275 | } else { 276 | resolve(resp); 277 | if (callback) callback(null, resp); 278 | } 279 | }); 280 | }); 281 | }, 282 | }; 283 | 284 | 285 | // -- Export 286 | export default Insert; 287 | 288 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 289 | -------------------------------------------------------------------------------- /src/private/projection.js: -------------------------------------------------------------------------------- 1 | /** ************************************************************************ 2 | * 3 | * A set of functions to format the documents returned by toArray. 4 | * 5 | * projection.js is just a literal object that contains a set of functions. 6 | * It can't be instantiated. 7 | * 8 | * Private Functions: 9 | * . _include returns an excerpt of the selected document, 10 | * . _exclude returns an excerpt of the selected document, 11 | * 12 | * 13 | * Public Static Methods: 14 | * . setProjection sets the projection value, 15 | * . isProjectionTypeInclude returns the type of projection, 16 | * . adds elements of the document to doc, 17 | * 18 | * 19 | * 20 | * @namespace - 21 | * @dependencies none 22 | * @exports - 23 | * @author - 24 | * @since 0.0.0 25 | * @version - 26 | * ********************************************************************** */ 27 | /* global */ 28 | /* eslint-disable one-var, semi-style, no-underscore-dangle */ 29 | 30 | 31 | // -- Vendor Modules 32 | 33 | 34 | // -- Local Modules 35 | import _ from '../lib/_'; 36 | 37 | 38 | // -- Local Constants 39 | 40 | 41 | // -- Local Variables 42 | 43 | 44 | // -- Private Functions ---------------------------------------------------- 45 | 46 | /** 47 | * Returns an excerpt of the selected document based on an include projection. 48 | * 49 | * Note: 50 | * It includes the fields listed in the projection with a value of 1. the 51 | * unknown fields or the fields with a value other than 1 are ignored. 52 | * 53 | * @function (arg1, arg2, arg3) 54 | * @private 55 | * @param {Object} the selected document, 56 | * @param {Object} the projection to apply, 57 | * @param {Object} the initial value of the document excerpt, 58 | * @returns {Object} the excerpt of the selected document, 59 | * @since 0.0.0 60 | */ 61 | /* eslint-disable no-param-reassign */ 62 | function _include(obj, source, data) { 63 | _.forPropIn(source, (prop) => { 64 | if (obj[prop]) { 65 | if (_.isObject(source[prop])) { 66 | data[prop] = {}; 67 | _include(obj[prop], source[prop], data[prop]); 68 | } else if (source[prop] === 1) { 69 | if (_.isObject(obj[prop])) { 70 | data[prop] = _.clone(obj[prop]); 71 | } else if (obj[prop]) { 72 | data[prop] = obj[prop]; 73 | } 74 | } 75 | } 76 | }); 77 | return data; 78 | } 79 | /* eslint-enable no-param-reassign */ 80 | 81 | /** 82 | * Returns an excerpt of the selected document based on an exclude projection. 83 | * 84 | * Note: 85 | * It excludes the fields listed in the projection with a value of 0. The 86 | * unspecified fields are kept. 87 | * 88 | * @function (arg1, arg2, arg3) 89 | * @private 90 | * @param {Object} the selected document, 91 | * @param {Object} the projection to apply, 92 | * @param {Object} the initial value of the document excerpt, 93 | * @returns {Object} the excerpt of the selected document, 94 | * @since 0.0.1 95 | */ 96 | /* eslint-disable no-param-reassign */ 97 | function _exclude(obj, source, data) { 98 | _.forPropIn(obj, (prop) => { 99 | if (source[prop] !== undefined) { 100 | if (_.isObject(source[prop])) { 101 | data[prop] = {}; 102 | _exclude(obj[prop], source[prop], data[prop]); 103 | } 104 | } else if (_.isObject(obj[prop])) { 105 | data[prop] = _.clone(obj[prop]); 106 | } else { 107 | data[prop] = obj[prop]; 108 | } 109 | }); 110 | return data; 111 | } 112 | /* eslint-enable no-param-reassign */ 113 | 114 | 115 | // -- Public Static Methods ------------------------------------------------ 116 | 117 | const Proj = { 118 | 119 | /** 120 | * Sets the projection value. 121 | * 122 | * Note: 123 | * If it is an include projection, the _id field is explicitely defined 124 | * in the projection. 125 | * 126 | * @method (arg1, arg2) 127 | * @public 128 | * @param {Object} the projection, 129 | * @param {Boolean} the current type, 130 | * @returns {Object} the updated projection, 131 | * @since 0.0.0 132 | */ 133 | setProjection(projection, type) { 134 | if (!type) { 135 | return projection; 136 | } 137 | 138 | if (projection._id !== undefined) { 139 | return projection; 140 | } 141 | return _.extend({ _id: 1 }, projection); 142 | }, 143 | 144 | /** 145 | * Returns the type of projection. 146 | * 147 | * Note: 148 | * If one 'field' is equal to 1, it's an include projection. It means that 149 | * only the fields defined in the projection, and equal to 1, are included 150 | * in the output. 151 | * 152 | * By default, '_id' is included except if it is explicitely defined to be 153 | * excluded in the projection (_id: 0). 154 | * 155 | * If all the fields in the projection are equal to 0, it's an exclude 156 | * projection. It means that only these fields are removed from the output. 157 | * 158 | * @method (arg1) 159 | * @public 160 | * @param {Object} the projection, 161 | * @returns {Boolean} true if it is an include projection, 162 | * @since 0.0.0 163 | */ 164 | /* eslint-disable no-restricted-syntax */ 165 | isProjectionTypeInclude(projection) { 166 | let prop; 167 | for (prop in projection) { 168 | if (_.isObject(projection[prop])) { 169 | if (this.isProjectionTypeInclude(projection[prop])) { 170 | return true; 171 | } 172 | } else if (projection[prop]) { 173 | return true; 174 | } 175 | } 176 | return false; 177 | }, 178 | /* eslint-enable no-restricted-syntax */ 179 | 180 | /** 181 | * Adds elements of the document to doc in accordance with projection. 182 | * 183 | * Note: this function mutates the argument `doc`. 184 | * 185 | * @method (arg1, arg2, arg3) 186 | * @public 187 | * @param {Object} the current list of documents already selected, 188 | * @param {Object} the current document, 189 | * @param {Object} the projection object, 190 | * @returns {} -, 191 | * @since 0.0.0 192 | */ 193 | add(doc, data, projection) { 194 | // If projection is empty means no filtering of the output! 195 | if (_.isEmpty(projection.value)) { 196 | doc.push(_.clone(data)); 197 | } else if (projection.type) { 198 | doc.push(_include(data, projection.value, {})); 199 | } else { 200 | doc.push(_exclude(data, projection.value, {})); 201 | } 202 | }, 203 | }; 204 | 205 | 206 | // -- Export 207 | export default Proj; 208 | 209 | /* eslint-enable one-var, semi-style, no-underscore-dangle */ 210 | -------------------------------------------------------------------------------- /test/int/lib.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | // Number of owned custom properties added by your library, 16 | // number of owned and inherited properties added by your library (instance), 17 | // number of items returned by '_setTestMode'. 18 | const LIBPROPS = 1 19 | , OWNPROPS = 3 20 | , INHPROPS = 15 21 | , TESTMODE = 3 22 | ; 23 | 24 | 25 | // -- Local Variables 26 | 27 | 28 | // -- Main 29 | module.exports = function(PicoDB, libname, version, type) { 30 | describe('PicoDB introspection:', () => { 31 | describe('Test the nature of PicoDB:', () => { 32 | it('Expects PicoDB to be a function.', () => { 33 | expect(PicoDB).to.be.a('function'); 34 | }); 35 | 36 | it(`Expects PicoDB to own ${4 + LIBPROPS} custom properties.`, () => { 37 | expect(Object.keys(PicoDB)).to.be.an('array').that.has.lengthOf(4 + LIBPROPS); 38 | }); 39 | 40 | 41 | // -- This section must not be modified -- 42 | // NAME, VERSION, _library, _setTestMode, noConflict 43 | describe('Check the owned generic custom properties:', () => { 44 | it(`Expects PicoDB to own the property "NAME" whose value is "${libname}".`, () => { 45 | expect(PicoDB).to.own.property('NAME').that.is.equal(libname); 46 | }); 47 | 48 | it(`Expects PicoDB to own the property "VERSION" whose value is "${version}".`, () => { 49 | expect(PicoDB).to.own.property('VERSION'); 50 | }); 51 | 52 | it('Expects PicoDB to own the property "_setTestMode" that is a function.', () => { 53 | expect(PicoDB).to.own.property('_setTestMode').that.is.a('function'); 54 | }); 55 | 56 | it('Expects PicoDB to own the property "noConflict" that is a function.', () => { 57 | expect(PicoDB).to.own.property('noConflict').that.is.a('function'); 58 | }); 59 | 60 | describe('Test the owned generic custom properties:', () => { 61 | it(`Expects the property "_setTestMode" to return an array with ${TESTMODE} item(s).`, () => { 62 | expect(PicoDB._setTestMode()).to.be.an('array').that.has.lengthOf(TESTMODE); 63 | }); 64 | 65 | it('Expects the property "noConflict" to return a function.', () => { 66 | expect(PicoDB.noConflict()).to.be.a('function'); 67 | }); 68 | }); 69 | 70 | 71 | // -- This section must be adapted -- 72 | // Add here the owned properties added by your library. 73 | // plugin 74 | describe('Check the owned specific custom properties:', () => { 75 | it('Expects PicoDB to own the property "plugin" that is a function.', () => { 76 | expect(PicoDB).to.own.property('plugin').that.is.a('function'); 77 | }); 78 | 79 | describe('Test the owned specific custom properties:', () => { 80 | it('Expects PicoDB the property ... to be completed or ... removed!', () => { 81 | expect(true).to.be.equal(true); 82 | }); 83 | }); 84 | }); 85 | }); 86 | }); 87 | 88 | 89 | describe('Test PicoDB constructor:', () => { 90 | if (type === 'with new') { 91 | it('Expects PicoDB() without the operator "new" to throw an error.', () => { 92 | try { 93 | PicoDB(); 94 | } catch (e) { 95 | expect(e.message).to.be.a('string').that.is.equal('PicoDB needs to be called with the new keyword!'); 96 | } 97 | }); 98 | } 99 | 100 | const o = type === 'with new' ? new PicoDB() : PicoDB(); 101 | const op = Object.getOwnPropertyNames(o); 102 | const io = Object.keys(Object.getPrototypeOf(o)); 103 | 104 | it('Expects the function PicoDB to return an object.', () => { 105 | expect(o).to.be.an('object'); 106 | }); 107 | 108 | it(`Expects PicoDB object to own ${1 + OWNPROPS} property(ies).`, () => { 109 | expect(op).to.be.an('array').that.has.lengthOf(1 + OWNPROPS); 110 | }); 111 | 112 | 113 | // -- This section must not be modified -- 114 | // _library 115 | describe('Check the owned generic properties:', () => { 116 | it('Expects PicoDB object to own the property "_library" that is an object.', () => { 117 | expect(o).to.own.property('_library').that.is.an('object'); 118 | }); 119 | 120 | describe('Test the owned generic properties:', () => { 121 | it('Expects the property "_library" to own two properties.', () => { 122 | expect(Object.keys(o._library)).to.be.an('array').that.has.lengthOf(2); 123 | }); 124 | it(`Expects the property "_library" to own the property "name" whose value is "${libname}".`, () => { 125 | expect(o._library).to.own.property('name').that.is.equal(libname); 126 | }); 127 | it(`Expects the property "_library" to own the property "version" whose value is "${version}".`, () => { 128 | expect(o._library).to.own.property('version').that.is.equal(version); 129 | }); 130 | }); 131 | 132 | 133 | // -- This section must be adapted -- 134 | // Add here the owned properties added by your library. 135 | // [ '_cursor', '_db', '_mess' ] 136 | describe('Check the owned specific custom properties:', () => { 137 | it('Expects PicoDB to own the property "_cursor" that is an object.', () => { 138 | expect(o).to.own.property('_cursor').that.is.an('object'); 139 | }); 140 | 141 | it('Expects PicoDB to own the property "_db" that is an object.', () => { 142 | expect(o).to.own.property('_db').that.is.an('object'); 143 | }); 144 | 145 | it('Expects PicoDB to own the property "_mess" that is a null.', () => { 146 | expect(o).to.own.property('_mess').that.is.a('null'); 147 | }); 148 | 149 | describe('Test the owned specific custom properties:', () => { 150 | it('Expects the property "_db" to own one property.', () => { 151 | expect(Object.keys(o._db)).to.be.an('array').that.has.lengthOf(1); 152 | }); 153 | it('Expects the property "_db" to own the property "data" that is an empty array.', () => { 154 | expect(o._db).to.own.property('data').that.is.an('array').that.has.lengthOf(0); 155 | }); 156 | }); 157 | }); 158 | }); 159 | 160 | // -- This section must not be modified -- 161 | // whoami 162 | describe('Check the inherited generic properties:', () => { 163 | it(`Expects PicoDB object to inherit ${1 + INHPROPS} property(ies).`, () => { 164 | expect(io).to.be.an('array').that.has.lengthOf(1 + INHPROPS); 165 | }); 166 | 167 | it('Expects PicoDB object to inherit the property "whoami" that is a function.', () => { 168 | expect(o).to.have.property('whoami').that.is.a('function'); 169 | }); 170 | 171 | describe('Test the inherited generic properties:', () => { 172 | it('Expects the property "whoami" to return an object.', () => { 173 | expect(o.whoami()).to.be.an('object'); 174 | }); 175 | it('Expects this object to own two properties.', () => { 176 | expect(Object.keys(o.whoami())).to.be.an('array').that.has.lengthOf(2); 177 | }); 178 | it(`Expects this object to own the property "name" whose value is "${libname}".`, () => { 179 | expect(o.whoami()).to.own.property('name').that.is.equal(libname); 180 | }); 181 | it(`Expects this object to own the property "version" whose value is "${version}".`, () => { 182 | expect(o.whoami()).to.own.property('version').that.is.equal(version); 183 | }); 184 | }); 185 | }); 186 | 187 | // -- This section must be adapted -- 188 | // Replace here 'getString' and 'getArray' by the inherited properties 189 | // added by your library. 190 | // ['count', 'deleteMany', 'deleteOne', 'insertMany', 'insertOne', 191 | // 'updateMany', 'updateOne', 'find', 'toArray', 'addEventListener', 192 | // 'addOneTimeEventListener', 'removeEventListener', 'on', 'one', 'off'] 193 | describe('Check the inherited specific properties:', () => { 194 | it('Expects PicoDB object to inherit the property "count" that is a function.', () => { 195 | expect(o).to.have.property('count').that.is.a('function'); 196 | }); 197 | it('Expects PicoDB object to inherit the property "deleteMany" that is a function.', () => { 198 | expect(o).to.have.property('deleteMany').that.is.a('function'); 199 | }); 200 | it('Expects PicoDB object to inherit the property "deleteOne" that is a function.', () => { 201 | expect(o).to.have.property('deleteOne').that.is.a('function'); 202 | }); 203 | it('Expects PicoDB object to inherit the property "insertMany" that is a function.', () => { 204 | expect(o).to.have.property('insertMany').that.is.a('function'); 205 | }); 206 | it('Expects PicoDB object to inherit the property "insertOne" that is a function.', () => { 207 | expect(o).to.have.property('insertOne').that.is.a('function'); 208 | }); 209 | it('Expects PicoDB object to inherit the property "updateMany" that is a function.', () => { 210 | expect(o).to.have.property('updateMany').that.is.a('function'); 211 | }); 212 | it('Expects PicoDB object to inherit the property "updateOne" that is a function.', () => { 213 | expect(o).to.have.property('updateOne').that.is.a('function'); 214 | }); 215 | it('Expects PicoDB object to inherit the property "find" that is a function.', () => { 216 | expect(o).to.have.property('find').that.is.a('function'); 217 | }); 218 | it('Expects PicoDB object to inherit the property "toArray" that is a function.', () => { 219 | expect(o).to.have.property('toArray').that.is.a('function'); 220 | }); 221 | it('Expects PicoDB object to inherit the property "addEventListener" that is a function.', () => { 222 | expect(o).to.have.property('addEventListener').that.is.a('function'); 223 | }); 224 | it('Expects PicoDB object to inherit the property "addOneTimeEventListener" that is a function.', () => { 225 | expect(o).to.have.property('addOneTimeEventListener').that.is.a('function'); 226 | }); 227 | it('Expects PicoDB object to inherit the property "removeEventListener" that is a function.', () => { 228 | expect(o).to.have.property('removeEventListener').that.is.a('function'); 229 | }); 230 | it('Expects PicoDB object to inherit the property "on" that is a function.', () => { 231 | expect(o).to.have.property('on').that.is.a('function'); 232 | }); 233 | it('Expects PicoDB object to inherit the property "one" that is a function.', () => { 234 | expect(o).to.have.property('one').that.is.a('function'); 235 | }); 236 | it('Expects PicoDB object to inherit the property "off" that is a function.', () => { 237 | expect(o).to.have.property('off').that.is.a('function'); 238 | }); 239 | 240 | describe('Test the inherited specific properties:', () => { 241 | it('Expects the property ... to be done ... later on!".', () => { 242 | expect(true).to.be.equal(true); 243 | }); 244 | }); 245 | }); 246 | }); 247 | }); 248 | }; 249 | -------------------------------------------------------------------------------- /test/int/private/_.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the extra functions of the library _.js:', () => { 23 | const [,, _] = PicoDB._setTestMode(); 24 | 25 | describe('Test _.normalize():', () => { 26 | const o1 = _.normalize({ a: 1 }) 27 | , o2 = _.normalize({ a: { b: 1 } }) 28 | , o3 = _.normalize({ 'a.b': 1 }) 29 | , o4 = _.normalize({ 'a.b': { 'c.d.e': { 'f.g.h': { i: { 'j.k': '007' } } } } }) 30 | ; 31 | 32 | // o1 = _.normalize({ a: 1 }) 33 | it('Expects _.normalize({ a: 1 }) to return the object { a: 1 }.', () => { 34 | expect(o1).to.be.an('object'); 35 | }); 36 | 37 | it('Expects this object to own one property.', () => { 38 | expect(Object.keys(o1)).to.be.an('array').that.has.lengthOf(1); 39 | }); 40 | 41 | it('Expects this object to own the property "a" that is equal to 1.', () => { 42 | expect(o1).to.own.property('a').that.is.a('number').that.is.equal(1); 43 | }); 44 | 45 | 46 | // o2 = _.normalize({ a: { b: 1 } }) 47 | it('Expects _.normalize({ a: { b: 1 } }) to return the object { a: { b: 1 } } }.', () => { 48 | expect(o2).to.be.an('object'); 49 | }); 50 | 51 | it('Expects this object to own one property.', () => { 52 | expect(Object.keys(o2)).to.be.an('array').that.has.lengthOf(1); 53 | }); 54 | 55 | it('Expects this object to own the property "a" that is an object.', () => { 56 | expect(o2).to.own.property('a').that.is.an('object'); 57 | }); 58 | 59 | it('Expects the object "a" to own one property.', () => { 60 | expect(Object.keys(o2.a)).to.be.an('array').that.has.lengthOf(1); 61 | }); 62 | 63 | it('Expects the object "a" to own the property "b" that is equal to 1.', () => { 64 | expect(o2.a).to.own.property('b').that.is.a('number').that.is.equal(1); 65 | }); 66 | 67 | 68 | // o3 = _.normalize({ 'a.b': 1 }) 69 | it('Expects _.normalize({ "a.b": 1 } }) to return the object { a: { b: 1 } } }.', () => { 70 | expect(o3).to.be.an('object'); 71 | }); 72 | 73 | it('Expects this object to own one property.', () => { 74 | expect(Object.keys(o3)).to.be.an('array').that.has.lengthOf(1); 75 | }); 76 | 77 | it('Expects this object to own the property "a" that is an object.', () => { 78 | expect(o3).to.own.property('a').that.is.an('object'); 79 | }); 80 | 81 | it('Expects the object "a" to own one property.', () => { 82 | expect(Object.keys(o3.a)).to.be.an('array').that.has.lengthOf(1); 83 | }); 84 | 85 | it('Expects the object "a" to own the property "b" that is equal to 1.', () => { 86 | expect(o3.a).to.own.property('b').that.is.a('number').that.is.equal(1); 87 | }); 88 | 89 | 90 | // o4 = _.normalize({ 'a.b': { 'c.d.e': { 'f.g.h': { i: { 'j.k': '007' } } } } }) 91 | it('Expects _.normalize({ "a.b": { "c.d.e": { "f.g.h": { i: { "j.k": "007" } } } } }) to return the object ...', () => { 92 | expect(o4).to.be.an('object'); 93 | }); 94 | 95 | it('Expects the returned object "o.a.b.c.d.e.f.g.h.i.j.k" to be equal "0.0.7".', () => { 96 | expect(o4.a.b.c.d.e.f.g.h.i.j.k).to.be.a('string').that.is.equal('007'); 97 | }); 98 | }); 99 | }); 100 | }; 101 | -------------------------------------------------------------------------------- /test/int/private/count.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./count/count_1') 11 | , test2 = require('./count/count_2') 12 | , test3 = require('./count/count_3') 13 | ; 14 | 15 | 16 | // -- Local Constants 17 | 18 | 19 | // -- Local Variables 20 | 21 | 22 | // -- Main 23 | module.exports = function(PicoDB) { 24 | describe('Test the count() method:', () => { 25 | // Test with wrong arguments: 26 | test1(PicoDB); 27 | 28 | // Test with real arguments: 29 | test2(PicoDB); 30 | 31 | // Test queries 32 | test3(PicoDB); 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /test/int/private/count/count_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the count method with wrong arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | // Zero argument: 26 | it('Expects db.count() to return a promise.', async () => { 27 | const resp = await db.count(); 28 | expect(resp).to.be.a('number'); 29 | }); 30 | 31 | it('Expects db.count() to return zero.', async () => { 32 | const resp = await db.count(); 33 | expect(resp).to.be.a('number').that.is.equal(0); 34 | }); 35 | 36 | // One argument: 37 | it('Expects db.count(1) to return zero.', async () => { 38 | const resp = await db.count(1); 39 | expect(resp).to.be.a('number').that.is.equal(0); 40 | }); 41 | 42 | it('Expects db.count((err, resp) => ...) to return zero.', (done) => { 43 | db.count((err, resp) => { 44 | expect(resp).to.be.a('number').that.is.equal(0); 45 | done(); 46 | }); 47 | }); 48 | 49 | // Two arguments: 50 | it('Expects db.count(1, (err, resp) => ...) to return zero.', (done) => { 51 | db.count(1, (err, resp) => { 52 | expect(resp).to.be.a('number').that.is.equal(0); 53 | done(); 54 | }); 55 | }); 56 | 57 | it('Expects db.count(1, 2) to return zero.', async () => { 58 | const resp = await db.count(1, 2); 59 | expect(resp).to.be.a('number').that.is.equal(0); 60 | }); 61 | 62 | // Three arguments: 63 | it('Expects db.count(1, 2, (err, resp) => ...) to return zero.', (done) => { 64 | db.count(1, 2, (err, resp) => { 65 | expect(resp).to.be.a('number').that.is.equal(0); 66 | done(); 67 | }); 68 | }); 69 | 70 | it('Expects db.count(1, 2, 3) to return zero.', async () => { 71 | const resp = await db.count(1, 2, 3); 72 | expect(resp).to.be.a('number').that.is.equal(0); 73 | }); 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /test/int/private/count/count_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the count method with real arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 1 }, 28 | { a: 1, b: 1, c: { d: 1 } }, 29 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 30 | { a: { b: { c: { d: { e: 1 } } } } }, 31 | ]; 32 | 33 | // Fill the db: 34 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 35 | const resp = await db.insertMany(doc); 36 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 37 | }); 38 | 39 | // One real argument: 40 | it('Expects db.count({ a: 1 }) to return 4 documents.', async () => { 41 | const resp = await db.count({ a: 1 }); 42 | expect(resp).to.be.a('number').that.is.equal(4); 43 | }); 44 | 45 | // Two real arguments: 46 | it('Expects db.count({ a: 1 }, 1) to return 4 documents.', async () => { 47 | const resp = await db.count({ a: 1 }, 1); 48 | expect(resp).to.be.a('number').that.is.equal(4); 49 | }); 50 | 51 | it('Expects db.count({ a: 1 }, {}) to return 4 documents.', async () => { 52 | const resp = await db.count({ a: 1 }, {}); 53 | expect(resp).to.be.a('number').that.is.equal(4); 54 | }); 55 | 56 | it('Expects db.count({ a: 1 }, (err, resp) => ...) to return 4 documents.', (done) => { 57 | db.count({ a: 1 }, (err, resp) => { 58 | expect(resp).to.be.a('number').that.is.equal(4); 59 | done(); 60 | }); 61 | }); 62 | 63 | // Three real arguments: 64 | it('Expects db.count({ a: 1 }, {}, (err, resp) => ...) to return 4 documents.', (done) => { 65 | db.count({ a: 1 }, {}, (err, resp) => { 66 | expect(resp).to.be.a('number').that.is.equal(4); 67 | done(); 68 | }); 69 | }); 70 | 71 | it('Expects db.count({ a: 1 }, {}, 1) to return 4 documents.', async () => { 72 | const resp = await db.count({ a: 1 }, {}, 1); 73 | expect(resp).to.be.a('number').that.is.equal(4); 74 | }); 75 | 76 | it('Expects db.count({ a: 1 }, [], (err, resp) => ...) to return 4 documents.', (done) => { 77 | db.count({ a: 1 }, [], (err, resp) => { 78 | expect(resp).to.be.a('number').that.is.equal(4); 79 | done(); 80 | }); 81 | }); 82 | 83 | it('Expects db.count({ a: 1 }, [], {}) to return 4 documents.', async () => { 84 | const resp = await db.count({ a: 1 }, [], {}); 85 | expect(resp).to.be.a('number').that.is.equal(4); 86 | }); 87 | }); 88 | }; 89 | -------------------------------------------------------------------------------- /test/int/private/count/count_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the count method with different queries:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 1 }, 28 | { a: 1, b: 1, c: { d: 1 } }, 29 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 30 | { a: { b: { c: { d: { e: 1 } } } } }, 31 | ]; 32 | 33 | // Fill the db: 34 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 35 | const resp = await db.insertMany(doc); 36 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 37 | }); 38 | 39 | it('Expects db.count({ a: 1 }) to return 4 documents.', async () => { 40 | const resp = await db.count({ a: 1 }); 41 | expect(resp).to.be.a('number').that.is.equal(4); 42 | }); 43 | 44 | it('Expects db.count({ a: 1, b: 1 }) to return 3 documents.', async () => { 45 | const resp = await db.count({ a: 1, b: 1 }); 46 | expect(resp).to.be.a('number').that.is.equal(3); 47 | }); 48 | 49 | it('Expects db.count({ a: 1, b: 1, c: { d: 1 } }) to return 2 documents.', async () => { 50 | const resp = await db.count({ a: 1, b: 1, c: { d: 1 } }); 51 | expect(resp).to.be.a('number').that.is.equal(2); 52 | }); 53 | 54 | it('Expects db.count({ a: 1, b: 1, c: { d: 1, e: ["A", "B", "C"] } }) to return 1 document.', async () => { 55 | const resp = await db.count({ a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }); 56 | expect(resp).to.be.a('number').that.is.equal(1); 57 | }); 58 | 59 | it('Expects db.count({ a: 2 }) to return 0 document.', async () => { 60 | const resp = await db.count({ a: 2 }); 61 | expect(resp).to.be.a('number').that.is.equal(0); 62 | }); 63 | 64 | it('Expects db.count({ a: { b: { c: { d: { e: 1 }}}} }) to return 1 document.', async () => { 65 | const resp = await db.count({ a: { b: { c: { d: { e: 1 } } } } }); 66 | expect(resp).to.be.a('number').that.is.equal(1); 67 | }); 68 | 69 | it('Expects db.count({ a: { b: { c: { d: { e: 2 }}}} }) to return 0 document.', async () => { 70 | const resp = await db.count({ a: { b: { c: { d: { e: 2 } } } } }); 71 | expect(resp).to.be.a('number').that.is.equal(0); 72 | }); 73 | 74 | it('Expects db.count({ a: { b: { c: { d: { e: 2 }}}} }) to return 0 document.', async () => { 75 | const resp = await db.count({ a: { b: { c: { d: { e: 2 } } } } }); 76 | expect(resp).to.be.a('number').that.is.equal(0); 77 | }); 78 | }); 79 | 80 | describe('Test the count method with queries using dot.notation:', () => { 81 | const db = PicoDB(); 82 | 83 | const doc = [ 84 | { a: 1 }, 85 | { a: 1, b: 1 }, 86 | { a: 1, b: 1, c: { d: 1 } }, 87 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 88 | { a: { b: { c: { d: { e: 1 } } } } }, 89 | ]; 90 | 91 | // Fill the db: 92 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 93 | const resp = await db.insertMany(doc); 94 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 95 | }); 96 | 97 | it('Expects db.count({ "c.d": 1 }) to return 2 documents.', async () => { 98 | const resp = await db.count({ 'c.d': 1 }); 99 | expect(resp).to.be.a('number').that.is.equal(2); 100 | }); 101 | 102 | it('Expects db.count({ "a.b.c.d.e": 1 }) to return 1 document.', async () => { 103 | const resp = await db.count({ 'a.b.c.d.e': 1 }); 104 | expect(resp).to.be.a('number').that.is.equal(1); 105 | }); 106 | 107 | it('Expects db.count({ "a.b.c.d.e": 2 }) to return 0 document.', async () => { 108 | const resp = await db.count({ 'a.b.c.d.e': 2 }); 109 | expect(resp).to.be.a('number').that.is.equal(0); 110 | }); 111 | }); 112 | }; 113 | -------------------------------------------------------------------------------- /test/int/private/delete.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./delete/delete_1') 11 | , test2 = require('./delete/delete_2') 12 | , test3 = require('./delete/delete_3') 13 | ; 14 | 15 | 16 | // -- Local Constants 17 | const doc = [ 18 | { a: 1 }, 19 | { a: 1, b: 1 }, 20 | { a: 1, b: 1, c: { d: 1 } }, 21 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 22 | { a: { b: { c: { d: { e: 1 } } } } }, 23 | ]; 24 | 25 | 26 | // -- Local Variables 27 | 28 | 29 | // -- Main 30 | module.exports = function(PicoDB) { 31 | describe('Test the delete() method:', () => { 32 | test1(PicoDB, doc); 33 | test2(PicoDB, doc); 34 | test3(PicoDB, doc); 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /test/int/private/delete/delete_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the delete methods with wrong arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | // Zero argument: 26 | it('Expects db.deleteOne() to return a promise.', async () => { 27 | const resp = await db.deleteOne(); 28 | expect(resp).to.be.an('number').that.is.equal(0); 29 | }); 30 | 31 | // One argument: 32 | it('Expects db.deleteOne((err, resp) => { ... }) to return zero document.', (done) => { 33 | db.deleteOne((err, resp) => { 34 | expect(err).to.be.a('null'); 35 | expect(resp).to.be.an('number').that.is.equal(0); 36 | done(); 37 | }); 38 | }); 39 | 40 | it('Expects db.deleteOne(1) to to return zero document.', async () => { 41 | const resp = await db.deleteOne(1); 42 | expect(resp).to.be.an('number').that.is.equal(0); 43 | }); 44 | 45 | // Two arguments 46 | it('Expects db.deleteOne(1, (err, resp) => { ... }) to return zero document.', (done) => { 47 | db.deleteOne(1, (err, resp) => { 48 | expect(err).to.be.a('null'); 49 | expect(resp).to.be.an('number').that.is.equal(0); 50 | done(); 51 | }); 52 | }); 53 | 54 | it('Expects db.deleteOne(1, 2) to to return zero document.', async () => { 55 | const resp = await db.deleteOne(1, 2); 56 | expect(resp).to.be.an('number').that.is.equal(0); 57 | }); 58 | 59 | // Three arguments: 60 | it('Expects db.deleteOne(1, {}, (err, resp) => { ... }) to return zero document.', (done) => { 61 | db.deleteOne(1, {}, (err, resp) => { 62 | expect(err).to.be.a('null'); 63 | expect(resp).to.be.an('number').that.is.equal(0); 64 | done(); 65 | }); 66 | }); 67 | 68 | it('Expects db.deleteOne(1, 2, (err, resp) => { ... }) to return zero document.', (done) => { 69 | db.deleteOne(1, 2, (err, resp) => { 70 | expect(err).to.be.a('null'); 71 | expect(resp).to.be.an('number').that.is.equal(0); 72 | done(); 73 | }); 74 | }); 75 | 76 | it('Expects db.deleteOne(1, {}, 3) to to return zero document.', async () => { 77 | const resp = await db.deleteOne(1, {}, 3); 78 | expect(resp).to.be.an('number').that.is.equal(0); 79 | }); 80 | 81 | it('Expects db.deleteOne(1, 2, 3) to to return zero document.', async () => { 82 | const resp = await db.deleteOne(1, 2, 3); 83 | expect(resp).to.be.an('number').that.is.equal(0); 84 | }); 85 | }); 86 | }; 87 | -------------------------------------------------------------------------------- /test/int/private/delete/delete_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, doc) { 22 | describe('Test the DeleteOne method with a real filter:', () => { 23 | const db = PicoDB(); 24 | 25 | // Fill the db: 26 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 27 | const resp = await db.insertMany(doc); 28 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 29 | }); 30 | 31 | // One argument: 32 | it('Expects db.deleteOne({ a: 2 }) not to delete any document.', async () => { 33 | const resp = await db.deleteOne({ a: 2 }); 34 | expect(resp).to.be.an('number').that.is.equal(0); 35 | }); 36 | 37 | // Two arguments: 38 | it('Expects db.deleteOne({ a: 2 }, {}) not to delete any document.', async () => { 39 | const resp = await db.deleteOne({ a: 2 }, {}); 40 | expect(resp).to.be.an('number').that.is.equal(0); 41 | }); 42 | 43 | it('Expects db.deleteOne({ a: 2 }, (err, resp) => {...}) not to delete any document.', (done) => { 44 | db.deleteOne({ a: 2 }, (err, resp) => { 45 | expect(err).to.be.a('null'); 46 | expect(resp).to.be.an('number').that.is.equal(0); 47 | done(); 48 | }); 49 | }); 50 | 51 | it('Expects db.deleteOne({ a: 2 }, 1) not to delete any document.', async () => { 52 | const resp = await db.deleteOne({ a: 2 }, 1); 53 | expect(resp).to.be.an('number').that.is.equal(0); 54 | }); 55 | 56 | // Three arguments: 57 | it('Expects db.deleteOne({ a: 2 }, {}, (err, resp) => {...}) not to delete any document.', (done) => { 58 | db.deleteOne({ a: 2 }, {}, (err, resp) => { 59 | expect(err).to.be.a('null'); 60 | expect(resp).to.be.an('number').that.is.equal(0); 61 | done(); 62 | }); 63 | }); 64 | 65 | it('Expects db.deleteOne({ a: 2 }, {}, 1) not to delete any document.', async () => { 66 | const resp = await db.deleteOne({ a: 2 }, {}, 1); 67 | expect(resp).to.be.an('number').that.is.equal(0); 68 | }); 69 | 70 | it('Expects db.deleteOne({ a: 2 }, 1, (err, resp) => {...}) not to delete any document.', (done) => { 71 | db.deleteOne({ a: 2 }, 1, (err, resp) => { 72 | expect(err).to.be.a('null'); 73 | expect(resp).to.be.an('number').that.is.equal(0); 74 | done(); 75 | }); 76 | }); 77 | 78 | it('Expects db.deleteOne({ a: 2 }, 1, 2) not to delete any document.', async () => { 79 | const resp = await db.deleteOne({ a: 2 }, 1, 2); 80 | expect(resp).to.be.an('number').that.is.equal(0); 81 | }); 82 | }); 83 | }; 84 | -------------------------------------------------------------------------------- /test/int/private/delete/delete_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, doc) { 22 | describe('Test DeleteOne operations:', () => { 23 | const db = PicoDB(); 24 | 25 | // Fill the db: 26 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 27 | const resp = await db.insertMany(doc); 28 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 29 | }); 30 | 31 | it('Expects db.deleteOne({ a: 1 }) to return 1 document deleted.', async () => { 32 | const resp = await db.deleteOne({ a: 1 }); 33 | expect(resp).to.be.an('number').that.is.equal(1); 34 | }); 35 | 36 | it('Expects db.deleteOne({}) to return 1 document deleted.', async () => { 37 | const resp = await db.deleteOne({}); 38 | expect(resp).to.be.an('number').that.is.equal(1); 39 | }); 40 | 41 | it('Expects db.count({}) to return 3 documents remaining into the db.', async () => { 42 | const resp = await db.count({}); 43 | expect(resp).to.be.an('number').that.is.equal(3); 44 | }); 45 | }); 46 | 47 | describe('Test DeleteMany operations:', () => { 48 | const db = PicoDB(); 49 | 50 | // Fill the db: 51 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 52 | const resp = await db.insertMany(doc); 53 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 54 | }); 55 | 56 | it('Expects db.deleteMany({ a: 1 }) to return 4 documents deleted.', async () => { 57 | const resp = await db.deleteMany({ a: 1 }); 58 | expect(resp).to.be.an('number').that.is.equal(4); 59 | }); 60 | 61 | it('Expects db.count({}) to return 1 document remaining into the db.', async () => { 62 | const resp = await db.count({}); 63 | expect(resp).to.be.an('number').that.is.equal(1); 64 | }); 65 | 66 | // Refill the db: 67 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 68 | const resp = await db.insertMany(doc); 69 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 70 | }); 71 | 72 | it('Expects db.deleteMany({}) to return 6 documents deleted.', async () => { 73 | const resp = await db.deleteMany({}); 74 | expect(resp).to.be.an('number').that.is.equal(6); 75 | }); 76 | 77 | it('Expects db.count({}) to return 0 document remaining into the db.', async () => { 78 | const resp = await db.count({}); 79 | expect(resp).to.be.an('number').that.is.equal(0); 80 | }); 81 | }); 82 | 83 | describe('Test DeleteMany operations using dot notation:', () => { 84 | const db = PicoDB(); 85 | 86 | // Fill the db: 87 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 88 | const resp = await db.insertMany(doc); 89 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 90 | }); 91 | 92 | it('Expects db.deleteMany({ "c.d": 2 }) to return 2 documents deleted.', async () => { 93 | const resp = await db.deleteMany({ 'c.d': 1 }); 94 | expect(resp).to.be.an('number').that.is.equal(2); 95 | }); 96 | 97 | it('Expects db.deleteMany({ "a.b.c.d.e": 1 }) to return 1 document deleted.', async () => { 98 | const resp = await db.deleteMany({ 'a.b.c.d.e': 1 }); 99 | expect(resp).to.be.an('number').that.is.equal(1); 100 | }); 101 | }); 102 | }; 103 | -------------------------------------------------------------------------------- /test/int/private/event.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./event/event_1') 11 | , test2 = require('./event/event_2') 12 | ; 13 | 14 | 15 | // -- Local Constants 16 | 17 | 18 | // -- Local Variables 19 | 20 | 21 | // -- Main 22 | module.exports = function(PicoDB, Messenger) { 23 | describe('Test event methods:', () => { 24 | test1(PicoDB, Messenger); 25 | test2(PicoDB, Messenger); 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /test/int/private/event/event_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const { expect } = require('chai') 11 | ; 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test event methods without installing the plugin:', () => { 23 | const db = PicoDB(); 24 | 25 | it('Expects db.addEventListener() to return an object.', () => { 26 | expect(db.addEventListener()).to.be.an('object'); 27 | }); 28 | 29 | it('Expects db.addOneTimeEventListener() to return an object.', () => { 30 | expect(db.addOneTimeEventListener()).to.be.an('object'); 31 | }); 32 | 33 | it('Expects db.removeEventListener() to return an object.', () => { 34 | expect(db.removeEventListener()).to.be.an('object'); 35 | }); 36 | 37 | it('Expects db.removeEventListener() to return an object.', () => { 38 | expect(db.removeEventListener()).to.be.an('object'); 39 | }); 40 | 41 | it('Expects db.on() to return an object.', () => { 42 | expect(db.on()).to.be.an('object'); 43 | }); 44 | 45 | it('Expects db.one() to return an object.', () => { 46 | expect(db.one()).to.be.an('object'); 47 | }); 48 | 49 | it('Expects db.off() to return an object.', () => { 50 | expect(db.off()).to.be.an('object'); 51 | }); 52 | }); 53 | }; 54 | -------------------------------------------------------------------------------- /test/int/private/event/event_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const { expect } = require('chai') 11 | ; 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, Messenger) { 22 | describe('Test event methods with the plugin installed:', () => { 23 | PicoDB.plugin({ messenger: Messenger }); 24 | 25 | describe('Test events for the insert method:', () => { 26 | const db = PicoDB(); 27 | 28 | let iresp 29 | , cresp 30 | ; 31 | 32 | it('Expects db.insertOne({ a: 1 }) to fire an "insert" event.', (done) => { 33 | db.one('insert', (resp) => { 34 | expect(resp).to.be.an('array'); 35 | iresp = resp; 36 | done(); 37 | }); 38 | db.insertOne({ a: 1 }); 39 | }); 40 | 41 | it('Expects the event payload to be an array containing one document.', () => { 42 | expect(iresp).to.be.an('array').that.has.lengthOf(1); 43 | }); 44 | 45 | it('Expects this document to own two properties.', () => { 46 | expect(Object.keys(iresp[0])).to.be.an('array').that.has.lengthOf(2); 47 | }); 48 | 49 | it('Expects this document to own the property "_id" that is a string.', () => { 50 | expect(iresp[0]).to.own.property('_id').that.is.a('string'); 51 | }); 52 | 53 | it('Expects this document to own the property "a" that is equal to 1.', () => { 54 | expect(iresp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 55 | }); 56 | 57 | 58 | it('Expects db.insertOne({ a: 1 }) to fire a "change" event.', (done) => { 59 | db.on('change', (resp) => { 60 | expect(resp).to.be.an('array'); 61 | cresp = resp; 62 | done(); 63 | }); 64 | db.insertOne({ a: 1 }); 65 | }); 66 | 67 | it('Expects the event payload to be an array containing one document.', () => { 68 | expect(cresp).to.be.an('array').that.has.lengthOf(1); 69 | }); 70 | 71 | it('Expects this document to own two properties.', () => { 72 | expect(Object.keys(cresp[0])).to.be.an('array').that.has.lengthOf(2); 73 | }); 74 | 75 | it('Expects this document to own the property "_id" that is a string.', () => { 76 | expect(cresp[0]).to.own.property('_id').that.is.a('string'); 77 | }); 78 | 79 | it('Expects this document to own the property "a" that is equal to 1.', () => { 80 | expect(cresp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 81 | }); 82 | }); 83 | 84 | 85 | describe('Test events for the update methods:', () => { 86 | const db = PicoDB(); 87 | 88 | let uresp 89 | , cresp 90 | ; 91 | 92 | it('Expects db.insertOne({ a: 1 }) to insert one document into the db.', async () => { 93 | const resp = await db.insertOne({ a: 1 }); 94 | expect(resp).to.be.an('array').that.has.lengthOf(1); 95 | }); 96 | 97 | it('Expects db.updateOne({ a: 1 }, { a: 2 }) to fire an "update" event.', (done) => { 98 | db.one('update', (resp) => { 99 | expect(resp).to.be.an('array'); 100 | uresp = resp; 101 | done(); 102 | }); 103 | db.updateOne({ a: 1 }, { a: 2 }); 104 | }); 105 | 106 | it('Expects the event payload to be an array containing one document.', () => { 107 | expect(uresp).to.be.an('array').that.has.lengthOf(1); 108 | }); 109 | 110 | it('Expects this document to own two properties.', () => { 111 | expect(Object.keys(uresp[0])).to.be.an('array').that.has.lengthOf(2); 112 | }); 113 | 114 | it('Expects this document to own the property "_id" that is a string.', () => { 115 | expect(uresp[0]).to.own.property('_id').that.is.a('string'); 116 | }); 117 | 118 | it('Expects this document to own the property "a" that is equal to 2.', () => { 119 | expect(uresp[0]).to.own.property('a').that.is.a('number').that.is.equal(2); 120 | }); 121 | 122 | it('Expects db.updateOne({ a: 2 }, { a: 1 }) to fire a "change" event.', (done) => { 123 | db.one('change', (resp) => { 124 | expect(resp).to.be.an('array'); 125 | cresp = resp; 126 | done(); 127 | }); 128 | db.updateOne({ a: 2 }, { a: 1 }); 129 | }); 130 | 131 | it('Expects the event payload to be an array containing one document.', () => { 132 | expect(cresp).to.be.an('array').that.has.lengthOf(1); 133 | }); 134 | 135 | it('Expects this document to own two properties.', () => { 136 | expect(Object.keys(cresp[0])).to.be.an('array').that.has.lengthOf(2); 137 | }); 138 | 139 | it('Expects this document to own the property "_id" that is a string.', () => { 140 | expect(cresp[0]).to.own.property('_id').that.is.a('string'); 141 | }); 142 | 143 | it('Expects this document to own the property "a" that is equal to 1.', () => { 144 | expect(cresp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 145 | }); 146 | }); 147 | 148 | 149 | describe('Test events for the delete methods:', () => { 150 | const db = PicoDB(); 151 | 152 | let dresp 153 | , cresp 154 | ; 155 | 156 | it('Expects db.insertMany([{ a: 1 }, { b: 2 }]) to insert two documents into the db.', async () => { 157 | const resp = await db.insertMany([{ a: 1 }, { b: 2 }]); 158 | expect(resp).to.be.an('array').that.has.lengthOf(2); 159 | }); 160 | 161 | it('Expects db.deleteOne({ a: 1 }) to fire a "delete" event.', (done) => { 162 | db.one('delete', (resp) => { 163 | expect(resp).to.be.an('array'); 164 | dresp = resp; 165 | done(); 166 | }); 167 | db.deleteOne({ a: 1 }); 168 | }); 169 | 170 | it('Expects the event payload to be an array containing one document.', () => { 171 | expect(dresp).to.be.an('array').that.has.lengthOf(1); 172 | }); 173 | 174 | it('Expects this document to own two properties.', () => { 175 | expect(Object.keys(dresp[0])).to.be.an('array').that.has.lengthOf(2); 176 | }); 177 | 178 | it('Expects this document to own the property "_id" that is a string.', () => { 179 | expect(dresp[0]).to.own.property('_id').that.is.a('string'); 180 | }); 181 | 182 | it('Expects this document to own the property "a" that is equal to 1.', () => { 183 | expect(dresp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 184 | }); 185 | 186 | it('Expects db.deleteOne({ b: 2 }) to fire a "change" event.', (done) => { 187 | db.one('change', (resp) => { 188 | expect(resp).to.be.an('array'); 189 | cresp = resp; 190 | done(); 191 | }); 192 | db.deleteOne({ b: 2 }); 193 | }); 194 | 195 | it('Expects the event payload to be an array containing one document.', () => { 196 | expect(cresp).to.be.an('array').that.has.lengthOf(1); 197 | }); 198 | 199 | it('Expects this document to own two properties.', () => { 200 | expect(Object.keys(cresp[0])).to.be.an('array').that.has.lengthOf(2); 201 | }); 202 | 203 | it('Expects this document to own the property "_id" that is a string.', () => { 204 | expect(cresp[0]).to.own.property('_id').that.is.a('string'); 205 | }); 206 | 207 | it('Expects this document to own the property "b" that is equal to 2.', () => { 208 | expect(cresp[0]).to.own.property('b').that.is.a('number').that.is.equal(2); 209 | }); 210 | }); 211 | 212 | describe('Test remove events :', () => { 213 | it('Expects db.off() to remove event listeners.', () => { 214 | const db = PicoDB(); 215 | const resp = db.off('change'); 216 | expect(resp).to.be.an('object'); 217 | }); 218 | }); 219 | }); 220 | }; 221 | -------------------------------------------------------------------------------- /test/int/private/find.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./find/find_1') 11 | , test2 = require('./find/find_2') 12 | , test3 = require('./find/find_3') 13 | ; 14 | 15 | 16 | // -- Local Constants 17 | 18 | 19 | // -- Local Variables 20 | 21 | 22 | // -- Main 23 | module.exports = function(PicoDB) { 24 | describe('Test find() and toArray() methods:', () => { 25 | // Test with wrong queries. 26 | test1(PicoDB); 27 | 28 | // Test basic queries and projections. 29 | test2(PicoDB); 30 | test3(PicoDB); 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /test/int/private/find/find_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test find().toArray() with a variation of arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 1 }, 28 | { a: 1, b: 1, c: { d: 1 } }, 29 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 30 | { a: { b: { c: { d: { e: 1 } } } } }, 31 | ]; 32 | 33 | // Fill db 34 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 35 | const resp = await db.insertMany(doc); 36 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 37 | }); 38 | 39 | // Test promises 40 | it('Expects db.find().toArray() to return a promise.', async () => { 41 | const resp = await db.find().toArray(); 42 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 43 | }); 44 | 45 | // Test callback 46 | it('Expects db.find().toArray((err, resp) => ...) to call a callback.', (done) => { 47 | db.find().toArray((err, resp) => { 48 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 49 | done(); 50 | }); 51 | }); 52 | 53 | // Test with invalid find arguments: 54 | 55 | // Zero arguments: 56 | it('Expects db.find().toArray() to return an array with all the documents.', async () => { 57 | const resp = await db.find().toArray(); 58 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 59 | }); 60 | 61 | // One argument: 62 | it('Expects db.find(1).toArray() to return an array with all the documents.', async () => { 63 | const resp = await db.find(1).toArray(); 64 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 65 | }); 66 | 67 | it('Expects db.find({}).toArray() to return an array with all documents.', async () => { 68 | const resp = await db.find({}).toArray(); 69 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 70 | }); 71 | 72 | // Two arguments: 73 | it('Expects db.find({}, "string").toArray() to return an array with all the documents.', async () => { 74 | const resp = await db.find({}, 'string').toArray(); 75 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 76 | }); 77 | 78 | it('Expects db.find({}, {}).toArray() to return an array with all the documents.', async () => { 79 | const resp = await db.find({}, {}).toArray(); 80 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 81 | }); 82 | 83 | it('Expects db.find("string", {}).toArray() to return an array with all the documents.', async () => { 84 | const resp = await db.find('string', {}).toArray(); 85 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 86 | }); 87 | 88 | it('Expects db.find("string", 123).toArray() to return an array with all the documents.', async () => { 89 | const resp = await db.find('string', 123).toArray(); 90 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 91 | }); 92 | }); 93 | }; 94 | -------------------------------------------------------------------------------- /test/int/private/find/find_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test find().toArray() with basic queries:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: null }, 28 | { a: 1, b: 1 }, 29 | { a: 1, b: 1, c: { d: 1 } }, 30 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 31 | { a: { b: { c: { d: { e: 1 } } } } }, 32 | ]; 33 | 34 | // Fill db 35 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 36 | const resp = await db.insertMany(doc); 37 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 38 | }); 39 | 40 | it('Expects db.find({ a: 1 }).toArray() to return 5 documents.', async () => { 41 | const resp = await db.find({ a: 1 }).toArray(); 42 | expect(resp).to.be.an('array').that.has.lengthOf(5); 43 | }); 44 | 45 | it('Expects db.find({ b: 1 }).toArray() to return 3 documents.', async () => { 46 | const resp = await db.find({ b: 1 }).toArray(); 47 | expect(resp).to.be.an('array').that.has.lengthOf(3); 48 | }); 49 | 50 | it('Expects db.find({ c: { d: 1, e: ["A", "B", "C"] } }).toArray() to return 1 document.', async () => { 51 | const resp = await db.find({ c: { d: 1, e: ['A', 'B', 'C'] } }).toArray(); 52 | expect(resp).to.be.an('array').that.has.lengthOf(1); 53 | }); 54 | 55 | it('Expects db.find({ b: null }).toArray() to return 1 document.', async () => { 56 | const resp = await db.find({ b: null }).toArray(); 57 | expect(resp).to.be.an('array').that.has.lengthOf(1); 58 | }); 59 | 60 | it('Expects db.find({ "a.b.c.d.e": 1 }).toArray() to return 1 document.', async () => { 61 | const resp = await db.find({ 'a.b.c.d.e': 1 }).toArray(); 62 | expect(resp).to.be.an('array').that.has.lengthOf(1); 63 | }); 64 | }); 65 | }; 66 | -------------------------------------------------------------------------------- /test/int/private/find/find_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test find().toArray() with projections:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: null }, 28 | { a: 1, b: 1 }, 29 | { a: 1, b: 1, c: { d: 1 } }, 30 | { a: 1, b: 1, c: { d: 1, e: ['A', 'B', 'C'] } }, 31 | { a: { b: { c: { d: { e: 1 } } } } }, 32 | ]; 33 | 34 | // Fill db 35 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 36 | const resp = await db.insertMany(doc); 37 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 38 | }); 39 | 40 | describe('Test include projections:', () => { 41 | let doc4 42 | , doc44 43 | , doc444 44 | , doc4444 45 | , doc44444 46 | ; 47 | 48 | // projection { a: 1 } 49 | it('Expects db.find({}, { a: 1 }).toArray() to return 6 documents.', async () => { 50 | const resp = await db.find({}, { a: 1 }).toArray(); 51 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 52 | doc4 = resp; 53 | }); 54 | it('Expects the returned documents to own 2 properties only.', () => { 55 | expect(Object.keys(doc4[4])).to.be.an('array').that.has.lengthOf(2); 56 | }); 57 | it('Expects the returned documents to own the property "_id" that is a string.', () => { 58 | expect(doc4[4]).to.own.property('_id').that.is.a('string'); 59 | }); 60 | it('Expects the returned documents to own the property "a".', () => { 61 | expect(doc4[4]).to.own.property('a').that.is.a('number').that.is.equal(1); 62 | }); 63 | 64 | 65 | // projection { b: 1 } 66 | it('Expects db.find({}, { b: 1 }).toArray((err, resp) => ...) to return 6 documents.', async () => { 67 | const resp = await db.find({}, { b: 1 }).toArray(); 68 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 69 | doc44 = resp; 70 | }); 71 | it('Expects the first returned document to own 1 property only.', () => { 72 | expect(Object.keys(doc44[0])).to.be.an('array').that.has.lengthOf(1); 73 | }); 74 | it('Expects the second returned document to own 1 property only.', () => { 75 | expect(Object.keys(doc44[1])).to.be.an('array').that.has.lengthOf(1); 76 | }); 77 | 78 | it('Expects the third returned document to own 2 properties.', () => { 79 | expect(Object.keys(doc44[2])).to.be.an('array').that.has.lengthOf(2); 80 | }); 81 | it('Expects this document to own the property "_id" that is a string.', () => { 82 | expect(doc44[2]).to.own.property('_id').that.is.a('string'); 83 | }); 84 | it('Expects this document to own the property "b" that is equal to 1.', () => { 85 | expect(doc44[2]).to.own.property('b').that.is.a('number').that.is.equal(1); 86 | }); 87 | 88 | // projection { c: { e: 1 }} 89 | it('Expects db.find({}, { c: { e: 1 } }).toArray() to return 6 documents.', async () => { 90 | const resp = await db.find({}, { c: { e: 1 } }).toArray(); 91 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 92 | doc444 = resp; 93 | }); 94 | it('Expects the first returned document to own 1 property only.', () => { 95 | expect(Object.keys(doc444[0])).to.be.an('array').that.has.lengthOf(1); 96 | }); 97 | it('Expects the second returned document to own 1 property only.', () => { 98 | expect(Object.keys(doc444[1])).to.be.an('array').that.has.lengthOf(1); 99 | }); 100 | it('Expects the third returned document to own 1 property only.', () => { 101 | expect(Object.keys(doc444[2])).to.be.an('array').that.has.lengthOf(1); 102 | }); 103 | 104 | it('Expects the fourth returned document to own 2 properties.', () => { 105 | expect(Object.keys(doc444[3])).to.be.an('array').that.has.lengthOf(2); 106 | }); 107 | it('Expects this document to own the property "_id" that is a string.', () => { 108 | expect(doc444[3]).to.own.property('_id').that.is.a('string'); 109 | }); 110 | it('Expects this document to own the property "c" that is an object.', () => { 111 | expect(doc444[3]).to.own.property('c').that.is.an('object'); 112 | }); 113 | it('Expects this object no to have any property.', () => { 114 | expect(Object.keys(doc444[3].c)).to.be.an('array').that.has.lengthOf(0); 115 | }); 116 | 117 | it('Expects the fifth returned document to own 2 properties.', () => { 118 | expect(Object.keys(doc444[4])).to.be.an('array').that.has.lengthOf(2); 119 | }); 120 | it('Expects this document to own the property "_id" that is a string.', () => { 121 | expect(doc444[4]).to.own.property('_id').that.is.a('string'); 122 | }); 123 | it('Expects this document to own the property "c" that is an object.', () => { 124 | expect(doc444[4]).to.own.property('c').that.is.an('object'); 125 | }); 126 | it('Expects this object to have one property.', () => { 127 | expect(Object.keys(doc444[4].c)).to.be.an('array').that.has.lengthOf(1); 128 | }); 129 | it('Expects this property to own the property "e" that is an array with 3 elements.', () => { 130 | expect(doc444[4].c).to.own.property('e').that.is.an('array').that.has.lengthOf(3); 131 | }); 132 | 133 | // projection { _id: 0, a: 1 } 134 | it('Expects db.find({}, { _id: 0, a: 1 }).toArray() to return 6 documents.', async () => { 135 | const resp = await db.find({}, { _id: 0, a: 1 }).toArray(); 136 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 137 | doc4444 = resp; 138 | }); 139 | it('Expects the first returned document to own 1 property only.', () => { 140 | expect(Object.keys(doc4444[0])).to.be.an('array').that.has.lengthOf(1); 141 | }); 142 | it('Expects the second returned document to own 1 property only.', () => { 143 | expect(Object.keys(doc4444[1])).to.be.an('array').that.has.lengthOf(1); 144 | }); 145 | it('Expects the third returned document to own 1 property only.', () => { 146 | expect(Object.keys(doc4444[2])).to.be.an('array').that.has.lengthOf(1); 147 | }); 148 | it('Expects the fourth returned document to own 1 property only.', () => { 149 | expect(Object.keys(doc4444[2])).to.be.an('array').that.has.lengthOf(1); 150 | }); 151 | it('Expects the fifth returned document to own 1 property only.', () => { 152 | expect(Object.keys(doc4444[2])).to.be.an('array').that.has.lengthOf(1); 153 | }); 154 | it('Expects the sixth returned document to own 0 property.', () => { 155 | expect(Object.keys(doc4444[2])).to.be.an('array').that.has.lengthOf(1); 156 | }); 157 | 158 | // projection { _id: 0, c: 1 } 159 | it('Expects db.find({}, { _id: 0, c: { d: 1 } }).toArray() to return 6 documents.', async () => { 160 | const resp = await db.find({}, { _id: 0, c: 1 }).toArray(); 161 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 162 | doc44444 = resp; 163 | }); 164 | it('Expects the first returned document to own 0 property.', () => { 165 | expect(Object.keys(doc44444[0])).to.be.an('array').that.has.lengthOf(0); 166 | }); 167 | it('Expects the second returned document to own 0 property.', () => { 168 | expect(Object.keys(doc44444[1])).to.be.an('array').that.has.lengthOf(0); 169 | }); 170 | it('Expects the third returned document to own 0 property.', () => { 171 | expect(Object.keys(doc44444[2])).to.be.an('array').that.has.lengthOf(0); 172 | }); 173 | it('Expects the fourth returned document to own 1 property.', () => { 174 | expect(Object.keys(doc44444[3])).to.be.an('array').that.has.lengthOf(1); 175 | }); 176 | it('Expects the fifth returned document to own 1 property.', () => { 177 | expect(Object.keys(doc44444[4])).to.be.an('array').that.has.lengthOf(1); 178 | }); 179 | it('Expects the sixth returned document to own 0 property.', () => { 180 | expect(Object.keys(doc44444[5])).to.be.an('array').that.has.lengthOf(0); 181 | }); 182 | // 183 | }); 184 | 185 | describe('Test exlude projections:', () => { 186 | let doc4 187 | , doc44 188 | ; 189 | 190 | it('Expects db.find({}, { b: 0, c: 0 }).toArray() to return 6 documents.', async () => { 191 | const resp = await db.find({}, { b: 0, c: 0 }).toArray(); 192 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 193 | doc4 = resp; 194 | }); 195 | it('Expects the first returned document to own 2 properties.', () => { 196 | expect(Object.keys(doc4[0])).to.be.an('array').that.has.lengthOf(2); 197 | }); 198 | it('Expects the second returned document to own 2 properties.', () => { 199 | expect(Object.keys(doc4[1])).to.be.an('array').that.has.lengthOf(2); 200 | }); 201 | it('Expects the third returned document to own 2 properties.', () => { 202 | expect(Object.keys(doc4[2])).to.be.an('array').that.has.lengthOf(2); 203 | }); 204 | it('Expects the fourth returned document to own 2 properties.', () => { 205 | expect(Object.keys(doc4[3])).to.be.an('array').that.has.lengthOf(2); 206 | }); 207 | it('Expects the fifth returned document to own 2 properties.', () => { 208 | expect(Object.keys(doc4[4])).to.be.an('array').that.has.lengthOf(2); 209 | }); 210 | it('Expects the sixth returned document to own 2 properties.', () => { 211 | expect(Object.keys(doc4[5])).to.be.an('array').that.has.lengthOf(2); 212 | }); 213 | 214 | it('Expects the fifth returned document to own the property "_id" that is a string.', () => { 215 | expect(doc4[4]).to.own.property('_id').that.is.a('string'); 216 | }); 217 | it('Expects the fifth returned document to own the property "a" that is a number equal to 1.', () => { 218 | expect(doc4[4]).to.own.property('a').that.is.a('number').that.is.equal(1); 219 | }); 220 | 221 | it('Expects db.find({}, { b: 0, c: { d: 0 } }).toArray() to return 6 documents.', async () => { 222 | const resp = await db.find({}, { b: 0, c: { d: 0 } }).toArray(); 223 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 224 | doc44 = resp; 225 | }); 226 | 227 | it('Expects the first returned document to own 2 properties.', () => { 228 | expect(Object.keys(doc44[0])).to.be.an('array').that.has.lengthOf(2); 229 | }); 230 | it('Expects the second returned document to own 2 properties.', () => { 231 | expect(Object.keys(doc44[1])).to.be.an('array').that.has.lengthOf(2); 232 | }); 233 | it('Expects the third returned document to own 2 properties.', () => { 234 | expect(Object.keys(doc44[2])).to.be.an('array').that.has.lengthOf(2); 235 | }); 236 | it('Expects the fourth returned document to own 3 properties.', () => { 237 | expect(Object.keys(doc44[3])).to.be.an('array').that.has.lengthOf(3); 238 | }); 239 | it('Expects the fifth returned document to own 3 properties.', () => { 240 | expect(Object.keys(doc44[4])).to.be.an('array').that.has.lengthOf(3); 241 | }); 242 | it('Expects the sixth returned document to own 2 properties.', () => { 243 | expect(Object.keys(doc44[5])).to.be.an('array').that.has.lengthOf(2); 244 | }); 245 | 246 | it('Expects the fifth returned document to own the property "_id" that is a string.', () => { 247 | expect(doc44[4]).to.own.property('_id').that.is.a('string'); 248 | }); 249 | it('Expects the fifth returned document to own the property "a" that is a number equal to 1.', () => { 250 | expect(doc44[4]).to.own.property('a').that.is.a('number').that.is.equal(1); 251 | }); 252 | it('Expects the fifth returned document to own the property "c" that is an object.', () => { 253 | expect(doc44[4]).to.own.property('c').that.is.an('object'); 254 | }); 255 | it('Expects this object to own one property.', () => { 256 | expect(Object.keys(doc44[4].c)).to.be.an('array').that.has.lengthOf(1); 257 | }); 258 | it('Expects this object to own the property e that is an array of 3 elements.', () => { 259 | expect(doc44[4].c).to.own.property('e').that.is.an('array').that.has.lengthOf(3); 260 | }); 261 | }); 262 | }); 263 | }; 264 | -------------------------------------------------------------------------------- /test/int/private/geo.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./geo/geo_1') 11 | , test2 = require('./geo/geo_2') 12 | , test3 = require('./geo/geo_3') 13 | ; 14 | 15 | 16 | // -- Local Constants 17 | 18 | 19 | // -- Local Variables 20 | 21 | 22 | // -- Main 23 | module.exports = function(PicoDB) { 24 | describe('Test the GeoSpatial Operators:', () => { 25 | test1(PicoDB); 26 | test2(PicoDB); 27 | test3(PicoDB); 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /test/int/private/geo/geo_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | const d = require('./geodb') 13 | , us = require('./usa.js') 14 | ; 15 | 16 | 17 | // -- Local Constants 18 | 19 | 20 | // -- Local Variables 21 | 22 | 23 | // -- Main 24 | module.exports = function(PicoDB) { 25 | describe('Test $geoIntersects:', () => { 26 | const db = PicoDB(); 27 | 28 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 29 | const doc = [ 30 | d.jfk, d.lax, d.sfo, d.san, d.phx, d.c2a, d.pinc, d.pca, d.pina, 31 | us.california, us.nevada, us.oregon, us.utah, 32 | ]; 33 | 34 | const resp = await db.insertMany(doc); 35 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 36 | }); 37 | 38 | describe('LineString:', () => { 39 | it('Expects db.find({ name: "LineString from California to Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: arizona } } } }).toArray() to return 1 document.', async () => { 40 | const resp = await db.find({ name: 'LineString from California to Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.arizona.geometry.coordinates } } } }).toArray(); 41 | expect(resp).to.be.an('array').that.has.lengthOf(1); 42 | }); 43 | 44 | it('Expects db.find({ name: "LineString from California to Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: california } } } }).toArray() to return 1 document.', async () => { 45 | const resp = await db.find({ name: 'LineString from California to Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.california.geometry.coordinates } } } }).toArray(); 46 | expect(resp).to.be.an('array').that.has.lengthOf(1); 47 | }); 48 | 49 | it('Expects db.find({ name: "LineString from California to Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: nevada } } } }).toArray() to return 0 document.', async () => { 50 | const resp = await db.find({ name: 'LineString from California to Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.nevada.geometry.coordinates } } } }).toArray(); 51 | expect(resp).to.be.an('array').that.has.lengthOf(0); 52 | }); 53 | }); 54 | 55 | describe('Polygon:', () => { 56 | it('Expects db.find({ name: "Polygon straddling California and Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: arizona } } } }).toArray() to return 1 document.', async () => { 57 | const resp = await db.find({ name: 'Polygon straddling California and Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.arizona.geometry.coordinates } } } }).toArray(); 58 | expect(resp).to.be.an('array').that.has.lengthOf(1); 59 | }); 60 | 61 | it('Expects db.find({ name: "Polygon straddling California and Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: california } } } }).toArray() to return 1 document.', async () => { 62 | const resp = await db.find({ name: 'Polygon straddling California and Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.california.geometry.coordinates } } } }).toArray(); 63 | expect(resp).to.be.an('array').that.has.lengthOf(1); 64 | }); 65 | 66 | it('Expects db.find({ name: "Polygon straddling California and Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: nevada } } } }).toArray() to return 0 document.', async () => { 67 | const resp = await db.find({ name: 'Polygon straddling California and Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.nevada.geometry.coordinates } } } }).toArray(); 68 | expect(resp).to.be.an('array').that.has.lengthOf(0); 69 | }); 70 | 71 | it('Expects db.find({ name: "Polygon inside Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: arizona } } } }).toArray() to return 0 document.', async () => { 72 | const resp = await db.find({ name: 'Polygon inside Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.arizona.geometry.coordinates } } } }).toArray(); 73 | expect(resp).to.be.an('array').that.has.lengthOf(0); 74 | }); 75 | 76 | it('Expects db.find({ name: "Polygon inside Arizona", loc: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: california } } } }).toArray() to return 0 document.', async () => { 77 | const resp = await db.find({ name: 'Polygon inside Arizona', loc: { $geoIntersects: { $geometry: { type: 'Polygon', coordinates: us.california.geometry.coordinates } } } }).toArray(); 78 | expect(resp).to.be.an('array').that.has.lengthOf(0); 79 | }); 80 | }); 81 | }); 82 | }; 83 | -------------------------------------------------------------------------------- /test/int/private/geo/geo_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0, max-len: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | const d = require('./geodb'); 13 | 14 | 15 | // -- Local Constants 16 | 17 | 18 | // -- Local Variables 19 | 20 | 21 | // -- Main 22 | module.exports = function(PicoDB) { 23 | const [Geo] = PicoDB._setTestMode(); 24 | 25 | describe('Test $near:', () => { 26 | describe('Test private Geo functions:', () => { 27 | describe('law of haversines:', () => { 28 | it('Expects the distance between the airports of SF and LA to be below 600 km.', () => { 29 | expect(Geo.lawOfHaversines(d.sfo.loc, d.lax.loc)).to.be.below(600000); 30 | }); 31 | }); 32 | 33 | describe('law of cosines:', () => { 34 | it('Expects the distance between the airports of SF and LA to be below 600 km.', () => { 35 | expect(Geo.lawOfCosines(d.sfo.loc, d.lax.loc)).to.be.below(600000); 36 | }); 37 | }); 38 | 39 | describe('equirectangular projection:', () => { 40 | it('Expects the distance between the airports of SF and LA to be below 600 km.', () => { 41 | expect(Geo.equirectangularProjection(d.sfo.loc, d.lax.loc)).to.be.below(600000); 42 | }); 43 | }); 44 | }); 45 | 46 | describe('Test of proximity:', () => { 47 | const db = PicoDB(); 48 | 49 | it('Expects db.insertMany([jfk, lax, sfo, san, phx, cai]) to return an array with all the documents.', async () => { 50 | const doc = [d.jfk, d.lax, d.sfo, d.san, d.phx, d.cai]; 51 | 52 | const resp = await db.insertMany(doc); 53 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 54 | }); 55 | 56 | it('Expects db.find({ { loc: { $near: { $geometry: jfk.loc } } }).toArray() to return 5 documents.', async () => { 57 | const resp = await db.find({ loc: { $near: { $geometry: d.jfk.loc } } }).toArray(); 58 | expect(resp).to.be.an('array').that.has.lengthOf(5); 59 | }); 60 | 61 | it('Expects db.find({ { loc: { $near: { $geometry: jfk.loc, $maxDistance: 100000 } } }).toArray() to return 1 document.', async () => { 62 | const resp = await db.find({ loc: { $near: { $geometry: d.jfk.loc, $maxDistance: 100000 } } }).toArray(); 63 | expect(resp).to.be.an('array').that.has.lengthOf(1); 64 | }); 65 | 66 | it('Expects db.find({ { loc: { $near: { $geometry: jfk.loc, $maxDistance: 100000, $minDistance: 10000 } } }).toArray() to return 0 document.', async () => { 67 | const resp = await db.find({ loc: { $near: { $geometry: d.jfk.loc, $maxDistance: 100000, $minDistance: 10000 } } }).toArray(); 68 | expect(resp).to.be.an('array').that.has.lengthOf(0); 69 | }); 70 | 71 | it('Expects db.find({ { loc: { $near: { $geometry: jfk.loc, $maxDistance: 10, $minDistance: 10000 } } }).toArray() to return 0 document.', async () => { 72 | const resp = await db.find({ loc: { $near: { $geometry: d.jfk.loc, $maxDistance: 10, $minDistance: 10000 } } }).toArray(); 73 | expect(resp).to.be.an('array').that.has.lengthOf(0); 74 | }); 75 | 76 | it('Expects db.find({ { loc: { $near: { $geometry: d.cai.loc } } }).toArray() to return 0 document.', async () => { 77 | const resp = await db.find({ loc: { $near: { $geometry: d.cai.loc } } }).toArray(); 78 | expect(resp).to.be.an('array').that.has.lengthOf(0); 79 | }); 80 | 81 | it('Expects db.find({ { loc: { $near: {} } }).toArray() to return 0 document.', async () => { 82 | const resp = await db.find({ loc: { $near: {} } }).toArray(); 83 | expect(resp).to.be.an('array').that.has.lengthOf(0); 84 | }); 85 | }); 86 | }); 87 | }; 88 | -------------------------------------------------------------------------------- /test/int/private/geo/geodb.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | 11 | 12 | // -- Local Constants 13 | 14 | 15 | // -- Local Variables 16 | 17 | 18 | // -- Main 19 | module.exports = { 20 | jfk: { 21 | name: 'John F Kennedy Intl', 22 | type: 'International', 23 | code: 'JFK', 24 | loc: { 25 | type: 'Point', 26 | coordinates: [-73.778889, 40.639722], 27 | }, 28 | }, 29 | lax: { 30 | name: 'Los Angeles International Airport', 31 | type: 'International', 32 | code: 'LAX', 33 | loc: { 34 | type: 'Point', 35 | coordinates: [-118.412581, 33.944117], 36 | }, 37 | }, 38 | sfo: { 39 | name: 'San Francisco International Airport', 40 | type: 'International', 41 | code: 'SFO', 42 | loc: { 43 | type: 'Point', 44 | coordinates: [-122.382674, 37.621642], 45 | }, 46 | }, 47 | san: { 48 | name: 'San Diego International Airport', 49 | type: 'International', 50 | code: 'SAN', 51 | loc: { 52 | type: 'Point', 53 | coordinates: [-117.189724, 32.733917], 54 | }, 55 | }, 56 | phx: { 57 | name: 'Sky Harbor International Airport', 58 | type: 'International', 59 | code: 'PHX', 60 | loc: { 61 | type: 'Point', 62 | coordinates: [-112.011559, 33.434539], 63 | }, 64 | }, 65 | cai: { 66 | name: 'California Airports', 67 | type: 'International', 68 | code: '-', 69 | loc: { 70 | type: 'MultiPoint', 71 | coordinates: [ 72 | [-118.412581, 33.944117], 73 | [-122.382674, 37.621642], 74 | [-117.189724, 32.733917], 75 | ], 76 | }, 77 | }, 78 | cpai: { 79 | name: 'California and Arizona Airports', 80 | type: 'International', 81 | code: '-', 82 | loc: { 83 | type: 'MultiPoint', 84 | coordinates: [ 85 | [-118.412581, 33.944117], 86 | [-122.382674, 37.621642], 87 | [-117.189724, 32.733917], 88 | [-112.011559, 33.434539], 89 | ], 90 | }, 91 | }, 92 | 93 | // Boxes surrounding airports: 94 | sfo_alone: [ 95 | [-122.416865, 37.569838], 96 | [-122.166926, 37.969322], 97 | ], 98 | lax_sfo_san_phx: [ 99 | [-123.422810, 38.859617], 100 | [-109.675695, 31.867779], 101 | ], 102 | lax_phx: [ 103 | [-119.158175, 34.352516], 104 | [-111.626853, 33.105325], 105 | ], 106 | sfo_lax: [ 107 | [-123.379009, 38.285678], 108 | [-116.984801, 33.550482], 109 | ], 110 | 111 | // Polygons surrounding airports: 112 | p_sfo: [ 113 | [-122.791995, 37.735612], 114 | [-122.407454, 38.069684], 115 | [-122.290926, 37.603405], 116 | ], 117 | p_sfo_san: [ 118 | [-123.464417, 38.010944], 119 | [-121.040755, 38.161299], 120 | [-118.820060, 33.169072], 121 | [-116.229249, 33.059071], 122 | [-117.148569, 31.351899], 123 | ], 124 | 125 | cia: { 126 | name: 'LineString inside California', 127 | loc: { 128 | type: 'LineString', 129 | coordinates: [ 130 | [-117.844126, 35.474386], 131 | [-115.680319, 34.163808], 132 | ], 133 | }, 134 | }, 135 | 136 | ciaplus: { 137 | name: 'Multiple LineString inside California', 138 | loc: { 139 | type: 'MultiLineString', 140 | coordinates: [ 141 | [ 142 | [-117.844126, 35.474386], 143 | [-115.680319, 34.163808], 144 | ], 145 | [ 146 | [-120.461033, 38.304856], 147 | [-120.233862, 37.408060], 148 | [-119.268383, 34.582782], 149 | ], 150 | [ 151 | [-116.429298, 34.506578], 152 | [-116.245495, 33.398331], 153 | [-115.191894, 33.264049], 154 | [-114.643132, 32.804465], 155 | ], 156 | ], 157 | }, 158 | }, 159 | 160 | c2a: { 161 | name: 'LineString from California to Arizona', 162 | loc: { 163 | type: 'LineString', 164 | coordinates: [ 165 | [-117.844126, 35.474386], 166 | [-115.680319, 34.163808], 167 | [-113.054724, 33.241810], 168 | ], 169 | }, 170 | }, 171 | 172 | c2aplus: { 173 | name: 'Multiple LineString from California to Arizona', 174 | loc: { 175 | type: 'LineString', 176 | coordinates: [ 177 | [ 178 | [-117.844126, 35.474386], 179 | [-115.680319, 34.163808], 180 | [-113.054724, 33.241810], 181 | ], 182 | [ 183 | [-120.742173, 37.608024], 184 | [-119.291514, 35.895264], 185 | [-116.252764, 34.308765], 186 | [-114.015695, 33.929515], 187 | ], 188 | [ 189 | [-110.191751, 36.313820], 190 | [-113.584705, 33.992627], 191 | [-116.084776, 33.204302], 192 | ], 193 | ], 194 | }, 195 | }, 196 | 197 | pinc: { 198 | name: 'Polygon inside California', 199 | loc: { 200 | type: 'Polygon', 201 | coordinates: [ 202 | [ 203 | [-121.145223, 36.328949], 204 | [-118.701559, 37.589239], 205 | [-116.035744, 33.060344], 206 | [-121.145223, 36.328949], 207 | ], 208 | ], 209 | }, 210 | }, 211 | 212 | pca: { 213 | name: 'Polygon straddling California and Arizona', 214 | loc: { 215 | type: 'Polygon', 216 | coordinates: [ 217 | [ 218 | [-123.611111, 39.738829], 219 | [-121.249398, 40.902991], 220 | [-117.869706, 35.879994], 221 | [-113.207358, 34.465468], 222 | [-116.566692, 33.333281], 223 | [-123.611111, 39.738829], 224 | ], 225 | ], 226 | }, 227 | }, 228 | 229 | pina: { 230 | name: 'Polygon inside Arizona', 231 | loc: { 232 | type: 'Polygon', 233 | coordinates: [ 234 | [ 235 | [-113.560760, 32.839403], 236 | [-109.928685, 31.845991], 237 | [-109.928685, 36.176015], 238 | [-113.613020, 34.900303], 239 | [-113.560760, 32.839403], 240 | ], 241 | ], 242 | }, 243 | }, 244 | }; 245 | -------------------------------------------------------------------------------- /test/int/private/insert.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const testargs = require('./insert/insert_1') 11 | , testinsertOne = require('./insert/insertone') 12 | , testinsertMany = require('./insert/insertmany') 13 | ; 14 | 15 | 16 | // -- Local Constants 17 | 18 | 19 | // -- Local Variables 20 | 21 | 22 | // -- Main 23 | module.exports = function(PicoDB) { 24 | describe('Test the insert() method:', () => { 25 | testargs(PicoDB); 26 | testinsertOne(PicoDB); 27 | testinsertMany(PicoDB); 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /test/int/private/insert/insert_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | // Test here the method with 0, 1, 2 or 3 arguments but with wrong 23 | // arguments. The goal is to test the function '_getArgs'. 24 | 25 | describe('Test the insertOne method with a variation of arguments:', () => { 26 | const db = PicoDB(); 27 | 28 | it('Expects db.insertOne() to return a promise.', async () => { 29 | const resp = await db.insertOne(); 30 | expect(resp).to.be.an('array').that.has.lengthOf(0); 31 | }); 32 | 33 | // Zero argument: 34 | it('Expects db.insertOne() to return an empty array.', async () => { 35 | const resp = await db.insertOne(); 36 | expect(resp).to.be.an('array').that.has.lengthOf(0); 37 | }); 38 | 39 | // One argument: 40 | it('Expects db.insertOne("string") to return an empty array.', async () => { 41 | const resp = await db.insertOne('string'); 42 | expect(resp).to.be.an('array').that.has.lengthOf(0); 43 | }); 44 | 45 | it('Expects db.insertOne((err, resp) => ...) to return an empty array.', (done) => { 46 | db.insertOne((err, resp) => { 47 | expect(resp).to.be.an('array').that.has.lengthOf(0); 48 | done(); 49 | }); 50 | }); 51 | 52 | // Two arguments: 53 | it('Expects db.insertOne(1, (err, res) => ...) to return an empty array.', (done) => { 54 | db.insertOne(1, (err, resp) => { 55 | expect(resp).to.be.an('array').that.has.lengthOf(0); 56 | done(); 57 | }); 58 | }); 59 | 60 | it('Expects db.insertOne(1, "string") to return an empty array.', async () => { 61 | const resp = await db.insertOne(1, 'string'); 62 | expect(resp).to.be.an('array').that.has.lengthOf(0); 63 | }); 64 | 65 | // Three arguments: 66 | it('Expects db.insertOne(1, "string", (err, res) => ...) to return an empty array.', (done) => { 67 | db.insertOne(1, 'string', (err, resp) => { 68 | expect(resp).to.be.an('array').that.has.lengthOf(0); 69 | done(); 70 | }); 71 | }); 72 | 73 | it('Expects db.insertOne(1, "string", { a: 1 }) to return an empty array.', async () => { 74 | const resp = await db.insertOne(1, 'string', { a: 1 }); 75 | expect(resp).to.be.an('array').that.has.lengthOf(0); 76 | }); 77 | }); 78 | }; 79 | -------------------------------------------------------------------------------- /test/int/private/insert/insertmany.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the method insertMany:', () => { 23 | const db = PicoDB(); 24 | 25 | // Classic: 26 | it('Expects db.inserMany([{...}, {...}]) to insert more than one document.', async () => { 27 | const resp = await db.insertMany([{ c: 1 }, { c: 2 }]); 28 | expect(resp).to.be.an('array').that.has.lengthOf(2); 29 | }); 30 | 31 | // Wrong argument: 32 | it('Expects db.inserMany([{...}, {...}, [...]]) not to insert the array.', async () => { 33 | const resp = await db.insertMany([{ c: 1 }, { c: 2 }, [1, 2, 3]]); 34 | expect(resp).to.be.an('array').that.has.lengthOf(2); 35 | }); 36 | 37 | // Same id: 38 | it('Expects db.inserMany([{ _id: 1, ...}, {_id: 1, ...}]) not to insert twice the same id.', async () => { 39 | const resp = await db.insertMany([{ _id: 1, c: 1 }, { _id: 1, c: 2 }]); 40 | expect(resp).to.be.an('array').that.has.lengthOf(1); 41 | }); 42 | 43 | // One document not inserted in an array: 44 | it('Expects db.inserMany({ a: 1 }) not to insert one document not in an array.', async () => { 45 | const resp = await db.insertMany({ a: 1 }); 46 | expect(resp).to.be.an('array').that.has.lengthOf(0); 47 | }); 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /test/int/private/insert/insertone.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the method insertOne:', () => { 23 | const db = PicoDB(); 24 | 25 | // One argument: 26 | it('Expects db.insertOne({ a: 1 })" to return an array containing one document.', async () => { 27 | const resp = await db.insertOne({ a: 1 }); 28 | expect(resp).to.be.an('array').that.has.lengthOf(1); 29 | }); 30 | 31 | it('Expects db.insertOne([{ a: 1 }])" to return an array containing one document.', async () => { 32 | const resp = await db.insertOne([{ a: 1 }]); 33 | expect(resp).to.be.an('array').that.has.lengthOf(1); 34 | }); 35 | 36 | it('Expects db.insertOne([{ a: 1 }, { b: 2}])" to return an array containing one document.', async () => { 37 | const resp = await db.insertOne([{ a: 1 }, { a: 2 }]); 38 | expect(resp).to.be.an('array').that.has.lengthOf(1); 39 | }); 40 | 41 | // Two arguments: 42 | it('Expects db.insertOne({ a: 1 }, {})" to return an array containing one document.', async () => { 43 | const resp = await db.insertOne({ a: 1 }, {}); 44 | expect(resp).to.be.an('array').that.has.lengthOf(1); 45 | }); 46 | 47 | it('Expects db.insertOne({ a: 1 }, "string")" to return an array containing one document.', async () => { 48 | const resp = await db.insertOne({ a: 1 }, 'string'); 49 | expect(resp).to.be.an('array').that.has.lengthOf(1); 50 | }); 51 | 52 | it('Expects db.insertOne({ a: 1 }, (err, resp) => ...)" to return an array containing one document.', (done) => { 53 | db.insertOne({ a: 1 }, (err, resp) => { 54 | expect(resp).to.be.an('array').that.has.lengthOf(1); 55 | done(); 56 | }); 57 | }); 58 | 59 | // Three arguments: 60 | it('Expects db.insertOne({ a: 1 }, 2, 3)" to return an array containing one document.', async () => { 61 | const resp = await db.insertOne({ a: 1 }, 2, 3); 62 | expect(resp).to.be.an('array').that.has.lengthOf(1); 63 | }); 64 | 65 | it('Expects db.insertOne({ a: 1 }, {}, 3)" to return an array containing one document.', async () => { 66 | const resp = await db.insertOne({ a: 1 }, {}, 3); 67 | expect(resp).to.be.an('array').that.has.lengthOf(1); 68 | }); 69 | 70 | it('Expects db.insertOne({ a: 1 }, "string", (err, resp) => ...)" to return an array containing one document.', (done) => { 71 | db.insertOne({ a: 1 }, 'string', (err, resp) => { 72 | expect(resp).to.be.an('array').that.has.lengthOf(1); 73 | done(); 74 | }); 75 | }); 76 | it('Expects db.insertOne({ a: 1 }, {}, (err, resp) => ...)" to return an array containing one document.', (done) => { 77 | db.insertOne({ a: 1 }, {}, (err, resp) => { 78 | expect(resp).to.be.an('array').that.has.lengthOf(1); 79 | done(); 80 | }); 81 | }); 82 | 83 | // Multiple documents: 84 | it('Expects db.insertOne([{ a: 1 }, { b: 1 }], (err, resp) => ...)" to return an array containing one document.', (done) => { 85 | db.insertOne([{ a: 1 }, { b: 1 }], (err, resp) => { 86 | expect(resp).to.be.an('array').that.has.lengthOf(1); 87 | done(); 88 | }); 89 | }); 90 | 91 | // Twice the same document: 92 | it('Expects "db.insertOne(...db.insertOne(...)" not to insert the same doc. twice.', async () => { 93 | const resp = await db.insertOne({ d: 1 }); 94 | const resp2 = await db.insertOne(resp); 95 | expect(resp2).to.have.lengthOf(0); 96 | }); 97 | 98 | // documents with id: 99 | it('Expects "db.insertOne([{ _id: 1, c: 1 }, { _id: 2, c: 2 }], ..." not to insert more than one document.', async () => { 100 | const resp = await db.insertOne([{ _id: 1, c: 1 }, { _id: 2, c: 2 }]); 101 | expect(resp).to.have.lengthOf(1); 102 | }); 103 | }); 104 | }; 105 | -------------------------------------------------------------------------------- /test/int/private/plugin.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./plugin/plugin_1') 11 | , test2 = require('./plugin/plugin_2') 12 | ; 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, Messenger) { 22 | describe('Test Plugin:', () => { 23 | test1(PicoDB); 24 | 25 | // test2 isn't executed because it attaches the plugin 'Messenger'. 26 | // It enters in conflict with the 'event' test. 27 | // test2(PicoDB, Messenger); 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /test/int/private/plugin/plugin_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | const [, P] = PicoDB._setTestMode(); 23 | 24 | describe('Test the library plugin:', () => { 25 | it('Expects [, P] = PicoDB._setTestMode() to return an object.', () => { 26 | expect(P).to.be.an('object'); 27 | }); 28 | 29 | it('Expects this object to own three properties.', () => { 30 | expect(Object.keys(P)).to.be.an('array').that.has.lengthOf(3); 31 | }); 32 | 33 | it('Expects this object to own the property "_db" that is an object.', () => { 34 | expect(P).to.own.property('_db').that.is.an('object'); 35 | }); 36 | 37 | it('Expects this object to own the property "plugin" that is a function.', () => { 38 | expect(P).to.own.property('plugin').that.is.a('function'); 39 | }); 40 | 41 | it('Expects this object to own the property "get" that is a function.', () => { 42 | expect(P).to.own.property('get').that.is.a('function'); 43 | }); 44 | 45 | it('Expects the property "_db" to own one property.', () => { 46 | expect(Object.keys(P._db)).to.be.an('array').that.has.lengthOf(1); 47 | }); 48 | 49 | // it('Expects the property "_db" to own the property "messenger" that is null.', () => { 50 | // expect(P._db).to.own.property('messenger').that.is.a('null'); 51 | // }); 52 | 53 | // Test plugin function: 54 | it('Expects P.plugin() to return false.', () => { 55 | expect(P.plugin()).to.be.equal(false); 56 | }); 57 | 58 | it('Expects P.plugin({}) to return false.', () => { 59 | expect(P.plugin({})).to.be.equal(false); 60 | }); 61 | 62 | // Test the get function: 63 | it('Expects P.get() to return null.', () => { 64 | expect(P.get()).to.be.a('null'); 65 | }); 66 | 67 | // it('Expects P.get("messenger") to return null.', () => { 68 | // expect(P.get('messenger')).to.be.a('null'); 69 | // }); 70 | }); 71 | 72 | describe('Test the library without attaching the right plugin:', () => { 73 | it('Expects P.plugin({ messenger: { NAME: "Nobody" } }) to return false.', () => { 74 | expect(P.plugin({ messenger: { NAME: 'Nobody' } })).to.be.equal(false); 75 | }); 76 | }); 77 | }; 78 | -------------------------------------------------------------------------------- /test/int/private/plugin/plugin_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, Messenger) { 22 | const [, P] = PicoDB._setTestMode(); 23 | describe('Test the library with the plugin @mobilabs/messenger attached:', () => { 24 | it('Expects P.plugin({ messenger: Messenger }) to return true.', () => { 25 | expect(P.plugin({ messenger: Messenger })).to.be.equal(true); 26 | }); 27 | 28 | it('Expects P.get("messenger") to return a function.', () => { 29 | expect(P.get('messenger')).to.be.a('function'); 30 | }); 31 | 32 | it('Expects this function to own the property "NAME".', () => { 33 | expect(P.get('messenger')).to.own.property('NAME'); 34 | }); 35 | 36 | it('Expects this property "NAME" to be equal to "Messenger".', () => { 37 | expect(P.get('messenger')) 38 | .to.own.property('NAME') 39 | .that.is.a('string') 40 | .that.is.equal('Messenger') 41 | ; 42 | }); 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /test/int/private/query.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const comparaison = require('./query/query_1') 11 | , elements = require('./query/query_2') 12 | , logical1 = require('./query/query_3') 13 | , logical2 = require('./query/query_4') 14 | , logical3 = require('./query/query_5') 15 | ; 16 | 17 | 18 | // -- Local Constants 19 | 20 | 21 | // -- Local Variables 22 | 23 | 24 | // -- Main 25 | module.exports = function(PicoDB) { 26 | describe('Test the Query Operators:', () => { 27 | comparaison(PicoDB); 28 | elements(PicoDB); 29 | logical1(PicoDB); 30 | logical2(PicoDB); 31 | logical3(PicoDB); 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /test/int/private/query/query_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the Comparison Operators:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 'bbb', c: 5 }, 28 | /* eslint-disable-next-line object-curly-newline */ 29 | { a: 2, b: 'bbb', c: ['a', 'b', 'c'], d: { e: { f: 'f' } } }, 30 | ]; 31 | 32 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 33 | const resp = await db.insertMany(doc); 34 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 35 | }); 36 | 37 | describe('$eq:', () => { 38 | it('Expects db.find({ a: { $eq: 1 } }).toArray() to return 2 documents.', async () => { 39 | const resp = await db.find({ a: { $eq: 1 } }).toArray(); 40 | expect(resp).to.be.an('array').that.has.lengthOf(2); 41 | }); 42 | 43 | it('Expects db.find({ b: { $eq: "bbb" } }).toArray() to return 2 documents.', async () => { 44 | const resp = await db.find({ b: { $eq: 'bbb' } }).toArray(); 45 | expect(resp).to.be.an('array').that.has.lengthOf(2); 46 | }); 47 | 48 | it('Expects db.find({ a: 1, b: { $eq: "bbb" }}).toArray() to return 1 document.', async () => { 49 | const resp = await db.find({ a: 1, b: { $eq: 'bbb' } }).toArray(); 50 | expect(resp).to.be.an('array').that.has.lengthOf(1); 51 | }); 52 | 53 | it('Expects db.find({ a: { $eq: 1 }, b: { $eq: "bbb" }}).toArray() to return 1 document.', async () => { 54 | const resp = await db.find({ a: { $eq: 1 }, b: { $eq: 'bbb' } }).toArray(); 55 | expect(resp).to.be.an('array').that.has.lengthOf(1); 56 | }); 57 | 58 | it('Expects db.find({ d: { e: { f: { $eq: "f" }}}}).toArray() to return 1 document.', async () => { 59 | const resp = await db.find({ d: { e: { f: { $eq: 'f' } } } }).toArray(); 60 | expect(resp).to.be.an('array').that.has.lengthOf(1); 61 | }); 62 | }); 63 | 64 | describe('$gt:', () => { 65 | it('Expects db.find({ a: { $gt: 0 }}).toArray() to return 3 documents.', async () => { 66 | const resp = await db.find({ a: { $gt: 0 } }).toArray(); 67 | expect(resp).to.be.an('array').that.has.lengthOf(3); 68 | }); 69 | 70 | it('Expects db.find({ a: { $gt: 1 }}).toArray() to return 1 document.', async () => { 71 | const resp = await db.find({ a: { $gt: 1 } }).toArray(); 72 | expect(resp).to.be.an('array').that.has.lengthOf(1); 73 | }); 74 | 75 | it('Expects db.find({ a: { $gt: 1 }, c: { $gt: 4 }}).toArray() to return 1 document.', async () => { 76 | const resp = await db.find({ a: { $gt: 0 }, c: { $gt: 4 } }).toArray(); 77 | expect(resp).to.be.an('array').that.has.lengthOf(1); 78 | }); 79 | }); 80 | 81 | describe('$gte:', () => { 82 | it('Expects db.find({ a: { $gte: 0 }}).toArray() to return 3 documents.', async () => { 83 | const resp = await db.find({ a: { $gte: 0 } }).toArray(); 84 | expect(resp).to.be.an('array').that.has.lengthOf(3); 85 | }); 86 | 87 | it('Expects db.find({ a: { $gte: 1 }}).toArray() to return 3 documents.', async () => { 88 | const resp = await db.find({ a: { $gte: 1 } }).toArray(); 89 | expect(resp).to.be.an('array').that.has.lengthOf(3); 90 | }); 91 | 92 | it('Expects db.find({ a: { $gte: 0 }, c: { $gte: 5 }}).toArray() to return 1 document.', async () => { 93 | const resp = await db.find({ a: { $gte: 0 }, c: { $gte: 5 } }).toArray(); 94 | expect(resp).to.be.an('array').that.has.lengthOf(1); 95 | }); 96 | }); 97 | 98 | describe('$lt:', () => { 99 | it('Expects db.find({ a: { $lt: 3 }}).toArray() to return 3 documents.', async () => { 100 | const resp = await db.find({ a: { $lt: 3 } }).toArray(); 101 | expect(resp).to.be.an('array').that.has.lengthOf(3); 102 | }); 103 | 104 | it('Expects db.find({ a: { $lt: 2 }}).toArray() to return 2 documents.', async () => { 105 | const resp = await db.find({ a: { $lt: 2 } }).toArray(); 106 | expect(resp).to.be.an('array').that.has.lengthOf(2); 107 | }); 108 | 109 | it('Expects db.find({ a: { $lt: 3 }, c: { $lt: 6 }}).toArray() to return 1 document.', async () => { 110 | const resp = await db.find({ a: { $lt: 3 }, c: { $lt: 6 } }).toArray(); 111 | expect(resp).to.be.an('array').that.has.lengthOf(1); 112 | }); 113 | }); 114 | 115 | describe('$lte:', () => { 116 | it('Expects db.find({ a: { $lte: 2 }}).toArray() to return 3 documents.', async () => { 117 | const resp = await db.find({ a: { $lte: 2 } }).toArray(); 118 | expect(resp).to.be.an('array').that.has.lengthOf(3); 119 | }); 120 | 121 | it('Expects db.find({ a: { $lte: 1 }}).toArray() to return 2 documents.', async () => { 122 | const resp = await db.find({ a: { $lte: 1 } }).toArray(); 123 | expect(resp).to.be.an('array').that.has.lengthOf(2); 124 | }); 125 | 126 | it('Expects db.find({ a: { $lte: 2 }, c: { $lte: 5 }}).toArray() to return 1 document.', async () => { 127 | const resp = await db.find({ a: { $lte: 2 }, c: { $lte: 5 } }).toArray(); 128 | expect(resp).to.be.an('array').that.has.lengthOf(1); 129 | }); 130 | }); 131 | 132 | describe('$ne:', () => { 133 | it('Expects db.find({ a: { $ne: 1 }}).toArray() to return 1 document.', async () => { 134 | const resp = await db.find({ a: { $ne: 1 } }).toArray(); 135 | expect(resp).to.be.an('array').that.has.lengthOf(1); 136 | }); 137 | 138 | it('Expects db.find({ a: { $ne: 2 }}).toArray() to return 2 documents.', async () => { 139 | const resp = await db.find({ a: { $ne: 2 } }).toArray(); 140 | expect(resp).to.be.an('array').that.has.lengthOf(2); 141 | }); 142 | 143 | it('Expects db.find({ b: { $ne: "bbb" }}).toArray() to return 1 document.', async () => { 144 | const resp = await db.find({ b: { $ne: 'bbb' } }).toArray(); 145 | expect(resp).to.be.an('array').that.has.lengthOf(1); 146 | }); 147 | 148 | it('Expects db.find({ bc: { $ne: "bbb" }}).toArray() to return 3 documents.', async () => { 149 | const resp = await db.find({ bc: { $ne: 'bbb' } }).toArray(); 150 | expect(resp).to.be.an('array').that.has.lengthOf(3); 151 | }); 152 | 153 | it('Expects db.find({ d: { e: { f: { $ne: "f" }}}}).toArray() to return 2 documents.', async () => { 154 | const resp = await db.find({ d: { e: { f: { $ne: 'f' } } } }).toArray(); 155 | expect(resp).to.be.an('array').that.has.lengthOf(2); 156 | }); 157 | 158 | it('Expects db.find({ c: { $ne: 5 }}).toArray() to return 2 documents.', async () => { 159 | const resp = await db.find({ c: { $ne: 5 } }).toArray(); 160 | expect(resp).to.be.an('array').that.has.lengthOf(2); 161 | }); 162 | 163 | it('Expects db.find({ a: { $eq: 2 }, d: { e: { f: { $ne: "f" }}}}).toArray() to return 0 document.', async () => { 164 | const resp = await db.find({ a: { $eq: 2 }, d: { e: { f: { $ne: 'f' } } } }).toArray(); 165 | expect(resp).to.be.an('array').that.has.lengthOf(0); 166 | }); 167 | }); 168 | 169 | describe('$in:', () => { 170 | it('Expects db.find({ b: { $in: ["aaa", "bbb"] }}).toArray() to return 2 documents.', async () => { 171 | const resp = await db.find({ b: { $in: ['aaa', 'bbb'] } }).toArray(); 172 | expect(resp).to.be.an('array').that.has.lengthOf(2); 173 | }); 174 | 175 | it('Expects db.find({ a: { $in: [1, 2] }}).toArray() to return 3 documents.', async () => { 176 | const resp = await db.find({ a: { $in: [1, 2] } }).toArray(); 177 | expect(resp).to.be.an('array').that.has.lengthOf(3); 178 | }); 179 | 180 | it('Expects db.find({ c: { $in: ["a", "b", "d"] }}).toArray() to return 1 document.', async () => { 181 | const resp = await db.find({ c: { $in: ['a', 'b', 'd'] } }).toArray(); 182 | expect(resp).to.be.an('array').that.has.lengthOf(1); 183 | }); 184 | 185 | it('Expects db.find({ c: { $in: ["d", "e"] }}).toArray() to return 0 document.', async () => { 186 | const resp = await db.find({ c: { $in: ['d', 'e'] } }).toArray(); 187 | expect(resp).to.be.an('array').that.has.lengthOf(0); 188 | }); 189 | }); 190 | 191 | describe('$nin:', () => { 192 | it('Expects db.find({ b: { $nin: ["ccc", "ddd"] }}).toArray() to return 3 documents.', async () => { 193 | const resp = await db.find({ b: { $nin: ['ccc', 'ddd'] } }).toArray(); 194 | expect(resp).to.be.an('array').that.has.lengthOf(3); 195 | }); 196 | 197 | it('Expects db.find({ b: { $nin: ["bbb", "ccc"] }}).toArray() to return 1 document.', async () => { 198 | const resp = await db.find({ b: { $nin: ['bbb', 'ccc'] } }).toArray(); 199 | expect(resp).to.be.an('array').that.has.lengthOf(1); 200 | }); 201 | 202 | it('Expects db.find({ c: { $nin: [1, 5] }}).toArray() to return 2 documents.', async () => { 203 | const resp = await db.find({ c: { $nin: [1, 5] } }).toArray(); 204 | expect(resp).to.be.an('array').that.has.lengthOf(2); 205 | }); 206 | 207 | it('Expects db.find({ c: { $nin: [1, "a"] }}).toArray() to return 1 document.', async () => { 208 | const resp = await db.find({ c: { $nin: [5, 'a'] } }).toArray(); 209 | expect(resp).to.be.an('array').that.has.lengthOf(1); 210 | }); 211 | }); 212 | 213 | describe('gt & $lt:', () => { 214 | it('Expects db.find({ a: { $gt: 1, $lt: 3 }}).toArray() to return 1 document.', async () => { 215 | const resp = await db.find({ a: { $gt: 1, $lt: 3 } }).toArray(); 216 | expect(resp).to.be.an('array').that.has.lengthOf(1); 217 | }); 218 | 219 | it('Expects db.find({ a: { $gte: 1, $lte: 2 }}).toArray() to return 3 documents.', async () => { 220 | const resp = await db.find({ a: { $gte: 1, $lte: 2 } }).toArray(); 221 | expect(resp).to.be.an('array').that.has.lengthOf(3); 222 | }); 223 | 224 | it('Expects db.find({ a: { $gt: 1, $lt: 2 }}).toArray() to return 0 document.', async () => { 225 | const resp = await db.find({ a: { $gt: 1, $lt: 2 } }).toArray(); 226 | expect(resp).to.be.an('array').that.has.lengthOf(0); 227 | }); 228 | }); 229 | 230 | describe('$ne & $nin:', () => { 231 | it('Expects db.find({ a: { $ne: 3 }, b: { $nin: ["bbb"] }}).toArray() to return 1 document.', async () => { 232 | const resp = await db.find({ a: { $ne: 3 }, b: { $nin: ['bbb'] } }).toArray(); 233 | expect(resp).to.be.an('array').that.has.lengthOf(1); 234 | }); 235 | 236 | it('Expects db.find({ b: { $nin: ["b"] }, c: { $nin: ["a"] }}).toArray() to return 2 documents.', async () => { 237 | const resp = await db.find({ b: { $nin: ['b'] }, c: { $nin: ['a'] } }).toArray(); 238 | expect(resp).to.be.an('array').that.has.lengthOf(2); 239 | }); 240 | 241 | it('Expects db.find({ b: { $nin: ["bbb"] }, c: { $nin: ["a"] }}).toArray() to return 1 document.', async () => { 242 | const resp = await db.find({ b: { $nin: ['bbb'] }, c: { $nin: ['a'] } }).toArray(); 243 | expect(resp).to.be.an('array').that.has.lengthOf(1); 244 | }); 245 | }); 246 | }); 247 | }; 248 | -------------------------------------------------------------------------------- /test/int/private/query/query_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the Element Operators:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 'bbb', c: 5 }, 28 | /* eslint-disable-next-line object-curly-newline */ 29 | { a: 2, b: 'bbb', c: ['a', 'b', 'c'], d: { e: { f: 'f' } } }, 30 | ]; 31 | 32 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 33 | const resp = await db.insertMany(doc); 34 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 35 | }); 36 | 37 | describe('$exists:', () => { 38 | it('Expects db.find({ a: { $exists: true } }).toArray() to return 3 documents.', async () => { 39 | const resp = await db.find({ a: { $exists: true } }).toArray(); 40 | expect(resp).to.be.an('array').that.has.lengthOf(3); 41 | }); 42 | 43 | it('Expects db.find({ a: { $exists: false } }).toArray() to return 0 document.', async () => { 44 | const resp = await db.find({ a: { $exists: false } }).toArray(); 45 | expect(resp).to.be.an('array').that.has.lengthOf(0); 46 | }); 47 | 48 | it('Expects db.find({ b: { $exists: true } }).toArray() to return 2 documents.', async () => { 49 | const resp = await db.find({ b: { $exists: true } }).toArray(); 50 | expect(resp).to.be.an('array').that.has.lengthOf(2); 51 | }); 52 | 53 | it('Expects db.find({ c: { $eq: 5 }, b: $exists: true }).toArray() to return 1 document.', async () => { 54 | const resp = await db.find({ c: { $eq: 5 }, b: { $exists: true } }).toArray(); 55 | expect(resp).to.be.an('array').that.has.lengthOf(1); 56 | }); 57 | 58 | it('Expects db.find({ b: { $exists: true }, c: { $ne: 5 } }).toArray() to return 1 document.', async () => { 59 | const resp = await db.find({ b: { $exists: true }, c: { $ne: 5 } }).toArray(); 60 | expect(resp).to.be.an('array').that.has.lengthOf(1); 61 | }); 62 | 63 | it('Expects db.find({ b: { $exists: true }, c: { $exists: false } }).toArray() to return 0 document.', async () => { 64 | const resp = await db.find({ b: { $exists: true }, c: { $exists: false } }).toArray(); 65 | expect(resp).to.be.an('array').that.has.lengthOf(0); 66 | }); 67 | 68 | it('Expects db.find({ b: { $exists: true }, d: { e: { f: { $exists: true }}} }).toArray() to return 1 document.', async () => { 69 | /* eslint-disable-next-line max-len */ 70 | const resp = await db.find({ b: { $exists: true }, d: { e: { f: { $exists: true } } } }).toArray(); 71 | expect(resp).to.be.an('array').that.has.lengthOf(1); 72 | }); 73 | }); 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /test/int/private/query/query_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the Logical Operators poorly built:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 'bbb', c: 5 }, 28 | /* eslint-disable-next-line object-curly-newline */ 29 | { a: 2, b: 'bbb', c: ['a', 'b', 'c'], d: { e: { f: 'f' } } }, 30 | ]; 31 | 32 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 33 | const resp = await db.insertMany(doc); 34 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 35 | }); 36 | 37 | describe('$and $or', () => { 38 | it('Expects db.find({ $and: 1 }).toArray() to return 0 document.', async () => { 39 | const resp = await db.find({ $and: 1 }).toArray(); 40 | expect(resp).to.be.an('array').that.has.lengthOf(0); 41 | }); 42 | 43 | it('Expects db.find({ $and: {} }).toArray() to return 0 document.', async () => { 44 | const resp = await db.find({ $and: {} }).toArray(); 45 | expect(resp).to.be.an('array').that.has.lengthOf(0); 46 | }); 47 | 48 | it('Expects db.find({ $and: [] }).toArray() to return 0 document.', async () => { 49 | const resp = await db.find({ $and: [] }).toArray(); 50 | expect(resp).to.be.an('array').that.has.lengthOf(0); 51 | }); 52 | 53 | it('Expects db.find({ $and: [1] }).toArray() to return 0 document.', async () => { 54 | const resp = await db.find({ $and: [1] }).toArray(); 55 | expect(resp).to.be.an('array').that.has.lengthOf(0); 56 | }); 57 | 58 | it('Expects db.find({ $and: [{ $or: [{ a: 1 }] }, { $and: [{ a: 1 }] }] }).toArray() to return 0 document.', async () => { 59 | const resp = await db.find({ $and: [{ $or: [{ a: 1 }] }, { $and: [{ a: 1 }] }] }).toArray(); 60 | expect(resp).to.be.an('array').that.has.lengthOf(0); 61 | }); 62 | 63 | it('Expects db.find({ $and: [{ $or: [{ a: 1 }, 2] }] }).toArray() to return 0 document.', async () => { 64 | const resp = await db.find({ $and: [{ $or: [{ a: 1 }, 2] }] }).toArray(); 65 | expect(resp).to.be.an('array').that.has.lengthOf(0); 66 | }); 67 | }); 68 | 69 | 70 | describe('$and', () => { 71 | it('Expects db.find({ $and: [{ a: 1 }, 2] }).toArray() to return 0 document.', async () => { 72 | const resp = await db.find({ $and: [{ a: 1 }, 2] }).toArray(); 73 | expect(resp).to.be.an('array').that.has.lengthOf(0); 74 | }); 75 | }); 76 | 77 | 78 | describe('$or', () => { 79 | it('Expects db.find({ $or: [{ a: 1 }, 2] }).toArray() to return 0 document.', async () => { 80 | const resp = await db.find({ $or: [{ a: 1 }, 2] }).toArray(); 81 | expect(resp).to.be.an('array').that.has.lengthOf(0); 82 | }); 83 | }); 84 | 85 | 86 | describe('$not', () => { 87 | // 88 | }); 89 | }); 90 | }; 91 | -------------------------------------------------------------------------------- /test/int/private/query/query_4.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the Logical Operators:', () => { 23 | const db = PicoDB(); 24 | 25 | const doc = [ 26 | { a: 1 }, 27 | { a: 1, b: 'bbb', c: 5 }, 28 | /* eslint-disable-next-line object-curly-newline */ 29 | { a: 2, b: 'bbb', c: ['a', 'b', 'c'], d: { e: { f: 'f' } } }, 30 | ]; 31 | 32 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 33 | const resp = await db.insertMany(doc); 34 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 35 | }); 36 | 37 | describe('$and', () => { 38 | it('Expects db.find({ $and: [{ a: 1 }] }).toArray() to return 2 documents.', async () => { 39 | const resp = await db.find({ $and: [{ a: 1 }] }).toArray(); 40 | expect(resp).to.be.an('array').that.has.lengthOf(2); 41 | }); 42 | 43 | it('Expects db.find({ $and: [{ a: 1 }, { b: "bbb" }] }).toArray() to return 1 document.', async () => { 44 | const resp = await db.find({ $and: [{ a: 1 }, { b: 'bbb' }] }).toArray(); 45 | expect(resp).to.be.an('array').that.has.lengthOf(1); 46 | }); 47 | 48 | it('Expects db.find({ $and: [{ a: 2 }, { d: { e: { f: "f" }} }] }).toArray() to return 1 document.', async () => { 49 | const resp = await db.find({ $and: [{ a: 2 }, { d: { e: { f: 'f' } } }] }).toArray(); 50 | expect(resp).to.be.an('array').that.has.lengthOf(1); 51 | }); 52 | 53 | it('Expects db.find({ $and: [{ a: { $gte: 1 } }, { b: "bbb" }] }).toArray() to return 2 documents.', async () => { 54 | const resp = await db.find({ $and: [{ a: { $gte: 1 } }, { b: 'bbb' }] }).toArray(); 55 | expect(resp).to.be.an('array').that.has.lengthOf(2); 56 | }); 57 | 58 | it('Expects db.find({ $and: [{ a: { $gte: 1 } }] }).toArray() to return 3 documents.', async () => { 59 | const resp = await db.find({ $and: [{ a: { $gte: 1 } }] }).toArray(); 60 | expect(resp).to.be.an('array').that.has.lengthOf(3); 61 | }); 62 | 63 | it('Expects db.find({ $and: [{ a: { $gte: 1 } }, { a: { $lt: 2 }}] }).toArray() to return 2 documents.', async () => { 64 | const resp = await db.find({ $and: [{ a: { $gte: 1 } }, { a: { $lt: 2 } }] }).toArray(); 65 | expect(resp).to.be.an('array').that.has.lengthOf(2); 66 | }); 67 | 68 | it('Expects db.find({ $and: [{ a: { $gte: 1 } }, { b: { $exists: true }] }).toArray() to return 2 documents.', async () => { 69 | /* eslint-disable-next-line */ 70 | const resp = await db.find({ $and: [{ a: { $gte: 1 } }, { b: { $exists: true } }] }).toArray(); 71 | expect(resp).to.be.an('array').that.has.lengthOf(2); 72 | }); 73 | 74 | it('Expects db.find({ $and: [{ a: { $gt: 1 } }, { b: { $exists: true }] }).toArray() to return 1 document.', async () => { 75 | /* eslint-disable-next-line */ 76 | const resp = await db.find({ $and: [{ a: { $gt: 1 } }, { b: { $exists: true } }] }).toArray(); 77 | expect(resp).to.be.an('array').that.has.lengthOf(1); 78 | }); 79 | }); 80 | 81 | 82 | describe('$or', () => { 83 | it('Expects db.find({ $or: [{ a: 1 }, { a: 2 }] }).toArray() to return 3 documents.', async () => { 84 | const resp = await db.find({ $or: [{ a: 1 }, { a: 2 }] }).toArray(); 85 | expect(resp).to.be.an('array').that.has.lengthOf(3); 86 | }); 87 | 88 | it('Expects db.find({ $or: [{ a: { $eq: 1 }}, { c: { $eq: 5 }} ] }).toArray() to return 2 documents.', async () => { 89 | const resp = await db.find({ $or: [{ a: { $eq: 1 } }, { c: { $eq: 5 } }] }).toArray(); 90 | expect(resp).to.be.an('array').that.has.lengthOf(2); 91 | }); 92 | 93 | it('Expects db.find({ $or: [{ a: { $eq: 1 }}, { b: { $in: ["bbb"] }}]}).toArray() to return 3 documents.', async () => { 94 | const resp = await db.find({ $or: [{ a: { $eq: 1 } }, { b: { $in: ['bbb'] } }] }).toArray(); 95 | expect(resp).to.be.an('array').that.has.lengthOf(3); 96 | }); 97 | 98 | it('Expects db.find({ $or: [{ a: { $gt: 1 }}, { b: { $in: ["bbb"] }}]}).toArray() to return 2 documents.', async () => { 99 | const resp = await db.find({ $or: [{ a: { $gt: 1 } }, { b: { $in: ['bbb'] } }] }).toArray(); 100 | expect(resp).to.be.an('array').that.has.lengthOf(2); 101 | }); 102 | 103 | it('Expects db.find({ $or: [{ a: { $gt: 1 }}, { b: { $nin: ["bbb"] }} ]}).toArray() to return 2 documents.', async () => { 104 | const resp = await db.find({ $or: [{ a: { $gt: 1 } }, { b: { $nin: ['bbb'] } }] }).toArray(); 105 | expect(resp).to.be.an('array').that.has.lengthOf(2); 106 | }); 107 | 108 | it('Expects db.find({ $or: [{ a: { $gt: 3 }}, { d: { e: { f: { $eq: "f" }}} }]}).toArray() to return 1 document.', async () => { 109 | const resp = await db.find({ $or: [{ a: { $gt: 3 } }, { d: { e: { f: { $eq: 'f' } } } }] }).toArray(); 110 | expect(resp).to.be.an('array').that.has.lengthOf(1); 111 | }); 112 | 113 | it('Expects db.find({ $or: [{ a: 3 }, { d: { e: { f: { $eq: "g" }}}}]}).toArray() to return 0 document.', async () => { 114 | const resp = await db.find({ $or: [{ a: 3 }, { d: { e: { f: { $eq: 'g' } } } }] }).toArray(); 115 | expect(resp).to.be.an('array').that.has.lengthOf(0); 116 | }); 117 | }); 118 | 119 | 120 | describe('$not', () => { 121 | it('Expects db.find({ a: { $not: { $eq: 1 }}).toArray() to return 1 document.', async () => { 122 | const resp = await db.find({ a: { $not: { $eq: 1 } } }).toArray(); 123 | expect(resp).to.be.an('array').that.has.lengthOf(1); 124 | }); 125 | 126 | it('Expects db.find({ a: { $not: { $gt: 1 }}).toArray() to return 2 documents.', async () => { 127 | const resp = await db.find({ a: { $not: { $gt: 1 } } }).toArray(); 128 | expect(resp).to.be.an('array').that.has.lengthOf(2); 129 | }); 130 | 131 | it('Expects db.find({ a: { $not: { $gte: 1 }}).toArray() to return 0 document.', async () => { 132 | const resp = await db.find({ a: { $not: { $gte: 1 } } }).toArray(); 133 | expect(resp).to.be.an('array').that.has.lengthOf(0); 134 | }); 135 | 136 | it('Expects db.find({ b: { $not: { $in: ["ccc"] }}).toArray() to return 3 documents.', async () => { 137 | const resp = await db.find({ b: { $not: { $in: ['ccc'] } } }).toArray(); 138 | expect(resp).to.be.an('array').that.has.lengthOf(3); 139 | }); 140 | 141 | it('Expects db.find({ b: { $not: { $nin: ["bbb"] }}).toArray() to return 3 documents.', async () => { 142 | const resp = await db.find({ b: { $not: { $nin: ['bbb'] } } }).toArray(); 143 | expect(resp).to.be.an('array').that.has.lengthOf(3); 144 | }); 145 | }); 146 | }); 147 | }; 148 | -------------------------------------------------------------------------------- /test/int/private/query/query_5.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the Logical Operators (next):', () => { 23 | describe('$and $or', () => { 24 | const db = PicoDB(); 25 | 26 | const doc = [ 27 | { a: 1, b: 1 }, 28 | { c: 1, d: 1 }, 29 | /* eslint-disable-next-line object-curly-newline */ 30 | { a: 10, b: 11, c: 20, d: 100 }, 31 | ]; 32 | 33 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 34 | const resp = await db.insertMany(doc); 35 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 36 | }); 37 | 38 | it('Expects db.find({ $and: [{ $or: [{ a: 1 }, { b: 2 }] }, { $or: [{ c: 1 }, { d: 2 }] }] }).toArray() to return 0 document.', async () => { 39 | const q = { 40 | $and: [ 41 | { $or: [{ a: 1 }, { b: 2 }] }, 42 | { $or: [{ c: 1 }, { d: 2 }] }, 43 | ], 44 | }; 45 | const resp = await db.find(q).toArray(); 46 | expect(resp).to.be.an('array').that.has.lengthOf(0); 47 | }); 48 | 49 | it('Expects db.find({ $and: [{ $or: [{ a: 2 }, { b: 1 }] }, { $or: [{ c: 1 }, { d: 1 }] }] }).toArray() to return 0 document.', async () => { 50 | const q = { 51 | $and: [ 52 | { $or: [{ a: 2 }, { b: 1 }] }, 53 | { $or: [{ c: 1 }, { d: 1 }] }, 54 | ], 55 | }; 56 | 57 | const resp = await db.find(q).toArray(); 58 | expect(resp).to.be.an('array').that.has.lengthOf(0); 59 | }); 60 | 61 | it('Expects db.find({ $and: [{ $or: [{ a: { $gte: 10 } }, { b: 1 }] }, { $or: [{ c: 21 }, { d: { $lte: 100 } }] }] }).toArray() to return 0 document.', async () => { 62 | const q = { 63 | $and: [ 64 | { $or: [{ a: { $gte: 10 } }, { b: 1 }] }, 65 | { $or: [{ c: 21 }, { d: { $lte: 100 } }] }, 66 | ], 67 | }; 68 | const resp = await db.find(q).toArray(); 69 | expect(resp).to.be.an('array').that.has.lengthOf(1); 70 | }); 71 | }); 72 | }); 73 | }; 74 | -------------------------------------------------------------------------------- /test/int/private/update.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | 8 | 9 | // -- Local Modules 10 | const test1 = require('./update/update_1') 11 | , test2 = require('./update/update_2') 12 | , test3 = require('./update/update_3') 13 | , test4 = require('./update/update_4') 14 | , test5 = require('./update/update_5') 15 | , test6 = require('./update/update_6') 16 | ; 17 | 18 | 19 | // -- Local Constants 20 | const doc = [ 21 | { a: 1 }, 22 | { a: 2, name: { first: 'John', last: 'Doe' } }, 23 | { a: 3, quantity: 5, metrics: { orders: 1, ratings: { value: 0.5, type: 'aaa' } } }, 24 | { a: 4, lastModified: null, cancellation: { date: null } }, 25 | ]; 26 | 27 | 28 | // -- Local Variables 29 | 30 | 31 | // -- Main 32 | module.exports = function(PicoDB) { 33 | describe('Test the update methods:', () => { 34 | test1(PicoDB, doc); 35 | test2(PicoDB, doc); 36 | 37 | describe('Test the updateOne method:', () => { 38 | test3(PicoDB, doc); 39 | test4(PicoDB, doc); 40 | test5(PicoDB, doc); 41 | test6(PicoDB, doc); 42 | }); 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /test/int/private/update/update_1.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB) { 22 | describe('Test the update methods with wrong arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | // Zero argument: 26 | it('Expects db.updateOne() to return a promise.', async () => { 27 | const resp = await db.updateOne(); 28 | expect(resp).to.be.an('array').that.has.lengthOf(0); 29 | }); 30 | 31 | it('Expects db.updateOne() to return an empty array.', async () => { 32 | const resp = await db.updateOne(); 33 | expect(resp).to.be.an('array').that.has.lengthOf(0); 34 | }); 35 | 36 | // One argument: 37 | it('Expects db.updateOne((err, resp) => {...}) to return an empty array.', (done) => { 38 | db.updateOne((err, resp) => { 39 | expect(resp).to.be.an('array').that.has.lengthOf(0); 40 | done(); 41 | }); 42 | }); 43 | 44 | it('Expects db.updateOne(1) to return an empty array.', async () => { 45 | const resp = await db.updateOne(1); 46 | expect(resp).to.be.an('array').that.has.lengthOf(0); 47 | }); 48 | 49 | // Two arguments: 50 | it('Expects db.updateOne({}, (err, resp) => {...}) to return an empty array.', (done) => { 51 | db.updateOne({}, (err, resp) => { 52 | expect(resp).to.be.an('array').that.has.lengthOf(0); 53 | done(); 54 | }); 55 | }); 56 | 57 | it('Expects db.updateOne({}, 1) to return an empty array.', async () => { 58 | const resp = await db.updateOne({}, 1); 59 | expect(resp).to.be.an('array').that.has.lengthOf(0); 60 | }); 61 | 62 | it('Expects db.updateOne(1, (err, resp) => {...}) to return an empty array.', (done) => { 63 | db.updateOne(1, (err, resp) => { 64 | expect(resp).to.be.an('array').that.has.lengthOf(0); 65 | done(); 66 | }); 67 | }); 68 | 69 | it('Expects db.updateOne(1, "s") to return an empty array.', async () => { 70 | const resp = await db.updateOne(1, 's'); 71 | expect(resp).to.be.an('array').that.has.lengthOf(0); 72 | }); 73 | 74 | // Three arguments: 75 | it('Expects db.updateOne(1, 2, (err, resp) => {...}) to return an empty array.', (done) => { 76 | db.updateOne({}, 's', (err, resp) => { 77 | expect(resp).to.be.an('array').that.has.lengthOf(0); 78 | done(); 79 | }); 80 | }); 81 | 82 | it('Expects db.updateOne({}, 2, (err, resp) => {...}) to return an empty array.', (done) => { 83 | db.updateOne({}, 's', (err, resp) => { 84 | expect(resp).to.be.an('array').that.has.lengthOf(0); 85 | done(); 86 | }); 87 | }); 88 | 89 | it('Expects db.updateOne(1, {}, (err, resp) => {...}) to return an empty array.', (done) => { 90 | db.updateOne({}, 's', (err, resp) => { 91 | expect(resp).to.be.an('array').that.has.lengthOf(0); 92 | done(); 93 | }); 94 | }); 95 | 96 | it('Expects db.updateOne(1, 2, 3) to return an empty array.', async () => { 97 | const resp = await db.updateOne({}, 2, 3); 98 | expect(resp).to.be.an('array').that.has.lengthOf(0); 99 | }); 100 | 101 | it('Expects db.updateOne({}, 2, 3) to return an empty array.', async () => { 102 | const resp = await db.updateOne({}, 2, 3); 103 | expect(resp).to.be.an('array').that.has.lengthOf(0); 104 | }); 105 | 106 | it('Expects db.updateOne(1, {}, 3) to return an empty array.', async () => { 107 | const resp = await db.updateOne({}, 2, 3); 108 | expect(resp).to.be.an('array').that.has.lengthOf(0); 109 | }); 110 | 111 | // Four arguments: 112 | it('Expects db.updateOne(1, 2, 3, (err, resp) => {...}) to return an empty array.', (done) => { 113 | db.updateOne(1, 2, 3, (err, resp) => { 114 | expect(resp).to.be.an('array').that.has.lengthOf(0); 115 | done(); 116 | }); 117 | }); 118 | 119 | it('Expects db.updateOne({}, 2, 3, (err, resp) => {...}) to return an empty array.', (done) => { 120 | db.updateOne({}, 2, 3, (err, resp) => { 121 | expect(resp).to.be.an('array').that.has.lengthOf(0); 122 | done(); 123 | }); 124 | }); 125 | 126 | it('Expects db.updateOne({}, 2, 3, (err, resp) => {...}) to return an empty array.', (done) => { 127 | db.updateOne(1, {}, 3, (err, resp) => { 128 | expect(resp).to.be.an('array').that.has.lengthOf(0); 129 | done(); 130 | }); 131 | }); 132 | 133 | it('Expects db.updateOne({}, 2, 3, (err, resp) => {...}) to return an empty array.', (done) => { 134 | db.updateOne(1, 2, {}, (err, resp) => { 135 | expect(resp).to.be.an('array').that.has.lengthOf(0); 136 | done(); 137 | }); 138 | }); 139 | 140 | it('Expects db.updateOne(1, 2, 3, 4) to return an empty array.', async () => { 141 | const resp = await db.updateOne(1, 2, 3, 4); 142 | expect(resp).to.be.an('array').that.has.lengthOf(0); 143 | }); 144 | 145 | it('Expects db.updateOne({}, 2, 3, 4) to return an empty array.', async () => { 146 | const resp = await db.updateOne({}, 2, 3, 4); 147 | expect(resp).to.be.an('array').that.has.lengthOf(0); 148 | }); 149 | 150 | it('Expects db.updateOne(1, {}, 3, 4) to return an empty array.', async () => { 151 | const resp = await db.updateOne(1, {}, 3, 4); 152 | expect(resp).to.be.an('array').that.has.lengthOf(0); 153 | }); 154 | 155 | it('Expects db.updateOne(1, 2, {}, 4) to return an empty array.', async () => { 156 | const resp = await db.updateOne(1, 2, {}, 4); 157 | expect(resp).to.be.an('array').that.has.lengthOf(0); 158 | }); 159 | }); 160 | }; 161 | -------------------------------------------------------------------------------- /test/int/private/update/update_2.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, doc) { 22 | describe('Test the updateOne method with real arguments:', () => { 23 | const db = PicoDB(); 24 | 25 | // Fill the db: 26 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 27 | const resp = await db.insertMany(doc); 28 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 29 | }); 30 | 31 | // Two arguments: 32 | it('Expects db.updateOne({ a: 1 }, { a: 2 }) to return one document.', async () => { 33 | const resp = await db.updateOne({ a: 1 }, { a: 2 }); 34 | expect(resp).to.be.an('array').that.has.lengthOf(1); 35 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(2); 36 | }); 37 | 38 | // Three arguments: 39 | it('Expects db.updateOne({ a: 2 }, { a: 1 }, {}) to return one document.', async () => { 40 | const resp = await db.updateOne({ a: 2 }, { a: 1 }, {}); 41 | expect(resp).to.be.an('array').that.has.lengthOf(1); 42 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 43 | }); 44 | 45 | it('Expects db.updateOne({ a: 1 }, { a: 2 }, (err, resp) => { ... }) to return one document.', (done) => { 46 | db.updateOne({ a: 1 }, { a: 2 }, (err, resp) => { 47 | expect(resp).to.be.an('array').that.has.lengthOf(1); 48 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(2); 49 | done(); 50 | }); 51 | }); 52 | 53 | it('Expects db.updateOne({ a: 2 }, { a: 1 }, 1) to return one document.', async () => { 54 | const resp = await db.updateOne({ a: 2 }, { a: 1 }, 1); 55 | expect(resp).to.be.an('array').that.has.lengthOf(1); 56 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 57 | }); 58 | 59 | // Four arguments: 60 | it('Expects db.updateOne({ a: 1 }, { a: 2 }, {}, (err, resp) => { ... }) to return one document.', (done) => { 61 | db.updateOne({ a: 1 }, { a: 2 }, {}, (err, resp) => { 62 | expect(resp).to.be.an('array').that.has.lengthOf(1); 63 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(2); 64 | done(); 65 | }); 66 | }); 67 | 68 | it('Expects db.updateOne({ a: 2 }, { a: 1 }, {}, 1) to return one document.', async () => { 69 | const resp = await db.updateOne({ a: 2 }, { a: 1 }, {}, 1); 70 | expect(resp).to.be.an('array').that.has.lengthOf(1); 71 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 72 | }); 73 | 74 | it('Expects db.updateOne({ a: 1 }, { a: 2 }, 1, (err, resp) => { ... }) to return one document.', (done) => { 75 | db.updateOne({ a: 1 }, { a: 2 }, 1, (err, resp) => { 76 | expect(resp).to.be.an('array').that.has.lengthOf(1); 77 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(2); 78 | done(); 79 | }); 80 | }); 81 | 82 | it('Expects db.updateOne({ a: 2 }, { a: 1 }, 1, 2) to return one document.', async () => { 83 | const resp = await db.updateOne({ a: 2 }, { a: 1 }, 1, 2); 84 | expect(resp).to.be.an('array').that.has.lengthOf(1); 85 | expect(resp[0]).to.own.property('a').that.is.a('number').that.is.equal(1); 86 | }); 87 | 88 | describe('Test the updateOne method with no matching:', () => { 89 | it('Expects db.updateOne({ a: 5 }, { a: 1 }, {}) to return an empty array.', async () => { 90 | const resp = await db.updateOne({ a: 5 }, { a: 1 }, {}); 91 | expect(resp).to.be.an('array').that.has.lengthOf(0); 92 | }); 93 | }); 94 | }); 95 | }; 96 | -------------------------------------------------------------------------------- /test/int/private/update/update_3.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, doc) { 22 | describe('No Operator:', () => { 23 | const db = PicoDB(); 24 | 25 | let docu 26 | , _id 27 | ; 28 | 29 | // Fill the db: 30 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 31 | const resp = await db.insertMany(doc); 32 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 33 | }); 34 | 35 | it('Expects db.updateOne({ a: 1 }, { b: 1 }) to return one document.', async () => { 36 | const docs = await db.find({ a: 1 }).toArray(); 37 | _id = docs[0]._id; 38 | const resp = await db.updateOne({ a: 1 }, { b: 1 }); 39 | [docu] = resp; 40 | expect(resp).to.be.an('array').that.has.lengthOf(1); 41 | }); 42 | 43 | it('Expected the returned document to own two properties.', () => { 44 | expect(Object.keys(docu)).to.be.an('array').that.has.lengthOf(2); 45 | }); 46 | 47 | it('Expected the returned document to own the property "_id" that is a string.', () => { 48 | expect(docu).to.own.property('_id').that.is.a('string'); 49 | }); 50 | 51 | it('Expected the property "_id" has not been modified by the update operation.', () => { 52 | expect(docu).to.own.property('_id').that.is.equal(_id); 53 | }); 54 | 55 | it('Expected the returned document to own the property "b" that is equal to 1.', () => { 56 | expect(docu).to.own.property('b').that.is.a('number').that.is.equal(1); 57 | }); 58 | }); 59 | 60 | describe('With dot notation for queries:', () => { 61 | const db = PicoDB(); 62 | 63 | let _id; 64 | 65 | // Fill the db: 66 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 67 | const resp = await db.insertMany(doc); 68 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 69 | }); 70 | 71 | it('Expects db.updateOne({ "name.first": "John" }, { b: 1 }) to return one document.', async () => { 72 | const docs = await db.find({ 'name.first': 'John' }).toArray(); 73 | _id = docs[0]._id; 74 | const resp = await db.updateOne({ 'name.first': 'John' }, { b: 1 }); 75 | expect(resp).to.be.an('array').that.has.lengthOf(1); 76 | }); 77 | 78 | it('Expects db.find({ b: 1 }).toArray() to return a document with the same _id as before updating.', async () => { 79 | const resp = await db.find({ b: 1 }).toArray(); 80 | expect(resp[0]._id).to.be.a('string').that.is.equal(_id); 81 | }); 82 | }); 83 | }; 84 | -------------------------------------------------------------------------------- /test/int/private/update/update_6.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe, it */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const { expect } = require('chai') 8 | ; 9 | 10 | 11 | // -- Local Modules 12 | 13 | 14 | // -- Local Constants 15 | 16 | 17 | // -- Local Variables 18 | 19 | 20 | // -- Main 21 | module.exports = function(PicoDB, doc) { 22 | describe('Test the updateMany method:', () => { 23 | const db = PicoDB(); 24 | 25 | // Fill the db: 26 | it('Expects db.insertMany([...]) to return an array with all the documents.', async () => { 27 | const resp = await db.insertMany(doc); 28 | expect(resp).to.be.an('array').that.has.lengthOf(doc.length); 29 | }); 30 | 31 | it('Expects { a: { $gte: 1 }} { a: 1 } to return 4 documents', async () => { 32 | const resp = await db.updateMany({ a: { $gte: 1 } }, { a: 1 }); 33 | expect(resp).to.be.an('array').that.has.lengthOf(4); 34 | }); 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | // ESLint declarations: 2 | /* global describe */ 3 | /* eslint one-var: 0, semi-style: 0, no-underscore-dangle: 0 */ 4 | 5 | 6 | // -- Vendor Modules 7 | const Messenger = require('@mobilabs/messenger'); 8 | 9 | 10 | // -- Local Modules 11 | const testlib = require('./int/lib') 12 | // , pack = require('../package.json') 13 | , test_ = require('./int/private/_') 14 | , plugin = require('./int/private/plugin') 15 | , insert = require('./int/private/insert') 16 | , find = require('./int/private/find') 17 | , query = require('./int/private/query') 18 | , geo = require('./int/private/geo') 19 | , count = require('./int/private/count') 20 | , deldoc = require('./int/private/delete') 21 | , update = require('./int/private/update') 22 | , event = require('./int/private/event') 23 | ; 24 | 25 | 26 | // -- Local Constants 27 | // const libname = 'PicoDB'; 28 | 29 | 30 | // -- Local Variables 31 | 32 | 33 | // -- Main 34 | 35 | // This define root for Node.js: 36 | global.root = {}; 37 | 38 | // Nota: 39 | // If you want that 'display-coverage' shows the coverage files by files, 40 | // you should set 'PicoDB' and 'testlib' like this: 41 | // . const PicoDB = require('../src/').default; 42 | // . testlib(PicoDB, '{{lib:name}}', '{{lib:version}}', 'without new'); 43 | // 44 | // But, if you want that 'display-coverage' shows the coverage in one file, 45 | // you should set 'PicoDB' and 'testlib' like this: 46 | // . const PicoDB = require('../index'); 47 | // . testlib(PicoDB, libname, pack.version, 'without new'); 48 | 49 | const PicoDB = require('../src/picodb').default; 50 | // const PicoDB = require('../index'); 51 | 52 | describe('Test PicoDB:', () => { 53 | testlib(PicoDB, '{{lib:name}}', '{{lib:version}}', 'without new'); 54 | // testlib(PicoDB, libname, pack.version, 'without new'); 55 | 56 | // Test the plugin: 57 | plugin(PicoDB, Messenger); 58 | 59 | // Test _.js lib: 60 | test_(PicoDB); 61 | 62 | // Test the methods insertOne & insertMany: 63 | insert(PicoDB); 64 | 65 | // Test the methods find and toArray: 66 | find(PicoDB); 67 | 68 | // Test the query operators: 69 | query(PicoDB); 70 | geo(PicoDB); 71 | 72 | // Test the method count: 73 | count(PicoDB); 74 | 75 | // Test the methods updateOne & updateMany: 76 | update(PicoDB); 77 | 78 | // Test the methods deleteOne & deleteMany: 79 | deldoc(PicoDB); 80 | 81 | // Test the methods addEventListener, addOneTimeEventListener 82 | // and removeEventListener). 83 | event(PicoDB, Messenger); 84 | }); 85 | 86 | // - oOo -- 87 | --------------------------------------------------------------------------------