From adb9dbe88fdf930f182bc71e2d741163f0e47179 Mon Sep 17 00:00:00 2001 From: zjx0905 <954270063@qq.com> Date: Mon, 10 Apr 2023 22:53:15 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=B5=8B=E8=AF=95=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E7=8E=87=20=F0=9F=92=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 5 + package.json | 5 +- pnpm-lock.yaml | 352 ++++++++++++++++++++++++----- src/core/Axios.ts | 8 +- src/core/AxiosDomain.ts | 2 +- src/core/dispatchRequest.ts | 11 +- src/core/mergeConfig.ts | 6 +- src/helpers/combineURL.ts | 2 +- src/helpers/dynamicURL.ts | 2 +- test/adapter.platform.test.ts | 14 ++ test/adapter.test.ts | 139 ++++++++++-- test/axios.api.test.ts | 27 +-- test/axios.instance.test.ts | 113 +-------- test/core/Axios.test.ts | 11 +- test/core/AxiosDomain.test.ts | 19 ++ test/core/dispatchRequest.test.ts | 18 +- test/core/mergeConfig.test.ts | 26 ++- test/core/request.test.ts | 57 ++++- test/helpers/buildURL.test.ts | 3 +- test/helpers/combineURL.test.ts | 8 +- test/helpers/deepMerge.test.ts | 2 +- test/helpers/dynamicURL.test.ts | 2 +- test/helpers/error.test.ts | 16 +- test/helpers/ignore.test.ts | 2 +- test/helpers/isAbsoluteURL.test.ts | 2 +- test/helpers/isTypes.test.ts | 2 +- vitest.config.ts | 7 +- 27 files changed, 619 insertions(+), 242 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1d3a75..db3605f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,3 +46,8 @@ jobs: - name: Test run: pnpm test + + # - name: Upload coverage reports to Codecov + # uses: codecov/codecov-action@v3 + # with: + # token: ${{ secrets.CODECOV_TOKEN }} diff --git a/package.json b/package.json index 6e4dd9e..7a6ba09 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "upload:asset": "esno scripts/upload-asset.ts", "test": "vitest run", "test:watch": "vitest", + "test:cov": "vitest run --coverage", "lint": "eslint --cache .", "lint:fix": "pnpm lint --fix", "docs:dev": "pnpm -C docs dev", @@ -55,7 +56,7 @@ "@types/node": "^18.15.5", "@typescript-eslint/eslint-plugin": "^5.55.0", "@typescript-eslint/parser": "^5.55.0", - "@vitest/coverage-c8": "^0.29.8", + "@vitest/coverage-istanbul": "^0.30.0", "actions-toolkit": "^6.0.1", "chalk": "^5.2.0", "consola": "^2.15.3", @@ -101,7 +102,7 @@ "peerDependencyRules": { "ignoreMissing": [ "@algolia/client-search", - "@octokit/core" + "esbuild" ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8621a3..8133364 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,7 +9,7 @@ importers: '@types/node': ^18.15.5 '@typescript-eslint/eslint-plugin': ^5.55.0 '@typescript-eslint/parser': ^5.55.0 - '@vitest/coverage-c8': ^0.29.8 + '@vitest/coverage-istanbul': ^0.30.0 actions-toolkit: ^6.0.1 chalk: ^5.2.0 consola: ^2.15.3 @@ -38,7 +38,7 @@ importers: '@types/node': 18.15.5 '@typescript-eslint/eslint-plugin': 5.56.0_2hcjazgfnbtq42tcc73br2vup4 '@typescript-eslint/parser': 5.56.0_j4766f7ecgqbon3u7zlxn5zszu - '@vitest/coverage-c8': 0.29.8_vitest@0.30.0 + '@vitest/coverage-istanbul': 0.30.0_vitest@0.30.0 actions-toolkit: 6.0.1 chalk: 5.2.0 consola: 2.15.3 @@ -206,6 +206,14 @@ packages: '@algolia/requester-common': 4.16.0 dev: true + /@ampproject/remapping/2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -219,7 +227,115 @@ packages: dependencies: '@babel/highlight': 7.18.6 dev: true - optional: true + + /@babel/compat-data/7.21.4: + resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core/7.21.4: + resolution: {integrity: sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.21.4 + '@babel/generator': 7.21.4 + '@babel/helper-compilation-targets': 7.21.4_@babel+core@7.21.4 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helpers': 7.21.0 + '@babel/parser': 7.21.4 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.4 + '@babel/types': 7.21.4 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator/7.21.4: + resolution: {integrity: sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets/7.21.4_@babel+core@7.21.4: + resolution: {integrity: sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.21.4 + '@babel/core': 7.21.4 + '@babel/helper-validator-option': 7.21.0 + browserslist: 4.21.5 + lru-cache: 5.1.1 + semver: 6.3.0 + dev: true + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name/7.21.0: + resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/types': 7.21.4 + dev: true + + /@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + dev: true + + /@babel/helper-module-imports/7.21.4: + resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + dev: true + + /@babel/helper-module-transforms/7.21.2: + resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.4 + '@babel/types': 7.21.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + dev: true + + /@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + dev: true /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} @@ -231,6 +347,22 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-option/7.21.0: + resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers/7.21.0: + resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.4 + '@babel/types': 7.21.4 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/highlight/7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} @@ -248,6 +380,41 @@ packages: '@babel/types': 7.21.3 dev: true + /@babel/parser/7.21.4: + resolution: {integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.21.4 + dev: true + + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.21.4 + '@babel/parser': 7.21.4 + '@babel/types': 7.21.4 + dev: true + + /@babel/traverse/7.21.4: + resolution: {integrity: sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.21.4 + '@babel/generator': 7.21.4 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.21.4 + '@babel/types': 7.21.4 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types/7.21.3: resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==} engines: {node: '>=6.9.0'} @@ -257,8 +424,13 @@ packages: to-fast-properties: 2.0.0 dev: true - /@bcoe/v8-coverage/0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + /@babel/types/7.21.4: + resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 dev: true /@commitlint/cli/17.5.0: @@ -760,11 +932,25 @@ packages: engines: {node: '>=8'} dev: true + /@jridgewell/gen-mapping/0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + /@jridgewell/resolve-uri/3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} dev: true + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} dev: true @@ -849,9 +1035,6 @@ packages: resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} peerDependencies: '@octokit/core': '>=2' - peerDependenciesMeta: - '@octokit/core': - optional: true dependencies: '@octokit/core': 2.5.4 '@octokit/types': 6.41.0 @@ -861,9 +1044,6 @@ packages: resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} peerDependencies: '@octokit/core': '>=3' - peerDependenciesMeta: - '@octokit/core': - optional: true dependencies: '@octokit/core': 2.5.4 dev: true @@ -974,10 +1154,6 @@ packages: resolution: {integrity: sha512-fHeEsm9hvmZ+QHpw6Fkvf19KIhuqnYLU6vtWLjd5BsMd/qVi7iTkMioDZl0mQmfNRA1A6NwvhrSRNr9hGYZGww==} dev: true - /@types/istanbul-lib-coverage/2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true @@ -1149,15 +1325,20 @@ packages: vue: 3.2.47 dev: true - /@vitest/coverage-c8/0.29.8_vitest@0.30.0: - resolution: {integrity: sha512-y+sEMQMctWokjnSqm3FCQEYFkjLrYaznsxEZHxcx8z2aftpYg3A5tvI1S5himfdEFo7o+OeHzh40bPSWZHW4oQ==} + /@vitest/coverage-istanbul/0.30.0_vitest@0.30.0: + resolution: {integrity: sha512-Pnpm20lsOA4NAQWptQFhc/855clQ2Z6PbJt8qfumBOCtcWCFHOC6JDarEqcodFSlRkeTqUNOnQ0e/xAjuRxSVQ==} peerDependencies: - vitest: '>=0.29.0 <1' + vitest: '>=0.30.0 <1' dependencies: - c8: 7.13.0 - picocolors: 1.0.0 - std-env: 3.3.2 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + test-exclude: 6.0.0 vitest: 0.30.0 + transitivePeerDependencies: + - supports-color dev: true /@vitest/expect/0.30.0: @@ -1521,27 +1702,19 @@ packages: fill-range: 7.0.1 dev: true - /buffer-from/1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /c8/7.13.0: - resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==} - engines: {node: '>=10.12.0'} + /browserslist/4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-report: 3.0.0 - istanbul-reports: 3.1.5 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.1.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 + caniuse-lite: 1.0.30001477 + electron-to-chromium: 1.4.356 + node-releases: 2.0.10 + update-browserslist-db: 1.0.10_browserslist@4.21.5 + dev: true + + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true /cac/6.7.14: @@ -1568,6 +1741,10 @@ packages: engines: {node: '>=6'} dev: true + /caniuse-lite/1.0.30001477: + resolution: {integrity: sha512-lZim4iUHhGcy5p+Ri/G7m84hJwncj+Kz7S5aD4hoQfslKZJgt0tHc/hafVbqHC5bbhHb+mrW2JOUHkI5KH7toQ==} + dev: true + /chai/4.3.7: resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} engines: {node: '>=4'} @@ -2034,6 +2211,10 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true + /electron-to-chromium/1.4.356: + resolution: {integrity: sha512-nEftV1dRX3omlxAj42FwqRZT0i4xd2dIg39sog/CnCJeCcL1TRd2Uh0i9Oebgv8Ou0vzTPw++xc+Z20jzS2B6A==} + dev: true + /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -2361,14 +2542,6 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /foreground-child/2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - /fs-extra/11.1.1: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} @@ -2394,6 +2567,11 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + /get-caller-file/2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2507,6 +2685,11 @@ packages: ini: 1.3.8 dev: true + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + /globals/13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} engines: {node: '>=8'} @@ -2728,6 +2911,19 @@ packages: engines: {node: '>=8'} dev: true + /istanbul-lib-instrument/5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.21.4 + '@babel/parser': 7.21.3 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-lib-report/3.0.0: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} engines: {node: '>=8'} @@ -2737,6 +2933,17 @@ packages: supports-color: 7.2.0 dev: true + /istanbul-lib-source-maps/4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-reports/3.1.5: resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} engines: {node: '>=8'} @@ -2770,6 +2977,12 @@ packages: argparse: 2.0.1 dev: true + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + /json-parse-better-errors/1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} dev: true @@ -2794,6 +3007,12 @@ packages: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: true + /json5/2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + /jsonc-parser/3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true @@ -2992,6 +3211,12 @@ packages: get-func-name: 2.0.0 dev: true + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -3182,6 +3407,10 @@ packages: whatwg-url: 5.0.0 dev: true + /node-releases/2.0.10: + resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + dev: true + /normalize-package-data/2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -3694,6 +3923,9 @@ packages: peerDependencies: esbuild: '>=0.10.1' rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 + peerDependenciesMeta: + esbuild: + optional: true dependencies: '@rollup/pluginutils': 5.0.2_rollup@3.20.0 debug: 4.3.4 @@ -4235,6 +4467,17 @@ packages: engines: {node: '>= 10.0.0'} dev: true + /update-browserslist-db/1.0.10_browserslist@4.21.5: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -4260,15 +4503,6 @@ packages: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true - /v8-to-istanbul/9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true - /validate-npm-package-license/3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -4578,6 +4812,10 @@ packages: engines: {node: '>=10'} dev: true + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true diff --git a/src/core/Axios.ts b/src/core/Axios.ts index 659f887..1d519a8 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -1,6 +1,7 @@ import { buildURL } from '../helpers/buildURL'; import { isAbsoluteURL } from '../helpers/isAbsoluteURL'; import { combineURL } from '../helpers/combineURL'; +import { isString } from '../helpers/isTypes'; import { AxiosAdapter, AxiosAdapterRequestMethod, @@ -232,10 +233,9 @@ export default class Axios extends AxiosDomain { /** * 派生领域 */ - fork(defaults: AxiosRequestConfig) { - const { baseURL = '' } = defaults; - if (!isAbsoluteURL(baseURL)) { - defaults.baseURL = combineURL(this.defaults.baseURL ?? '', baseURL); + fork(defaults: AxiosRequestConfig = {}) { + if (isString(defaults.baseURL) && !isAbsoluteURL(defaults.baseURL)) { + defaults.baseURL = combineURL(this.defaults.baseURL, defaults.baseURL); } return new AxiosDomain(mergeConfig(this.defaults, defaults), (config) => this.#processRequest(config), diff --git a/src/core/AxiosDomain.ts b/src/core/AxiosDomain.ts index b07de45..43705b6 100644 --- a/src/core/AxiosDomain.ts +++ b/src/core/AxiosDomain.ts @@ -141,7 +141,7 @@ export default class AxiosDomain { connect!: AxiosDomainAsRequest; constructor( - defaults: AxiosRequestConfig = {}, + defaults: AxiosRequestConfig, processRequest: (config: AxiosRequestConfig) => Promise, ) { this.defaults = defaults; diff --git a/src/core/dispatchRequest.ts b/src/core/dispatchRequest.ts index 9d25b11..7d571c4 100644 --- a/src/core/dispatchRequest.ts +++ b/src/core/dispatchRequest.ts @@ -1,12 +1,12 @@ import { isFunction, isString } from '../helpers/isTypes'; import { assert } from '../helpers/error'; -import { isCancel, isCancelToken } from './cancel'; +import { Cancel, isCancel, isCancelToken } from './cancel'; import { flattenHeaders } from './flattenHeaders'; import { AxiosTransformer, transformData } from './transformData'; import { request } from './request'; import { AxiosRequestConfig, AxiosResponse } from './Axios'; import { transformURL } from './transformURL'; -import { isAxiosError } from './createError'; +import { AxiosErrorResponse } from './createError'; function throwIfCancellationRequested(config: AxiosRequestConfig) { const { cancelToken } = config; @@ -35,13 +35,10 @@ export function dispatchRequest(config: AxiosRequestConfig) { return response; } - function onError(reason: unknown) { + function onError(reason: Cancel | AxiosErrorResponse) { if (!isCancel(reason)) { throwIfCancellationRequested(config); - - if (isAxiosError(reason)) { - transformer(reason.response as AxiosResponse, transformResponse); - } + transformer(reason.response, transformResponse); } if (isFunction(errorHandler)) { diff --git a/src/core/mergeConfig.ts b/src/core/mergeConfig.ts index 2b2d03d..7958d4f 100644 --- a/src/core/mergeConfig.ts +++ b/src/core/mergeConfig.ts @@ -37,10 +37,10 @@ export function mergeConfig( else if (deepMergeConfigMap[key]) { if (isPlainObject(val1) && isPlainObject(val2)) { config[key] = deepMerge(val1, val2); - } else if (isPlainObject(val1)) { - config[key] = deepMerge(val1); } else if (isPlainObject(val2)) { - config[key] = deepMerge(val2); + config[key] = val2; + } else if (isPlainObject(val1)) { + config[key] = val1; } } // 优先从 config2 中取值,如果没有值就从 config1 中取值 diff --git a/src/helpers/combineURL.ts b/src/helpers/combineURL.ts index 21b58f4..94540a0 100644 --- a/src/helpers/combineURL.ts +++ b/src/helpers/combineURL.ts @@ -1,5 +1,5 @@ const combineRE = /(^|[^:])\/{2,}/g; const removeRE = /\/$/; -export function combineURL(baseURL: string, url: string): string { +export function combineURL(baseURL = '', url = ''): string { return `${baseURL}/${url}`.replace(combineRE, '$1/').replace(removeRE, ''); } diff --git a/src/helpers/dynamicURL.ts b/src/helpers/dynamicURL.ts index 26f43e7..b98b6c8 100644 --- a/src/helpers/dynamicURL.ts +++ b/src/helpers/dynamicURL.ts @@ -1,4 +1,4 @@ const dynamicRE = /\/:([^/]+)/g; -export function dynamicURL(url: string, data: AnyObject = {}): string { +export function dynamicURL(url: string, data: AnyObject) { return url.replace(dynamicRE, (_, $2) => `/${data[$2]}`); } diff --git a/test/adapter.platform.test.ts b/test/adapter.platform.test.ts index 32879db..b0a87b4 100644 --- a/test/adapter.platform.test.ts +++ b/test/adapter.platform.test.ts @@ -53,3 +53,17 @@ describe.each(platforms)('src/adapter.ts', (p) => { expect(getAdapterDefault()).toBeUndefined(); }); }); + +describe.each(platforms)('src/adapter.ts', (p) => { + beforeEach(() => { + vi.stubGlobal(p, undefined); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + }); + + test('应该获取不到默认的平台适配器', () => { + expect(getAdapterDefault()).toBeUndefined(); + }); +}); diff --git a/test/adapter.test.ts b/test/adapter.test.ts index 37879cb..1a20f5a 100644 --- a/test/adapter.test.ts +++ b/test/adapter.test.ts @@ -155,14 +155,29 @@ describe('src/adapter.ts', () => { upload: vi.fn(), download: vi.fn((config) => { config.success({ - filePath: config.filePath, tempFilePath: '/path/temp/file', }); }), }; const p2 = { - request: vi.fn(), - upload: vi.fn(), + ...p1, + download: vi.fn((config) => { + config.success({ + apFilePath: '/path/temp/file', + }); + }), + }; + const p3 = { + ...p1, + download: vi.fn((config) => { + config.success({ + filePath: config.filePath, + tempFilePath: '/path/temp/file', + }); + }), + }; + const p4 = { + ...p1, download: vi.fn((config) => { config.success({ filePath: config.filePath, @@ -170,37 +185,127 @@ describe('src/adapter.ts', () => { }); }), }; - - createAdapter(p1)({ + const c1 = { type: 'download' as const, url: 'test', method: 'GET' as const, - params: { filePath: '/test/file' }, success: (response: any) => { expect(response.data).toMatchInlineSnapshot(` { - "filePath": "/test/file", + "filePath": undefined, "tempFilePath": "/path/temp/file", } `); }, fail: noop, - }); - - createAdapter(p2)({ - type: 'download' as const, - url: 'test', - method: 'GET' as const, - params: { filePath: '/test/file' }, + }; + const c2 = { + ...c1, success: (response: any) => { expect(response.data).toMatchInlineSnapshot(` { - "filePath": "/test/file", + "filePath": undefined, "tempFilePath": "/path/temp/file", } `); }, - fail: noop, - }); + }; + const c3 = { + ...c1, + params: { + filePath: '/user/path', + }, + success: (response: any) => { + expect(response.data).toMatchInlineSnapshot(` + { + "filePath": "/user/path", + "tempFilePath": "/path/temp/file", + } + `); + }, + }; + const c4 = { + ...c1, + params: { + filePath: '/user/path', + }, + success: (response: any) => { + expect(response.data).toMatchInlineSnapshot(` + { + "filePath": "/user/path", + "tempFilePath": "/path/temp/file", + } + `); + }, + }; + + createAdapter(p1)(c1); + createAdapter(p2)(c2); + createAdapter(p3)(c3); + createAdapter(p4)(c4); + }); + + test('应该支持转换失败的请求', () => { + const p1 = { + request: vi.fn(({ fail }) => fail({})), + upload: vi.fn(), + download: vi.fn(), + }; + const p2 = { + ...p1, + request: vi.fn(({ fail }) => fail({ data: { result: null } })), + }; + const p3 = { + ...p1, + request: vi.fn(({ fail }) => + fail({ statusCode: 500, header: {}, errMsg: 'request:fail' }), + ), + }; + const c1 = { + type: 'request' as const, + url: 'test', + method: 'GET' as const, + success: noop, + fail: (response: any) => { + expect(response).toMatchInlineSnapshot(` + { + "headers": undefined, + "status": 400, + "statusText": "Bad Adapter", + } + `); + }, + }; + const c2 = { + ...c1, + fail: (response: any) => { + expect(response).toMatchInlineSnapshot(` + { + "data": { + "result": null, + }, + "headers": undefined, + "status": 200, + "statusText": "OK", + } + `); + }, + }; + const c3 = { + ...c1, + fail: (response: any) => { + expect(response).toMatchInlineSnapshot(` + { + "headers": {}, + "status": 500, + "statusText": "request:fail", + } + `); + }, + }; + + createAdapter(p1)(c1); + createAdapter(p2)(c2); + createAdapter(p3)(c3); }); }); diff --git a/test/axios.api.test.ts b/test/axios.api.test.ts index 9776be3..e65356a 100644 --- a/test/axios.api.test.ts +++ b/test/axios.api.test.ts @@ -17,30 +17,21 @@ describe('src/axios.ts', () => { }); test('应该可以创建实例', () => { - const i2 = axios.create({ + const instance = axios.create({ baseURL: 'http://api.com', }); - expect(i2.defaults).toEqual({ ...defaults, baseURL: 'http://api.com' }); - expect(i2.interceptors).toBeTypeOf('object'); - expect(i2.getUri).toBeTypeOf('function'); - expect(i2.fork).toBeTypeOf('function'); - expect(i2.request).toBeTypeOf('function'); - - [...Axios.as, ...Axios.asp, ...Axios.asd].forEach((k) => { - expect(i2[k]).toBeTypeOf('function'); + expect(instance.defaults).toEqual({ + ...defaults, + baseURL: 'http://api.com', }); - }); - - test('创建的实例应该有这些实例属性及方法', () => { - expect(axios.defaults).toBe(defaults); - expect(axios.interceptors).toBeTypeOf('object'); - expect(axios.getUri).toBeTypeOf('function'); - expect(axios.fork).toBeTypeOf('function'); - expect(axios.request).toBeTypeOf('function'); + expect(instance.interceptors).toBeTypeOf('object'); + expect(instance.getUri).toBeTypeOf('function'); + expect(instance.fork).toBeTypeOf('function'); + expect(instance.request).toBeTypeOf('function'); [...Axios.as, ...Axios.asp, ...Axios.asd].forEach((k) => { - expect(axios[k]).toBeTypeOf('function'); + expect(instance[k]).toBeTypeOf('function'); }); }); }); diff --git a/test/axios.instance.test.ts b/test/axios.instance.test.ts index e8b8669..537bbb7 100644 --- a/test/axios.instance.test.ts +++ b/test/axios.instance.test.ts @@ -1,23 +1,9 @@ -import { describe, test, expect, beforeAll, afterAll } from 'vitest'; -import { mockAdapter } from 'scripts/test.utils'; +import { describe, test, expect } from 'vitest'; import Axios from '@/core/Axios'; -import AxiosDomain from '@/core/AxiosDomain'; -import defaults from '@/defaults'; import axios from '@/axios'; +import defaults from '@/defaults'; describe('src/axios.ts', () => { - const data = { - result: null, - }; - - beforeAll(() => { - axios.defaults.baseURL = 'http://api.com'; - }); - - afterAll(() => { - axios.defaults.baseURL = undefined; - }); - test('应该有这些实例属性及方法', () => { expect(axios.defaults).toBe(defaults); expect(axios.interceptors).toBeTypeOf('object'); @@ -29,99 +15,4 @@ describe('src/axios.ts', () => { expect(axios[k]).toBeTypeOf('function'); }); }); - - test('应该可以发送普通别名请求', () => { - const c = { - adapter: mockAdapter({ - before: (config) => { - expect(config.url).toBe('http://api.com/test'); - }, - data, - }), - }; - - Axios.as.forEach((a) => { - axios[a]('test', c).then((res) => { - expect(res.data).toEqual(data); - }); - }); - }); - - test('应该可以发送带参数的别名请求', () => { - const p = { id: 1 }; - const c1 = { - adapter: mockAdapter({ - before: (config) => { - expect(config.url).toBe('http://api.com/test?id=1'); - expect(config.params).toEqual(p); - }, - data, - }), - }; - const c2 = { - adapter: mockAdapter({ - before: (config) => { - expect(config.url).toBe('http://api.com/test/1?id=1'); - expect(config.params).toEqual(p); - }, - data, - }), - }; - - Axios.asp.forEach((a) => { - axios[a]('test', p, c1).then((res) => { - expect(res.data).toEqual(data); - }); - axios[a]('test/:id', p, c2).then((res) => { - expect(res.data).toEqual(data); - }); - }); - }); - - test('应该可以发送带数据的别名请求', () => { - const d = { id: 1 }; - const c1 = { - adapter: mockAdapter({ - before: (config) => { - expect(config.url).toBe('http://api.com/test'); - expect(config.data).toEqual(d); - }, - data, - }), - }; - const c2 = { - adapter: mockAdapter({ - before: (config) => { - expect(config.url).toBe('http://api.com/test/1'); - expect(config.data).toEqual(d); - }, - data, - }), - }; - - Axios.asd.forEach((a) => { - axios[a]('test', d, c1).then((res) => { - expect(res.data).toEqual(data); - }); - axios[a]('test/:id', d, c2).then((res) => { - expect(res.data).toEqual(data); - }); - }); - }); - - test('应该可以获取 URI', () => { - expect( - axios.getUri({ - url: 'test', - }), - ).toBe('test'); - }); - - test('应该可以派生领域', () => { - const a = axios.fork({ - baseURL: 'test', - }); - expect(a.defaults.baseURL).toBe('http://api.com/test'); - expect(a instanceof AxiosDomain).toBeTruthy(); - }); }); diff --git a/test/core/Axios.test.ts b/test/core/Axios.test.ts index 5faded2..066f485 100644 --- a/test/core/Axios.test.ts +++ b/test/core/Axios.test.ts @@ -290,13 +290,20 @@ describe('src/core/Axios.ts', () => { ); }); - test('应该可以派生领域', () => { + test('派生的领域应该为 AxiosDomain 的实例', () => { + expect(axios.fork() instanceof AxiosDomain).toBeTruthy(); + }); + + test('应该支持 绝对路径/相对路径 派生领域', () => { const a1 = axios.fork({ baseURL: 'test' }); const a2 = new Axios().fork({ baseURL: 'test' }); + const a3 = axios.fork({ baseURL: 'https://api.com' }); + const a4 = axios.fork(); expect(a1.defaults.baseURL).toBe('http://api.com/test'); - expect(a1 instanceof AxiosDomain).toBeTruthy(); expect(a2.defaults.baseURL).toBe('/test'); + expect(a3.defaults.baseURL).toBe('https://api.com'); + expect(a4.defaults.baseURL).toBe('http://api.com'); }); test('基于当前实例派生的领域应该可以复用当前实例上的中间件', async () => { diff --git a/test/core/AxiosDomain.test.ts b/test/core/AxiosDomain.test.ts index e034c99..9598463 100644 --- a/test/core/AxiosDomain.test.ts +++ b/test/core/AxiosDomain.test.ts @@ -48,6 +48,25 @@ describe('src/core/AxiosDomain.ts', () => { }); }); + test('请求方法应该支持空参数', () => { + const cb = vi.fn(); + const a = new AxiosDomain({}, cb); + + a.request('test'); + + AxiosDomain.as.forEach((k) => a[k]('test')); + AxiosDomain.asp.forEach((k) => a[k]('test')); + AxiosDomain.asd.forEach((k) => a[k]('test')); + + const l = + AxiosDomain.as.length + + AxiosDomain.asp.length + + AxiosDomain.asd.length + + 1; + expect(cb.mock.calls.length).toBe(l); + cb.mock.calls.forEach(([config]) => expect(config.url).toBe('test')); + }); + test('应该可以调用请求方法', () => { const cb = vi.fn(); const d = { diff --git a/test/core/dispatchRequest.test.ts b/test/core/dispatchRequest.test.ts index aec977c..74ba0c8 100644 --- a/test/core/dispatchRequest.test.ts +++ b/test/core/dispatchRequest.test.ts @@ -1,14 +1,13 @@ import { describe, test, expect, vi } from 'vitest'; import { asyncNext, - asyncTimeout, mockAdapter, mockAdapterError, mockAdapterFail, } from 'scripts/test.utils'; import { dispatchRequest } from '@/core/dispatchRequest'; -import _defaults from '@/defaults'; import axios from '@/axios'; +import _defaults from '@/defaults'; describe('src/core/dispatchRequest.ts', () => { const defaults = { @@ -33,6 +32,21 @@ describe('src/core/dispatchRequest.ts', () => { ).toThrowErrorMatchingInlineSnapshot( '"[axios-miniprogram]: method 不是一个 string"', ); + expect(() => + dispatchRequest({ adapter: mockAdapter(), url: '/', method: 'get' }), + ).not.toThrowError(); + }); + + test('坏的适配器', () => { + expect(() => + dispatchRequest({ + adapter: () => { + throw 'bad adapter'; + }, + url: '/', + method: 'get', + }), + ).toMatchInlineSnapshot('[Function]'); }); test('应该支持转换 URL', () => { diff --git a/test/core/mergeConfig.test.ts b/test/core/mergeConfig.test.ts index 2107fff..7be708a 100644 --- a/test/core/mergeConfig.test.ts +++ b/test/core/mergeConfig.test.ts @@ -6,7 +6,12 @@ import { CancelToken } from '@/core/cancel'; describe('src/core/mergeConfig.ts', () => { test('应该支持空参数', () => { expect(mergeConfig()).toEqual({}); + expect(mergeConfig({})).toEqual({}); + expect(mergeConfig(undefined, {})).toEqual({}); expect(mergeConfig({ baseURL: '/api' })).toEqual({ baseURL: '/api' }); + expect(mergeConfig(undefined, { baseURL: '/api' })).toEqual({ + baseURL: '/api', + }); }); test('应该只取 config2', () => { @@ -36,7 +41,7 @@ describe('src/core/mergeConfig.ts', () => { test('应该深度合并', () => { const o1 = { - v1: 1, + v1: {}, v2: 1, v3: { v1: 1, @@ -47,14 +52,16 @@ describe('src/core/mergeConfig.ts', () => { v3: { v2: 2, }, + v4: {}, }; const o3 = { - v1: 1, + v1: {}, v2: 2, v3: { v1: 1, v2: 2, }, + v4: {}, }; const c1 = { headers: { @@ -106,6 +113,21 @@ describe('src/core/mergeConfig.ts', () => { }); }); + test('深度合并应该丢弃非普通对象值', () => { + const c1 = { + headers: 1, + params: '1', + data: [], + }; + const c2 = { + headers: () => null, + params: null, + data: new Date(), + }; + + expect(mergeConfig(c1 as any, c2 as any)).toEqual({}); + }); + test('应该优先取 config2', () => { const c1 = { adapter: vi.fn(), diff --git a/test/core/request.test.ts b/test/core/request.test.ts index 7f39288..42a4fe6 100644 --- a/test/core/request.test.ts +++ b/test/core/request.test.ts @@ -1,14 +1,13 @@ import { describe, test, expect, vi } from 'vitest'; import { - asyncNext, asyncTimeout, mockAdapter, mockAdapterError, mockAdapterFail, } from 'scripts/test.utils'; import { request } from '@/core/request'; -import axios from '@/axios'; import Axios from '@/core/Axios'; +import axios from '@/axios'; describe('src/core/request.ts', () => { test('应该正确的响应请求', async () => { @@ -157,6 +156,24 @@ describe('src/core/request.ts', () => { expect(cb).toBeCalled(); }); + test('无 task 也应该可以取消请求', async () => { + const cb = vi.fn(); + + const { cancel, token } = axios.CancelToken.source(); + + cancel(); + + await request({ + adapter: () => undefined, + url: '/test', + method: 'get' as const, + cancelToken: token, + }).catch(cb); + + expect(cb).toBeCalled(); + expect(axios.isCancel(cb.mock.calls[0][0])).toBeTruthy(); + }); + test('应该发送不同类型的请求', () => { request({ adapter: ({ type }) => { @@ -225,11 +242,13 @@ describe('src/core/request.ts', () => { expect(axios.isCancel(err)).toBeTruthy(); }); + await asyncTimeout(); + expect(on).toBeCalled(); expect(on.mock.calls[0][0]).toBe(cb); }); - test('应该可以监听下载进度', () => { + test('应该可以监听下载进度', async () => { const on = vi.fn(); const cb = vi.fn(); @@ -243,6 +262,8 @@ describe('src/core/request.ts', () => { onDownloadProgress: cb, }); + await asyncTimeout(); + expect(on).toBeCalled(); expect(on.mock.calls[0][0]).toBe(cb); }); @@ -270,4 +291,34 @@ describe('src/core/request.ts', () => { expect(on).toBeCalled(); expect(on.mock.calls[0][0]).toBe(cb); }); + + test('上传不应该监听下载进度/下载不应该监听上传进度', async () => { + const on = vi.fn(); + const cb = vi.fn(); + + request({ + adapter: () => ({ + onProgressUpdate: on, + }), + url: 'test', + method: 'post', + upload: true, + onDownloadProgress: cb, + }); + + request({ + adapter: () => ({ + onProgressUpdate: on, + }), + url: 'test', + method: 'get', + download: true, + onUploadProgress: cb, + }); + + await asyncTimeout(); + + expect(on).not.toBeCalled(); + expect(cb).not.toBeCalled(); + }); }); diff --git a/test/helpers/buildURL.test.ts b/test/helpers/buildURL.test.ts index c7c8801..3ec96ee 100644 --- a/test/helpers/buildURL.test.ts +++ b/test/helpers/buildURL.test.ts @@ -1,8 +1,9 @@ import { describe, test, expect } from 'vitest'; -import { buildURL } from 'src/helpers/buildURL'; +import { buildURL } from '@/helpers/buildURL'; describe('src/helpers/buildURL.ts', () => { test('应该支持空参数', () => { + expect(buildURL()).toBe(''); expect(buildURL('/test')).toBe('/test'); }); diff --git a/test/helpers/combineURL.test.ts b/test/helpers/combineURL.test.ts index 2293bb4..c13226f 100644 --- a/test/helpers/combineURL.test.ts +++ b/test/helpers/combineURL.test.ts @@ -1,7 +1,13 @@ import { describe, test, expect } from 'vitest'; -import { combineURL } from 'src/helpers/combineURL'; +import { combineURL } from '@/helpers/combineURL'; describe('src/helpers/combineURL.ts', () => { + test('应该支持空参数', () => { + expect(combineURL()).toBe(''); + expect(combineURL('')).toBe(''); + expect(combineURL(undefined, '')).toBe(''); + }); + test('应该直接返回第一个参数', () => { expect(combineURL('http://api.com', '')).toBe('http://api.com'); expect(combineURL('file://api.com', '')).toBe('file://api.com'); diff --git a/test/helpers/deepMerge.test.ts b/test/helpers/deepMerge.test.ts index 39199dd..98a6496 100644 --- a/test/helpers/deepMerge.test.ts +++ b/test/helpers/deepMerge.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { deepMerge } from 'src/helpers/deepMerge'; +import { deepMerge } from '@/helpers/deepMerge'; describe('src/helpers/deepMerge.ts', () => { test('应该支持空参数', () => { diff --git a/test/helpers/dynamicURL.test.ts b/test/helpers/dynamicURL.test.ts index 6d741df..85ee4d6 100644 --- a/test/helpers/dynamicURL.test.ts +++ b/test/helpers/dynamicURL.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { dynamicURL } from 'src/helpers/dynamicURL'; +import { dynamicURL } from '@/helpers/dynamicURL'; describe('src/helpers/dynamicURL.ts', () => { test('应该替换关键字', () => { diff --git a/test/helpers/error.test.ts b/test/helpers/error.test.ts index 1d81038..5b88823 100644 --- a/test/helpers/error.test.ts +++ b/test/helpers/error.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect } from 'vitest'; import { captureError, checkStack } from 'scripts/test.utils'; -import { assert, throwError, cleanStack } from 'src/helpers/error'; +import { assert, throwError, cleanStack } from '@/helpers/error'; describe('src/helpers/error.ts', () => { test('第一个参数为 true 时应该无事发生', () => { @@ -22,6 +22,20 @@ describe('src/helpers/error.ts', () => { expect(checkStack(captureError(() => throwError('error')))).toBeTruthy(); }); + test('应该支持空错误栈', () => { + const ce = () => { + const error = new Error(); + error.stack = undefined; + return error; + }; + const error = ce(); + + cleanStack(error); + + expect(checkStack(error)).toBeTruthy(); + expect(error.stack).toBeUndefined(); + }); + test('应该清掉多余的错误栈', () => { const ce = () => new Error(); const error = ce(); diff --git a/test/helpers/ignore.test.ts b/test/helpers/ignore.test.ts index ddbaa77..cb6ad53 100644 --- a/test/helpers/ignore.test.ts +++ b/test/helpers/ignore.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { ignore } from 'src/helpers/ignore'; +import { ignore } from '@/helpers/ignore'; describe('src/helpers/ignore.ts', () => { test('不应该改变传入的对象', () => { diff --git a/test/helpers/isAbsoluteURL.test.ts b/test/helpers/isAbsoluteURL.test.ts index e3f560c..70b58dd 100644 --- a/test/helpers/isAbsoluteURL.test.ts +++ b/test/helpers/isAbsoluteURL.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { isAbsoluteURL } from 'src/helpers/isAbsoluteURL'; +import { isAbsoluteURL } from '@/helpers/isAbsoluteURL'; describe('src/helpers/isAbsoluteURL.ts', () => { test('应该不是绝对路径', () => { diff --git a/test/helpers/isTypes.test.ts b/test/helpers/isTypes.test.ts index beaee11..f8a10bb 100644 --- a/test/helpers/isTypes.test.ts +++ b/test/helpers/isTypes.test.ts @@ -8,7 +8,7 @@ import { isNull, isUndefined, isString, -} from 'src/helpers/isTypes'; +} from '@/helpers/isTypes'; describe('src/helpers/isTypes.ts', () => { test('应该能判断是数组', () => { diff --git a/vitest.config.ts b/vitest.config.ts index c302594..ebe184a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,10 +9,11 @@ export default defineConfig({ '@': resolve('src'), }, coverage: { - provider: 'c8', + provider: 'istanbul', reportsDirectory: resolve('test/coverage'), - enabled: true, + enabled: false, + include: ['src/**/*.ts'], }, - include: ['./test/**/*.test.ts'], + include: ['test/**/*.test.ts'], }, });