{"_id":"mocaron","_rev":"34-d14e75cc34e9f025cd6a4bba33472d08","name":"mocaron","dist-tags":{"latest":"1.1.0","alpha":"0.0.3-alpha.1","beta":"1.1.0-beta.0"},"versions":{"0.0.0-empty":{"name":"mocaron","version":"0.0.0-empty","_id":"mocaron@0.0.0-empty","_nodeVersion":"17.4.0","_npmVersion":"7.24.2","dist":{"integrity":"sha512-Tss0uwo9X05UwSlVMVTKtKhyGQy8QDHeODGmc0eVX4hKHWx0S7ls8B54znRfEi6RQ5gT6l5/IDiVFB2b6A0VCg==","shasum":"3194cfd54cdafa3d3f8e3a815620c5d9ed0daa02","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.0.0-empty.tgz","fileCount":1,"unpackedSize":52,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGLFVoUSQXPWVjJ4mvytL7AWHUuh+3BxEz2p7IDO/Ad+AiBOg8E8CZICdOFglfvzGDki4VN1uBdmR5eiakYXQ5ESrg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi0XWiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqkgw//baVczWoieSebqQWIIgaK4OivN34I0FDvnrvEgZP7022rq4Sa\r\n0przErarGcd0/XApwQc9/7vzQFf1VQa8YNwZvCxQoWkqb+U4Gu5Qklex0yO1\r\nfxKVlP73Vk878HHMQkybYFF0BSJneD59G4aA5PDVGApsE9Y/xxrW1seroufS\r\n5OJxnbaAkAxNt12suJxQP8wIA5N8oDhr0gxJ+OopJXezED7WQPzehdVIgn3V\r\ngiwW4JxvPEphGAZzLdmjWOetZeh1qHyTcPCnxU5az7TOvcgbRwWRfBbsCflZ\r\nBF8BkrkwYSwJl3/anYst8oPDxqLDN3gg2yhGmPwulZHWi1kyg593Ny2lviy2\r\nfmBABbhcousS2IIiGdu+//LV/30hAXcecyoPDg5OMZHAlb/WNn9zGNMC//W2\r\nbraySszwIGTBchCLNJ/3GGEz7+3lvF9TXca2PLc9VUcF6RLYmcCVwI3SIpLr\r\nvBdZdfLV3ZCi3IspPIDqALos0S0+Ou2T2Dgb6rsSQPN4/tp/jfXAwj74tS6R\r\nnzmU5VHIwrZhYykPk2jFhDDH9dItmCjWBF0FFvHGKoN++zQC7wEWM0f2G+OL\r\nMnoJ6zmn+3pPDml+EU7L2oL/wLNmPlMTQRhbyAd3Lgek1nEw349R97UKCAb1\r\npC0168IkX1/el7BaJbgJq0NJ+UjGPXjy7FU=\r\n=UIgJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.0.0-empty_1657894306398_0.2702801957004941"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.0.1":{"name":"mocaron","version":"0.0.1","exports":{"default":"./dist/index.js","types":"./dist/index.d.ts"},"main":"./dist/index.js","types":"./dist/index.d.ts","license":"MIT","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"scripts":{"typecheck":"tsc","format":"prettier -w --ignore-path=.gitignore .","format:check":"prettier -c --ignore-path=.gitignore .","build":"rimraf dist && tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"dependencies":{"express":"^4.18.1"},"devDependencies":{"@types/express":"^4.17.13","prettier":"^2.7.1","rimraf":"^3.0.2","typescript":"^4.7.4"},"gitHead":"d9b2c0aa2798a92d97de224a464165d12906c0b3","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.0.1","_nodeVersion":"16.13.0","_npmVersion":"8.4.0","dist":{"integrity":"sha512-03Gh47ouNMNZAmfIlWlfzLLSz3/vNM3wp/ZVWiHwSmOawM+E7dOYr5Uw5985UEw6l4vj9iFlwcgVntjPDXlDPA==","shasum":"0f00c0d55485a660213ba5ecd760b95a5cd983bf","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.0.1.tgz","fileCount":4,"unpackedSize":13037,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG7JF87ULvmTE8iwgWh3rU3q1iVnN9BsV8mqcsHOjDgjAiB5nNhTfEJjfBGVbNv5Ck9Bvqp0G6H55lk92uuTpJc+CA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2Y8DACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmovwRAAm2QDyeDWxMvNDRtHJMBtS9Ge/xRNGRQBnkbamvuDCwNjMH9p\r\n0sRixUGll9qchW1H5XylMGTpeBy/RHXmKK4Lk0sfcAWWNZqhFAqiW+LUwSsJ\r\nHKSdvh8+jzdAFkGNXLB7Sj0sHYV+Jm/tIWmOBIbIhZuFqDm0NAn8DJ+muDmY\r\n265tPnwTWFoY59M969qR4l1CsQlmuxVpsQ/xGaJJGZGy5UDraxhuPeqfLue8\r\n+E0tvImvnozHNPkEyVCf8jYmOJ7GKMxHwD6PovgNV1MbNYfDZhs7mWE2UpC4\r\nyDyeVJDKVRQBZvEB3sOGbhVNpmnLwnFuIacjuFN7WijY43P9VZqIWAKTzSxj\r\nqrk2UVDnCo2J3f2gQHIpzDdG5zogKHsMz+Ul5lrugRsm+TuyM+/binCdFSbW\r\n4LkibYOMQROUq6Ygx0C8o9OGZnWAcd0ebQ7HRWgbKXNAfh0lvtlzibKb2/e3\r\nZIArsi36qOPUP6tRNKd6/sO5U6vZTbf3D8HaySdv0KVvwR7TC2i60AdCbPC8\r\nutfKVvo2j1K9TRCqnKq4HGB64hf46m6HGkzC9d8CDwClsEbZy0FEd94Vj+tb\r\npAWB7RIrGYc76vhsIoT0HJ36WuSawvyqI8JL+Qq3B/yjdo4S2KfkCt3dkQkp\r\nacbEsYAi7ViJsQA1sbt6Jjo5gtG2UPC499s=\r\n=eo0C\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.0.1_1658425091474_0.47785658401284525"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.0.2":{"name":"mocaron","version":"0.0.2","exports":{"default":"./dist/index.js","types":"./dist/index.d.ts"},"main":"./dist/index.js","types":"./dist/index.d.ts","license":"MIT","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"scripts":{"typecheck":"tsc","format":"prettier -w --ignore-path=.gitignore .","format:check":"prettier -c --ignore-path=.gitignore .","build":"rimraf dist && tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"dependencies":{"body-parser":"^1.20.0","deep-equal":"^2.0.5","express":"^4.18.1"},"devDependencies":{"@types/deep-equal":"^1.0.1","@types/express":"^4.17.13","prettier":"^2.7.1","rimraf":"^3.0.2","typescript":"^4.7.4"},"gitHead":"3d5c5cdea2050e441fceab89f95d82fb54168943","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.0.2","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-XBt23DO7366HnE4CXtvQF0RMKS+RWWm3V+7GXA2WNj4uRywdEgUqa/F62RSsPX8Ie2yEtN4KVIVWCZXbVD4lNw==","shasum":"2400a0f018719ae0172f3b08cfe7a7a680563bbf","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.0.2.tgz","fileCount":4,"unpackedSize":13472,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAvpFZoqVFG4Zzk0tVqOhkaY/J/3xb/NrwuiTVkBAtbjAiEA//38fp0I9JNApBH8Da46/gPQTKQbnum7WpCY/aIgACM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2mh+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqwpRAAo+ifjtFipNqpgW/PJqPeqgExU2rYWa+ai6HtJKUMS2HQ5VA1\r\ns6W2M7ONOTIRsDFyRWeAjJ0IKa8q2n2sVcZ2N9u7Z11+V9hCptjZ85ZNHD1A\r\n5zUVHRN6eFk8PEnXJcs4AqiCxx3YuWrF0Nq67zIMo2Nl7NAdqRT2LMhCOjBQ\r\n6pCWVBwQA4mksDV5Tl6mpIH+rhNyCqDWprCQGa/eMaBlQdsMSeatYFYxlY6q\r\n5a47CUOiHHPTNAyybw2vI3MaIbqbSn1VoZ7rmx50zkek04vBOCSNezGkqxob\r\n8EzSrNbOauTkdQvmZ/zgLdgNIsa9jig8o/XMF/ohXGD1YZvZKIM+unP2qEUc\r\nFqSwJ19TUi/cMQPVHHE2N70GCZeRsom83jiqCL6Aoe81nkY+zLmWTSO7ezxU\r\nSJIIHcK80DbDgiFP3JYze0QWiUu45tnAjWaORzRyonPZhVJzzs4ZvxQGv9DO\r\nmHE03bpKBN2YpcQbuSM/04jjHHU9DRDVSD1u0hgjrDB6w2S/N4dmVs8Hah5u\r\n+BKolQ9z4EC9WLyKbu/PRSmFvZHp2KcK/qUCqlyLv/Ijn7fu+jCK+nYABXmr\r\nrdS5PQGSd0VeO9I4CakNzVBdhuskGYh0Ci41xifJv1HYnQB8RSsg7QCpV43v\r\nMoThE2Q+n3LABI6zOuyouHE+qzrXUdAl1Qw=\r\n=dfMS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.0.2_1658480765964_0.6352525816737407"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.0.3-alpha.0":{"name":"mocaron","version":"0.0.3-alpha.0","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc tsx test.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.45.0","eslint-config-prettier":"^8.8.0","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","tsx":"^3.12.7","typescript":"^5.1.6"},"gitHead":"36692db6c658374471ee5a8bf24446aa64cb37c7","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"readme":"ERROR: No README data found!","homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.0.3-alpha.0","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-lNFA9KylfHRkEbgb0RBlNpf4a1R/LJ3LvdrewD2lcUNanpcED4mCtQ9BVo8gw1uVC51lLTWsVhHjBDrjKna1WA==","shasum":"c55242e14cb5cc3f68b243c363e8edaaef9da73b","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.0.3-alpha.0.tgz","fileCount":5,"unpackedSize":13771,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAER1pEXcdHb9VY5E9wvYBMIp/2WMMlT+KnbRXxzFvFgIgGyBH7aE4+TPF4W0bfhk2B+Xilv3eqNSN0kwmiY7ZqBw="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.0.3-alpha.0_1690446133074_0.3408314330463076"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.0.3-alpha.1":{"name":"mocaron","version":"0.0.3-alpha.1","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc tsx test.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.45.0","eslint-config-prettier":"^8.8.0","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","tsx":"^3.12.7","typescript":"^5.1.6"},"gitHead":"36692db6c658374471ee5a8bf24446aa64cb37c7","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"readme":"ERROR: No README data found!","homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.0.3-alpha.1","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-/E8xLcmriqVgjj6KmZ4C4Wr85tIDPVBmTh/jVEkVlwqRXglU4WN1F7B9LWwNKxJx49wuwlh4VqUYj1Pyp1i+rQ==","shasum":"b08a9737490d6c3cebfe54d76e4341d68fc36cf2","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.0.3-alpha.1.tgz","fileCount":5,"unpackedSize":14131,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDlFvfXer49UQw8FdSQXpPR8AouvdM29C2oBAhN/iA+ugIgLLf1EWP99TiJmAa4ywUmnerwsusAT1jHykrmYBHdAMo="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.0.3-alpha.1_1690446305402_0.846364237425024"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.0":{"name":"mocaron","version":"0.1.0-beta.0","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"readme":"<p align=\"center\">\n  <img src=\"./logo.png\" alt=\"mocaron\"/>\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"Downloads\"/>\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\"/>\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\"/>\n  </a>\n</p>\n\nMocaron (pronounced _moh-kah-rohn_) is a configurable mock server for easy use during testing and development.\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"c5d4e625c9b7e58a020f20a512148b40b671daa1","description":"<p align=\"center\">   <img src=\"./logo.png\" alt=\"mocaron\"/>   <a href=\"https://npmjs.com/package/mocaron\">     <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"Downloads\"/>   </a>     <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">     <img ","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.1.0-beta.0","_nodeVersion":"20.2.0","_npmVersion":"9.1.2","dist":{"integrity":"sha512-m7d8C9MQ7NmaZTT2f716wA4biMZqm40pEYGpMpoFucd4+rECWRrvqLb1Z8wQ43XawWgNHl0nG7r3/ity9i16gA==","shasum":"ea4b4b7987210c2c0523c40dcef3400f2f6a0902","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.0.tgz","fileCount":12,"unpackedSize":17465,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFGAqm97Cp3K6yjFbi2zcMFHdFuF8Zp//N0gqZIMYubsAiAKXBPa2TrzsTavbDhfNdGXsY9HxSq1YMxAirsLI/tQ7A=="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.0_1690629606279_0.033442081582230054"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.1":{"name":"mocaron","version":"0.1.0-beta.1","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"readme":"<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/c5d4e625c9b7e58a020f20a512148b40b671daa1/logo.png\" alt=\"mocaron\"/>\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"Downloads\"/>\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\"/>\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\"/>\n  </a>\n</p>\n\nMocaron (pronounced _moh-kah-rohn_) is a configurable mock server for easy use during testing and development.\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"c5d4e625c9b7e58a020f20a512148b40b671daa1","description":"<p align=\"center\">   <img src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/c5d4e625c9b7e58a020f20a512148b40b671daa1/logo.png\" alt=\"mocaron\"/>   <a href=\"https://npmjs.com/package/mocaron\">     <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_id":"mocaron@0.1.0-beta.1","_nodeVersion":"20.2.0","_npmVersion":"9.1.2","dist":{"integrity":"sha512-UcYcBYbgK9dEki6/6OEe6/79+iI+x7N9jBrUbF022wQ1wvf5n1w1760TfjbfZyH2CxFRG4ty4M4HcA9GsyO0mg==","shasum":"7e149ed49d851272cfc3d53f3f689f53b63c07c1","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.1.tgz","fileCount":12,"unpackedSize":17557,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiEgTUkY/NWVzVhrOZjC8LL6Kt/9a+tAGcGws62aCkogIhAMHbrqb1dVANwmg8QkPH3IguoPvmnFepyE/sFBj5cD/l"}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.1_1690629746281_0.5423102771384736"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.2":{"name":"mocaron","version":"0.1.0-beta.2","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.2","readme":"<p align=\"center\">\n  <img width=\"80%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with an API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>.\n</p>\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# API\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreates a new `MockServer` instance.\ng\n| Param   | Type      | Description    |\n| ------- | --------- | -------------- |\n| options | `Options` | options to use |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n### `start(): Promise<void>`\n\nStarts the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n### `stop(): Promise<void>`\n\nStops the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n### `get(matcher, response): MockServer`\n\nRegister a mock for requests with method `GET`.\n\nReturns the `MockServer` instance.\n\n| Param    | Type                                             | Description     |\n| -------- | ------------------------------------------------ | --------------- |\n| matcher  | `string \\| RegExp \\| Omit<MatcherObj, \"method\">` | options to use  |\n| response | `string \\| number \\| Response`                   | response to use |\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n### `post(matcher, response): MockServer`\n\nRegister a mock for requests with method `POST`.\n\nReturns the `MockServer` instance.\n\n| Param    | Type                                             | Description     |\n| -------- | ------------------------------------------------ | --------------- |\n| matcher  | `string \\| RegExp \\| Omit<MatcherObj, \"method\">` | options to use  |\n| response | `string \\| number \\| Response`                   | response to use |\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", { status: 201, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hi\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n### `patch(matcher, response): MockServer`\n\nRegister a mock for requests with method `PATCH`.\n\nReturns the `MockServer` instance.\n\n| Param    | Type                                             | Description     |\n| -------- | ------------------------------------------------ | --------------- |\n| matcher  | `string \\| RegExp \\| Omit<MatcherObj, \"method\">` | options to use  |\n| response | `string \\| number \\| Response`                   | response to use |\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n### `delete(matcher, response): MockServer`\n\nRegister a mock for requests with method `DELETE`.\n\nReturns the `MockServer` instance.\n\n| Param    | Type                                             | Description     |\n| -------- | ------------------------------------------------ | --------------- |\n| matcher  | `string \\| RegExp \\| Omit<MatcherObj, \"method\">` | options to use  |\n| response | `string \\| number \\| Response`                   | response to use |\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n### `mock(matcher, response, options): MockServer`\n\n### `hasBeenCalledWith(matcher: Matcher): boolean`\n\nReturns `true` if the route has been called with the given `path` and `method`.\n\n### `hasBeenCalledTimes(times: number, matcher: Matcher): boolean`\n\nReturns `true` if the route has been called `times` times with the given `matcher`.\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"b826936de6e5d472ffa86a2c6717c94cd4b99cda","description":"<p align=\"center\">   <img width=\"80%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />   <br />   <br />   <a href=\"https://npmjs.com/package/mocaron\">     <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm ","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-5rV6ii4hXyEUdv7MpSSr/zxyNdguM/wlT6hd+BH4pq7T7is4Ndjdf5yzQLxjBrV1Vv4ZU1BxJEkCoELsIwu3bg==","shasum":"2b9c50828b0ac1abe55838975547be1f447480c1","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.2.tgz","fileCount":12,"unpackedSize":29245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID5ZibCjomRXY8Jt7Q2O4IkSYmPWLo1Q0MYyEHJwttxVAiEAjJuof6ERGzrSyDytqzR/D62t8cOwyQ75Iz96SSR0MvQ="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.2_1690644068057_0.07616415692358203"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.3":{"name":"mocaron","version":"0.1.0-beta.3","description":"Simple express mock server with an API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.3","readme":"<p align=\"center\">\n  <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with an API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`Options`](#options)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreates a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStarts the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStops the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | [`Matcher`](#matcher)                           | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks); // [{ matcher: \"/test\", response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\", request: <express.Request> } }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| times   | `number`              | -       |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: \"/test\", response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ path: \"/test\", method: \"GET\", request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `Options`\n\nobject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nobject with the following properties:\n\n| Property | Type                                                                                        | Description                       |\n| -------- | ------------------------------------------------------------------------------------------- | --------------------------------- |\n| method   | `string` \\| `undefined`                                                                     | http method to match against      |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                         | path to match against             |\n| query    | [`express.Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                        | headers to match against          |\n| body     | `string` \\| `object` \\| `undefined`                                                         | body to match against             |\n\n## `MatcherFn`\n\nA function that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: express.Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nobject with the following properties:\n\n| Property | Type                                    | Description                 |\n| -------- | --------------------------------------- | --------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with     |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with        |\n\n## `ResponseFn`\n\nA function that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns an [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: express.Request) => ResponseObj;\n```\n\n## `MockOptions`\n\nobject with the following properties:\n\n| Property  | Type                     | Description                                                                          |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous mocks matching the same request will be overwritten |\n\n## `Mock`\n\nobject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nobject with the following properties:\n\n| Property | Type                                                          | Description                         |\n| -------- | ------------------------------------------------------------- | ----------------------------------- |\n| request  | [`express.Request`](https://expressjs.com/en/4x/api.html#req) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher)                                         | matcher thr request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"5eda61ff13cd5a16c26d3dc79bfc6d71a3f169f7","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-WxbeuF9T37kX2oPCnz1jrar67c6weExNu9TDBD69cbzl+jkIyxhDXK364W7ELGpXcrK27cei6lMegENGcP8ohw==","shasum":"e27c72e60cf0a13ea58af3102c92c944b8fe7a0b","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.3.tgz","fileCount":12,"unpackedSize":32032,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIQCN/LuOQWwR7hxEdml7uyxjY2KpaN1Wv9s3i4sUnoAZ6gIeHbQsBNujn4xvWh9CclVxxpjZaUftFaaKwXf1gMt7"}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.3_1690667797281_0.048973199034396675"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.4":{"name":"mocaron","version":"0.1.0-beta.4","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","coverage":"mkdir -p coverage && touch coverage/lcov.info && nyc report --reporter=text-lcov > coverage/lcov.info","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.4","readme":"<p align=\"center\">\n  <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`Options`](#options)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreates a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStarts the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStops the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | [`Matcher`](#matcher)                           | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the http `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks); // [{ matcher: \"/test\", response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\", request: <express.Request> } }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| times   | `number`              | -       |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: \"/test\", response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ path: \"/test\", method: \"GET\", request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `Options`\n\nobject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nobject with the following properties:\n\n| Property | Type                                                                                        | Description                       |\n| -------- | ------------------------------------------------------------------------------------------- | --------------------------------- |\n| method   | `string` \\| `undefined`                                                                     | http method to match against      |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                         | path to match against             |\n| query    | [`express.Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                        | headers to match against          |\n| body     | `string` \\| `object` \\| `undefined`                                                         | body to match against             |\n\n## `MatcherFn`\n\nA function that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: express.Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nobject with the following properties:\n\n| Property | Type                                    | Description                 |\n| -------- | --------------------------------------- | --------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with     |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with        |\n\n## `ResponseFn`\n\nA function that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns an [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: express.Request) => ResponseObj;\n```\n\n## `MockOptions`\n\nobject with the following properties:\n\n| Property  | Type                     | Description                                                                          |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous mocks matching the same request will be overwritten |\n\n## `Mock`\n\nobject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nobject with the following properties:\n\n| Property | Type                                                          | Description                         |\n| -------- | ------------------------------------------------------------- | ----------------------------------- |\n| request  | [`express.Request`](https://expressjs.com/en/4x/api.html#req) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher)                                         | matcher thr request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"374476616e3633c04a54a6f9d40929097d6a7203","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-/V6pAW+PauoIMC/XKoG+DPGeeUwYY111gRWC1C/z77UyQMgr+Q1Q2uWoOZ92iinu/NC8M6BFd3BQF5dRqefedg==","shasum":"005f2d552361925823c06ee55d5a0c6c173bb1a7","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.4.tgz","fileCount":12,"unpackedSize":32066,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFiJSPR8T0mapuHebN/Dmiako7dKWJD0g2FRk5t7tAvxAiEA1T5OOYT4oyTUpusYGJQaWcX255sT41eB3YKsn8yzV48="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.4_1690668272488_0.5762900226475476"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.5":{"name":"mocaron","version":"0.1.0-beta.5","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.5","readme":"<p align=\"center\">\n  <a href=\"https://github.com/joshuajaco/mocaron\">\n    <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  </a>\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n## Starting and stopping the mock server\n\nSee [`constructor()`](#constructoroptions-mockserver) [`start()`](#start-promisevoid) [`stop()`](#stop-promisevoid)\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\n// ...\n\nawait mockServer.stop();\n```\n\n## Registering a mock\n\nRegister a mock using [`mock()`](#mockmatcher-response-options-mockserver).\n\n```ts\nmockServer.mock(\n  { path: \"/test\", method: \"GET\" },\n  { status: 200, body: { message: \"Hello World\" } },\n);\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n## Method specific mocks\n\nYou can also register mocks that only match a specific HTTP method.\n\nSee [`get()`](#getmatcher-response-options-mockserver) [`post()`](#postmatcher-response-options-mockserver) [`patch()`](#patchmatcher-response-options-mockserver) [`delete()`](#deletematcher-response-options-mockserver)\n\n```ts\nmockServer\n  .get(\"/test\", { status: 200, body: { message: \"Hello World\" } })\n  .post(\"/test\", { status: 201, body: { message: \"Created\" } })\n  .patch(\"/test\", { status: 200, body: { message: \"Updated\" } })\n  .delete(\"/test\", { status: 204 });\n```\n\n## Unmatched requests\n\nIf a request does not match any of the registered mocks the server will respond with a 404 status code.\n\n```ts\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 404\n```\n\n## Ambiguous mocks\n\nIf two or more mocks match the same request the server will respond with a 404 status code.\n\n```ts\nmockServer.mock({ path: \"/foo\" }, \"foo\").mock({ path: \"/foo\" }, \"bar\");\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 404\n```\n\nYou can override this behavior by passing the [`overwrite`](#mockoptions) option to the last matching mock.\n\n```ts\nmockServer\n  .mock({ path: \"/foo\" }, \"foo\")\n  .mock({ path: \"/foo\" }, \"bar\", { overwrite: true });\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.text()); // bar\n```\n\n## Resetting the mock server\n\nCalling [`reset()`](#reset-void) will reset the mock server to its initial state.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nlet response = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 200\n\nmockServer.reset();\n\nresponse = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 404\n```\n\n## Testing\n\nSet up the mock server for each test using [`start()`](#start-promisevoid), [`stop()`](#stop-promisevoid) and [`reset()`](#reset-void).\n\n```ts\nimport { MockServer } from \"mocaron\";\nimport { beforeAll, afterAll, beforeEach, test, assert } from \"my-test-library\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nbeforeAll(() => mockServer.start());\nafterAll(() => mockServer.stop());\nbeforeEach(() => mockServer.reset());\n```\n\nTest that a mock has been called using [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n```ts\ntest(\"mock has been called\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledWith({ path: \"/test\" }));\n});\n```\n\nTest that a mock has been called a specific number of times using [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n```ts\ntest(\"mock has been called 3 times\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledTimes(3, { path: \"/test\" }));\n});\n```\n\nCustom assertions using [`calls()`](#calls-readonly-call).\n\n```ts\ntest(\"custom assertion\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.calls().length === 1);\n  assert(mockServer.calls()[0].request.path === \"/test\");\n});\n```\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`Options`](#options)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreate a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStart the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStop the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | [`Matcher`](#matcher)                           | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks);\n// [{ matcher: { path: \"/test\" }, response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\" }, request: <express.Request> }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| times   | `number`              | -       |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `Options`\n\nObject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nObject with the following properties:\n\n| Property | Type                                                                                        | Description                                                                                                   |\n| -------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| method   | `string` \\| `undefined`                                                                     | HTTP method to match against                                                                                  |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                         | path to match against                                                                                         |\n| query    | [`express.Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against.<br/>Parameters explicitly set to `undefined` will not match when provided. |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                        | headers to match against.<br/>Headers explicitly set to `undefined` will not match when provided.             |\n| body     | `string` \\| `object` \\| `undefined`                                                         | body to match against.<br/>If an `object` is given it will be compared to the request body parsed as JSON.    |\n\n## `MatcherFn`\n\nFunction that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: express.Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nObject with the following properties:\n\n| Property | Type                                    | Description                                                                              |\n| -------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with (defaults to `200`)                                          |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with                                                                  |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with.<br/>If an `object` is given it will be converted to a JSON string. |\n\n## `ResponseFn`\n\nFunction that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns a [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: express.Request) => ResponseObj;\n```\n\n## `MockOptions`\n\nObject with the following properties:\n\n| Property  | Type                     | Description                                                                                                        |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous [ambiguous mocks](#ambiguous-mocks) matching the same request will be overwritten |\n\n## `Mock`\n\nObject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nObject with the following properties:\n\n| Property | Type                                                          | Description                         |\n| -------- | ------------------------------------------------------------- | ----------------------------------- |\n| request  | [`express.Request`](https://expressjs.com/en/4x/api.html#req) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher)                                         | matcher the request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"d30240c39a7f59d5b62c4598419844f36385e30e","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-nlX1hX+tTQD131S3Gwv4CSwv19DVtF7pzaaEXnWnPQCKQwdt5LWEta2sjfOObJxx5luw/fiOVZfspMv7k6EfAQ==","shasum":"83a2401a786d96b202ae8bd16fa4a6eb65e0eaef","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.5.tgz","fileCount":12,"unpackedSize":56559,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1+t9qIzm2pmojCyb+89UZ+WvxjKYaVevfJX1f/XLXuwIgYCnXTUcWVMAnl2aQVewfrPBYSjdZgLKTwx22ma5tc0g="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.5_1690735344990_0.5689203734711588"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.6":{"name":"mocaron","version":"0.1.0-beta.6","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.6","readme":"<p align=\"center\">\n  <a href=\"https://github.com/joshuajaco/mocaron\">\n    <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  </a>\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n## Starting and stopping the mock server\n\nSee [`constructor()`](#constructoroptions-mockserver) [`start()`](#start-promisevoid) [`stop()`](#stop-promisevoid)\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\n// ...\n\nawait mockServer.stop();\n```\n\n## Registering a mock\n\nRegister a mock using [`mock()`](#mockmatcher-response-options-mockserver).\n\n```ts\nmockServer.mock(\n  { path: \"/test\", method: \"GET\" },\n  { status: 200, body: { message: \"Hello World\" } },\n);\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n## Method specific mocks\n\nYou can also register mocks that only match a specific HTTP method.\n\nSee [`get()`](#getmatcher-response-options-mockserver) [`post()`](#postmatcher-response-options-mockserver) [`patch()`](#patchmatcher-response-options-mockserver) [`delete()`](#deletematcher-response-options-mockserver)\n\n```ts\nmockServer\n  .get(\"/test\", { status: 200, body: { message: \"Hello World\" } })\n  .post(\"/test\", { status: 201, body: { message: \"Created\" } })\n  .patch(\"/test\", { status: 200, body: { message: \"Updated\" } })\n  .delete(\"/test\", { status: 204 });\n```\n\n## Unmatched requests\n\nIf a request does not match any of the registered mocks the server will respond with a 404 status code.\n\n```ts\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 404\n```\n\n## Ambiguous mocks\n\nIf two or more mocks match the same request the server will respond with a 404 status code.\n\n```ts\nmockServer.mock({ path: \"/foo\" }, \"foo\").mock({ path: \"/foo\" }, \"bar\");\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 404\n```\n\nYou can override this behavior by passing the [`overwrite`](#mockoptions) option to the last matching mock.\n\n```ts\nmockServer\n  .mock({ path: \"/foo\" }, \"foo\")\n  .mock({ path: \"/foo\" }, \"bar\", { overwrite: true });\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.text()); // bar\n```\n\n## Resetting the mock server\n\nCalling [`reset()`](#reset-void) will reset the mock server to its initial state.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nlet response = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 200\n\nmockServer.reset();\n\nresponse = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 404\n```\n\n## Testing\n\nSet up the mock server for each test using [`start()`](#start-promisevoid), [`stop()`](#stop-promisevoid) and [`reset()`](#reset-void).\n\n```ts\nimport { MockServer } from \"mocaron\";\nimport { beforeAll, afterAll, beforeEach, test, assert } from \"my-test-library\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nbeforeAll(() => mockServer.start());\nafterAll(() => mockServer.stop());\nbeforeEach(() => mockServer.reset());\n```\n\nTest that a mock has been called using [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n```ts\ntest(\"mock has been called\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledWith({ path: \"/test\" }));\n});\n```\n\nTest that a mock has been called a specific number of times using [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n```ts\ntest(\"mock has been called 3 times\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledTimes(3, { path: \"/test\" }));\n});\n```\n\nCustom assertions using [`calls()`](#calls-readonly-call).\n\n```ts\ntest(\"custom assertion\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.calls().length === 1);\n  assert(mockServer.calls()[0].request.path === \"/test\");\n});\n```\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`Options`](#options)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreate a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStart the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStop the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | [`Matcher`](#matcher)                           | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks);\n// [{ matcher: { path: \"/test\" }, response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\" }, request: <express.Request> }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| times   | `number`              | -       |\n| matcher | [`Matcher`](#matcher) | -       |\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `Options`\n\nObject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nObject with the following properties:\n\n| Property | Type                                                                                        | Description                                                                                                   |\n| -------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| method   | `string` \\| `undefined`                                                                     | HTTP method to match against                                                                                  |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                         | path to match against                                                                                         |\n| query    | [`express.Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against.<br/>Parameters explicitly set to `undefined` will not match when provided. |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                        | headers to match against.<br/>Headers explicitly set to `undefined` will not match when provided.             |\n| body     | `string` \\| `object` \\| `undefined`                                                         | body to match against.<br/>If an `object` is given it will be compared to the request body parsed as JSON.    |\n\n## `MatcherFn`\n\nFunction that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: express.Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nObject with the following properties:\n\n| Property | Type                                    | Description                                                                              |\n| -------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with (defaults to `200`)                                          |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with                                                                  |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with.<br/>If an `object` is given it will be converted to a JSON string. |\n\n## `ResponseFn`\n\nFunction that takes an [`express.Request`](https://expressjs.com/en/4x/api.html#req) and returns a [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: express.Request) => ResponseObj;\n```\n\n## `MockOptions`\n\nObject with the following properties:\n\n| Property  | Type                     | Description                                                                                                        |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous [ambiguous mocks](#ambiguous-mocks) matching the same request will be overwritten |\n\n## `Mock`\n\nObject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nObject with the following properties:\n\n| Property | Type                                                          | Description                         |\n| -------- | ------------------------------------------------------------- | ----------------------------------- |\n| request  | [`express.Request`](https://expressjs.com/en/4x/api.html#req) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher)                                         | matcher the request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"6008b27e6c8dc57a4ea4034f37c390101226c8e8","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-GnubWLec0jviGV5rf8RKId7hNsE/5O+yRLCxFrb/Hf6hLhzMKf0PYh6Vz5Ss0ugzyTdwZouoRKcU8VTghkujXA==","shasum":"1391646c578695b51c46b62b0865935b91403c45","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.6.tgz","fileCount":12,"unpackedSize":55267,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEaQoaG3gsoFioC3SM2V0quUehsxUthsNZv6Yiv0ZxCHAiEA04ac7yJF0MeJARIR/OuB7TZWm8PadbqH/Zio6Xd0Rik="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.6_1690743463394_0.9806578064926992"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.1.0-beta.7":{"name":"mocaron","version":"0.1.0-beta.7","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.1.0-beta.7","readme":"<p align=\"center\">\n  <a href=\"https://github.com/joshuajaco/mocaron\">\n    <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  </a>\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n## Starting and stopping the mock server\n\nSee [`constructor()`](#constructoroptions-mockserver) [`start()`](#start-promisevoid) [`stop()`](#stop-promisevoid)\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\n// ...\n\nawait mockServer.stop();\n```\n\n## Registering a mock\n\nRegister a mock using [`mock()`](#mockmatcher-response-options-mockserver).\n\n```ts\nmockServer.mock(\n  { path: \"/test\", method: \"GET\" },\n  { status: 200, body: { message: \"Hello World\" } },\n);\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n## Method specific mocks\n\nYou can also register mocks that only match a specific HTTP method.\n\nSee [`get()`](#getmatcher-response-options-mockserver) [`post()`](#postmatcher-response-options-mockserver) [`put()`](#putmatcher-response-options-mockserver) [`patch()`](#patchmatcher-response-options-mockserver) [`delete()`](#deletematcher-response-options-mockserver)\n\n```ts\nmockServer\n  .get(\"/test\", { status: 200, body: { message: \"Hello World\" } })\n  .post(\"/test\", { status: 201, body: { message: \"Created\" } })\n  .put(\"/test\", { status: 200, body: { message: \"Replaced\" } })\n  .patch(\"/test\", { status: 200, body: { message: \"Updated\" } })\n  .delete(\"/test\", { status: 204 });\n```\n\n## Unmatched requests\n\nIf a request does not match any of the registered mocks the server will respond with a 404 status code.\n\n```ts\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 404\n```\n\n## Ambiguous mocks\n\nIf two or more mocks match the same request the server will respond with a 404 status code.\n\n```ts\nmockServer.mock({ path: \"/foo\" }, \"foo\").mock({ path: \"/foo\" }, \"bar\");\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 404\n```\n\nYou can override this behavior by passing the [`overwrite`](#mockoptions) option to the last matching mock.\n\n```ts\nmockServer\n  .mock({ path: \"/foo\" }, \"foo\")\n  .mock({ path: \"/foo\" }, \"bar\", { overwrite: true });\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.text()); // bar\n```\n\n## Resetting the mock server\n\nCalling [`reset()`](#reset-void) will reset the mock server to its initial state.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nlet response = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 200\n\nmockServer.reset();\n\nresponse = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 404\n```\n\n## Testing\n\nSet up the mock server for each test using [`start()`](#start-promisevoid), [`stop()`](#stop-promisevoid) and [`reset()`](#reset-void).\n\n```ts\nimport { MockServer } from \"mocaron\";\nimport { beforeAll, afterAll, beforeEach, test, assert } from \"my-test-library\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nbeforeAll(() => mockServer.start());\nafterAll(() => mockServer.stop());\nbeforeEach(() => mockServer.reset());\n```\n\nTest that a mock has been called using [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n```ts\ntest(\"mock has been called\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledWith({ path: \"/test\" }));\n});\n```\n\nTest that a mock has been called a specific number of times using [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n```ts\ntest(\"mock has been called 3 times\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledTimes(3, { path: \"/test\" }));\n});\n```\n\nCustom assertions using [`calls()`](#calls-readonly-call).\n\n```ts\ntest(\"custom assertion\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.calls().length === 1);\n  assert(mockServer.calls()[0].request.path === \"/test\");\n});\n```\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`put()`](#putmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`Options`](#options)\n- [`Request`](#request)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreate a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStart the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStop the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`Matcher`](#matcher)   | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `put(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PUT` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.put(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PUT\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks);\n// [{ matcher: { path: \"/test\" }, response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\" }, request: <express.Request> }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| times   | `number`                                      | -       |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `Options`\n\nObject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Request`\n\nType alias for [`express.Request`](https://expressjs.com/en/4x/api.html#req) with the `body` property typed as `Buffer` | `undefined`.\n\n```ts\ntype Request = express.Request<{}, unknown, Buffer | undefined>;\n```\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nObject with the following properties:\n\n| Property | Type                                                                                | Description                                                                                                   |\n| -------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| method   | `string` \\| `undefined`                                                             | HTTP method to match against                                                                                  |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                 | path to match against                                                                                         |\n| query    | [`Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against.<br/>Parameters explicitly set to `undefined` will not match when provided. |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                | headers to match against.<br/>Headers explicitly set to `undefined` will not match when provided.             |\n| body     | `string` \\| `object` \\| `undefined`                                                 | body to match against.<br/>If an `object` is given it will be compared to the request body parsed as JSON.    |\n\n## `MatcherFn`\n\nFunction that takes a [`Request`](#request) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nObject with the following properties:\n\n| Property | Type                                    | Description                                                                              |\n| -------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with (defaults to `200`)                                          |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with                                                                  |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with.<br/>If an `object` is given it will be converted to a JSON string. |\n\n## `ResponseFn`\n\nFunction that takes a [`Request`](#request) and returns a [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: Request) => ResponseObj;\n```\n\n## `MockOptions`\n\nObject with the following properties:\n\n| Property  | Type                     | Description                                                                                                        |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous [ambiguous mocks](#ambiguous-mocks) matching the same request will be overwritten |\n\n## `Mock`\n\nObject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nObject with the following properties:\n\n| Property | Type                  | Description                         |\n| -------- | --------------------- | ----------------------------------- |\n| request  | [`Request`](#request) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher) | matcher the request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"dc87a0d0076fe16ac0d7a2707a7d3633cbeaaa9b","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-KvaaTPh7k76McK/Ak6TOlnps6OP5FzQTRJXatEa0rtJY8qWOaOaGjVsC/WASRwcQfwIm7xb69wHc35AbnrxFrQ==","shasum":"2955451bb1a7a049539a5c381b07ab3a57f1ae1e","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.1.0-beta.7.tgz","fileCount":12,"unpackedSize":60921,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLLVJmB3n4+27ICjA4iZOO/cTrd+RTLzlmyZap1qUzaQIhAOzHpNnRg4L+TmzD49KYUVPTuYh83FyzOPNDPVpPTcMA"}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.1.0-beta.7_1690792180079_0.12544123846050037"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"0.3.0":{"name":"mocaron","version":"0.3.0","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@0.3.0","gitHead":"03a46a0f7ea3d3aebe6a76bdda07c5a216f3a9df","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-BbMVLVAv5VKd3Fx7cfwULeUcx2FWanGIRJFcTrlRtGe7aTETiZo2Fcigu7zEwI+v3cj88iluT5RGH948JuSaqw==","shasum":"46d40e940c6a096c108532c6e39271c71837eba6","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-0.3.0.tgz","fileCount":12,"unpackedSize":60914,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCnDCKPe8vx8IA7XXk4BybSYCvC4szOxK0nXSIbHRP41AIgIt/uTBNQEE38LWSMW032yYciQiesKbb+T+Dnak5Rerc="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_0.3.0_1690795555458_0.3100523436043612"},"_hasShrinkwrap":false,"deprecated":"Deprecated"},"1.0.0":{"name":"mocaron","version":"1.0.0","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test tests/run.ts","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.17","body-parser":"^1.20.2","deep-equal":"^2.2.2","express":"^4.18.2"},"devDependencies":{"@types/deep-equal":"^1.0.1","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0","eslint":"^8.46.0","eslint-config-prettier":"^8.9.0","get-port-please":"^3.0.1","node-mocks-http":"^1.12.2","nyc":"^15.1.0","prettier":"^3.0.0","rimraf":"^5.0.1","ts-node":"^10.9.1","typescript":"^5.1.6"},"_id":"mocaron@1.0.0","gitHead":"75f43b2afc457d86bca634c897ab58fe7fb65352","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"20.5.0","_npmVersion":"9.8.0","dist":{"integrity":"sha512-aCA29oV835sxzZEqjPLqrlLE2ZQ7ptrjzsZycVkwoiwBcx3K4WB7dxKRi40q6DWFi9MUDL3WAXWDUs2FjlVLJg==","shasum":"3b8161143610fbbd778963e78081bd0746b46f12","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-1.0.0.tgz","fileCount":12,"unpackedSize":60914,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAVMhsahS5GCIjUzJlrXTrW48hcxhrNoZr0Rkc22QPePAiEAsRyWuB80q5t+TeWJ3l1u8CRZYDk6bDTomQ+YCW+SJdg="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_1.0.0_1690795939847_0.8577146318193043"},"_hasShrinkwrap":false},"1.1.0-beta.0":{"name":"mocaron","version":"1.1.0-beta.0","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test \"**/*.test.ts\"","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.21","body-parser":"^1.20.2","deep-equal":"^2.2.3","express":"^4.19.2","jest-diff":"^29.7.0"},"devDependencies":{"@types/deep-equal":"^1.0.4","@typescript-eslint/eslint-plugin":"^7.7.0","@typescript-eslint/parser":"^7.7.0","eslint":"^8.57.0","eslint-config-prettier":"^9.1.0","get-port-please":"^3.1.2","node-mocks-http":"^1.14.1","nyc":"^15.1.0","prettier":"^3.2.5","rimraf":"^5.0.5","ts-node":"^10.9.2","typescript":"^5.4.5"},"_id":"mocaron@1.1.0-beta.0","readme":"<p align=\"center\">\n  <a href=\"https://github.com/joshuajaco/mocaron\">\n    <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  </a>\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n## Starting and stopping the mock server\n\nSee [`constructor()`](#constructoroptions-mockserver) [`start()`](#start-promisevoid) [`stop()`](#stop-promisevoid)\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\n// ...\n\nawait mockServer.stop();\n```\n\n## Registering a mock\n\nRegister a mock using [`mock()`](#mockmatcher-response-options-mockserver).\n\n```ts\nmockServer.mock(\n  { path: \"/test\", method: \"GET\" },\n  { status: 200, body: { message: \"Hello World\" } },\n);\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n## Method specific mocks\n\nYou can also register mocks that only match a specific HTTP method.\n\nSee [`get()`](#getmatcher-response-options-mockserver) [`post()`](#postmatcher-response-options-mockserver) [`put()`](#putmatcher-response-options-mockserver) [`patch()`](#patchmatcher-response-options-mockserver) [`delete()`](#deletematcher-response-options-mockserver)\n\n```ts\nmockServer\n  .get(\"/test\", { status: 200, body: { message: \"Hello World\" } })\n  .post(\"/test\", { status: 201, body: { message: \"Created\" } })\n  .put(\"/test\", { status: 200, body: { message: \"Replaced\" } })\n  .patch(\"/test\", { status: 200, body: { message: \"Updated\" } })\n  .delete(\"/test\", { status: 204 });\n```\n\n## Unmatched requests\n\nIf a request does not match any of the registered mocks the server will respond with a 404 status code.\n\n```ts\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 404\n```\n\n## Ambiguous mocks\n\nIf two or more mocks match the same request the server will respond with a 404 status code.\n\n```ts\nmockServer.mock({ path: \"/foo\" }, \"foo\").mock({ path: \"/foo\" }, \"bar\");\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 404\n```\n\nYou can override this behavior by passing the [`overwrite`](#mockoptions) option to the last matching mock.\n\n```ts\nmockServer\n  .mock({ path: \"/foo\" }, \"foo\")\n  .mock({ path: \"/foo\" }, \"bar\", { overwrite: true });\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.text()); // bar\n```\n\n## Resetting the mock server\n\nCalling [`reset()`](#reset-void) will reset the mock server to its initial state.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nlet response = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 200\n\nmockServer.reset();\n\nresponse = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 404\n```\n\n## Testing\n\nSet up the mock server for each test using [`start()`](#start-promisevoid), [`stop()`](#stop-promisevoid) and [`reset()`](#reset-void).\n\n```ts\nimport { MockServer } from \"mocaron\";\nimport { beforeAll, afterAll, beforeEach, test, assert } from \"my-test-library\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nbeforeAll(() => mockServer.start());\nafterAll(() => mockServer.stop());\nbeforeEach(() => mockServer.reset());\n```\n\nTest that a mock has been called using [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n```ts\ntest(\"mock has been called\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledWith({ path: \"/test\" }));\n});\n```\n\nTest that a mock has been called a specific number of times using [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n```ts\ntest(\"mock has been called 3 times\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledTimes(3, { path: \"/test\" }));\n});\n```\n\nCustom assertions using [`calls()`](#calls-readonly-call).\n\n```ts\ntest(\"custom assertion\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.calls().length === 1);\n  assert(mockServer.calls()[0].request.path === \"/test\");\n});\n```\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`put()`](#putmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`countCalls()`](#countcallsmatcher-number)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`ExpectationMessage`](#expectationmessage)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmockserver-matcher-string)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimesmockserver-times-matcher-string)\n- [`Options`](#options)\n- [`Request`](#request)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreate a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStart the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStop the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`Matcher`](#matcher)   | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `put(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PUT` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.put(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PUT\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks);\n// [{ matcher: { path: \"/test\" }, response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\" }, request: <express.Request> }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| times   | `number`                                      | -       |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `countCalls(matcher): number`\n\nCount the number of times the server was called with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns the number of times the server has been called with the given `matcher`.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.countCalls({ path: \"/test\" })); // 0\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.countCalls({ path: \"/test\" })); // 1\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `ExpectationMessage`\n\n### `hasBeenCalledWith(mockServer, matcher): string`\n\nFormat an expectation message for [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n| Param      | Type                        | Default |\n| ---------- | --------------------------- | ------- |\n| mockServer | [`MockServer`](#mockserver) | -       |\n| matcher    | [`Matcher`](#matcher)       | -       |\n\nReturns a string with the formatted expectation message.\n\n#### Example\n\n```ts\nif (!mockServer.hasBeenCalledWith(matcher)) {\n  throw new Error(ExpectationMessage.hasBeenCalledWith(mockServer, matcher));\n}\n```\n\n### `hasBeenCalledTimes(mockServer, times, matcher): string`\n\nFormat an expectation message for [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n| Param      | Type                        | Default |\n| ---------- | --------------------------- | ------- |\n| mockServer | [`MockServer`](#mockserver) | -       |\n| times      | number                      | -       |\n| matcher    | [`Matcher`](#matcher)       | -       |\n\nReturns a string with the formatted expectation message.\n\n#### Example\n\n```ts\nif (!mockServer.hasBeenCalledTimes(mockServer, 2, matcher)) {\n  throw new Error(\n    ExpectationMessage.hasBeenCalledTimes(mockServer, 2, matcher),\n  );\n}\n```\n\n## `Options`\n\nObject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Request`\n\nType alias for [`express.Request`](https://expressjs.com/en/4x/api.html#req) with the `body` property typed as `Buffer` | `undefined`.\n\n```ts\ntype Request = express.Request<{}, unknown, Buffer | undefined>;\n```\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nObject with the following properties:\n\n| Property | Type                                                                                | Description                                                                                                   |\n| -------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| method   | `string` \\| `undefined`                                                             | HTTP method to match against                                                                                  |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                 | path to match against                                                                                         |\n| query    | [`Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against.<br/>Parameters explicitly set to `undefined` will not match when provided. |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                | headers to match against.<br/>Headers explicitly set to `undefined` will not match when provided.             |\n| body     | `string` \\| `object` \\| `undefined`                                                 | body to match against.<br/>If an `object` is given it will be compared to the request body parsed as JSON.    |\n\n## `MatcherFn`\n\nFunction that takes a [`Request`](#request) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nObject with the following properties:\n\n| Property | Type                                    | Description                                                                              |\n| -------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with (defaults to `200`)                                          |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with                                                                  |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with.<br/>If an `object` is given it will be converted to a JSON string. |\n| delay    | `number` \\| `undefined`                 | delay in milliseconds before responding                                                  |\n\n## `ResponseFn`\n\nFunction or async function that takes a [`Request`](#request) and returns a [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: Request) => ResponseObj | Promise<ResponseObj>;\n```\n\n## `MockOptions`\n\nObject with the following properties:\n\n| Property  | Type                     | Description                                                                                                        |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous [ambiguous mocks](#ambiguous-mocks) matching the same request will be overwritten |\n\n## `Mock`\n\nObject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nObject with the following properties:\n\n| Property | Type                  | Description                         |\n| -------- | --------------------- | ----------------------------------- |\n| request  | [`Request`](#request) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher) | matcher the request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","gitHead":"6794e4223af7c9141be51c363da7584fffd7d2d9","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"21.7.3","_npmVersion":"10.5.0","dist":{"integrity":"sha512-pwVuiIWCvFFkKovGc/mWcU9icb6WstN3bHhq3fTXYH+bAPD6enBWL8LUH2DFYZnxeQF4r1XQ1w1oNVI0wRsqNw==","shasum":"95dda0538b8d6a334bde24f66bf0ba298691e1ac","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-1.1.0-beta.0.tgz","fileCount":15,"unpackedSize":75898,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBnuyrqW8lBkRyZ3wkGbwji86L1vKzf+BSO1nu8AFK9mAiEAwGLijHQV9qu0orFU5DeenuMj1yFV/cQ0KAE+SeuARG0="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_1.1.0-beta.0_1713444256863_0.27062660592518806"},"_hasShrinkwrap":false},"1.1.0":{"name":"mocaron","version":"1.1.0","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"],"repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"license":"MIT","exports":"./dist/index.js","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier -w .","format:check":"prettier -c .","lint":"eslint --ignore-path .gitignore --max-warnings 0 .","lint:fix":"npm run lint -- --fix","prepublishOnly":"npm run build","test":"nyc -r=lcov -r=text node --trace-warnings -r ts-node/register --test \"**/*.test.ts\"","typecheck":"tsc"},"dependencies":{"@types/express":"^4.17.21","body-parser":"^1.20.2","deep-equal":"^2.2.3","express":"^4.19.2","jest-diff":"^29.7.0"},"devDependencies":{"@types/deep-equal":"^1.0.4","@typescript-eslint/eslint-plugin":"^7.7.0","@typescript-eslint/parser":"^7.7.0","eslint":"^8.57.0","eslint-config-prettier":"^9.1.0","get-port-please":"^3.1.2","node-mocks-http":"^1.14.1","nyc":"^15.1.0","prettier":"^3.2.5","rimraf":"^5.0.5","ts-node":"^10.9.2","typescript":"^5.4.5"},"_id":"mocaron@1.1.0","gitHead":"86271c05e13643c2d129e7fd899c13bb53eee9d0","bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"homepage":"https://github.com/joshuajaco/mocaron#readme","_nodeVersion":"21.7.3","_npmVersion":"10.5.0","dist":{"integrity":"sha512-92qhosYIr6HdGhiYU3PUufpuVNZQfON8HylqlUy3QE+EIy0adv5nPz6/RBUdlIkR8LuKE5/c/IG5bmttXV/ZxA==","shasum":"28433c11577a83d73fc7aaeee4e8ac18aa1ec0c5","tarball":"https://registry.npmjs.org/mocaron/-/mocaron-1.1.0.tgz","fileCount":15,"unpackedSize":75891,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID1+FZwbJh3Asf4jpciqwshQlz3DucQ3vsNg6NYTP8IqAiBoqbCdhedcFAttsDmUyefqmgcwckq/KGHdb7XiLAUUpw=="}]},"_npmUser":{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"},"directories":{},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mocaron_1.1.0_1713445766314_0.9598133020534201"},"_hasShrinkwrap":false}},"time":{"created":"2022-07-15T14:11:46.398Z","0.0.0-empty":"2022-07-15T14:11:46.607Z","modified":"2024-04-18T13:09:26.685Z","0.0.1":"2022-07-21T17:38:11.677Z","0.0.2":"2022-07-22T09:06:06.153Z","0.0.3-alpha.0":"2023-07-27T08:22:13.255Z","0.0.3-alpha.1":"2023-07-27T08:25:05.574Z","0.1.0-beta.0":"2023-07-29T11:20:06.435Z","0.1.0-beta.1":"2023-07-29T11:22:26.433Z","0.1.0-beta.2":"2023-07-29T15:21:08.274Z","0.1.0-beta.3":"2023-07-29T21:56:37.444Z","0.1.0-beta.4":"2023-07-29T22:04:32.637Z","0.1.0-beta.5":"2023-07-30T16:42:25.184Z","0.1.0-beta.6":"2023-07-30T18:57:43.614Z","0.1.0-beta.7":"2023-07-31T08:29:40.278Z","0.3.0":"2023-07-31T09:25:55.678Z","1.0.0":"2023-07-31T09:32:20.038Z","1.1.0-beta.0":"2024-04-18T12:44:17.057Z","1.1.0":"2024-04-18T13:09:26.457Z"},"maintainers":[{"name":"joshuajaco","email":"joshua.jacobowitz@yahoo.de"}],"readme":"<p align=\"center\">\n  <a href=\"https://github.com/joshuajaco/mocaron\">\n    <img width=\"85%\" src=\"https://raw.githubusercontent.com/joshuajaco/mocaron/main/logo.png\" alt=\"mocaron\" />\n  </a>\n  <br />\n  <br />\n  <a href=\"https://npmjs.com/package/mocaron\">\n    <img src=\"https://img.shields.io/npm/dw/mocaron\" alt=\"npm downloads\" />\n  </a>  \n  <a href=\"https://coveralls.io/github/joshuajaco/mocaron\">\n    <img src=\"https://coveralls.io/repos/github/joshuajaco/mocaron/badge.svg\" alt=\"Coverage Status\" />\n  </a>\n  <a href=\"https://github.com/prettier/prettier\">\n    <img src=\"https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\" alt=\"code style: prettier\" />\n  </a>\n  <br />\n  <br />\n  Simple <a href=\"https://expressjs.com\">express</a> mock server with a flexible API inspired by <a href=\"https://www.wheresrhys.co.uk/fetch-mock\">fetch-mock</a>\n</p>\n\n---\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [API](#api)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n# Installation\n\n```bash\n# npm\nnpm install -D mocaron\n\n# yarn\nyarn add -D mocaron\n\n# pnpm\npnpm add -D mocaron\n```\n\n# Quick Start\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\nmockServer.get(\"/test\", { status: 200, body: { message: \"Hello World\" } });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n\nawait mockServer.stop();\n```\n\n# Usage\n\n## Starting and stopping the mock server\n\nSee [`constructor()`](#constructoroptions-mockserver) [`start()`](#start-promisevoid) [`stop()`](#stop-promisevoid)\n\n```ts\nimport { MockServer } from \"mocaron\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nawait mockServer.start();\n\n// ...\n\nawait mockServer.stop();\n```\n\n## Registering a mock\n\nRegister a mock using [`mock()`](#mockmatcher-response-options-mockserver).\n\n```ts\nmockServer.mock(\n  { path: \"/test\", method: \"GET\" },\n  { status: 200, body: { message: \"Hello World\" } },\n);\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n## Method specific mocks\n\nYou can also register mocks that only match a specific HTTP method.\n\nSee [`get()`](#getmatcher-response-options-mockserver) [`post()`](#postmatcher-response-options-mockserver) [`put()`](#putmatcher-response-options-mockserver) [`patch()`](#patchmatcher-response-options-mockserver) [`delete()`](#deletematcher-response-options-mockserver)\n\n```ts\nmockServer\n  .get(\"/test\", { status: 200, body: { message: \"Hello World\" } })\n  .post(\"/test\", { status: 201, body: { message: \"Created\" } })\n  .put(\"/test\", { status: 200, body: { message: \"Replaced\" } })\n  .patch(\"/test\", { status: 200, body: { message: \"Updated\" } })\n  .delete(\"/test\", { status: 204 });\n```\n\n## Unmatched requests\n\nIf a request does not match any of the registered mocks the server will respond with a 404 status code.\n\n```ts\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 404\n```\n\n## Ambiguous mocks\n\nIf two or more mocks match the same request the server will respond with a 404 status code.\n\n```ts\nmockServer.mock({ path: \"/foo\" }, \"foo\").mock({ path: \"/foo\" }, \"bar\");\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 404\n```\n\nYou can override this behavior by passing the [`overwrite`](#mockoptions) option to the last matching mock.\n\n```ts\nmockServer\n  .mock({ path: \"/foo\" }, \"foo\")\n  .mock({ path: \"/foo\" }, \"bar\", { overwrite: true });\n\nconst response = await fetch(\"http://localhost:3000/foo\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.text()); // bar\n```\n\n## Resetting the mock server\n\nCalling [`reset()`](#reset-void) will reset the mock server to its initial state.\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nlet response = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 200\n\nmockServer.reset();\n\nresponse = await fetch(\"http://localhost:3000/test\");\nconsole.log(response.status); // 404\n```\n\n## Testing\n\nSet up the mock server for each test using [`start()`](#start-promisevoid), [`stop()`](#stop-promisevoid) and [`reset()`](#reset-void).\n\n```ts\nimport { MockServer } from \"mocaron\";\nimport { beforeAll, afterAll, beforeEach, test, assert } from \"my-test-library\";\n\nconst mockServer = new MockServer({ port: 3000 });\n\nbeforeAll(() => mockServer.start());\nafterAll(() => mockServer.stop());\nbeforeEach(() => mockServer.reset());\n```\n\nTest that a mock has been called using [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n```ts\ntest(\"mock has been called\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledWith({ path: \"/test\" }));\n});\n```\n\nTest that a mock has been called a specific number of times using [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n```ts\ntest(\"mock has been called 3 times\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.hasBeenCalledTimes(3, { path: \"/test\" }));\n});\n```\n\nCustom assertions using [`calls()`](#calls-readonly-call).\n\n```ts\ntest(\"custom assertion\", async () => {\n  mockServer.get(\"/test\", { status: 200 });\n\n  await fetch(\"http://localhost:3000/test\");\n\n  assert(mockServer.calls().length === 1);\n  assert(mockServer.calls()[0].request.path === \"/test\");\n});\n```\n\n# API\n\n- [`MockServer`](#mockserver)\n  - [`constructor()`](#constructoroptions-mockserver)\n  - [`start()`](#start-promisevoid)\n  - [`stop()`](#stop-promisevoid)\n  - [`port()`](#port-number)\n  - [`mock()`](#mockmatcher-response-options-mockserver)\n  - [`get()`](#getmatcher-response-options-mockserver)\n  - [`post()`](#postmatcher-response-options-mockserver)\n  - [`put()`](#putmatcher-response-options-mockserver)\n  - [`patch()`](#patchmatcher-response-options-mockserver)\n  - [`delete()`](#deletematcher-response-options-mockserver)\n  - [`mocks()`](#mocks-readonly-mock)\n  - [`calls()`](#calls-readonly-call)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean)\n  - [`countCalls()`](#countcallsmatcher-number)\n  - [`reset()`](#reset-void)\n  - [`resetMocks()`](#resetmocks-void)\n  - [`resetCalls()`](#resetcalls-void)\n- [`ExpectationMessage`](#expectationmessage)\n  - [`hasBeenCalledWith()`](#hasbeencalledwithmockserver-matcher-string)\n  - [`hasBeenCalledTimes()`](#hasbeencalledtimesmockserver-times-matcher-string)\n- [`Options`](#options)\n- [`Request`](#request)\n- [`Matcher`](#matcher)\n- [`MatcherObj`](#matcherobj)\n- [`MatcherFn`](#matcherfn)\n- [`Response`](#response)\n- [`ResponseObj`](#responseobj)\n- [`ResponseFn`](#responsefn)\n- [`MockOptions`](#mockoptions)\n- [`Mock`](#mock)\n- [`Call`](#call)\n\n## `MockServer`\n\n### `constructor(options): MockServer`\n\nCreate a new [`MockServer`](#mockserver) instance.\n\n| Param   | Type                  | Default |\n| ------- | --------------------- | ------- |\n| options | [`Options`](#options) | -       |\n\n#### Example\n\n```ts\nconst mockServer = new MockServer({ port: 3000 });\n```\n\n---\n\n### `start(): Promise<void>`\n\nStart the mock server.\n\n#### Example\n\n```ts\nawait mockServer.start();\n```\n\n---\n\n### `stop(): Promise<void>`\n\nStop the mock server.\n\n#### Example\n\n```ts\nawait mockServer.stop();\n```\n\n---\n\n### `port(): number`\n\nGet the port the mock server is running on.\n\n#### Example\n\n```ts\nconst port = mockServer.port();\nconsole.log(port); // 3000\n```\n\n---\n\n### `mock(matcher, response, options): MockServer`\n\nRegister a mock.\n\n| Param    | Type                                            | Default |\n| -------- | ----------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`Matcher`](#matcher)   | -       |\n| response | `string` \\| `number` \\| [`Response`](#response) | -       |\n| options  | [`MockOptions`](#mockoptions)                   | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `get(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `GET` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\");\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `post(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `POST` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.post(\"/test\", {\n  status: 201,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"POST\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 201\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `put(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PUT` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.put(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PUT\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `patch(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `PATCH` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.patch(\"/test\", {\n  status: 200,\n  body: { message: \"Hello World\" },\n});\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"PATCH\",\n  body: JSON.stringify({ message: \"Hello World\" }),\n});\n\nconsole.log(response.status); // 200\nconsole.log(await response.json()); // { message: \"Hello World\" }\n```\n\n---\n\n### `delete(matcher, response, options): MockServer`\n\nRegister a mock that only responds to requests using the HTTP `DELETE` method.\n\n| Param    | Type                                                | Default |\n| -------- | --------------------------------------------------- | ------- |\n| matcher  | `string` \\| `RegExp` \\| [`MatcherObj`](#matcherobj) | -       |\n| response | `string` \\| `number` \\| [`Response`](#response)     | -       |\n| options  | [`MockOptions`](#mockoptions)                       | `{}`    |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.  \nIf `response` is a `string`, it will be used as the response body.  \nIf `response` is a `number`, it will be used as the response status code.\n\nReturns the [`MockServer`](#mockserver) instance.\n\n#### Example\n\n```ts\nmockServer.delete(\"/test\", { status: 204 });\n\nconst response = await fetch(\"http://localhost:3000/test\", {\n  method: \"DELETE\",\n});\n\nconsole.log(response.status); // 204\n```\n\n---\n\n### `mocks(): readonly Mock[]`\n\nGet all registered mocks.\n\nReturns an array of [`Mock`](#mock) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\n\nconst mocks = mockServer.mocks();\n\nconsole.log(mocks);\n// [{ matcher: { path: \"/test\" }, response: { status: 204 } }]\n```\n\n---\n\n### `calls(): readonly Call[]`\n\nGet all registered calls.\n\nReturns an array of [`Call`](#call) objects.\n\n#### Example\n\n```ts\nmockServer.mock({ path: \"/test\" }, { status: 204 });\nawait fetch(\"http://localhost:3000/test\");\n\nconst calls = mockServer.calls();\n\nconsole.log(calls);\n// [{ matcher: { path: \"/test\" }, request: <express.Request> }]\n```\n\n---\n\n### `hasBeenCalledWith(matcher): boolean`\n\nCheck if the route has been called with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledWith({ path: \"/test\" })); // true\n```\n\n---\n\n### `hasBeenCalledTimes(times, matcher): boolean`\n\nCheck if the route has been called a certain number of times with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| times   | `number`                                      | -       |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns `true` if the route has been called `times` times with the given `matcher`, `false` otherwise.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // true\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // false\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.hasBeenCalledTimes(0, { path: \"/test\" })); // false\nconsole.log(mockServer.hasBeenCalledTimes(1, { path: \"/test\" })); // true\n```\n\n---\n\n### `countCalls(matcher): number`\n\nCount the number of times the server was called with the given `matcher`.\n\n| Param   | Type                                          | Default |\n| ------- | --------------------------------------------- | ------- |\n| matcher | `string` \\| `RegExp` \\| [`Matcher`](#matcher) | -       |\n\nIf `matcher` is a `string` or `RegExp`, it will be used to match the request path.\n\nReturns the number of times the server has been called with the given `matcher`.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.countCalls({ path: \"/test\" })); // 0\n\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.countCalls({ path: \"/test\" })); // 1\n```\n\n---\n\n### `reset(): void`\n\nReset all mocks and calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.reset();\n\nconsole.log(mockServer.mocks()); // []\nconsole.log(mockServer.calls()); // []\n```\n\n---\n\n### `resetMocks(): void`\n\nReset all mocks.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\n\nconsole.log(mockServer.mocks());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, response: { status: 200 } }]\n\nmockServer.resetMocks();\n\nconsole.log(mockServer.mocks()); // []\n```\n\n---\n\n### `resetCalls(): void`\n\nReset all calls.\n\n#### Example\n\n```ts\nmockServer.get(\"/test\", { status: 200 });\nawait fetch(\"http://localhost:3000/test\");\n\nconsole.log(mockServer.calls());\n// [{ matcher: { path: \"/test\", method: \"GET\" }, request: <express.Request> }]\n\nmockServer.resetCalls();\n\nconsole.log(mockServer.calls()); // []\n```\n\n## `ExpectationMessage`\n\n### `hasBeenCalledWith(mockServer, matcher): string`\n\nFormat an expectation message for [`hasBeenCalledWith()`](#hasbeencalledwithmatcher-boolean).\n\n| Param      | Type                        | Default |\n| ---------- | --------------------------- | ------- |\n| mockServer | [`MockServer`](#mockserver) | -       |\n| matcher    | [`Matcher`](#matcher)       | -       |\n\nReturns a string with the formatted expectation message.\n\n#### Example\n\n```ts\nif (!mockServer.hasBeenCalledWith(matcher)) {\n  throw new Error(ExpectationMessage.hasBeenCalledWith(mockServer, matcher));\n}\n```\n\n### `hasBeenCalledTimes(mockServer, times, matcher): string`\n\nFormat an expectation message for [`hasBeenCalledTimes()`](#hasbeencalledtimestimes-matcher-boolean).\n\n| Param      | Type                        | Default |\n| ---------- | --------------------------- | ------- |\n| mockServer | [`MockServer`](#mockserver) | -       |\n| times      | number                      | -       |\n| matcher    | [`Matcher`](#matcher)       | -       |\n\nReturns a string with the formatted expectation message.\n\n#### Example\n\n```ts\nif (!mockServer.hasBeenCalledTimes(mockServer, 2, matcher)) {\n  throw new Error(\n    ExpectationMessage.hasBeenCalledTimes(mockServer, 2, matcher),\n  );\n}\n```\n\n## `Options`\n\nObject with the following properties:\n\n| Property | Type     | Description                    |\n| -------- | -------- | ------------------------------ |\n| port     | `number` | port to run the mock server on |\n\n## `Request`\n\nType alias for [`express.Request`](https://expressjs.com/en/4x/api.html#req) with the `body` property typed as `Buffer` | `undefined`.\n\n```ts\ntype Request = express.Request<{}, unknown, Buffer | undefined>;\n```\n\n## `Matcher`\n\nType alias for [`MatcherObj`](#matcherobj) | [`MatcherFn`](#matcherfn).\n\n```ts\ntype Matcher = MatcherObj | MatcherFn;\n```\n\n## `MatcherObj`\n\nObject with the following properties:\n\n| Property | Type                                                                                | Description                                                                                                   |\n| -------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| method   | `string` \\| `undefined`                                                             | HTTP method to match against                                                                                  |\n| path     | `string` \\| `RegExp` \\| `undefined`                                                 | path to match against                                                                                         |\n| query    | [`Request[\"query\"]`](https://expressjs.com/en/4x/api.html#req.query) \\| `undefined` | query parameters to match against.<br/>Parameters explicitly set to `undefined` will not match when provided. |\n| headers  | `Record<string, string \\| undefined>` \\| `undefined`                                | headers to match against.<br/>Headers explicitly set to `undefined` will not match when provided.             |\n| body     | `string` \\| `object` \\| `undefined`                                                 | body to match against.<br/>If an `object` is given it will be compared to the request body parsed as JSON.    |\n\n## `MatcherFn`\n\nFunction that takes a [`Request`](#request) and returns whether the request should match.\n\n```ts\ntype MatcherFn = (req: Request) => boolean;\n```\n\n## `Response`\n\nType alias for [`ResponseObj`](#responseobj) | [`ResponseFn`](#responsefn).\n\n```ts\ntype Response = ResponseObj | ResponseFn;\n```\n\n## `ResponseObj`\n\nObject with the following properties:\n\n| Property | Type                                    | Description                                                                              |\n| -------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |\n| status   | `number` \\| `undefined`                 | status code to respond with (defaults to `200`)                                          |\n| headers  | `Record<string, string>` \\| `undefined` | headers to respond with                                                                  |\n| body     | `string` \\| `object` \\| `undefined`     | body to respond with.<br/>If an `object` is given it will be converted to a JSON string. |\n| delay    | `number` \\| `undefined`                 | delay in milliseconds before responding                                                  |\n\n## `ResponseFn`\n\nFunction or async function that takes a [`Request`](#request) and returns a [`ResponseObj`](#responseobj).\n\n```ts\ntype ResponseFn = (req: Request) => ResponseObj | Promise<ResponseObj>;\n```\n\n## `MockOptions`\n\nObject with the following properties:\n\n| Property  | Type                     | Description                                                                                                        |\n| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| overwrite | `boolean` \\| `undefined` | when set to `true`,<br/>previous [ambiguous mocks](#ambiguous-mocks) matching the same request will be overwritten |\n\n## `Mock`\n\nObject with the following properties:\n\n| Property | Type                          | Description                                        |\n| -------- | ----------------------------- | -------------------------------------------------- |\n| matcher  | [`Matcher`](#matcher)         | matcher to match against the request               |\n| response | [`Response`](#response)       | response the server will respond with when matched |\n| options  | [`MockOptions`](#mockoptions) | see [`MockOptions`](#mockoptions)                  |\n\n## `Call`\n\nObject with the following properties:\n\n| Property | Type                  | Description                         |\n| -------- | --------------------- | ----------------------------------- |\n| request  | [`Request`](#request) | request the server was called with  |\n| matcher  | [`Matcher`](#matcher) | matcher the request matched against |\n\n# Changelog\n\n[CHANGELOG.md](https://github.com/joshuajaco/mocaron/blob/main/CHANGELOG.md)\n\n# License\n\n[MIT](https://github.com/joshuajaco/mocaron/blob/main/LICENSE)\n","readmeFilename":"README.md","homepage":"https://github.com/joshuajaco/mocaron#readme","repository":{"type":"git","url":"git+https://github.com/joshuajaco/mocaron.git"},"bugs":{"url":"https://github.com/joshuajaco/mocaron/issues"},"license":"MIT","description":"Simple express mock server with a flexible API inspired by fetch-mock","keywords":["mock","mocking","mocks","mock-server","server","express","fetch-mock"]}