diff --git a/.eslintrc b/.eslintrc
index c799fe5..9bcdb46 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,3 +1,6 @@
{
- "extends": "eslint-config-egg"
+ "extends": [
+ "eslint-config-egg/typescript",
+ "eslint-config-egg/lib/rules/enforce-node-prefix"
+ ]
}
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index 4b0c095..9ed9cf2 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -3,7 +3,6 @@ name: CI
on:
push:
branches: [ master ]
-
pull_request:
branches: [ master ]
@@ -12,5 +11,6 @@ jobs:
name: Node.js
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
with:
- os: 'ubuntu-latest, macos-latest, windows-latest'
- version: '14, 16, 18, 20'
+ version: '18.19.0, 18, 20, 22, 23'
+ secrets:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml
new file mode 100644
index 0000000..bac3fac
--- /dev/null
+++ b/.github/workflows/pkg.pr.new.yml
@@ -0,0 +1,23 @@
+name: Publish Any Commit
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - run: corepack enable
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build
+ run: npm run prepublishOnly --if-present
+
+ - run: npx pkg-pr-new publish
diff --git a/.gitignore b/.gitignore
index 86e3a6f..2f5d06e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,7 @@ results
node_modules
npm-debug.log
coverage
+package-lock.json
+.tshy*
+.eslintcache
+dist
diff --git a/README.md b/README.md
index dd09cc2..37c4973 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
[![Node.js CI](https://github.com/node-modules/mm/actions/workflows/nodejs.yml/badge.svg)](https://github.com/node-modules/mm/actions/workflows/nodejs.yml)
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
+[![Node.js Version](https://img.shields.io/node/v/mm.svg?style=flat)](https://nodejs.org/en/download/)
[npm-image]: https://img.shields.io/npm/v/mm.svg?style=flat-square
[npm-url]: https://npmjs.org/package/mm
@@ -22,9 +23,9 @@ npm install mm --save-dev
## Usage
-```js
-var mm = require('mm');
-var fs = require('fs');
+```ts
+import fs from 'node:fs';
+import mm from 'mm';
mm(fs, 'readFileSync', function(filename) {
return filename + ' content';
@@ -33,8 +34,7 @@ mm(fs, 'readFileSync', function(filename) {
console.log(fs.readFileSync('《九评 Java》'));
// => 《九评 Java》 content
-mm.restore();
-
+restore();
console.log(fs.readFileSync('《九评 Java》'));
// => throw `Error: ENOENT, no such file or directory '《九评 Java》`
```
@@ -43,7 +43,9 @@ console.log(fs.readFileSync('《九评 Java》'));
If mocked property is a function, it will be spied, every time it called, mm will modify `.called`, `.calledArguments` and `.lastCalledArguments`. For example:
-```js
+```ts
+import mm from 'mm';
+
const target = {
async add(a, b) {
return a + b;
@@ -65,7 +67,9 @@ assert.deepEqual(target.add.lastCalledArguments, [ 2, 2 ]);
If you only need spy and don't need mock, you can use `mm.spy` method directly:
-```js
+```ts
+import mm from 'mm';
+
const target = {
async add(a, b) {
await this.foo();
@@ -90,9 +94,9 @@ assert.deepEqual(target.add.lastCalledArguments, [ 2, 2 ]);
### .error(module, propertyName, errerMessage, errorProperties)
-```js
-var mm = require('mm');
-var fs = require('fs');
+```ts
+import fs from 'node:fs';
+import mm from 'mm';
mm.error(fs, 'readFile', 'mock fs.readFile return error');
@@ -114,9 +118,9 @@ fs.readFile('/etc/hosts', 'utf8', function (err, content) {
Just like `mm.error()`, but only mock error once.
-```js
-const mm = require('mm');
-const fs = require('fs');
+```ts
+import fs from 'node:fs';
+import mm from 'mm';
mm.errorOnce(fs, 'readFile', 'mock fs.readFile return error');
@@ -135,12 +139,12 @@ fs.readFile('/etc/hosts', 'utf8', function (err, content) {
### .data(module, propertyName, secondCallbackArg)
```js
-mm.data(fs, 'readFile', new Buffer('some content'));
+mm.data(fs, 'readFile', Buffer.from('some content'));
// equals
fs.readFile = function (...args, callback) {
- callback(null, new Buffer('some content'))
+ callback(null, Buffer.from('some content'))
};
```
@@ -191,12 +195,12 @@ mysql.query = function (...args, callback) {
### .datas(module, propertyName, argsArray)
```js
-mm.datas(urllib, 'request', [new Buffer('data'), {headers: { foo: 'bar' }}]);
+mm.datas(urllib, 'request', [Buffer.from('data'), {headers: { foo: 'bar' }}]);
// equals
urllib.request = function (...args, callback) {
- callback(null, new Buffer('data'), {headers: { foo: 'bar' }});
+ callback(null, Buffer.from('data'), {headers: { foo: 'bar' }});
}
```
@@ -221,12 +225,12 @@ fs.readFileSync = function (...args) {
### .syncData(module, propertyName, value)
```js
-mm.syncData(fs, 'readFileSync', new Buffer('some content'));
+mm.syncData(fs, 'readFileSync', Buffer.from('some content'));
// equals
fs.readFileSync = function (...args) {
- return new Buffer('some content');
+ return Buffer.from('some content');
};
```
@@ -337,15 +341,8 @@ assert(await foo1.fetch() === 3);
[MIT](LICENSE)
-
-
## Contributors
-|[
fengmk2](https://github.com/fengmk2)
|[
dead-horse](https://github.com/dead-horse)
|[
alsotang](https://github.com/alsotang)
|[
popomore](https://github.com/popomore)
|[
semantic-release-bot](https://github.com/semantic-release-bot)
|[
gemwuu](https://github.com/gemwuu)
|
-| :---: | :---: | :---: | :---: | :---: | :---: |
-|[
paranoidjk](https://github.com/paranoidjk)
|[
nightink](https://github.com/nightink)
|[
killagu](https://github.com/killagu)
|[
gxkl](https://github.com/gxkl)
|[
iyuq](https://github.com/iyuq)
|[
atian25](https://github.com/atian25)
|
-[
xavierchow](https://github.com/xavierchow)
|[
whxaxes](https://github.com/whxaxes)
-
-This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Dec 09 2023 11:34:46 GMT+0800`.
+[![Contributors](https://contrib.rocks/image?repo=node-modules/mm)](https://github.com/node-modules/mm/graphs/contributors)
-
+Made with [contributors-img](https://contrib.rocks).
diff --git a/index.js b/index.js
deleted file mode 100644
index 33756d5..0000000
--- a/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = require('./lib/mm');
-
-require('./lib/es6');
diff --git a/lib/es6.js b/lib/es6.js
deleted file mode 100644
index dfa7dbb..0000000
--- a/lib/es6.js
+++ /dev/null
@@ -1,98 +0,0 @@
-const is = require('is-type-of');
-const mm = require('./mm');
-
-function sleep(ms) {
- return new Promise(resolve => {
- setTimeout(resolve, ms);
- });
-}
-
-const mockDatas = mm.datas;
-// support generator
-mm.datas = function(mod, method, datas, timeout) {
- const isGeneratorFunction = is.generatorFunction(mod[method]);
- const isAsyncFunction = is.asyncFunction(mod[method]);
- if (!isGeneratorFunction && !isAsyncFunction) {
- return mockDatas.call(mm, mod, method, datas, timeout);
- }
-
- if (timeout) {
- timeout = parseInt(timeout, 10);
- }
- timeout = timeout || 0;
- if (isGeneratorFunction) {
- mm(mod, method, function* () {
- yield sleep(timeout);
- return datas;
- });
- } else {
- mm(mod, method, async function() {
- await sleep(timeout);
- return datas;
- });
- }
- return this;
-};
-
-const mockData = mm.data;
-mm.data = function(mod, method, data, timeout) {
- if (!is.generatorFunction(mod[method]) && !is.asyncFunction(mod[method])) {
- return mockData.call(mm, mod, method, data, timeout);
- }
-
- return mm.datas(mod, method, data, timeout);
-};
-
-mm.dataWithAsyncDispose = function(mod, method, data, timeout) {
- data = {
- ...data,
- async [Symbol.asyncDispose]() {
- // do nothing
- },
- };
- return mm.data(mod, method, data, timeout);
-};
-
-const mockError = mm.error;
-mm.error = function(mod, method, error, props, timeout) {
- if (!is.generatorFunction(mod[method])) {
- return mockError.call(mm, mod, method, error, props, timeout);
- }
-
- error = mm._createError(error, props);
-
- if (timeout) {
- timeout = parseInt(timeout, 10);
- }
- timeout = timeout || 0;
- mm(mod, method, function* () {
- yield sleep(timeout);
- throw error;
- });
- return this;
-};
-
-const mockErrorOnce = mm.errorOnce;
-mm.errorOnce = function(mod, method, error, props, timeout) {
- if (!is.generatorFunction(mod[method])) {
- return mockErrorOnce.call(mm, mod, method, error, props, timeout);
- }
-
- error = mm._createError(error, props);
-
- if (timeout) {
- timeout = parseInt(timeout, 10);
- }
- timeout = timeout || 0;
- mm(mod, method, function* () {
- yield sleep(timeout);
- mm.restore();
- throw error;
- });
- return this;
-};
-
-// mock class method from instance
-mm.classMethod = function(instance, property, value) {
- return mm(instance.constructor.prototype, property, value);
-};
diff --git a/package.json b/package.json
index 66cd1c3..04fa0ff 100644
--- a/package.json
+++ b/package.json
@@ -2,41 +2,6 @@
"name": "mm",
"version": "3.4.0",
"description": "mock mate, mock http request, fs access and so on.",
- "main": "index.js",
- "files": [
- "index.js",
- "index.d.ts",
- "lib"
- ],
- "scripts": {
- "test": "npm run lint && egg-bin test --ts false",
- "test-ts": "egg-bin test --ts true",
- "ci": "npm run lint && egg-bin cov --ts false && npm run test-ts",
- "lint": "eslint --fix lib test index.js",
- "contributor": "git-contributor"
- },
- "dependencies": {
- "is-type-of": "^1.2.1",
- "muk-prop": "^1.2.1",
- "thenify": "^3.3.0"
- },
- "devDependencies": {
- "@eggjs/tsconfig": "^1.3.3",
- "@hazae41/symbol-dispose-polyfill": "^1.0.2",
- "@types/mocha": "^10.0.6",
- "@types/node": "^20.10.4",
- "chunkstream": "^0.0.1",
- "co": "^4.6.0",
- "egg-bin": "^6.4.0",
- "eslint": "^8.55.0",
- "eslint-config-egg": "^12.0.0",
- "git-contributor": "^2.1.5",
- "pedding": "^1.1.0",
- "should": "^13.2.3",
- "thunkify-wrap": "^1.0.4",
- "typescript": "^5.3.3",
- "urllib": "^3.5.1"
- },
"homepage": "http://github.com/node-modules/mm",
"repository": {
"type": "git",
@@ -48,9 +13,63 @@
"mock",
"test"
],
+ "author": "fengmk2 (https://github.com/fengmk2)",
+ "license": "MIT",
"engines": {
- "node": ">=14.0.0"
+ "node": ">= 18.19.0"
},
- "author": "fengmk2 (https://github.com/fengmk2)",
- "license": "MIT"
+ "dependencies": {
+ "@cnpmjs/muk-prop": "^1.0.0",
+ "is-type-of": "^2.2.0",
+ "thenify": "^3.3.1"
+ },
+ "devDependencies": {
+ "@arethetypeswrong/cli": "^0.17.1",
+ "@eggjs/tsconfig": "1",
+ "@types/mocha": "10",
+ "@types/node": "22",
+ "egg-bin": "6",
+ "eslint": "8",
+ "eslint-config-egg": "14",
+ "pedding": "^1.1.0",
+ "should": "^13.2.3",
+ "tshy": "3",
+ "tshy-after": "1",
+ "typescript": "5"
+ },
+ "scripts": {
+ "lint": "eslint --cache src test --ext .ts",
+ "pretest": "npm run lint -- --fix && npm run prepublishOnly",
+ "test": "egg-bin test",
+ "preci": "npm run lint && npm run prepublishOnly && attw --pack",
+ "ci": "egg-bin cov",
+ "prepublishOnly": "tshy && tshy-after"
+ },
+ "type": "module",
+ "tshy": {
+ "exports": {
+ ".": "./src/index.ts",
+ "./package.json": "./package.json"
+ }
+ },
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/esm/index.d.ts",
+ "default": "./dist/esm/index.js"
+ },
+ "require": {
+ "types": "./dist/commonjs/index.d.ts",
+ "default": "./dist/commonjs/index.js"
+ }
+ },
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "dist",
+ "src"
+ ],
+ "types": "./dist/commonjs/index.d.ts",
+ "main": "./dist/commonjs/index.js",
+ "module": "./dist/esm/index.js"
}
diff --git a/index.d.ts b/src/index.d.ts
similarity index 100%
rename from index.d.ts
rename to src/index.d.ts
diff --git a/lib/mm.js b/src/index.ts
similarity index 57%
rename from lib/mm.js
rename to src/index.ts
index f14ec3d..53884d5 100644
--- a/lib/mm.js
+++ b/src/index.ts
@@ -1,19 +1,21 @@
-const EventEmitter = require('events');
-const is = require('is-type-of');
-const muk = require('muk-prop');
-const http = require('http');
-const https = require('https');
-const cp = require('child_process');
-const thenify = require('thenify').withCallback;
-const Readable = require('stream').Readable;
-const Duplex = require('stream').Duplex;
-
-const mock = module.exports = function mock(target, property, value) {
+import { EventEmitter } from 'node:events';
+import http from 'node:http';
+import https from 'node:https';
+import cp from 'node:child_process';
+import { scheduler } from 'node:timers/promises';
+import { Readable, Duplex } from 'node:stream';
+import { muk, isMocked, restore } from '@cnpmjs/muk-prop';
+import is from 'is-type-of';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+import thenify from 'thenify';
+
+function mock(target: any, property: string, value?: any) {
value = spyFunction(target, property, value);
return muk(target, property, value);
-};
+}
-function spyFunction(target, property, fn) {
+function spyFunction(target: any, property: string, fn: any) {
if (!is.function(fn)) return fn;
// support mock with jest.fn()
if (fn._isMockFunction && fn.mock) return fn;
@@ -37,16 +39,14 @@ function spyFunction(target, property, fn) {
});
}
-function isAsyncLikeFunction(target, property) {
+function isAsyncLikeFunction(target: any, property: string) {
// don't call getter
// Object.getOwnPropertyDescriptor can't find getter in prototypes
- if (target.__lookupGetter__(property)) return false;
+ if (typeof target.__lookupGetter__ === 'function' && target.__lookupGetter__(property)) return false;
return is.asyncFunction(target[property]) || is.generatorFunction(target[property]);
}
-exports = mock;
-
-function getCallback(args) {
+function getCallback(args: any[]) {
let index = args.length - 1;
let callback = args[index];
while (typeof callback !== 'function') {
@@ -68,7 +68,7 @@ function getCallback(args) {
return callback;
}
-exports.isMocked = muk.isMocked;
+export type MockError = Error | string;
/**
* create an error instance
@@ -77,7 +77,7 @@ exports.isMocked = muk.isMocked;
* @param {Object} props - props
* @return {Error} error - error
*/
-exports._createError = function(error, props) {
+function _createError(error?: MockError, props?: Record): Error {
if (!error) {
error = new Error('mm mock error');
error.name = 'MockError';
@@ -86,36 +86,51 @@ exports._createError = function(error, props) {
error = new Error(error);
error.name = 'MockError';
}
- props = props || {};
- for (const key in props) {
- error[key] = props[key];
- }
-
+ Object.assign(error, props);
return error;
-};
+}
-exports._mockError = function(mod, method, error, props, timeout, once) {
+function _mockError(mod: any, method: string, error?: MockError, props?: Record | number,
+ timeout?: number | string, once?: boolean) {
if (typeof props === 'number') {
timeout = props;
props = {};
}
- error = exports._createError(error, props);
+ error = _createError(error, props);
- if (timeout) {
- timeout = parseInt(timeout, 10);
+ if (typeof timeout !== 'number') {
+ timeout = parseInt(String(timeout || '0'), 10);
}
- timeout = timeout || 0;
- mock(mod, method, thenify(function() {
- const callback = getCallback(arguments);
- setTimeout(function() {
+ const isGeneratorFunction = is.generatorFunction(mod[method]);
+ const isAsyncFunction = is.asyncFunction(mod[method]);
+ if (isGeneratorFunction) {
+ mock(mod, method, function* () {
+ yield scheduler.wait(timeout);
if (once) {
- exports.restore();
+ restore();
+ }
+ throw error;
+ });
+ } else if (isAsyncFunction) {
+ mock(mod, method, async function() {
+ await scheduler.wait(timeout);
+ if (once) {
+ restore();
+ }
+ throw error;
+ });
+ }
+
+ mock(mod, method, thenify.withCallback((...args: any[]) => {
+ const callback = getCallback(args);
+ setTimeout(() => {
+ if (once) {
+ restore();
}
callback(error);
}, timeout);
}));
- return this;
-};
+}
/**
* Mock async function error.
@@ -124,16 +139,12 @@ exports._mockError = function(mod, method, error, props, timeout, once) {
* @param {String|Error} error, error string message or error instance.
* @param {Object} props, error properties
* @param {Number} timeout, mock async callback timeout, default is 0.
- * @param mod
- * @param method
- * @param error
- * @param props
- * @param timeout
- * @return {mm} this - mm
*/
-exports.error = function(mod, method, error, props, timeout) {
- return exports._mockError(mod, method, error, props, timeout);
-};
+function mockError(mod: any, method: string, error?: MockError,
+ props?: Record | number,
+ timeout?: number) {
+ return _mockError(mod, method, error, props, timeout);
+}
/**
* Mock async function error once.
@@ -142,16 +153,12 @@ exports.error = function(mod, method, error, props, timeout) {
* @param {String|Error} error, error string message or error instance.
* @param {Object} props, error properties
* @param {Number} timeout, mock async callback timeout, default is 0.
- * @param mod
- * @param method
- * @param error
- * @param props
- * @param timeout
- * @return {mm} this - mm
*/
-exports.errorOnce = function(mod, method, error, props, timeout) {
- return exports._mockError(mod, method, error, props, timeout, true);
-};
+function errorOnce(mod: any, method: string, error?: MockError,
+ props?: Record | number,
+ timeout?: number) {
+ return _mockError(mod, method, error, props, timeout, true);
+}
/**
* mock return callback(null, data1, data2).
@@ -160,28 +167,38 @@ exports.errorOnce = function(mod, method, error, props, timeout) {
* @param {String} method, mock module object method name.
* @param {Array} datas, return datas array.
* @param {Number} timeout, mock async callback timeout, default is 10.
- * @param mod
- * @param method
- * @param datas
- * @param timeout
- * @return {mm} this - mm
*/
-exports.datas = function(mod, method, datas, timeout) {
+function mockDatas(mod: any, method: string, datas: any[] | any, timeout?: number) {
if (timeout) {
- timeout = parseInt(timeout, 10);
+ timeout = parseInt(String(timeout), 10);
}
timeout = timeout || 0;
+ const isGeneratorFunction = is.generatorFunction(mod[method]);
+ const isAsyncFunction = is.asyncFunction(mod[method]);
+ if (isGeneratorFunction) {
+ mock(mod, method, function* () {
+ yield scheduler.wait(timeout);
+ return datas;
+ });
+ return;
+ } else if (isAsyncFunction) {
+ mock(mod, method, async function() {
+ await scheduler.wait(timeout);
+ return datas;
+ });
+ return;
+ }
+
if (!Array.isArray(datas)) {
datas = [ datas ];
}
- mock(mod, method, thenify(function() {
- const callback = getCallback(arguments);
- setTimeout(function() {
+ mock(mod, method, thenify.withCallback((...args: any[]) => {
+ const callback = getCallback(args);
+ setTimeout(() => {
callback.apply(mod, [ null ].concat(datas));
}, timeout);
}));
- return this;
-};
+}
/**
* mock return callback(null, data).
@@ -190,15 +207,25 @@ exports.datas = function(mod, method, datas, timeout) {
* @param {String} method, mock module object method name.
* @param {Object} data, return data.
* @param {Number} timeout, mock async callback timeout, default is 0.
- * @param mod
- * @param method
- * @param data
- * @param timeout
- * @return {mm} this - mm
*/
-exports.data = function(mod, method, data, timeout) {
- return exports.datas(mod, method, [ data ], timeout);
-};
+function mockData(mod: any, method: string, data: any, timeout?: number) {
+ const isGeneratorFunction = is.generatorFunction(mod[method]);
+ const isAsyncFunction = is.asyncFunction(mod[method]);
+ if (isGeneratorFunction || isAsyncFunction) {
+ return mockDatas(mod, method, data, timeout);
+ }
+ return mockDatas(mod, method, [ data ], timeout);
+}
+
+function dataWithAsyncDispose(mod: any, method: string, data: any, timeout?: number) {
+ data = {
+ ...data,
+ async [Symbol.asyncDispose]() {
+ // do nothing
+ },
+ };
+ return mockData(mod, method, data, timeout);
+}
/**
* mock return callback(null, null).
@@ -206,30 +233,26 @@ exports.data = function(mod, method, data, timeout) {
* @param {Object} mod, module object
* @param {String} method, mock module object method name.
* @param {Number} [timeout], mock async callback timeout, default is 0.
- * @param mod
- * @param method
- * @param timeout
- * @return {mm} this - mm
*/
-exports.empty = function(mod, method, timeout) {
- return exports.datas(mod, method, null, timeout);
-};
+function mockEmpty(mod: any, method: string, timeout?: number) {
+ return mockDatas(mod, method, [ null ], timeout);
+}
/**
* spy a function
* @param {Object} mod, module object
* @param {String} method, mock module object method name.
- * @param mod
- * @param method
*/
-exports.spy = function(mod, method) {
- if (typeof mod[method] !== 'function') throw new Error(`spy target ${method} is not a function`);
+function spy(mod: any, method: string) {
+ if (typeof mod[method] !== 'function') {
+ throw new Error(`spy target ${method} is not a function`);
+ }
const originalFn = mod[method];
- const wrap = function proxy() {
- return originalFn.apply(this, arguments);
+ const wrap = function proxy(this: any, ...args: any[]) {
+ return originalFn.apply(this, args);
};
mock(mod, method, wrap);
-};
+}
/**
* mock function sync throw error
@@ -238,17 +261,13 @@ exports.spy = function(mod, method) {
* @param {String} method, mock module object method name.
* @param {String|Error} error, error string message or error instance.
* @param {Object} [props], error properties
- * @param mod
- * @param method
- * @param error
- * @param props
*/
-exports.syncError = function(mod, method, error, props) {
- error = exports._createError(error, props);
- mock(mod, method, function() {
+function syncError(mod: any, method: string, error?: MockError, props?: Record) {
+ error = _createError(error, props);
+ mock(mod, method, () => {
throw error;
});
-};
+}
/**
* mock function sync return data
@@ -256,32 +275,24 @@ exports.syncError = function(mod, method, error, props) {
* @param {Object} mod, module object
* @param {String} method, mock module object method name.
* @param {Object} data, return data.
- * @param mod
- * @param method
- * @param data
*/
-exports.syncData = function(mod, method, data) {
- mock(mod, method, function() {
+function syncData(mod: any, method: string, data?: any) {
+ mock(mod, method, () => {
return data;
});
-};
+}
/**
* mock function sync return nothing
*
* @param {Object} mod, module object
* @param {String} method, mock module object method name.
- * @param mod
- * @param method
*/
-exports.syncEmpty = function(mod, method) {
- exports.syncData(mod, method);
-};
-
-exports.http = {};
-exports.https = {};
+function syncEmpty(mod: any, method: string) {
+ return syncData(mod, method);
+}
-function matchURL(options, params) {
+function matchURL(options: any, params: any) {
const url = params && params.url || params;
const host = params && params.host;
@@ -308,19 +319,22 @@ function mockRequest() {
const req = new Duplex({
write() {},
read() {},
- });
- req.abort = function() {
+ }) as any;
+ req.abort = () => {
req._aborted = true;
- process.nextTick(function() {
+ process.nextTick(() => {
const err = new Error('socket hang up');
- err.code = 'ECONNRESET';
+ Reflect.set(err, 'code', 'ECONNRESET');
req.emit('error', err);
});
};
- req.socket = {};
+ req.socket = { remoteAddress: '127.0.0.1' };
return req;
}
+export type RequestURL = string | RegExp | URL | object;
+export type ResponseData = string | Buffer | Readable;
+
/**
* Mock http.request().
* @param {String|RegExp|Object} url, request url path.
@@ -329,16 +343,11 @@ function mockRequest() {
* If data is Array, then res will emit `data` event many times.
* @param {Object} headers, mock response headers.
* @param {Number} [delay], response delay time, default is 10.
- * @param url
- * @param data
- * @param headers
- * @param delay
- * @return {mm} this - mm
*/
-exports.http.request = function(url, data, headers, delay) {
+function mockHttpRequest(url: RequestURL, data: ResponseData, headers?: Record, delay?: number) {
backupOriginalRequest(http);
- return _request.call(this, http, url, data, headers, delay);
-};
+ return _request(http, url, data, headers, delay);
+}
/**
* Mock https.request().
@@ -348,18 +357,13 @@ exports.http.request = function(url, data, headers, delay) {
* If data is Array, then res will emit `data` event many times.
* @param {Object} headers, mock response headers.
* @param {Number} [delay], response delay time, default is 0.
- * @param url
- * @param data
- * @param headers
- * @param delay
- * @return {mm} this - mm
*/
-exports.https.request = function(url, data, headers, delay) {
+function mockHttpsRequest(url: RequestURL, data: ResponseData, headers?: Record, delay?: number) {
backupOriginalRequest(https);
- return _request.call(this, https, url, data, headers, delay);
-};
+ return _request(https, url, data, headers, delay);
+}
-function backupOriginalRequest(mod) {
+function backupOriginalRequest(mod: any) {
if (!mod.__sourceRequest) {
mod.__sourceRequest = mod.request;
}
@@ -368,20 +372,25 @@ function backupOriginalRequest(mod) {
}
}
-function _request(mod, url, data, headers, delay) {
+function _request(mod: any, url: any, data: any, headers?: any, delay?: number) {
headers = headers || {};
if (delay) {
- delay = parseInt(delay, 10);
+ delay = parseInt(String(delay), 10);
}
delay = delay || 0;
- mod.get = function(options, callback) {
+ // mod.get = function(options: any, callback: any) {
+ // const req = mod.request(options, callback);
+ // req.end();
+ // return req;
+ // };
+ mock(mod, 'get', function(options: any, callback: any) {
const req = mod.request(options, callback);
req.end();
return req;
- };
+ });
- mod.request = function(options, callback) {
+ mock(mod, 'request', function(options: any, callback: any) {
let datas = [];
let stream = null; // read stream
if (typeof data.read === 'function') {
@@ -405,7 +414,7 @@ function _request(mod, url, data, headers, delay) {
req.on('response', callback);
}
- let res;
+ let res: any;
if (stream) {
res = stream;
} else {
@@ -421,16 +430,16 @@ function _request(mod, url, data, headers, delay) {
if (!req._aborted) {
if (typeof chunk === 'string') {
- chunk = Buffer.from ? Buffer.from(chunk) : new Buffer(chunk);
+ chunk = Buffer.from(chunk);
}
- if (this.charset) {
+ if ('charset' in this && this.charset) {
chunk = chunk.toString(this.charset);
}
this.push(chunk);
}
},
});
- res.setEncoding = function(charset) {
+ res.setEncoding = function(charset: string) {
res.charset = charset;
};
}
@@ -452,8 +461,7 @@ function _request(mod, url, data, headers, delay) {
}
return req;
- };
- return this;
+ });
}
/**
@@ -462,15 +470,11 @@ function _request(mod, url, data, headers, delay) {
* @param {String|Error} reqError, request error.
* @param {String|Error} resError, response error.
* @param {Number} [delay], request error delay time, default is 0.
- * @param url
- * @param reqError
- * @param resError
- * @param delay
*/
-exports.http.requestError = function(url, reqError, resError, delay) {
+function mockHttpRequestError(url: RequestURL, reqError?: MockError, resError?: MockError, delay?: number) {
backupOriginalRequest(http);
- _requestError.call(this, http, url, reqError, resError, delay);
-};
+ _requestError(http, url, reqError, resError, delay);
+}
/**
* Mock https.request() error.
@@ -478,19 +482,15 @@ exports.http.requestError = function(url, reqError, resError, delay) {
* @param {String|Error} reqError, request error.
* @param {String|Error} resError, response error.
* @param {Number} [delay], request error delay time, default is 0.
- * @param url
- * @param reqError
- * @param resError
- * @param delay
*/
-exports.https.requestError = function(url, reqError, resError, delay) {
+function mockHttpsRequestError(url: RequestURL, reqError?: MockError, resError?: MockError, delay?: number) {
backupOriginalRequest(https);
- _requestError.call(this, https, url, reqError, resError, delay);
-};
+ _requestError(https, url, reqError, resError, delay);
+}
-function _requestError(mod, url, reqError, resError, delay) {
+function _requestError(mod: any, url: any, reqError?: MockError, resError?: MockError, delay?: number) {
if (delay) {
- delay = parseInt(delay, 10);
+ delay = parseInt(String(delay), 10);
}
delay = delay || 0;
if (reqError && typeof reqError === 'string') {
@@ -502,13 +502,13 @@ function _requestError(mod, url, reqError, resError, delay) {
resError.name = 'MockHttpResponseError';
}
- mod.get = function(options, callback) {
+ mock(mod, 'get', function(options: any, callback: any) {
const req = mod.request(options, callback);
req.end();
return req;
- };
+ });
- mod.request = function(options, callback) {
+ mock(mod, 'request', function(options: any, callback: any) {
const match = matchURL(options, url);
if (!match) {
return mod.__sourceRequest(options, callback);
@@ -528,13 +528,13 @@ function _requestError(mod, url, reqError, resError, delay) {
const res = new Duplex({
read() {},
write() {},
- });
+ }) as any;
res.socket = req.socket;
res.statusCode = 200;
res.headers = {
server: 'MockMateServer',
};
- process.nextTick(function() {
+ process.nextTick(() => {
if (!req._aborted) {
req.emit('error', resError);
}
@@ -545,8 +545,7 @@ function _requestError(mod, url, reqError, resError, delay) {
}, delay);
return req;
- };
- return this;
+ });
}
/**
@@ -556,44 +555,21 @@ function _requestError(mod, url, reqError, resError, delay) {
* @param {String} stderr stderr
* @param {Integer} timeout stdout/stderr/close event emit timeout
*/
-exports.spawn = function(code, stdout, stderr, timeout) {
+function spawn(code: number, stdout: string, stderr: string, timeout: number = 0) {
const evt = new EventEmitter();
- mock(cp, 'spawn', function() {
+ mock(cp, 'spawn', () => {
return evt;
});
- setTimeout(function() {
+ setTimeout(() => {
stdout && evt.emit('stdout', stdout);
stderr && evt.emit('stderr', stderr);
evt.emit('close', code);
evt.emit('exit', code);
}, timeout);
-};
-
-/**
- * remove all mock effects.
- * @return {mm} this - mm
- */
-exports.restore = function() {
- if (http.__sourceRequest) {
- http.request = http.__sourceRequest;
- http.__sourceRequest = null;
- }
- if (http.__sourceGet) {
- http.get = http.__sourceGet;
- http.__sourceGet = null;
- }
-
- if (https.__sourceRequest) {
- https.request = https.__sourceRequest;
- https.__sourceRequest = null;
- }
-
- muk.restore();
- return this;
-};
+}
-function omit(obj, key) {
- const newObj = {};
+function omit(obj: Record, key: string) {
+ const newObj: Record = {};
for (const k in obj) {
if (k !== key) {
newObj[k] = obj[k];
@@ -601,3 +577,73 @@ function omit(obj, key) {
}
return newObj;
}
+
+/**
+ * mock class method from instance
+ */
+function classMethod(instance: any, property: string, value?: any) {
+ mock(instance.constructor.prototype, property, value);
+}
+
+const mockHttp = {
+ request: mockHttpRequest,
+ requestError: mockHttpRequestError,
+};
+
+const mockHttps = {
+ request: mockHttpsRequest,
+ requestError: mockHttpsRequestError,
+};
+
+// import { mm, restore } from 'mm';
+export {
+ isMocked,
+ mock,
+ mock as mm,
+ mockDatas as datas,
+ mockDatas,
+ mockData as data,
+ mockData,
+ dataWithAsyncDispose,
+ mockEmpty as empty,
+ mockEmpty,
+ mockError as error,
+ mockError,
+ spy,
+ errorOnce,
+ syncError,
+ syncEmpty,
+ syncData,
+ mockHttp as http,
+ mockHttps as https,
+ spawn,
+ restore,
+ classMethod,
+};
+
+// import mm from 'mm';
+export default Object.assign(mock, {
+ isMocked,
+ mock,
+ mm: mock,
+ datas: mockDatas,
+ mockDatas,
+ data: mockData,
+ mockData,
+ dataWithAsyncDispose,
+ empty: mockEmpty,
+ mockEmpty,
+ error: mockError,
+ mockError,
+ spy,
+ errorOnce,
+ syncError,
+ syncEmpty,
+ syncData,
+ http: mockHttp,
+ https: mockHttps,
+ spawn,
+ restore,
+ classMethod,
+});
+
diff --git a/test/async-await.js b/test/async-await.test.ts
similarity index 65%
rename from test/async-await.js
rename to test/async-await.test.ts
index 1f6982e..ce691fd 100644
--- a/test/async-await.js
+++ b/test/async-await.test.ts
@@ -1,6 +1,7 @@
-const mm = require('..');
+import { strict as assert } from 'node:assert';
+import { mm, restore, mockDatas } from '../src/index.js';
-describe('test/async-await.test.js', () => {
+describe('test/async-await.test.ts', () => {
const foo = {
async request() {
return 'yes';
@@ -10,7 +11,7 @@ describe('test/async-await.test.js', () => {
},
};
- afterEach(mm.restore);
+ afterEach(restore);
describe('mm()', () => {
it('should mock async function', async () => {
@@ -19,11 +20,11 @@ describe('test/async-await.test.js', () => {
return 'no';
});
datas = await foo.request();
- datas.should.equal('no');
+ assert.equal(datas, 'no');
- mm.restore();
+ restore();
datas = await foo.request();
- datas.should.equal('yes');
+ assert(datas, 'yes');
});
it('should mock async function to normal throw type error', async () => {
@@ -34,7 +35,8 @@ describe('test/async-await.test.js', () => {
foo.request();
throw new Error('should not run this');
} catch (err) {
- err.message.should.equal('Can\'t mock async function to normal function for property "request"');
+ assert(err instanceof Error);
+ assert.equal(err.message, 'Can\'t mock async function to normal function for property "request"');
}
});
@@ -46,7 +48,8 @@ describe('test/async-await.test.js', () => {
foo.generatorRequest();
throw new Error('should not run this');
} catch (err) {
- err.message.should.equal('Can\'t mock async function to normal function for property "generatorRequest"');
+ assert(err instanceof Error);
+ assert.equal(err.message, 'Can\'t mock async function to normal function for property "generatorRequest"');
}
});
@@ -58,7 +61,8 @@ describe('test/async-await.test.js', () => {
foo.request();
throw new Error('should not run this');
} catch (err) {
- err.message.should.equal('should not run this');
+ assert(err instanceof Error);
+ assert.equal(err.message, 'should not run this');
}
});
});
@@ -66,13 +70,13 @@ describe('test/async-await.test.js', () => {
describe('datas(), data()', () => {
it('should mock async function', async () => {
let datas;
- mm.datas(foo, 'request', 'no');
+ mockDatas(foo, 'request', 'no');
datas = await foo.request();
- datas.should.equal('no');
+ assert.equal(datas, 'no');
- mm.restore();
+ restore();
datas = await foo.request();
- datas.should.equal('yes');
+ assert.equal(datas, 'yes');
});
});
});
diff --git a/test/asyncDispose.test.ts b/test/asyncDispose.test.ts
index f172f69..3a4bc2a 100644
--- a/test/asyncDispose.test.ts
+++ b/test/asyncDispose.test.ts
@@ -1,6 +1,5 @@
import { strict as assert } from 'node:assert';
-require('@hazae41/symbol-dispose-polyfill');
-import mm from '../index';
+import * as mm from '../src/index.js';
describe('test/asyncDispose.test.ts', () => {
const foo = {
diff --git a/test/co.js b/test/co.js
deleted file mode 100644
index d5a4582..0000000
--- a/test/co.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-const urllib = require('urllib');
-const co = require('co');
-const fs = require('fs');
-const mm = require('../');
-
-co(function* () {
- mm.http.request(/\//, fs.createReadStream(__filename), { statusCode: 404 });
- const r = yield urllib.request('http://nodejs.org');
- console.log(r.status, r.headers, r.data.length);
- r.data.toString().should.equal(fs.readFileSync(__filename, 'utf8'));
-})();
diff --git a/test/es6.js b/test/es6.test.ts
similarity index 57%
rename from test/es6.js
rename to test/es6.test.ts
index fca410f..f86c207 100644
--- a/test/es6.js
+++ b/test/es6.test.ts
@@ -1,14 +1,12 @@
-'use strict';
+import { strict as assert } from 'node:assert';
+import mm from '../src/index.js';
-const assert = require('assert');
-const mm = require('..');
-
-describe('test/es6.test.js', () => {
+describe('test/es6.test.ts', () => {
const foo = {
- * getMultiValues() {
+ async getMultiValues() {
return [ 1, 2, 3 ];
},
- * getValue() {
+ async getValue() {
return 1;
},
};
@@ -16,24 +14,24 @@ describe('test/es6.test.js', () => {
afterEach(mm.restore);
describe('datas(), data()', () => {
- it('should mock generator function', function* () {
+ it('should mock async function', async () => {
let datas;
mm.datas(foo, 'getMultiValues', [ 'b1', 'b2', 'b3' ]);
- datas = yield* foo.getMultiValues();
- datas.should.eql([ 'b1', 'b2', 'b3' ]);
+ datas = await foo.getMultiValues();
+ assert.deepEqual(datas, [ 'b1', 'b2', 'b3' ]);
mm.datas(foo, 'getMultiValues', 1);
- datas = yield* foo.getMultiValues();
- datas.should.equal(1);
+ datas = await foo.getMultiValues();
+ assert.equal(datas, 1);
let data;
mm.data(foo, 'getValue', 2, 500);
- data = yield* foo.getValue();
- data.should.equal(2);
+ data = await foo.getValue();
+ assert.equal(data, 2);
mm.restore();
- data = yield* foo.getValue();
- data.should.equal(1);
+ data = await foo.getValue();
+ assert.equal(data, 1);
});
});
@@ -77,76 +75,77 @@ describe('test/es6.test.js', () => {
});
describe('error(), errorOnce()', () => {
- it('should mock error', function* () {
+ it('should mock error', async () => {
mm.error(foo, 'getValue');
try {
- yield foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
} catch (err) {
- err.message.should.equal('mm mock error');
+ assert(err instanceof Error);
+ assert.equal(err.message, 'mm mock error');
}
- mm.error(foo, 'getValue', 'foo error', 200);
+ mm.error(foo, 'getValue', 'foo error', { foo: '200' });
try {
- yield* foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
} catch (err) {
- err.message.should.equal('foo error');
+ assert(err instanceof Error);
+ assert.equal(err.message, 'foo error');
}
mm.error(foo, 'getValue', new Error('new foo error'));
try {
- yield* foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('new foo error');
+ } catch (err: any) {
+ assert.equal(err.message, 'new foo error');
}
mm.error(foo, 'getValue', new Error('new foo error'), { status: 500 });
try {
- yield* foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('new foo error');
- err.status.should.equal(500);
+ } catch (err: any) {
+ assert.equal(err.message, 'new foo error');
+ assert.equal(err.status, 500);
}
mm.error(foo, 'getValue', new Error('new foo error'), { status: 500 }, 100);
- let start;
+ const start = Date.now();
try {
- start = Date.now();
- yield* foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
- } catch (err) {
+ } catch (err: any) {
const use = Date.now() - start;
- err.message.should.equal('new foo error');
- err.status.should.equal(500);
- use.should.above(90);
+ assert.equal(err.message, 'new foo error');
+ assert.equal(err.status, 500);
+ assert(use > 90);
}
});
- it('should mock error once', function* () {
+ it('should mock error once', async () => {
mm.errorOnce(foo, 'getValue');
try {
- yield foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('mm mock error');
+ } catch (err: any) {
+ assert.equal(err.message, 'mm mock error');
}
- const v = yield foo.getValue();
- v.should.equal(1);
+ const v = await foo.getValue();
+ assert.equal(v, 1);
mm.errorOnce(foo, 'getValue');
try {
- yield* foo.getValue();
+ await foo.getValue();
throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('mm mock error');
+ } catch (err: any) {
+ assert.equal(err.message, 'mm mock error');
}
- const v1 = yield* foo.getValue();
- v1.should.equal(1);
+ const v1 = await foo.getValue();
+ assert.equal(v1, 1);
});
});
});
diff --git a/test/foo.js b/test/foo.js
deleted file mode 100644
index 6a6758d..0000000
--- a/test/foo.js
+++ /dev/null
@@ -1,30 +0,0 @@
-'use strict';
-
-exports.get = function(query, callback, headers, cache) {
- process.nextTick(callback.bind(null, null, {
- query,
- headers,
- cache,
- }));
-};
-
-exports.check = function(callback, a1, a2) {
- process.nextTick(callback.bind(null, null, {
- a1,
- a2,
- }));
-};
-
-exports.query = function(callback) {
- process.nextTick(callback.bind(null, null, {
- result: 'result',
- }));
-};
-
-exports.getMultiValues = function(callback) {
- process.nextTick(callback.bind(null, null, 'a1', 'a2', 'a3'));
-};
-
-exports.mirror = function(input) {
- return input;
-};
diff --git a/test/foo.ts b/test/foo.ts
new file mode 100644
index 0000000..1a29d7e
--- /dev/null
+++ b/test/foo.ts
@@ -0,0 +1,59 @@
+interface QueryResult {
+ query: any;
+ headers: any;
+ cache: any;
+}
+
+interface CheckResult {
+ a1: any;
+ a2: any;
+}
+
+interface QueryCallback {
+ (err: any, result: QueryResult): void;
+}
+
+interface CheckCallback {
+ (err: any, result: CheckResult): void;
+}
+
+interface SimpleCallback {
+ (err: any, result: { result: string }): void;
+}
+
+interface MultiValuesCallback {
+ (err: any, ...results: any[]): void;
+}
+
+export const foo = {
+ get(query: any, callback: QueryCallback, headers?: any, cache?: any): void {
+ process.nextTick(callback.bind(null, null, {
+ query,
+ headers,
+ cache,
+ }));
+ },
+
+ check(callback: CheckCallback, a1: any, a2: any): void {
+ process.nextTick(callback.bind(null, null, {
+ a1,
+ a2,
+ }));
+ },
+
+ query(callback?: SimpleCallback): void {
+ if (!callback) return;
+ process.nextTick(callback.bind(null, null, {
+ result: 'result',
+ }));
+ },
+
+ getMultiValues(callback: MultiValuesCallback): void {
+ process.nextTick(callback.bind(null, null, 'a1', 'a2', 'a3'));
+ },
+
+ mirror(input: T): T {
+ return input;
+ },
+};
+
diff --git a/test/mm.test.js b/test/mm.test.ts
similarity index 80%
rename from test/mm.test.js
rename to test/mm.test.ts
index 3a66fda..4316fa5 100644
--- a/test/mm.test.js
+++ b/test/mm.test.ts
@@ -1,25 +1,30 @@
-require('should');
-const os = require('os');
-const path = require('path');
-const fs = require('fs');
-const assert = require('assert');
-const http = require('http');
-const https = require('https');
-const child_process = require('child_process');
-const { randomUUID } = require('crypto');
-const pedding = require('pedding');
-const ChunkStream = require('chunkstream');
-const mm = require('../');
-const foo = require('./foo');
+import 'should';
+import os from 'node:os';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import fs from 'node:fs';
+import assert from 'node:assert';
+import http from 'node:http';
+import https from 'node:https';
+import child_process from 'node:child_process';
+import { randomUUID } from 'node:crypto';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+import pedding from 'pedding';
+import mm from '../src/index.js';
+import { foo } from './foo.js';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
describe('test/mm.test.js', () => {
- let port = null;
- let sslPort = null;
+ let port: any;
+ let sslPort: any;
before(function(done) {
done = pedding(2, done);
- const app = http.createServer(function(req, res) {
+ const app: any = http.createServer(function(req, res) {
res.end(req.method + ' ' + req.url);
});
app.listen(0, function() {
@@ -28,7 +33,7 @@ describe('test/mm.test.js', () => {
});
const fixtures = path.join(__dirname, 'fixtures');
- const appssl = https.createServer({
+ const appssl: any = https.createServer({
key: fs.readFileSync(path.join(fixtures, 'test_key.pem')),
cert: fs.readFileSync(path.join(fixtures, 'test_cert.pem')),
}, function(req, res) {
@@ -102,7 +107,7 @@ describe('test/mm.test.js', () => {
mm.data(foo, 'get', [ 'b1', 'b2' ]);
foo.get('q1', function(err, data) {
assert(!err);
- data.should.eql([ 'b1', 'b2' ]);
+ assert.deepEqual(data, [ 'b1', 'b2' ]);
done();
});
});
@@ -112,12 +117,12 @@ describe('test/mm.test.js', () => {
done = pedding(2, done);
foo.get('q1', function(err, data) {
assert(!err);
- data.should.eql([ 'b1', 'b2' ]);
+ assert.deepEqual(data, [ 'b1', 'b2' ]);
done();
});
foo.get('q1', function(err, data) {
assert(!err);
- data.should.eql([ 'b1', 'b2' ]);
+ assert.deepEqual(data, [ 'b1', 'b2' ]);
done();
});
});
@@ -200,7 +205,7 @@ describe('test/mm.test.js', () => {
assert(err);
err.name.should.equal('MockError');
err.message.should.equal('mm mock error');
- err.code.should.equal('ENOENT');
+ err.code!.should.equal('ENOENT');
assert(!data);
done();
});
@@ -228,7 +233,7 @@ describe('test/mm.test.js', () => {
assert(err);
err.name.should.equal('MockError');
err.message.should.equal('500ms timeout');
- err.code.should.equal('ENOENT');
+ err.code!.should.equal('ENOENT');
assert(!data);
use.should.above(490);
done();
@@ -236,7 +241,6 @@ describe('test/mm.test.js', () => {
});
it.skip('should work for callback is not the last params case', function(done) {
- const foo = require('./foo');
done = pedding(3, done);
mm.error(foo, 'get', 'mock foo.get error');
@@ -264,7 +268,6 @@ describe('test/mm.test.js', () => {
});
it.skip('should throw error', function() {
- const foo = require('./foo');
mm.error(foo, 'query', 'mock foo.check error');
(function() {
foo.query();
@@ -275,13 +278,11 @@ describe('test/mm.test.js', () => {
describe('syncData, syncEmpty', function() {
it('should mock data ok', function() {
- const foo = require('./foo');
mm.syncData(foo, 'mirror', 'test');
foo.mirror('input').should.equal('test');
});
it('should mock empty ok', function() {
- const foo = require('./foo');
mm.syncEmpty(foo, 'mirror');
assert(!foo.mirror('input'));
});
@@ -289,7 +290,6 @@ describe('test/mm.test.js', () => {
describe('syncError', function() {
it('should mock error with out error message ok', function() {
- const foo = require('./foo');
mm.syncError(foo, 'mirror');
(function() {
foo.mirror('input');
@@ -297,7 +297,6 @@ describe('test/mm.test.js', () => {
});
it('should mock error with string error message ok', function() {
- const foo = require('./foo');
mm.syncError(foo, 'mirror', 'mock error');
(function() {
foo.mirror('input');
@@ -305,7 +304,6 @@ describe('test/mm.test.js', () => {
});
it('should mock error with error object ok', function() {
- const foo = require('./foo');
mm.syncError(foo, 'mirror', new Error('mock error'));
(function() {
foo.mirror('input');
@@ -325,7 +323,7 @@ describe('test/mm.test.js', () => {
const mockURL = '/foo';
const mockResData = 'mock data';
const mockResHeaders = { server: 'mock server' };
- mm[modName].request(mockURL, mockResData, mockResHeaders);
+ (mm as any)[modName].request(mockURL, mockResData, mockResHeaders);
mod.get({
host: '127.0.0.1',
@@ -368,7 +366,7 @@ describe('test/mm.test.js', () => {
const mockURL = /foo$/;
const mockResData = 'mock data with regex url';
const mockResHeaders = { server: 'mock server' };
- mm[modName].request(mockURL, mockResData, mockResHeaders);
+ (mm as any)[modName].request(mockURL, mockResData, mockResHeaders);
done = pedding(2, done);
@@ -409,7 +407,7 @@ describe('test/mm.test.js', () => {
const mockURL = /foo$/;
const mockResData = [ 'mock data with regex url', '哈哈' ];
const mockResHeaders = { server: 'mock server' };
- mm[modName].request(mockURL, mockResData, mockResHeaders, 500);
+ (mm as any)[modName].request(mockURL, mockResData, mockResHeaders, 500);
const start = Date.now();
mod.get({
@@ -435,7 +433,7 @@ describe('test/mm.test.js', () => {
it('should mock ' + modName + '.request({url: "/bar/foo"}) 500ms response delay', function(done) {
const mockResData = [ 'mock data with regex url', '哈哈' ];
const mockResHeaders = { server: 'mock server' };
- mm[modName].request({ url: '/bar/foo' }, mockResData, mockResHeaders, 500);
+ (mm as any)[modName].request({ url: '/bar/foo' }, mockResData, mockResHeaders, 500);
const start = Date.now();
mod.get({
@@ -458,44 +456,17 @@ describe('test/mm.test.js', () => {
});
});
- it.skip('should mock ' + modName + '.request({url: "/bar/foo"}) with stream 500ms response delay',
- function(done) {
- const mockResData = new ChunkStream([ 'mock data with regex url', '哈哈' ]);
- const mockResHeaders = { server: 'mock server' };
- mm[modName].request({ url: '/bar/foo' }, mockResData, mockResHeaders, 500);
-
- const start = Date.now();
- mod.get({
- host: 'npmjs.org',
- path: '/bar/foo',
- }, function(res) {
- res.headers.should.eql(mockResHeaders);
- res.setEncoding('utf8');
- let body = '';
- res.on('data', function(chunk) {
- chunk.should.be.a.String;
- body += chunk;
- });
- res.on('end', function() {
- const use = Date.now() - start;
- body.should.equal([ 'mock data with regex url', '哈哈' ].join(''));
- use.should.above(490);
- done();
- });
- });
- });
-
it('should mock ' + modName + '.request({url: "/bar/foo"}) pipe res work', done => {
const mockResData = fs.createReadStream(__filename);
const mockResHeaders = { server: 'mock server', statusCode: 200 };
- mm[modName].request('', mockResData, mockResHeaders);
+ (mm as any)[modName].request('', mockResData, mockResHeaders);
mod.get({
host: 'npmjs.org',
path: '/bar/foo',
}, onResponse);
- function onResponse(res) {
+ function onResponse(res: any) {
res.statusCode.should.equal(200);
res.headers.should.eql({ server: 'mock server' });
@@ -511,7 +482,7 @@ describe('test/mm.test.js', () => {
function(done) {
const mockResData = fs.createReadStream(__filename);
const mockResHeaders = { server: 'mock server', statusCode: 201 };
- mm[modName].request('', mockResData, mockResHeaders);
+ (mm as any)[modName].request('', mockResData, mockResHeaders);
const length = 5;
done = pedding(length, done);
for (let i = 0; i < length; i++) {
@@ -520,12 +491,12 @@ describe('test/mm.test.js', () => {
path: '/bar/foo',
}, onResponse);
}
- function onResponse(res) {
+ function onResponse(res: any) {
res.statusCode.should.equal(201);
res.headers.should.eql({ server: 'mock server' });
res.setEncoding('utf8');
let body = '';
- res.on('data', function(chunk) {
+ res.on('data', function(chunk: string) {
console.log('data emit: chunk size: %d', chunk.length);
chunk.should.be.a.String;
body += chunk;
@@ -543,7 +514,7 @@ describe('test/mm.test.js', () => {
it('should mock ' + modName + '.request({host: "cnodejs.org"}) 500ms response delay', function(done) {
const mockResData = [ 'mock data with regex url', '哈哈' ];
const mockResHeaders = { server: 'mock server' };
- mm[modName].request({ host: 'cnodejs.org' }, mockResData, mockResHeaders, 500);
+ (mm as any)[modName].request({ host: 'cnodejs.org' }, mockResData, mockResHeaders, 500);
const start = Date.now();
mod.get({
@@ -569,7 +540,7 @@ describe('test/mm.test.js', () => {
it('should mock ' + modName + '.request({host: /cnodejs/}) 500ms response delay', function(done) {
const mockResData = [ 'mock data with regex url', '哈哈' ];
const mockResHeaders = { server: 'mock server' };
- mm[modName].request({ host: /cnodejs/ }, mockResData, mockResHeaders, 500);
+ (mm as any)[modName].request({ host: /cnodejs/ }, mockResData, mockResHeaders, 500);
const start = Date.now();
mod.get({
@@ -596,7 +567,7 @@ describe('test/mm.test.js', () => {
const mockURL = /foo$/;
const mockResData = 'mock data with regex url';
const mockResHeaders = { server: 'mock server' };
- mm[modName].request(mockURL, mockResData, mockResHeaders, 500);
+ (mm as any)[modName].request(mockURL, mockResData, mockResHeaders, 500);
done = pedding(2, done);
const start = Date.now();
@@ -628,7 +599,7 @@ describe('test/mm.test.js', () => {
const mockURL = /foo$/;
const mockResData = 'mock data with regex url';
const mockResHeaders = { server: 'mock server' };
- mm[modName].request(mockURL, mockResData, mockResHeaders, 1000);
+ (mm as any)[modName].request(mockURL, mockResData, mockResHeaders, 1000);
const req = mod.get({
host: 'cnodejs.org',
@@ -652,14 +623,14 @@ describe('test/mm.test.js', () => {
describe('http(s).requestError()', function() {
[ 'http', 'https' ].forEach(function(modName) {
const mod = modName === 'http' ? http : https;
- it('should ' + modName + '.reqeust() return req error', function(done) {
+ it('should ' + modName + '.request() return req error', function(done) {
const modPort = modName === 'http' ? port : sslPort;
done = pedding(2, done);
const mockURL = '/req';
const reqError = 'mock req error';
- mm[modName].requestError(mockURL, reqError);
+ (mm as any)[modName].requestError(mockURL, reqError);
let req = mod.get({
path: '/req',
@@ -696,12 +667,12 @@ describe('test/mm.test.js', () => {
it('should ' + modName + '.reqeust() return req error after response emit', function(done) {
const mockURL = '/res';
const resError = 'mock res error';
- mm[modName].requestError(mockURL, null, resError);
+ (mm as any)[modName].requestError(mockURL, null, resError);
done = pedding(2, done);
const req = mod.get({
path: '/res',
- }, function(res) {
+ }, function(res: any) {
res.statusCode.should.eql(200);
res.headers.server.should.eql('MockMateServer');
done();
@@ -717,14 +688,14 @@ describe('test/mm.test.js', () => {
it('should ' + modName + '.reqeust() return res error 500ms delay', function(done) {
const mockURL = '/res';
const resError = 'mock res error with 500ms delay';
- mm[modName].requestError(mockURL, null, resError, 500);
+ (mm as any)[modName].requestError(mockURL, null, resError, 500);
done = pedding(2, done);
const start = Date.now();
const req = mod.get({
path: '/res',
- }, function(res) {
- res.statusCode.should.eql(200);
+ }, function(res: any) {
+ res.statusCode!.should.eql(200);
res.headers.server.should.eql('MockMateServer');
done();
});
@@ -741,7 +712,7 @@ describe('test/mm.test.js', () => {
it('should ' + modName + '.reqeust() not emit req error 1000ms delay after req.abort()', function(done) {
const mockURL = '/res';
const resError = 'mock res error with 500ms delay';
- mm[modName].requestError(mockURL, null, resError, 1000);
+ (mm as any)[modName].requestError(mockURL, null, resError, 1000);
const start = Date.now();
const req = mod.get({
@@ -780,7 +751,7 @@ describe('test/mm.test.js', () => {
done();
});
ls.on('close', function(code) {
- code.should.equal(1);
+ code!.should.equal(1);
done();
});
mm.restore();
@@ -797,25 +768,25 @@ describe('test/mm.test.js', () => {
it('should mock process.env.KEY work', function() {
const orginalEnv = process.env.NODE_ENV;
mm(process.env, 'NODE_ENV', 'test2');
- process.env.NODE_ENV.should.equal('test2');
+ process.env.NODE_ENV!.should.equal('test2');
mm.restore();
assert(process.env.NODE_ENV === orginalEnv);
mm(process.env, 'NODE_ENV', 'test2');
- process.env.NODE_ENV.should.equal('test2');
+ process.env.NODE_ENV!.should.equal('test2');
mm(process.env, 'NODE_ENV', 'production');
- process.env.NODE_ENV.should.equal('production');
+ process.env.NODE_ENV!.should.equal('production');
mm.restore();
assert(process.env.NODE_ENV === orginalEnv);
});
it('should mm() just like muk()', function(done) {
- mm(fs, 'readFile', function(filename, callback) {
+ mm(fs, 'readFile', function(filename: any, callback: any) {
process.nextTick(function() {
const str = 'filename: ' + filename;
- const buf = Buffer.from ? Buffer.from(str) : new Buffer(str);
+ const buf = Buffer.from ? Buffer.from(str) : Buffer.from(str);
callback(null, buf);
});
});
@@ -861,12 +832,12 @@ describe('test/mm.test.js', () => {
it('shoud mock function with property', () => {
const NativeDate = Date;
- const mockNow = function(date) {
- const NewDate = function(...args) {
+ const mockNow = function(date: any) {
+ const NewDate = function(...args: any[]) {
if (args.length === 0) {
return new NativeDate(date);
}
- return new NativeDate(...args);
+ return new NativeDate(args[0], args[1], args[2]);
};
NewDate.now = function() {
return new NativeDate(date).getTime();
@@ -892,20 +863,20 @@ describe('test/mm.test.js', () => {
});
it('should mock HOME env', function() {
- process.env.HOME.should.equal(this.HOME);
+ process.env.HOME!.should.equal(this.HOME);
mm(process.env, 'HOME', '/tmp/home');
- process.env.HOME.should.equal('/tmp/home');
- process.env.TEST_ENV.should.equal('foo');
+ process.env.HOME!.should.equal('/tmp/home');
+ process.env.TEST_ENV!.should.equal('foo');
});
it('should mock HOME env to another value', function() {
- process.env.HOME.should.equal(this.HOME);
+ process.env.HOME!.should.equal(this.HOME);
mm(process.env, 'HOME', '/tmp/home2');
- process.env.HOME.should.equal('/tmp/home2');
- process.env.TEST_ENV.should.equal('foo');
+ process.env.HOME!.should.equal('/tmp/home2');
+ process.env.TEST_ENV!.should.equal('foo');
mm.restore();
- process.env.HOME.should.equal(this.HOME);
+ process.env.HOME!.should.equal(this.HOME);
assert(!process.env.TEST_ENV);
});
@@ -918,14 +889,14 @@ describe('test/mm.test.js', () => {
});
describe('restore', function() {
- let orgRequest;
+ let orgRequest: any;
beforeEach(function() {
orgRequest = http.request;
});
afterEach(function() {
http.request = orgRequest;
});
- it('should not alter the http.request function withou http(s) used', function() {
+ it('should not alter the http.request function without http(s) used', function() {
const obj = {
foo() {
return 'original foo';
@@ -944,7 +915,7 @@ describe('test/mm.test.js', () => {
try {
http.request({ path: '/foo' }, function() {});
throw new Error('should not run this');
- } catch (e) {
+ } catch (e: any) {
e.message.should.equal('Never want to send request out');
}
});
@@ -959,15 +930,15 @@ describe('test/mm.test.js', () => {
mod.request = function() {
throw new Error('Never want to send request out');
};
- mm[modName].request(mockURLFoo, mockResData, mockResHeaders);
- mm[modName].request(mockURLBar, mockResData, mockResHeaders);
+ (mm as any)[modName].request(mockURLFoo, mockResData, mockResHeaders);
+ (mm as any)[modName].request(mockURLBar, mockResData, mockResHeaders);
mm.restore();
try {
const req = mod.request({ path: '/baz' }, function() {});
req.end();
throw new Error('should not run this');
- } catch (e) {
+ } catch (e: any) {
e.message.should.equal('Never want to send request out');
}
});
@@ -986,7 +957,7 @@ describe('test/mm.test.js', () => {
it('should spy function with data', () => {
const target = {
- add(a, b) {
+ add(a: number, b: number) {
return a + b;
},
};
@@ -994,14 +965,14 @@ describe('test/mm.test.js', () => {
mm.syncData(target, 'add', 3);
target.add(1, 1).should.equal(3);
target.add(2, 2).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
+ (target.add as any).called.should.equal(2);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 2, 2 ]);
});
it('should spy async function with data', async () => {
const target = {
- async add(a, b) {
+ async add(a: number, b: number) {
return a + b;
},
};
@@ -1009,89 +980,54 @@ describe('test/mm.test.js', () => {
mm.data(target, 'add', 3);
(await target.add(1, 1)).should.equal(3);
(await target.add(2, 2)).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
- });
-
- it('should spy generator function with data', function* () {
- const target = {
- * add(a, b) {
- return a + b;
- },
- };
-
- mm.data(target, 'add', 3);
- (yield target.add(1, 1)).should.equal(3);
- (yield target.add(2, 2)).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
+ (target.add as any).called.should.equal(2);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 2, 2 ]);
});
it('should spy function', () => {
const target = {
- add(a, b) {
+ add(a: number, b: number) {
this.foo();
return a + b;
},
foo() { /* */ },
};
- mm(target, 'add', function() {
+ mm(target, 'add', function(this: any) {
this.foo();
return 3;
});
target.add(1, 1).should.equal(3);
target.add(2, 2).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
+ (target.add as any).called.should.equal(2);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 2, 2 ]);
});
it('should spy async function', async () => {
const target = {
- async add(a, b) {
+ async add(a: number, b: number) {
await this.foo();
return a + b;
},
async foo() { /* */ },
};
- mm(target, 'add', async function() {
+ mm(target, 'add', async function(this: any) {
await this.foo();
return 3;
});
(await target.add(1, 1)).should.equal(3);
(await target.add(2, 2)).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
- });
-
- it('should spy generator function', function* () {
- const target = {
- * add(a, b) {
- yield this.foo();
- return a + b;
- },
- * foo() { /* */ },
- };
-
- mm(target, 'add', function* () {
- yield this.foo();
- return 3;
- });
- (yield target.add(1, 1)).should.equal(3);
- (yield target.add(2, 2)).should.equal(3);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
+ (target.add as any).called.should.equal(2);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 2, 2 ]);
});
it('should ignore jest.fn()', () => {
const target = {
- add(a, b) {
+ add(a: number, b: number) {
return a + b;
},
};
@@ -1109,7 +1045,7 @@ describe('test/mm.test.js', () => {
it('should mm.spy() work', async () => {
const target = {
- async add(a, b) {
+ async add(a: number, b: number) {
await this.foo();
return a + b;
},
@@ -1119,30 +1055,26 @@ describe('test/mm.test.js', () => {
mm.spy(target, 'add');
(await target.add(1, 1)).should.equal(2);
(await target.add(2, 2)).should.equal(4);
- target.add.called.should.equal(2);
- target.add.calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
- target.add.lastCalledArguments.should.eql([ 2, 2 ]);
+ (target.add as any).called.should.equal(2);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ], [ 2, 2 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 2, 2 ]);
});
it('should reset spy statistics after restore', () => {
const target = {
- add(a, b) {
+ add(a: number, b: number) {
return a + b;
},
};
mm.spy(target, 'add');
target.add(1, 1);
- target.add.called.should.equal(1);
- target.add.calledArguments.should.eql([[ 1, 1 ]]);
- target.add.lastCalledArguments.should.eql([ 1, 1 ]);
+ (target.add as any).called.should.equal(1);
+ (target.add as any).calledArguments.should.eql([[ 1, 1 ]]);
+ (target.add as any).lastCalledArguments.should.eql([ 1, 1 ]);
mm.restore();
- assert.strictEqual(target.add.called, undefined);
- assert.strictEqual(target.add.calledArguments, undefined);
- assert.strictEqual(target.add.lastCalledArguments, undefined);
+ assert.strictEqual((target.add as any).called, undefined);
+ assert.strictEqual((target.add as any).calledArguments, undefined);
+ assert.strictEqual((target.add as any).lastCalledArguments, undefined);
});
});
});
-
-require('./es6');
-require('./thunk');
-require('./async-await');
diff --git a/test/thunk.js b/test/thunk.js
deleted file mode 100644
index b1d74d5..0000000
--- a/test/thunk.js
+++ /dev/null
@@ -1,69 +0,0 @@
-'use strict';
-
-const thunkify = require('thunkify-wrap');
-const mm = require('..');
-
-describe('test/thunk.test.js', function() {
- const foo = {
- getMultiValues: thunkify(function(arg, callback) {
- setImmediate(function() {
- callback(null, 1, 2, 3);
- });
- }),
- getValue: thunkify(function(arg, callback) {
- setImmediate(function() {
- callback(null, 1);
- });
- }),
- };
-
- afterEach(mm.restore);
-
- describe('datas(), data()', function() {
- it('should mock generator function', function* () {
- mm.datas(foo, 'getMultiValues', [ 'b1', 'b2', 'b3' ]);
- let datas = yield foo.getMultiValues();
- datas.should.eql([ 'b1', 'b2', 'b3' ]);
-
- mm.datas(foo, 'getMultiValues', 1);
- datas = yield foo.getMultiValues('key');
- datas.should.equal(1);
-
- mm.data(foo, 'getValue', 2);
- let data = yield foo.getValue('key');
- data.should.equal(2);
-
- mm.restore();
- data = yield foo.getValue('key');
- data.should.equal(1);
- });
- });
-
- describe('error()', function() {
- it('should mock error', function* () {
- mm.error(foo, 'getValue');
- try {
- yield foo.getValue();
- throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('mm mock error');
- }
-
- mm.error(foo, 'getValue', 'foo error', 200);
- try {
- yield foo.getValue();
- throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('foo error');
- }
-
- mm.error(foo, 'getValue', new Error('new foo error'));
- try {
- yield foo.getValue();
- throw new Error('should not run this');
- } catch (err) {
- err.message.should.equal('new foo error');
- }
- });
- });
-});