test: 测试覆盖率 💯

pull/41/head
zjx0905 2023-04-10 22:53:15 +08:00
parent 4ba1249146
commit adb9dbe88f
27 changed files with 619 additions and 242 deletions

View File

@ -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 }}

View File

@ -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"
]
}
}

View File

@ -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

View File

@ -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),

View File

@ -141,7 +141,7 @@ export default class AxiosDomain {
connect!: AxiosDomainAsRequest;
constructor(
defaults: AxiosRequestConfig = {},
defaults: AxiosRequestConfig,
processRequest: (config: AxiosRequestConfig) => Promise<AxiosResponse>,
) {
this.defaults = defaults;

View File

@ -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)) {

View File

@ -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 中取值

View File

@ -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, '');
}

View File

@ -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]}`);
}

View File

@ -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();
});
});

View File

@ -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);
});
});

View File

@ -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');
});
});
});

View File

@ -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();
});
});

View File

@ -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 () => {

View File

@ -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 = {

View File

@ -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', () => {

View File

@ -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(),

View File

@ -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();
});
});

View File

@ -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');
});

View File

@ -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');

View File

@ -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('应该支持空参数', () => {

View File

@ -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('应该替换关键字', () => {

View File

@ -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();

View File

@ -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('不应该改变传入的对象', () => {

View File

@ -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('应该不是绝对路径', () => {

View File

@ -8,7 +8,7 @@ import {
isNull,
isUndefined,
isString,
} from 'src/helpers/isTypes';
} from '@/helpers/isTypes';
describe('src/helpers/isTypes.ts', () => {
test('应该能判断是数组', () => {

View File

@ -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'],
},
});