Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support mock function which has properties #53

Merged
merged 2 commits into from Nov 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/nodejs.yml
@@ -0,0 +1,46 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
schedule:
- cron: '0 2 * * *'

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
node-version: [14, 16, 18]
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- name: Checkout Git Source
uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: npm i

- name: Continuous Integration
run: npm run ci

- name: Code Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
15 changes: 0 additions & 15 deletions .travis.yml

This file was deleted.

51 changes: 0 additions & 51 deletions azure-pipelines.template.yml

This file was deleted.

16 changes: 0 additions & 16 deletions azure-pipelines.yml

This file was deleted.

53 changes: 16 additions & 37 deletions lib/mm.js
Expand Up @@ -19,45 +19,24 @@ function spyFunction(target, property, fn) {
if (!is.function(fn)) return fn;
// support mock with jest.fn()
if (fn._isMockFunction && fn.mock) return fn;
if (is.asyncFunction(fn)) {
const spy = async function(...args) {
spy.called = spy.called || 0;
spy.calledArguments = spy.calledArguments || [];
spy.calledArguments.push(args);
spy.lastCalledArguments = args;
spy.called++;
return await fn.call(this, ...args);
};
return spy;
}

if (is.generatorFunction(fn)) {
const spy = function* (...args) {
spy.called = spy.called || 0;
spy.calledArguments = spy.calledArguments || [];
spy.calledArguments.push(args);
spy.lastCalledArguments = args;
spy.called++;
return yield fn.call(this, ...args);
};
return spy;
}

// don't allow mock async function to common function
const isAsyncLike = isAsyncLikeFunction(target, property);
const spy = function(...args) {
spy.called = spy.called || 0;
spy.calledArguments = spy.calledArguments || [];
spy.calledArguments.push(args);
spy.lastCalledArguments = args;
spy.called++;
const res = fn.call(this, ...args);
if (isAsyncLike && !is.promise(res)) {
throw new Error(`Can\'t mock async function to normal function for property "${property}"`);
}
return res;
};
return spy;
const isGenerator = is.generatorFunction(fn);
const isAsyncLike = !isGenerator && isAsyncLikeFunction(target, property);
return new Proxy(fn, {
apply(target, thisArg, args) {
fn.called = fn.called || 0;
fn.calledArguments = fn.calledArguments || [];
fn.calledArguments.push(args);
fn.lastCalledArguments = args;
fn.called++;
const res = Reflect.apply(target, thisArg, args);
if (isAsyncLike && !is.promise(res)) {
throw new Error(`Can\'t mock async function to normal function for property "${property}"`);
}
return res;
},
});
}

function isAsyncLikeFunction(target, property) {
Expand Down
7 changes: 3 additions & 4 deletions package.json
Expand Up @@ -25,7 +25,7 @@
"chunkstream": "^0.0.1",
"co": "^4.6.0",
"egg-bin": "^1.11.1",
"egg-ci": "^1.13.1",
"egg-ci": "^2.2.0",
"enable": "^3.4.0",
"eslint": "^6.8.0",
"eslint-config-egg": "^8.0.1",
Expand All @@ -48,11 +48,10 @@
"test"
],
"engines": {
"node": ">=8.0.0"
"node": ">=14.0.0"
},
"ci": {
"type": "travis, azure-pipelines",
"version": "8, 10, 12, 13"
"version": "14, 16, 18"
},
"author": "fengmk2 <fengmk2@gmail.com> (https://fengmk2.com)",
"license": "MIT"
Expand Down
22 changes: 22 additions & 0 deletions test/mm.test.js
Expand Up @@ -860,6 +860,28 @@ describe('test/mm.test.js', () => {
});
});
});

it('shoud mock function with property', () => {
const NativeDate = Date;
const mockNow = function(date) {
const NewDate = function(...args) {
if (args.length === 0) {
return new NativeDate(date);
}
return new NativeDate(...args);
};
NewDate.now = function() {
return new NativeDate(date).getTime();
};
NewDate.UTC = NativeDate.UTC;
NewDate.parse = NativeDate.parse;
NewDate.prototype = NativeDate.prototype;
return NewDate;
};
mm(global, 'Date', mockNow('2022-11-20T05:22:04.569Z'));
assert(Date.now() === 1668921724569);
assert(new Date().getTime() === 1668921724569);
});
});

describe('mm(process.env, "HOME")', function() {
Expand Down