From 7581288b807a3f1f61bd1027ac0b451f7ddfad0c Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 9 Dec 2023 12:56:44 +0800 Subject: [PATCH] feat: support mock.dataWithAsyncDispose() (#59) see https://www.totaltypescript.com/typescript-5-2-new-keyword-using --- .github/workflows/codeql.yml | 74 ----------------------------------- .github/workflows/nodejs.yml | 4 +- .github/workflows/release.yml | 6 +-- AUTHORS | 10 ----- README.md | 50 +++++++++++++++++++++-- index.d.ts | 5 +++ lib/es6.js | 10 +++++ package.json | 18 ++++++--- test/async-await.js | 2 - test/asyncDispose.test.ts | 41 +++++++++++++++++++ test/mm.test.js | 2 - tsconfig.json | 11 ++++++ 12 files changed, 129 insertions(+), 104 deletions(-) delete mode 100644 .github/workflows/codeql.yml delete mode 100644 AUTHORS create mode 100644 test/asyncDispose.test.ts create mode 100644 tsconfig.json diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 1a24a09..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,74 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master" ] - schedule: - - cron: '43 19 * * 2' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 3687113..4b0c095 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -7,12 +7,10 @@ on: pull_request: branches: [ master ] - workflow_dispatch: {} - jobs: Job: name: Node.js - uses: artusjs/github-actions/.github/workflows/node-test.yml@v1 + uses: node-modules/github-actions/.github/workflows/node-test.yml@master with: os: 'ubuntu-latest, macos-latest, windows-latest' version: '14, 16, 18, 20' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1612587..1c6cbb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,14 +4,10 @@ on: push: branches: [ master ] - workflow_dispatch: {} - jobs: release: name: Node.js - uses: artusjs/github-actions/.github/workflows/node-release.yml@v1 + uses: node-modules/github-actions/.github/workflows/node-release.yml@master secrets: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GIT_TOKEN: ${{ secrets.GIT_TOKEN }} - with: - checkTest: false diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index c3ca087..0000000 --- a/AUTHORS +++ /dev/null @@ -1,10 +0,0 @@ -# Ordered by date of first contribution. -# Auto-generated by 'contributors' on Fri, 27 Dec 2013 10:43:58 GMT. -# https://github.com/xingrz/node-contributors - -fengmk2 (https://github.com/fengmk2) -dead_horse (https://github.com/dead-horse) -AlsoTang (https://github.com/alsotang) -Haoliang Gao (https://github.com/popomore) -xavierzhou (https://github.com/xavierchow) - diff --git a/README.md b/README.md index 491c7b5..dd09cc2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -mm -======= +# mm, mock mate [![NPM version][npm-image]][npm-url] [![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) @@ -18,7 +17,7 @@ An simple but flexible **mock(or say stub)** package, mock mate. ## Install ```bash -$ npm install mm --save-dev +npm install mm --save-dev ``` ## Usage @@ -145,6 +144,38 @@ fs.readFile = function (...args, callback) { }; ``` +### .dataWithAsyncDispose(module, propertyName, promiseResolveArg) + +Support [Symbol.asyncDispose](https://www.totaltypescript.com/typescript-5-2-new-keyword-using) + +```js +mm.dataWithAsyncDispose(locker, 'tryLock', { + locked: true, +}); + +// equals + +locker.tryLock = async () => { + return { + locked: true, + [Symbol.asyncDispose](): async () => { + // do nothing + }, + }; +} +``` + +Run test with `await using` should work: + +```js +mm.dataWithAsyncDispose(locker, 'tryLock', { + locked: true, +}); + +await using lock = await locker.tryLock('foo-key'); +assert.equal(lock.locked, true); +``` + ### .empty(module, propertyName) ```js @@ -305,3 +336,16 @@ assert(await foo1.fetch() === 3); ## License [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`. + + diff --git a/index.d.ts b/index.d.ts index 5030c34..9991e5e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -33,6 +33,11 @@ declare namespace mm { */ function data(mod: any, method: string, data: any, timeout?: number): MockMate; + /** + * mock return data with Symbol.asyncDispose method + */ + function dataWithAsyncDispose(mod: any, method: string, data: object, timeout?: number): MockMate; + /** * mock return callback(null, null). */ diff --git a/lib/es6.js b/lib/es6.js index e755051..dfa7dbb 100644 --- a/lib/es6.js +++ b/lib/es6.js @@ -43,6 +43,16 @@ mm.data = function(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])) { diff --git a/package.json b/package.json index aa1c5db..247f28a 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,11 @@ "lib" ], "scripts": { - "test": "npm run lint && egg-bin test", - "ci": "npm run lint && egg-bin cov", - "lint": "eslint --fix lib test index.js" + "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", @@ -19,14 +21,20 @@ "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.28.0", - "eslint-config-egg": "^12.1.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", diff --git a/test/async-await.js b/test/async-await.js index 020af9c..1f6982e 100644 --- a/test/async-await.js +++ b/test/async-await.js @@ -1,5 +1,3 @@ -'use strict'; - const mm = require('..'); describe('test/async-await.test.js', () => { diff --git a/test/asyncDispose.test.ts b/test/asyncDispose.test.ts new file mode 100644 index 0000000..f172f69 --- /dev/null +++ b/test/asyncDispose.test.ts @@ -0,0 +1,41 @@ +import { strict as assert } from 'node:assert'; +require('@hazae41/symbol-dispose-polyfill'); +import mm from '../index'; + +describe('test/asyncDispose.test.ts', () => { + const foo = { + async request() { + return 'yes'; + }, + async echo() { + return { + hi: 'yes', + async [Symbol.asyncDispose]() { + console.log('asyncDispose run'); + }, + }; + }, + * generatorRequest() { + return 'yes'; + }, + }; + + afterEach(mm.restore); + + describe('dataWithAsyncDispose()', () => { + it('should mock async function with asyncDispose', async () => { + await using data0 = await foo.echo(); + assert.equal(data0.hi, 'yes'); + + mm.dataWithAsyncDispose(foo, 'echo', { + hi: 'no', + }); + await using data1 = await foo.echo(); + assert.equal(data1.hi, 'no'); + + mm.restore(); + await using data2 = await foo.echo(); + assert.equal(data2.hi, 'yes'); + }); + }); +}); diff --git a/test/mm.test.js b/test/mm.test.js index b299ce7..3a66fda 100644 --- a/test/mm.test.js +++ b/test/mm.test.js @@ -1,5 +1,3 @@ -'use strict'; - require('should'); const os = require('os'); const path = require('path'); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..298cdd2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@eggjs/tsconfig", + "compileOnSave": true, + "compilerOptions": { + "strict": true, + "noImplicitAny": true, + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + } +}