diff --git a/.gitignore b/.gitignore index 86fc182f4989..64814d0c96ea 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ npm-debug.log coverage .nyc_output **/*.tgz +acceptance/*/dist packages/*/dist examples/*/dist benchmark/dist diff --git a/.prettierignore b/.prettierignore index 11b97565882e..14d6d600fe4d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,6 +7,7 @@ packages/tsdocs/fixtures/monorepo/docs packages/tsdocs/fixtures/monorepo/**/dist packages/tsdocs/fixtures/monorepo/**/docs **/.sandbox +acceptance/*/dist packages/*/dist examples/*/dist benchmark/dist diff --git a/.travis.yml b/.travis.yml index 9723e4fac8e4..6151aa275b1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,33 @@ matrix: os: linux env: TASK=verify-docs script: ./bin/verify-doc-changes.sh + - node_js: "10" + os: linux + env: + - TASK=test-repository-mongodb + services: + - mongodb + script: + - npm run postinstall -- --scope "@loopback/test-repository-mongodb" --include-filtered-dependencies + - npm run build -- --scope "@loopback/test-repository-mongodb" --include-filtered-dependencies + - cd acceptance/repository-mongodb && npm run mocha + - node_js: "10" + os: linux + env: + - TASK=test-repository-mysql + - MYSQL_USER=test + - MYSQL_PASSWORD=test + services: + - mysql + before_install: + - mysql -u root -e "CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';" + - mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='test'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'test'@'localhost' WITH GRANT OPTION;FLUSH PRIVILEGES;" + - mysql -e "GRANT SUPER ON *.* TO 'test'@'localhost' IDENTIFIED BY 'test';FLUSH PRIVILEGES;" + script: + - npm run postinstall -- --scope "@loopback/test-repository-mysql" --include-filtered-dependencies + - npm run build -- --scope "@loopback/test-repository-mysql" --include-filtered-dependencies + - cd acceptance/repository-mysql && npm run mocha branches: only: diff --git a/CODEOWNERS b/CODEOWNERS index 14e00f913f4c..8d1bf7d3cae7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,6 +6,8 @@ * @bajtos @raymondfeng +acceptance/repository-mongodb/* @bajtos +acceptance/repository-mysql/* @bajtos packages/authentication/* @bajtos @raymondfeng packages/boot/* @raymondfeng @hacksparrow packages/booter-lb3app/* @bajtos @nabdelgadir @@ -21,6 +23,7 @@ packages/openapi-spec-builder/* @bajtos @raymondfeng packages/openapi-v3/* @bajtos @jannyHou packages/openapi-v3-types/* @bajtos @jannyHou packages/repository/* @raymondfeng +packages/repository-tests/* @bajtos packages/repository-json-schema/* @bajtos packages/rest/* @bajtos @raymondfeng packages/service-proxy/* @raymondfeng diff --git a/acceptance/README.md b/acceptance/README.md new file mode 100644 index 000000000000..a21cdee462da --- /dev/null +++ b/acceptance/README.md @@ -0,0 +1,5 @@ +## Acceptance tests + +This directory contains packages with acceptance-level tests. These tests are +not invoked as part of root `npm test`, you have to run them manually. Consult +README files of individual packages for instructions on how to run the tests. diff --git a/acceptance/repository-mongodb/.npmrc b/acceptance/repository-mongodb/.npmrc new file mode 100644 index 000000000000..cafe685a112d --- /dev/null +++ b/acceptance/repository-mongodb/.npmrc @@ -0,0 +1 @@ +package-lock=true diff --git a/acceptance/repository-mongodb/LICENSE b/acceptance/repository-mongodb/LICENSE new file mode 100644 index 000000000000..0f8648d55604 --- /dev/null +++ b/acceptance/repository-mongodb/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) IBM Corp. 2017,2019. All Rights Reserved. +Node module: @loopback/test-repository-mongodb +This project is licensed under the MIT License, full text below. + +-------- + +MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/acceptance/repository-mongodb/README.md b/acceptance/repository-mongodb/README.md new file mode 100644 index 000000000000..8ef5992a9d24 --- /dev/null +++ b/acceptance/repository-mongodb/README.md @@ -0,0 +1,63 @@ +# @loopback/test-repository-mongodb + +Acceptance tests for `@loopback/repository` + `loopback-connector-mongodb`. + +## Running the test suite + +### Using own MongoDB instance + +If you have a local MongoDB instance listening on `localhost` and the default +port, use the following command: + +```bash +npm test +``` + +If you have a local or remote MongoDB instance and would like to use that to run +the test suite, use the following command: + +**Linux & MacOS** + +```bash +MONGODB_HOST= MONGODB_PORT= MONGODB_DATABASE= npm test +``` + +**Windows** + +```bash +SET MONGODB_HOST= +SET MONGODB_PORT= +SET MONGODB_DATABASE= +npm test +``` + +### Using Docker (Linux, MacOS, WSL) + +If you do not have a local MongoDB instance, you can also run the test suite +with very minimal requirements. + +- Assuming you have [Docker](https://docs.docker.com/engine/installation/) + installed, run the following script which would spawn a MongoDB instance on + your local: + + ```bash + source setup.sh + ``` + + Where ``, `` and `` are optional parameters. The default + values are `localhost`, `27017` and `testdb` respectively. + +- Run the test: + + ```bash + npm test + ``` + +## Contributors + +See +[all contributors](https://github.com/strongloop/loopback-next/graphs/contributors). + +## License + +MIT diff --git a/acceptance/repository-mongodb/index.d.ts b/acceptance/repository-mongodb/index.d.ts new file mode 100644 index 000000000000..1c6ea27f7625 --- /dev/null +++ b/acceptance/repository-mongodb/index.d.ts @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mongodb +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +export * from './dist'; diff --git a/acceptance/repository-mongodb/index.js b/acceptance/repository-mongodb/index.js new file mode 100644 index 000000000000..0e52f1f18501 --- /dev/null +++ b/acceptance/repository-mongodb/index.js @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mongodb +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +module.exports = require('./dist'); diff --git a/acceptance/repository-mongodb/index.ts b/acceptance/repository-mongodb/index.ts new file mode 100644 index 000000000000..dc8bef8423fd --- /dev/null +++ b/acceptance/repository-mongodb/index.ts @@ -0,0 +1,8 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mongodb +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +// DO NOT EDIT THIS FILE +// Add any additional (re)exports to src/index.ts instead. +export * from './src'; diff --git a/acceptance/repository-mongodb/package-lock.json b/acceptance/repository-mongodb/package-lock.json new file mode 100644 index 000000000000..04ebbacf54cb --- /dev/null +++ b/acceptance/repository-mongodb/package-lock.json @@ -0,0 +1,653 @@ +{ + "name": "@loopback/test-repository-mongodb", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "10.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", + "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==", + "dev": true + }, + "accept-language": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz", + "integrity": "sha1-9QJfF79lpGaoRYOMz5jNuHfYM4Q=", + "dev": true, + "requires": { + "bcp47": "^1.1.2", + "stable": "^0.1.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcp47": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz", + "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4=", + "dev": true + }, + "bl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", + "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "cldrjs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.1.tgz", + "integrity": "sha512-xyiP8uAm8K1IhmpDndZLraloW1yqu0L+HYdQ7O1aGPxx9Cr+BMnPANlNhSt++UKfxytL2hd2NPXgTjiy7k43Ew==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globalize": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/globalize/-/globalize-1.4.2.tgz", + "integrity": "sha512-IfKeYI5mAITBmT5EnH8kSQB5uGson4Fkj2XtTpyEbIS7IHNfLHoeTyLJ6tfjiKC6cJXng3IhVurDk5C7ORqFhQ==", + "dev": true, + "requires": { + "cldrjs": "^0.5.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "loopback-connector": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/loopback-connector/-/loopback-connector-4.7.0.tgz", + "integrity": "sha512-NIN8XB9CILRsXtu6TWjliaM1yadOolGi9tCc6tP3f1nKdN749TjvjfWXZyO+fB+EWuhWOHyh1UApr9DtptgIqg==", + "dev": true, + "requires": { + "async": "^2.1.5", + "bluebird": "^3.4.6", + "debug": "^3.1.0", + "msgpack5": "^4.2.0", + "strong-globalize": "^4.1.1", + "uuid": "^3.0.1" + } + }, + "loopback-connector-mongodb": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loopback-connector-mongodb/-/loopback-connector-mongodb-4.2.0.tgz", + "integrity": "sha512-/rv4QQ9428XYlQ22P3dH3ELQKu6iZRXWZgrR2ilB9fX1WnUdOwegVWBT+MizpLLqjD2wr0Sq9M0lS1eZSUvyGQ==", + "dev": true, + "requires": { + "async": "^2.6.1", + "bson": "^1.0.6", + "debug": "^3.1.0", + "loopback-connector": "^4.5.0", + "mongodb": "^3.1.4", + "strong-globalize": "^4.1.1" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "dev": true, + "optional": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mongodb": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.7.tgz", + "integrity": "sha512-2YdWrdf1PJgxcCrT1tWoL6nHuk6hCxhddAAaEh8QJL231ci4+P9FLyqopbTm2Z2sAU6mhCri+wd9r1hOcHdoMw==", + "dev": true, + "requires": { + "mongodb-core": "3.2.7", + "safe-buffer": "^5.1.2" + } + }, + "mongodb-core": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz", + "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==", + "dev": true, + "requires": { + "bson": "^1.1.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "msgpack5": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.2.1.tgz", + "integrity": "sha512-Xo7nE9ZfBVonQi1rSopNAqPdts/QHyuSEUwIEzAkB+V2FtmkkLUbP6MyVqVVQxsZYI65FpvW3Bb8Z9ZWEjbgHQ==", + "dev": true, + "requires": { + "bl": "^2.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.3.6", + "safe-buffer": "^5.1.2" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "dev": true, + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "dev": true, + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "dev": true, + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strong-globalize": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-4.1.3.tgz", + "integrity": "sha512-SJegV7w5D4AodEspZJtJ7rls3fmi+Zc0PdyJCqBsg4RN9B8TC80/uAI2fikC+s1Jp9FLvr2vDX8f0Fqc62M4OA==", + "dev": true, + "requires": { + "accept-language": "^3.0.18", + "debug": "^4.1.1", + "globalize": "^1.4.2", + "lodash": "^4.17.4", + "md5": "^2.2.1", + "mkdirp": "^0.5.1", + "os-locale": "^3.1.0", + "yamljs": "^0.3.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + } + } +} diff --git a/acceptance/repository-mongodb/package.json b/acceptance/repository-mongodb/package.json new file mode 100644 index 000000000000..a47f901ad502 --- /dev/null +++ b/acceptance/repository-mongodb/package.json @@ -0,0 +1,40 @@ +{ + "name": "@loopback/test-repository-mongodb", + "version": "0.1.0", + "description": "", + "private": "true", + "engines": { + "node": ">=8.9" + }, + "scripts": { + "build": "lb-tsc", + "clean": "lb-clean loopback-test-repository-mongodb*.tgz dist tsconfig.build.tsbuildinfo package", + "pretest": "npm run build", + "test": "npm run mocha", + "mocha": "lb-mocha \"dist/__tests__/**/*.js\"", + "verify": "npm pack && tar xf loopback-test-repository-mongodb*.tgz && tree package && npm run clean" + }, + "author": "IBM Corp.", + "copyright.owner": "IBM Corp.", + "license": "MIT", + "devDependencies": { + "@loopback/build": "^1.7.1", + "@loopback/eslint-config": "^1.1.1", + "@loopback/repository": "^1.6.1", + "@loopback/repository-tests": "^0.1.0", + "@types/node": "^10.14.8", + "loopback-connector-mongodb": "^4.2.0" + }, + "files": [ + "README.md", + "index.js", + "index.d.ts", + "dist", + "src", + "!*/__tests__" + ], + "repository": { + "type": "git", + "url": "https://github.com/strongloop/loopback-next.git" + } +} diff --git a/acceptance/repository-mongodb/setup.sh b/acceptance/repository-mongodb/setup.sh new file mode 100644 index 000000000000..ed01c959c896 --- /dev/null +++ b/acceptance/repository-mongodb/setup.sh @@ -0,0 +1 @@ +source ./node_modules/loopback-connector-mongodb/setup.sh diff --git a/acceptance/repository-mongodb/src/__tests__/mongodb-default-repository.acceptance.ts b/acceptance/repository-mongodb/src/__tests__/mongodb-default-repository.acceptance.ts new file mode 100644 index 000000000000..e96bc5f19f37 --- /dev/null +++ b/acceptance/repository-mongodb/src/__tests__/mongodb-default-repository.acceptance.ts @@ -0,0 +1,20 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mongodb +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {DefaultCrudRepository} from '@loopback/repository'; +import { + CrudRepositoryCtor, + crudRepositoryTestSuite, +} from '@loopback/repository-tests'; +import {MONGODB_CONFIG, MONGODB_FEATURES} from './mongodb.datasource'; + +describe('MongoDB + DefaultCrudRepository', () => { + crudRepositoryTestSuite( + MONGODB_CONFIG, + // Workaround for https://github.com/microsoft/TypeScript/issues/31840 + DefaultCrudRepository as CrudRepositoryCtor, + MONGODB_FEATURES, + ); +}); diff --git a/acceptance/repository-mongodb/src/__tests__/mongodb.datasource.ts b/acceptance/repository-mongodb/src/__tests__/mongodb.datasource.ts new file mode 100644 index 000000000000..36f7a27e45a7 --- /dev/null +++ b/acceptance/repository-mongodb/src/__tests__/mongodb.datasource.ts @@ -0,0 +1,23 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + CrudConnectorFeatures, + DataSourceOptions, +} from '@loopback/repository-tests'; + +const connector = require('loopback-connector-mongodb'); + +export const MONGODB_CONFIG: DataSourceOptions = { + connector, + host: process.env.MONGODB_HOST || 'localhost', + port: process.env.MONGODB_PORT || 27017, + database: process.env.MONGODB_DATABASE || 'repository-tests', +}; + +export const MONGODB_FEATURES: CrudConnectorFeatures = { + idType: 'string', + freeFormProperties: false, +}; diff --git a/acceptance/repository-mongodb/tsconfig.build.json b/acceptance/repository-mongodb/tsconfig.build.json new file mode 100644 index 000000000000..c7b8e49eaca5 --- /dev/null +++ b/acceptance/repository-mongodb/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "@loopback/build/config/tsconfig.common.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/acceptance/repository-mysql/.npmrc b/acceptance/repository-mysql/.npmrc new file mode 100644 index 000000000000..cafe685a112d --- /dev/null +++ b/acceptance/repository-mysql/.npmrc @@ -0,0 +1 @@ +package-lock=true diff --git a/acceptance/repository-mysql/LICENSE b/acceptance/repository-mysql/LICENSE new file mode 100644 index 000000000000..8905c55ede77 --- /dev/null +++ b/acceptance/repository-mysql/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) IBM Corp. 2017,2019. All Rights Reserved. +Node module: @loopback/test-repository-mysql +This project is licensed under the MIT License, full text below. + +-------- + +MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/acceptance/repository-mysql/README.md b/acceptance/repository-mysql/README.md new file mode 100644 index 000000000000..5e0004b21731 --- /dev/null +++ b/acceptance/repository-mysql/README.md @@ -0,0 +1,66 @@ +# @loopback/test-repository-mysql + +Acceptance tests for `@loopback/repository` + `loopback-connector-mysql`. + +## Running the test suite + +### Using own MySQL instance + +If you have a local MySQL instance listening on `localhost` and the default +port, with a `root` user and an empty password, use the following command: + +```bash +npm test +``` + +If you have a local or remote MySQL instance and would like to use that to run +the test suite, use the following command: + +**Linux & MacOS** + +```bash +MYSQL_HOST= MYSQL_PORT= MYSQL_USER= MYSQL_PASSWORD= MYSQL_DATABASE= npm test +``` + +**Windows** + +```bash +SET MYSQL_HOST= +SET MYSQL_PORT= +SET MYSQL_USER= +SET MYSQL_PASSWORD= +SET MYSQL_DATABASE= +npm test +``` + +### Using Docker (Linux, MacOS, WSL) + +If you do not have a local MySQL instance, you can also run the test suite with +very minimal requirements. + +- Assuming you have [Docker](https://docs.docker.com/engine/installation/) + installed, run the following script which would spawn a MySQL instance on your + local: + + ```bash + source setup.sh + ``` + + Where ``, ``, ``, `` and `` are optional + parameters. The default values are `localhost`, `3306`, `root`, `pass` and + `testdb` respectively. + +- Run the test: + + ```bash + npm test + ``` + +## Contributors + +See +[all contributors](https://github.com/strongloop/loopback-next/graphs/contributors). + +## License + +MIT diff --git a/acceptance/repository-mysql/index.d.ts b/acceptance/repository-mysql/index.d.ts new file mode 100644 index 000000000000..bb2a6970cc08 --- /dev/null +++ b/acceptance/repository-mysql/index.d.ts @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +export * from './dist'; diff --git a/acceptance/repository-mysql/index.js b/acceptance/repository-mysql/index.js new file mode 100644 index 000000000000..6620c9bb0f1e --- /dev/null +++ b/acceptance/repository-mysql/index.js @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +module.exports = require('./dist'); diff --git a/acceptance/repository-mysql/index.ts b/acceptance/repository-mysql/index.ts new file mode 100644 index 000000000000..e210342ff487 --- /dev/null +++ b/acceptance/repository-mysql/index.ts @@ -0,0 +1,8 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +// DO NOT EDIT THIS FILE +// Add any additional (re)exports to src/index.ts instead. +export * from './src'; diff --git a/acceptance/repository-mysql/package-lock.json b/acceptance/repository-mysql/package-lock.json new file mode 100644 index 000000000000..06b4db4a363a --- /dev/null +++ b/acceptance/repository-mysql/package-lock.json @@ -0,0 +1,606 @@ +{ + "name": "@loopback/test-repository-mysql", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "10.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", + "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==", + "dev": true + }, + "accept-language": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz", + "integrity": "sha1-9QJfF79lpGaoRYOMz5jNuHfYM4Q=", + "dev": true, + "requires": { + "bcp47": "^1.1.2", + "stable": "^0.1.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcp47": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz", + "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4=", + "dev": true + }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "dev": true + }, + "bl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", + "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "cldrjs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.1.tgz", + "integrity": "sha512-xyiP8uAm8K1IhmpDndZLraloW1yqu0L+HYdQ7O1aGPxx9Cr+BMnPANlNhSt++UKfxytL2hd2NPXgTjiy7k43Ew==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globalize": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/globalize/-/globalize-1.4.2.tgz", + "integrity": "sha512-IfKeYI5mAITBmT5EnH8kSQB5uGson4Fkj2XtTpyEbIS7IHNfLHoeTyLJ6tfjiKC6cJXng3IhVurDk5C7ORqFhQ==", + "dev": true, + "requires": { + "cldrjs": "^0.5.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "loopback-connector": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/loopback-connector/-/loopback-connector-4.7.0.tgz", + "integrity": "sha512-NIN8XB9CILRsXtu6TWjliaM1yadOolGi9tCc6tP3f1nKdN749TjvjfWXZyO+fB+EWuhWOHyh1UApr9DtptgIqg==", + "dev": true, + "requires": { + "async": "^2.1.5", + "bluebird": "^3.4.6", + "debug": "^3.1.0", + "msgpack5": "^4.2.0", + "strong-globalize": "^4.1.1", + "uuid": "^3.0.1" + } + }, + "loopback-connector-mysql": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/loopback-connector-mysql/-/loopback-connector-mysql-5.4.1.tgz", + "integrity": "sha512-+nXuodxmAVotvXGYrJRyzF21AT+3250Rodhsbh7lUrwRHOsYuja6ulT15P1P9NAoHeoZkzbw6XV9DQSJe6JyXw==", + "dev": true, + "requires": { + "async": "^2.6.1", + "debug": "^3.1.0", + "lodash": "^4.17.11", + "loopback-connector": "^4.0.0", + "mysql": "^2.11.1", + "strong-globalize": "^4.1.1" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "msgpack5": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.2.1.tgz", + "integrity": "sha512-Xo7nE9ZfBVonQi1rSopNAqPdts/QHyuSEUwIEzAkB+V2FtmkkLUbP6MyVqVVQxsZYI65FpvW3Bb8Z9ZWEjbgHQ==", + "dev": true, + "requires": { + "bl": "^2.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.3.6", + "safe-buffer": "^5.1.2" + } + }, + "mysql": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz", + "integrity": "sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA==", + "dev": true, + "requires": { + "bignumber.js": "7.2.1", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "dev": true + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strong-globalize": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-4.1.3.tgz", + "integrity": "sha512-SJegV7w5D4AodEspZJtJ7rls3fmi+Zc0PdyJCqBsg4RN9B8TC80/uAI2fikC+s1Jp9FLvr2vDX8f0Fqc62M4OA==", + "dev": true, + "requires": { + "accept-language": "^3.0.18", + "debug": "^4.1.1", + "globalize": "^1.4.2", + "lodash": "^4.17.4", + "md5": "^2.2.1", + "mkdirp": "^0.5.1", + "os-locale": "^3.1.0", + "yamljs": "^0.3.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + } + } +} diff --git a/acceptance/repository-mysql/package.json b/acceptance/repository-mysql/package.json new file mode 100644 index 000000000000..ee2d1f55667d --- /dev/null +++ b/acceptance/repository-mysql/package.json @@ -0,0 +1,40 @@ +{ + "name": "@loopback/test-repository-mysql", + "version": "0.1.0", + "description": "", + "private": "true", + "engines": { + "node": ">=8.9" + }, + "scripts": { + "build": "lb-tsc", + "clean": "lb-clean loopback-test-repository-mysql*.tgz dist tsconfig.build.tsbuildinfo package", + "pretest": "npm run build", + "test": "npm run mocha", + "mocha": "lb-mocha \"dist/__tests__/**/*.js\"", + "verify": "npm pack && tar xf loopback-test-repository-mysql*.tgz && tree package && npm run clean" + }, + "author": "IBM Corp.", + "copyright.owner": "IBM Corp.", + "license": "MIT", + "devDependencies": { + "@loopback/build": "^1.7.1", + "@loopback/eslint-config": "^1.1.1", + "@loopback/repository": "^1.6.1", + "@loopback/repository-tests": "^0.1.0", + "@types/node": "^10.14.8", + "loopback-connector-mysql": "^5.4.1" + }, + "files": [ + "README.md", + "index.js", + "index.d.ts", + "dist", + "src", + "!*/__tests__" + ], + "repository": { + "type": "git", + "url": "https://github.com/strongloop/loopback-next.git" + } +} diff --git a/acceptance/repository-mysql/setup.sh b/acceptance/repository-mysql/setup.sh new file mode 100644 index 000000000000..892b4a1544c3 --- /dev/null +++ b/acceptance/repository-mysql/setup.sh @@ -0,0 +1 @@ +source ./node_modules/loopback-connector-mysql/setup.sh diff --git a/acceptance/repository-mysql/src/__tests__/mysql-default-repository.acceptance.ts b/acceptance/repository-mysql/src/__tests__/mysql-default-repository.acceptance.ts new file mode 100644 index 000000000000..7a8ae693776a --- /dev/null +++ b/acceptance/repository-mysql/src/__tests__/mysql-default-repository.acceptance.ts @@ -0,0 +1,20 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {DefaultCrudRepository} from '@loopback/repository'; +import { + CrudRepositoryCtor, + crudRepositoryTestSuite, +} from '@loopback/repository-tests'; +import {MYSQL_CONFIG, MYSQL_FEATURES} from './mysql.datasource'; + +describe('MySQL + DefaultCrudRepository', () => { + crudRepositoryTestSuite( + MYSQL_CONFIG, + // Workaround for https://github.com/microsoft/TypeScript/issues/31840 + DefaultCrudRepository as CrudRepositoryCtor, + MYSQL_FEATURES, + ); +}); diff --git a/acceptance/repository-mysql/src/__tests__/mysql.datasource.ts b/acceptance/repository-mysql/src/__tests__/mysql.datasource.ts new file mode 100644 index 000000000000..2fe2c0d6e9fb --- /dev/null +++ b/acceptance/repository-mysql/src/__tests__/mysql.datasource.ts @@ -0,0 +1,26 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/test-repository-mysql +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + CrudConnectorFeatures, + DataSourceOptions, +} from '@loopback/repository-tests'; + +const connector = require('loopback-connector-mysql'); + +export const MYSQL_CONFIG: DataSourceOptions = { + connector, + host: process.env.MYSQL_HOST || 'localhost', + port: process.env.MYSQL_PORT || 3306, + database: process.env.MYSQL_DATABASE || 'repository-tests', + username: process.env.MYSQL_USER || 'root', + password: process.env.MYSQL_PASSWORD || '', + createDatabase: true, +}; + +export const MYSQL_FEATURES: CrudConnectorFeatures = { + idType: 'number', + freeFormProperties: false, +}; diff --git a/acceptance/repository-mysql/test/schema.sql b/acceptance/repository-mysql/test/schema.sql new file mode 100644 index 000000000000..44800b9617ba --- /dev/null +++ b/acceptance/repository-mysql/test/schema.sql @@ -0,0 +1,4 @@ +-- Seed database schema & data +-- See https://github.com/strongloop/loopback-connector-mysql/blob/master/test/schema.sql +-- The repository test suite does not require any seed data to exist, +-- we can keep this SQL file empty. diff --git a/acceptance/repository-mysql/tsconfig.build.json b/acceptance/repository-mysql/tsconfig.build.json new file mode 100644 index 000000000000..c7b8e49eaca5 --- /dev/null +++ b/acceptance/repository-mysql/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "@loopback/build/config/tsconfig.common.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/docs/site/MONOREPO.md b/docs/site/MONOREPO.md index 1fe2fe6e8414..47862b8d221e 100644 --- a/docs/site/MONOREPO.md +++ b/docs/site/MONOREPO.md @@ -5,39 +5,42 @@ The [loopback-next](https://github.com/strongloop/loopback-next) repository uses -| Package | npm | Description | -| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [authentication](https://github.com/strongloop/loopback-next/tree/master/packages/authentication) | @loopback/authentication | A component for authentication support | -| [booter-lb3app](https://github.com/strongloop/loopback-next/tree/master/packages/booter-lb3app) | @loopback/booter-lb3app | A booter component for LoopBack 3 applications to expose their REST API via LoopBack 4. | -| [boot](https://github.com/strongloop/loopback-next/tree/master/packages/boot) | @loopback/boot | Convention based Bootstrapper and Booters | -| [build](https://github.com/strongloop/loopback-next/tree/master/packages/build) | @loopback/build | A set of common scripts and default configurations to build LoopBack 4 or other TypeScript modules | -| [cli](https://github.com/strongloop/loopback-next/tree/master/packages/cli) | @loopback/cli | CLI for LoopBack 4 | -| [context](https://github.com/strongloop/loopback-next/tree/master/packages/context) | @loopback/context | Facilities to manage artifacts and their dependencies in your Node.js applications. The module exposes TypeScript/JavaScript APIs and decorators to register artifacts, declare dependencies, and resolve artifacts by keys. It also serves as an IoC container to support dependency injection. | -| [core](https://github.com/strongloop/loopback-next/tree/master/packages/core) | @loopback/core | Define and implement core constructs such as Application and Component | -| [docs](https://github.com/strongloop/loopback-next/tree/master/docs) | @loopback/docs | Documentation files rendered at [https://loopback.io](https://loopback.io) | -| [eslint-config](https://github.com/strongloop/loopback-next/tree/master/packages/eslint-config) | @loopback/eslint-config | ESLint configuration for LoopBack projects | -| [example-context](https://github.com/strongloop/loopback-next/tree/master/examples/context) | @loopback/example-context | Standalone examples to illustrate features provided by @loopback/context | -| [example-express-composition](https://github.com/strongloop/loopback-next/tree/master/examples/express-composition) | @loopback/example-express-composition | A simple Express application that uses LoopBack 4 REST API | -| [example-greeter-extension](https://github.com/strongloop/loopback-next/tree/master/examples/greeter-extension) | @loopback/example-greeter-extension | An example showing how to implement the extension point/extension pattern using LoopBack 4 | -| [example-hello-world](https://github.com/strongloop/loopback-next/tree/master/examples/hello-world) | @loopback/example-hello-world | A simple hello-world application using LoopBack 4 | -| [example-lb3-application](https://github.com/strongloop/loopback-next/tree/master/examples/lb3-application) | @loopback/example-lb3-application | An example LoopBack 3 application mounted in a LoopBack 4 project. | -| [example-log-extension](https://github.com/strongloop/loopback-next/tree/master/examples/log-extension) | @loopback/example-log-extension | An example showing how to write a complex log extension for LoopBack 4 | -| [example-rpc-server](https://github.com/strongloop/loopback-next/tree/master/examples/rpc-server) | @loopback/example-rpc-server | An example RPC server and application to demonstrate the creation of your own custom server | -| [example-soap-calculator](https://github.com/strongloop/loopback-next/tree/master/examples/soap-calculator) | @loopback/example-soap-calculator | A tutorial demonstrating integration with a SOAP webservice | -| [example-todo-list](https://github.com/strongloop/loopback-next/tree/master/examples/todo-list) | @loopback/example-todo-list | Continuation of the todo example using relations in LoopBack 4 | -| [example-todo](https://github.com/strongloop/loopback-next/tree/master/examples/todo) | @loopback/example-todo | A basic tutorial for getting started with Loopback 4 | -| [http-caching-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/http-caching-proxy) | @loopback/http-caching-proxy | A caching HTTP proxy for integration tests. NOT SUITABLE FOR PRODUCTION USE! | -| [http-server](https://github.com/strongloop/loopback-next/tree/master/packages/http-server) | @loopback/http-server | A wrapper for creating HTTP/HTTPS servers | -| [metadata](https://github.com/strongloop/loopback-next/tree/master/packages/metadata) | @loopback/metadata | Utilities to help developers implement TypeScript decorators, define/merge metadata, and inspect metadata | -| [openapi-spec-builder](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-spec-builder) | @loopback/openapi-spec-builder | Builders to create OpenAPI (Swagger) specification documents in tests | -| [openapi-v3-types](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-v3-types) | @loopback/openapi-v3-types | TypeScript type definitions for OpenAPI Specifications | -| [openapi-v3](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-v3) | @loopback/openapi-v3 | Decorators that annotate LoopBack artifacts with OpenAPI v3 metadata and utilities that transform LoopBack metadata to OpenAPI v3 specifications | -| [repository-json-schema](https://github.com/strongloop/loopback-next/tree/master/packages/repository-json-schema) | @loopback/repository-json-schema | Convert a TypeScript class/model to a JSON Schema | -| [repository](https://github.com/strongloop/loopback-next/tree/master/packages/repository) | @loopback/repository | Define and implement a common set of interfaces for interacting with databases | -| [rest](https://github.com/strongloop/loopback-next/tree/master/packages/rest) | @loopback/rest | Expose controllers as REST endpoints and route REST API requests to controller methods | -| [service-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/service-proxy) | @loopback/service-proxy | A common set of interfaces for interacting with service oriented backends such as REST APIs, SOAP Web Services, and gRPC microservices | -| [testlab](https://github.com/strongloop/loopback-next/tree/master/packages/testlab) | @loopback/testlab | A collection of test utilities we use to write LoopBack tests | -| [tsdocs](https://github.com/strongloop/loopback-next/tree/master/packages/tsdocs) | @loopback/tsdocs | An internal package to generate api docs using Microsoft api-extractor and api-documenter | +| Package | npm | Description | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [acceptance/repository-mongodb](https://github.com/strongloop/loopback-next/tree/master/acceptance/repository-mongodb) | _(private)_ | Acceptance tests for `@loopback/repository` + `loopback-connector-mongodb` | +| [acceptance/repository-mysql](https://github.com/strongloop/loopback-next/tree/master/acceptance/repository-mysql) | _(private)_ | Acceptance tests for `@loopback/repository` + `loopback-connector-mysql` | +| [authentication](https://github.com/strongloop/loopback-next/tree/master/packages/authentication) | @loopback/authentication | A component for authentication support | +| [booter-lb3app](https://github.com/strongloop/loopback-next/tree/master/packages/booter-lb3app) | @loopback/booter-lb3app | A booter component for LoopBack 3 applications to expose their REST API via LoopBack 4. | +| [boot](https://github.com/strongloop/loopback-next/tree/master/packages/boot) | @loopback/boot | Convention based Bootstrapper and Booters | +| [build](https://github.com/strongloop/loopback-next/tree/master/packages/build) | @loopback/build | A set of common scripts and default configurations to build LoopBack 4 or other TypeScript modules | +| [cli](https://github.com/strongloop/loopback-next/tree/master/packages/cli) | @loopback/cli | CLI for LoopBack 4 | +| [context](https://github.com/strongloop/loopback-next/tree/master/packages/context) | @loopback/context | Facilities to manage artifacts and their dependencies in your Node.js applications. The module exposes TypeScript/JavaScript APIs and decorators to register artifacts, declare dependencies, and resolve artifacts by keys. It also serves as an IoC container to support dependency injection. | +| [core](https://github.com/strongloop/loopback-next/tree/master/packages/core) | @loopback/core | Define and implement core constructs such as Application and Component | +| [docs](https://github.com/strongloop/loopback-next/tree/master/docs) | @loopback/docs | Documentation files rendered at [https://loopback.io](https://loopback.io) | +| [eslint-config](https://github.com/strongloop/loopback-next/tree/master/packages/eslint-config) | @loopback/eslint-config | ESLint configuration for LoopBack projects | +| [example-context](https://github.com/strongloop/loopback-next/tree/master/examples/context) | @loopback/example-context | Standalone examples to illustrate features provided by @loopback/context | +| [example-express-composition](https://github.com/strongloop/loopback-next/tree/master/examples/express-composition) | @loopback/example-express-composition | A simple Express application that uses LoopBack 4 REST API | +| [example-greeter-extension](https://github.com/strongloop/loopback-next/tree/master/examples/greeter-extension) | @loopback/example-greeter-extension | An example showing how to implement the extension point/extension pattern using LoopBack 4 | +| [example-hello-world](https://github.com/strongloop/loopback-next/tree/master/examples/hello-world) | @loopback/example-hello-world | A simple hello-world application using LoopBack 4 | +| [example-lb3-application](https://github.com/strongloop/loopback-next/tree/master/examples/lb3-application) | @loopback/example-lb3-application | An example LoopBack 3 application mounted in a LoopBack 4 project. | +| [example-log-extension](https://github.com/strongloop/loopback-next/tree/master/examples/log-extension) | @loopback/example-log-extension | An example showing how to write a complex log extension for LoopBack 4 | +| [example-rpc-server](https://github.com/strongloop/loopback-next/tree/master/examples/rpc-server) | @loopback/example-rpc-server | An example RPC server and application to demonstrate the creation of your own custom server | +| [example-soap-calculator](https://github.com/strongloop/loopback-next/tree/master/examples/soap-calculator) | @loopback/example-soap-calculator | A tutorial demonstrating integration with a SOAP webservice | +| [example-todo-list](https://github.com/strongloop/loopback-next/tree/master/examples/todo-list) | @loopback/example-todo-list | Continuation of the todo example using relations in LoopBack 4 | +| [example-todo](https://github.com/strongloop/loopback-next/tree/master/examples/todo) | @loopback/example-todo | A basic tutorial for getting started with Loopback 4 | +| [http-caching-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/http-caching-proxy) | @loopback/http-caching-proxy | A caching HTTP proxy for integration tests. NOT SUITABLE FOR PRODUCTION USE! | +| [http-server](https://github.com/strongloop/loopback-next/tree/master/packages/http-server) | @loopback/http-server | A wrapper for creating HTTP/HTTPS servers | +| [metadata](https://github.com/strongloop/loopback-next/tree/master/packages/metadata) | @loopback/metadata | Utilities to help developers implement TypeScript decorators, define/merge metadata, and inspect metadata | +| [openapi-spec-builder](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-spec-builder) | @loopback/openapi-spec-builder | Builders to create OpenAPI (Swagger) specification documents in tests | +| [openapi-v3-types](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-v3-types) | @loopback/openapi-v3-types | TypeScript type definitions for OpenAPI Specifications | +| [openapi-v3](https://github.com/strongloop/loopback-next/tree/master/packages/openapi-v3) | @loopback/openapi-v3 | Decorators that annotate LoopBack artifacts with OpenAPI v3 metadata and utilities that transform LoopBack metadata to OpenAPI v3 specifications | +| [repository-json-schema](https://github.com/strongloop/loopback-next/tree/master/packages/repository-json-schema) | @loopback/repository-json-schema | Convert a TypeScript class/model to a JSON Schema | +| [repository](https://github.com/strongloop/loopback-next/tree/master/packages/repository) | @loopback/repository | Define and implement a common set of interfaces for interacting with databases | +| [repository-tests](https://github.com/strongloop/loopback-next/tree/master/packages/repository-tests) | @loopback/repository-tests | A shared test suite to verify `@loopback/repository` functionality with a given compatible connector | +| [rest](https://github.com/strongloop/loopback-next/tree/master/packages/rest) | @loopback/rest | Expose controllers as REST endpoints and route REST API requests to controller methods | +| [service-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/service-proxy) | @loopback/service-proxy | A common set of interfaces for interacting with service oriented backends such as REST APIs, SOAP Web Services, and gRPC microservices | +| [testlab](https://github.com/strongloop/loopback-next/tree/master/packages/testlab) | @loopback/testlab | A collection of test utilities we use to write LoopBack tests | +| [tsdocs](https://github.com/strongloop/loopback-next/tree/master/packages/tsdocs) | @loopback/tsdocs | An internal package to generate api docs using Microsoft api-extractor and api-documenter | We use npm scripts declared in [package.json](https://github.com/strongloop/loopback-next/blob/master/package.json) diff --git a/lerna.json b/lerna.json index f00f9624453c..2e572dfd0396 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,7 @@ { "lerna": "3.3.0", "packages": [ + "acceptance/*", "benchmark", "docs", "examples/*", diff --git a/packages/repository-tests/.npmrc b/packages/repository-tests/.npmrc new file mode 100644 index 000000000000..cafe685a112d --- /dev/null +++ b/packages/repository-tests/.npmrc @@ -0,0 +1 @@ +package-lock=true diff --git a/packages/repository-tests/LICENSE b/packages/repository-tests/LICENSE new file mode 100644 index 000000000000..267bd0bd36bf --- /dev/null +++ b/packages/repository-tests/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) IBM Corp. 2017,2019. All Rights Reserved. +Node module: @loopback/repository-tests +This project is licensed under the MIT License, full text below. + +-------- + +MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/repository-tests/README.md b/packages/repository-tests/README.md new file mode 100644 index 000000000000..74b12bc91c53 --- /dev/null +++ b/packages/repository-tests/README.md @@ -0,0 +1,117 @@ +# @loopback/repository-tests + +A test suite verifying functionality of `@loopback/repository` in a +connector-independent way. + +## Overview + +The module provides test-suite factories to define standardized test suite +capable of testing any combination of a Repository class and a corresponding +connector, for example `DefaultCrudRepository` with connectors like `memory`, +`mysql` and `mongodb`. + +## Installation + +```sh +npm install --save @loopback/repository-tests +``` + +## Basic use + +Add the following file to your test suite, and make the following changes: + +- Replace `DefaultCrudRepository` with the repository class you want to test. +- Replace the string `'memory'` with the default export of the connector to use, + e.g. `require('loopback-connector-mysql')`. +- If your database uses string primary keys (e.g. GUID/UUID), then change + `idType` to `'string'`. + +```ts +import {DefaultCrudRepository} from '@loopback/repository'; +import { + CrudRepositoryCtor, + crudRepositoryTestSuite, +} from '@loopback/repository-tests'; + +describe('DefaultCrudRepository + memory connector', () => { + crudRepositoryTestSuite( + { + connector: 'memory', + // add any database-specific configuration, e.g. credentials & db name + }, + // Workaround for the following TypeScript error + // Type 'DefaultCrudRepository' is not assignable to + // type 'EntityCrudRepository'. + // See https://github.com/microsoft/TypeScript/issues/31840 + DefaultCrudRepository as CrudRepositoryCtor, + { + idType: 'number', + }, + ); +}); +``` + +## Developer guide + +Under the hood, the test suite is composed from individual test suite files, +e.g. `src/__tests__/crud/create-retrieve.suite.ts`. + +**IMPORTANT** Keep the size of test files small. Each test file should cover a +small & cohesive subset of our features. If a new test does fit the remaining +tests in a test file, then move it to a new one. + +A test suite file exports a single factory function that's called to define the +tests: + +```ts +export function createRetrieveSuite( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + connectorFeatures: CrudConnectorFeatures, +) { + // test code +} +``` + +The factory functions can use `describe`, `it` and other Mocha API like +`before`/`after` hooks to define the tests to be executed. + +Besides the arguments passed to the factory function, the test context (`this` +provided by Mocha) is initialized with additional properties like +`this.dataSource` (a data-source instance created with `dataSourceOptions` to be +used by tests). + +Because accessing Mocha's `this` in a type-safe way is cumbersome, we have a +helper converting `this` to a named function argument. Example usage: + +```ts +let repo: EntityCrudRepository; +before( + withCrudCtx(async function setupRepository(ctx: CrudTestContext) { + repo = new repositoryClass(Product, ctx.dataSource); + await ctx.dataSource.automigrate(Product.name); + }), +); +``` + +## Contributions + +- [Guidelines](https://github.com/strongloop/loopback-next/blob/master/docs/CONTRIBUTING.md) +- [Join the team](https://github.com/strongloop/loopback-next/issues/110) + +## Tests + +Run `npm test` from the root folder. + +## Contributors + +See +[all contributors](https://github.com/strongloop/loopback-next/graphs/contributors). + +## License + +MIT + +``` + +``` diff --git a/packages/repository-tests/index.d.ts b/packages/repository-tests/index.d.ts new file mode 100644 index 000000000000..1d827438989f --- /dev/null +++ b/packages/repository-tests/index.d.ts @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +export * from './dist'; diff --git a/packages/repository-tests/index.js b/packages/repository-tests/index.js new file mode 100644 index 000000000000..c1c89a9847d5 --- /dev/null +++ b/packages/repository-tests/index.js @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +module.exports = require('./dist'); diff --git a/packages/repository-tests/index.ts b/packages/repository-tests/index.ts new file mode 100644 index 000000000000..26f5a91e410f --- /dev/null +++ b/packages/repository-tests/index.ts @@ -0,0 +1,8 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +// DO NOT EDIT THIS FILE +// Add any additional (re)exports to src/index.ts instead. +export * from './src'; diff --git a/packages/repository-tests/package-lock.json b/packages/repository-tests/package-lock.json new file mode 100644 index 000000000000..d80de3267c7d --- /dev/null +++ b/packages/repository-tests/package-lock.json @@ -0,0 +1,32 @@ +{ + "name": "@loopback/repository-tests", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/debug": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.4.tgz", + "integrity": "sha512-D9MyoQFI7iP5VdpEyPZyjjqIJ8Y8EDNQFIFVLOmeg1rI1xiHOChyUPMPRUVfqFCerxfE+yS3vMyj37F6IdtOoQ==" + }, + "@types/node": { + "version": "10.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", + "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } +} diff --git a/packages/repository-tests/package.json b/packages/repository-tests/package.json new file mode 100644 index 000000000000..498502b2c3fd --- /dev/null +++ b/packages/repository-tests/package.json @@ -0,0 +1,48 @@ +{ + "name": "@loopback/repository-tests", + "version": "0.1.0", + "description": "Shared test-suite for repository based persistence", + "engines": { + "node": ">=8.9" + }, + "main": "index", + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "lb-tsc", + "clean": "lb-clean loopback-repository-tests*.tgz dist package", + "pretest": "npm run build", + "test": "lb-mocha \"dist/__tests__/**/*.js\"", + "verify": "npm pack && tar xf loopback-repository*.tgz && tree package && npm run clean" + }, + "author": "IBM Corp.", + "copyright.owner": "IBM Corp.", + "license": "MIT", + "devDependencies": { + "@loopback/build": "^1.7.1", + "@loopback/repository": "^1.6.1", + "@types/debug": "^4.1.4", + "@types/node": "^10.11.2" + }, + "dependencies": { + "@loopback/testlab": "^1.5.0", + "@types/debug": "^4.1.4", + "debug": "^4.0.1" + }, + "peerDependencies": { + "@loopback/repository": "^1.6.1" + }, + "files": [ + "README.md", + "index.js", + "index.d.ts", + "dist", + "src", + "!*/__tests__" + ], + "repository": { + "type": "git", + "url": "https://github.com/strongloop/loopback-next.git" + } +} diff --git a/packages/repository-tests/src/__tests__/acceptance/default-repository.memory.acceptance.ts b/packages/repository-tests/src/__tests__/acceptance/default-repository.memory.acceptance.ts new file mode 100644 index 000000000000..b2738d1e5ea6 --- /dev/null +++ b/packages/repository-tests/src/__tests__/acceptance/default-repository.memory.acceptance.ts @@ -0,0 +1,21 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {DefaultCrudRepository} from '@loopback/repository'; +import {CrudRepositoryCtor, crudRepositoryTestSuite} from '../..'; + +describe('DefaultCrudRepository + memory connector', () => { + crudRepositoryTestSuite( + {connector: 'memory'}, + // Workaround for the following TypeScript error + // Type 'DefaultCrudRepository' is not assignable to + // type 'EntityCrudRepository'. + // See https://github.com/microsoft/TypeScript/issues/31840 + DefaultCrudRepository as CrudRepositoryCtor, + { + idType: 'number', + }, + ); +}); diff --git a/packages/repository-tests/src/crud-test-suite.ts b/packages/repository-tests/src/crud-test-suite.ts new file mode 100644 index 000000000000..73f052fe154e --- /dev/null +++ b/packages/repository-tests/src/crud-test-suite.ts @@ -0,0 +1,79 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {juggler} from '@loopback/repository'; +import * as debugFactory from 'debug'; +import * as fs from 'fs'; +import * as path from 'path'; +import {withCrudCtx} from './helpers.repository-tests'; +import { + CrudConnectorFeatures, + CrudRepositoryCtor, + CrudTestContext, + DataSourceOptions, +} from './types.repository-tests'; + +const debug = debugFactory('loopback:repository-tests'); + +type SuiteFn = ( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + connectorFeatures: CrudConnectorFeatures, +) => void; + +export function crudRepositoryTestSuite( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + connectorFeatures: Partial, +) { + const features: CrudConnectorFeatures = { + idType: 'string', + freeFormProperties: true, + ...connectorFeatures, + }; + + describe('CRUD Repository operations', () => { + before( + withCrudCtx(function setupContext(ctx: CrudTestContext) { + ctx.dataSourceOptions = dataSourceOptions; + ctx.repositoryClass = repositoryClass; + ctx.connectorFeatures = features; + }), + ); + before( + withCrudCtx(function setupGlobalDataSource(ctx: CrudTestContext) { + ctx.dataSource = new juggler.DataSource(ctx.dataSourceOptions); + }), + ); + + const testRoot = path.resolve(__dirname, 'crud'); + let testFiles = fs.readdirSync(testRoot); + testFiles = testFiles.filter(function(it) { + return ( + !!require.extensions[path.extname(it).toLowerCase()] && + /\.suite\.[^.]+$/.test(it) + ); + }); + + for (const ix in testFiles) { + const name = testFiles[ix]; + const fullPath = path.resolve(testRoot, name); + debug('Loading CRUD test suite %j', fullPath); + const allExports = require(fullPath); + for (const key in allExports) { + const suite: SuiteFn = allExports[key]; + if (typeof suite !== 'function') continue; + debug( + 'Calling suite function %j with args', + suite.name, + dataSourceOptions, + 'class ' + repositoryClass.name, + connectorFeatures, + ); + suite(dataSourceOptions, repositoryClass, features); + } + } + }); +} diff --git a/packages/repository-tests/src/crud/create-retrieve.suite.ts b/packages/repository-tests/src/crud/create-retrieve.suite.ts new file mode 100644 index 000000000000..d191282b3702 --- /dev/null +++ b/packages/repository-tests/src/crud/create-retrieve.suite.ts @@ -0,0 +1,60 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {Entity, model, property} from '@loopback/repository'; +import {EntityCrudRepository} from '@loopback/repository/src'; +import {expect, toJSON} from '@loopback/testlab'; +import {withCrudCtx} from '../helpers.repository-tests'; +import { + CrudConnectorFeatures, + CrudRepositoryCtor, + CrudTestContext, + DataSourceOptions, +} from '../types.repository-tests'; + +// Core scenarios around creating new model instances and retrieving them back +// Please keep this file short, put any advanced scenarios to other files +export function createRetrieveSuite( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + connectorFeatures: CrudConnectorFeatures, +) { + @model() + class Product extends Entity { + @property({ + type: connectorFeatures.idType, + id: true, + generated: true, + description: 'The unique identifier for a product', + }) + id: number | string; + + @property({type: 'string', required: true}) + name: string; + + constructor(data?: Partial) { + super(data); + } + } + + describe('create-retrieve', () => { + let repo: EntityCrudRepository; + before( + withCrudCtx(async function setupRepository(ctx: CrudTestContext) { + repo = new repositoryClass(Product, ctx.dataSource); + await ctx.dataSource.automigrate(Product.name); + }), + ); + + it('retrieves a newly created model with id set by the database', async () => { + const created = await repo.create({name: 'Pencil'}); + expect(created.toObject()).to.have.properties('id', 'name'); + expect(created.id).to.be.ok(); + + const found = await repo.findById(created.id); + expect(toJSON(created)).to.deepEqual(toJSON(found)); + }); + }); +} diff --git a/packages/repository-tests/src/crud/freeform-properties.suite.ts b/packages/repository-tests/src/crud/freeform-properties.suite.ts new file mode 100644 index 000000000000..d88cdb2a90c0 --- /dev/null +++ b/packages/repository-tests/src/crud/freeform-properties.suite.ts @@ -0,0 +1,73 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {Entity, model, property} from '@loopback/repository'; +import {EntityCrudRepository} from '@loopback/repository/src'; +import {expect, skipIf, toJSON} from '@loopback/testlab'; +import {Suite} from 'mocha'; +import {withCrudCtx} from '../helpers.repository-tests'; +import { + CrudConnectorFeatures, + CrudRepositoryCtor, + CrudTestContext, + DataSourceOptions, +} from '../types.repository-tests'; + +export function freeformPropertiesSuite( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + connectorFeatures: CrudConnectorFeatures, +) { + skipIf<[(this: Suite) => void], void>( + !connectorFeatures.freeFormProperties, + describe, + 'free-form properties (strict: false)', + () => { + @model({settings: {strict: false}}) + class Freeform extends Entity { + @property({ + type: connectorFeatures.idType, + id: true, + description: 'The unique identifier for a product', + }) + id: number | string; + + @property({type: 'string', required: true}) + name: string; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [propName: string]: any; + + constructor(data?: Partial) { + super(data); + } + } + + let repo: EntityCrudRepository; + + before( + withCrudCtx(async function setupRepository(ctx: CrudTestContext) { + repo = new repositoryClass(Freeform, ctx.dataSource); + await ctx.dataSource.automigrate(Freeform.name); + }), + ); + + it('stores extra properties on create', async () => { + // FIXME(bajtos) Fix repository types so that explicit cast can be removed + // ATM, compiler complains that {name: 'Pencil', color: 'red'} cannot be + // assigned to DeepPartial + const created = await repo.create(>{ + name: 'Pencil', + color: 'red', + }); + expect(created.toObject()).to.have.properties('id', 'name'); + expect(created.id).to.be.ok(); + + const found = await repo.findById(created.id); + expect(toJSON(created)).to.deepEqual(toJSON(found)); + }); + }, + ); +} diff --git a/packages/repository-tests/src/helpers.repository-tests.ts b/packages/repository-tests/src/helpers.repository-tests.ts new file mode 100644 index 000000000000..d12aad5ff352 --- /dev/null +++ b/packages/repository-tests/src/helpers.repository-tests.ts @@ -0,0 +1,31 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {CrudTestContext} from './types.repository-tests'; + +/** + * Obtain CrudTestContext from the Mocha context. + * @internal + * @param context - Mocha context as provided to the test function via `this`. + */ +export function getCrudContext(context: Mocha.Context) { + return (context as unknown) as CrudTestContext; +} + +/** + * Convert a function accepting context in the first argument into a regular + * Mocha function. + * @param fn A Mocha function (describe/it/before/after callback) accepting + * `CrudTestContext` as the regular argument. + */ +export function withCrudCtx( + fn: (context: CrudTestContext) => PromiseLike | void, +): Mocha.AsyncFunc | Mocha.Func { + return function(this: Mocha.Context) { + // See https://github.com/typescript-eslint/typescript-eslint/issues/604 + // eslint-disable-next-line no-invalid-this + return fn.call(this, getCrudContext(this)); + }; +} diff --git a/packages/repository-tests/src/index.ts b/packages/repository-tests/src/index.ts new file mode 100644 index 000000000000..d42191835d57 --- /dev/null +++ b/packages/repository-tests/src/index.ts @@ -0,0 +1,9 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +export * from './crud-test-suite'; +export * from './types.repository-tests'; + +// TODO(bajtos) Implement test suite for KeyValue repository diff --git a/packages/repository-tests/src/types.repository-tests.ts b/packages/repository-tests/src/types.repository-tests.ts new file mode 100644 index 000000000000..435d74ee8a04 --- /dev/null +++ b/packages/repository-tests/src/types.repository-tests.ts @@ -0,0 +1,65 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/repository-tests +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + Entity, + EntityCrudRepository, + juggler, + Options, +} from '@loopback/repository'; + +/** + * DataSource configuration (connector name, connection string, etc.). + */ +export type DataSourceOptions = Options; + +/** + * List of flags describing connector-specific behavior. These flags + * are used by the test suite to tweak assertions and skip tests + * for scenarios not supported by some connectors. + */ +export interface CrudConnectorFeatures { + /** + * What type is used for auto-generated primary keys? + * - SQL databases typically use auto-incremented numbers, + * - NoSQL databases tend to use GUID/UUID strings. + * + * Default: `'string'`. + */ + idType: 'string' | 'number'; + + /** + * Does the database (or the connector) require a fixed schema, + * or can it support additional (free-form) properties? + * SQL databases typically don't support free-form properties. + * + * Default: `true` + */ + freeFormProperties: boolean; +} + +/** + * A constructor of a class implementing CrudRepository interface, + * accepting the Entity class (constructor) and a dataSource instance. + */ +export type CrudRepositoryCtor = new < + T extends Entity, + ID, + Relations extends object +>( + entityClass: typeof Entity & {prototype: T}, + dataSource: juggler.DataSource, +) => EntityCrudRepository; + +/** + * Additional properties added to Mocha TestContext/SuiteContext. + * @internal + */ +export interface CrudTestContext { + dataSourceOptions: DataSourceOptions; + repositoryClass: CrudRepositoryCtor; + connectorFeatures: CrudConnectorFeatures; + dataSource: juggler.DataSource; +} diff --git a/packages/repository-tests/tsconfig.build.json b/packages/repository-tests/tsconfig.build.json new file mode 100644 index 000000000000..c7b8e49eaca5 --- /dev/null +++ b/packages/repository-tests/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "@loopback/build/config/tsconfig.common.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +}