Browse Source

feat(test): add jest test suite

Vben 3 years ago
parent
commit
f6fe1dd62d

+ 1 - 0
.eslintrc.js

@@ -22,6 +22,7 @@ module.exports = defineConfig({
     'plugin:@typescript-eslint/recommended',
     'prettier',
     'plugin:prettier/recommended',
+    'plugin:jest/recommended',
   ],
   rules: {
     '@typescript-eslint/ban-ts-ignore': 'off',

+ 1 - 0
.gitignore

@@ -10,6 +10,7 @@ test/server/static
 # local env files
 .env.local
 .env.*.local
+.eslintcache
 
 # Log files
 npm-debug.log*

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -15,6 +15,7 @@
 - **Drawer** `useDrawer`新增`closeDrawer`函数
 - **Preview** 新增`createImgPreview`图片预览函数
 - **Setup** 新增引导页示例
+- **Tests** 添加 jest 测试套件,暂不支持 Vue 组件单测
 
 ### 🐛 Bug Fixes
 

+ 37 - 0
jest.config.mjs

@@ -0,0 +1,37 @@
+export default {
+  preset: 'ts-jest',
+  roots: ['<rootDir>/tests/'],
+  clearMocks: true,
+  moduleDirectories: ['node_modules', 'src'],
+  moduleFileExtensions: ['js', 'ts', 'vue', 'tsx', 'jsx', 'json', 'node'],
+  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
+  testMatch: [
+    '**/tests/**/*.[jt]s?(x)',
+    '**/?(*.)+(spec|test).[tj]s?(x)',
+    '(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$',
+  ],
+  testPathIgnorePatterns: [
+    '<rootDir>/tests/server/',
+    '<rootDir>/tests/__mocks__/',
+    '/node_modules/',
+  ],
+  transform: {
+    '^.+\\.tsx?$': 'ts-jest',
+    '^.+\\.(vue)$': 'vue-jest',
+  },
+  transformIgnorePatterns: ['<rootDir>/tests/__mocks__/', '/node_modules/'],
+  // A map from regular expressions to module names that allow to stub out resources with a single module
+  moduleNameMapper: {
+    '\\.(vs|fs|vert|frag|glsl|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
+      '<rootDir>/tests/__mocks__/fileMock.ts',
+    '\\.(sass|s?css|less)$': '<rootDir>/tests/__mocks__/styleMock.ts',
+    '\\?worker$': '<rootDir>/tests/__mocks__/workerMock.ts',
+    '^/@/(.*)$': '<rootDir>/src/$1',
+  },
+  testEnvironment: 'jsdom',
+  verbose: true,
+  collectCoverage: false,
+  coverageDirectory: 'coverage',
+  collectCoverageFrom: ['src/**/*.{js,ts,vue}'],
+  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
+};

+ 11 - 2
package.json

@@ -19,11 +19,13 @@
     "log": "conventional-changelog -p angular -i CHANGELOG.md -s",
     "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
     "clean:lib": "rimraf node_modules",
-    "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
+    "lint:eslint": "eslint --cache --max-warnings 0  \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
     "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
-    "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
+    "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
     "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
     "lint:pretty": "pretty-quick --staged",
+    "test:unit": "jest",
+    "test:unit-coverage": "jest --coverage",
     "test:gzip": "http-server dist --cors --gzip -c-1",
     "test:br": "http-server dist --cors --brotli -c-1",
     "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
@@ -71,6 +73,7 @@
     "@types/fs-extra": "^9.0.11",
     "@types/inquirer": "^7.3.1",
     "@types/intro.js": "^3.0.1",
+    "@types/jest": "^26.0.23",
     "@types/lodash-es": "^4.17.4",
     "@types/mockjs": "^1.0.3",
     "@types/node": "^15.12.2",
@@ -84,7 +87,9 @@
     "@vitejs/plugin-vue": "^1.2.3",
     "@vitejs/plugin-vue-jsx": "^1.1.5",
     "@vue/compiler-sfc": "3.0.11",
+    "@vue/test-utils": "^2.0.0-rc.6",
     "autoprefixer": "^10.2.6",
+    "babel-jest": "^27.0.2",
     "commitizen": "^4.2.4",
     "conventional-changelog-cli": "^2.1.1",
     "cross-env": "^7.0.3",
@@ -92,6 +97,7 @@
     "eslint": "^7.28.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-define-config": "^1.0.8",
+    "eslint-plugin-jest": "^24.3.6",
     "eslint-plugin-prettier": "^3.4.0",
     "eslint-plugin-vue": "^7.11.1",
     "esno": "^0.7.3",
@@ -100,6 +106,7 @@
     "husky": "^6.0.0",
     "inquirer": "^8.1.1",
     "is-ci": "^3.0.0",
+    "jest": "^27.0.4",
     "less": "^4.1.1",
     "lint-staged": "^11.0.0",
     "postcss": "^8.3.5",
@@ -111,6 +118,7 @@
     "stylelint-config-prettier": "^8.0.2",
     "stylelint-config-standard": "^22.0.0",
     "stylelint-order": "^4.1.0",
+    "ts-jest": "^27.0.3",
     "ts-node": "^10.0.0",
     "typescript": "4.3.3",
     "vite": "2.3.7",
@@ -125,6 +133,7 @@
     "vite-plugin-theme": "^0.8.1",
     "vite-plugin-windicss": "^1.0.4",
     "vue-eslint-parser": "^7.6.0",
+    "vue-jest": "^5.0.0-alpha.10",
     "vue-tsc": "^0.1.7"
   },
   "resolutions": {

+ 1 - 0
src/views/dashboard/workbench/components/DynamicInfo.vue

@@ -10,6 +10,7 @@
             <template #description>
               {{ item.date }}
             </template>
+            <!-- eslint-disable-next-line -->
             <template #title> {{ item.name }} <span v-html="item.desc"> </span> </template>
             <template #avatar>
               <Icon :icon="item.avatar" :size="30" />

+ 2 - 2
src/views/demo/feat/tabs/index.vue

@@ -2,10 +2,10 @@
   <PageWrapper title="标签页操作示例">
     <CollapseContainer title="在下面输入框输入文本,切换后回来内容会保存">
       <a-alert banner message="该操作不会影响页面标题,仅修改Tab标题" />
-      <template class="mt-2 flex flex-grow-0">
+      <div class="mt-2 flex flex-grow-0">
         <a-button class="mr-2" @click="setTabTitle" type="primary"> 设置Tab标题 </a-button>
         <a-input placeholder="请输入" v-model:value="title" class="mr-4 w-12" />
-      </template>
+      </div>
     </CollapseContainer>
 
     <CollapseContainer class="mt-4" title="标签页操作">

+ 0 - 149
stylelint.config.js

@@ -54,155 +54,6 @@ module.exports = {
       ],
       { severity: 'warning' },
     ],
-    // Specify the alphabetical order of the attributes in the declaration block
-    'order/properties-order': [
-      'position',
-      'top',
-      'right',
-      'bottom',
-      'left',
-      'z-index',
-      'display',
-      'float',
-      'width',
-      'height',
-      'max-width',
-      'max-height',
-      'min-width',
-      'min-height',
-      'padding',
-      'padding-top',
-      'padding-right',
-      'padding-bottom',
-      'padding-left',
-      'margin',
-      'margin-top',
-      'margin-right',
-      'margin-bottom',
-      'margin-left',
-      'margin-collapse',
-      'margin-top-collapse',
-      'margin-right-collapse',
-      'margin-bottom-collapse',
-      'margin-left-collapse',
-      'overflow',
-      'overflow-x',
-      'overflow-y',
-      'clip',
-      'clear',
-      'font',
-      'font-family',
-      'font-size',
-      'font-smoothing',
-      'osx-font-smoothing',
-      'font-style',
-      'font-weight',
-      'hyphens',
-      'src',
-      'line-height',
-      'letter-spacing',
-      'word-spacing',
-      'color',
-      'text-align',
-      'text-decoration',
-      'text-indent',
-      'text-overflow',
-      'text-rendering',
-      'text-size-adjust',
-      'text-shadow',
-      'text-transform',
-      'word-break',
-      'word-wrap',
-      'white-space',
-      'vertical-align',
-      'list-style',
-      'list-style-type',
-      'list-style-position',
-      'list-style-image',
-      'pointer-events',
-      'cursor',
-      'background',
-      'background-attachment',
-      'background-color',
-      'background-image',
-      'background-position',
-      'background-repeat',
-      'background-size',
-      'border',
-      'border-collapse',
-      'border-top',
-      'border-right',
-      'border-bottom',
-      'border-left',
-      'border-color',
-      'border-image',
-      'border-top-color',
-      'border-right-color',
-      'border-bottom-color',
-      'border-left-color',
-      'border-spacing',
-      'border-style',
-      'border-top-style',
-      'border-right-style',
-      'border-bottom-style',
-      'border-left-style',
-      'border-width',
-      'border-top-width',
-      'border-right-width',
-      'border-bottom-width',
-      'border-left-width',
-      'border-radius',
-      'border-top-right-radius',
-      'border-bottom-right-radius',
-      'border-bottom-left-radius',
-      'border-top-left-radius',
-      'border-radius-topright',
-      'border-radius-bottomright',
-      'border-radius-bottomleft',
-      'border-radius-topleft',
-      'content',
-      'quotes',
-      'outline',
-      'outline-offset',
-      'opacity',
-      'filter',
-      'visibility',
-      'size',
-      'zoom',
-      'transform',
-      'box-align',
-      'box-flex',
-      'box-orient',
-      'box-pack',
-      'box-shadow',
-      'box-sizing',
-      'table-layout',
-      'animation',
-      'animation-delay',
-      'animation-duration',
-      'animation-iteration-count',
-      'animation-name',
-      'animation-play-state',
-      'animation-timing-function',
-      'animation-fill-mode',
-      'transition',
-      'transition-delay',
-      'transition-duration',
-      'transition-property',
-      'transition-timing-function',
-      'background-clip',
-      'backface-visibility',
-      'resize',
-      'appearance',
-      'user-select',
-      'interpolation-mode',
-      'direction',
-      'marks',
-      'page',
-      'set-link-source',
-      'unicode-bidi',
-      'speak',
-    ],
   },
   ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
 };

+ 1 - 0
tests/__mocks__/fileMock.ts

@@ -0,0 +1 @@
+export default '';

+ 1 - 0
tests/__mocks__/styleMock.ts

@@ -0,0 +1 @@
+export default {};

+ 5 - 0
tests/__mocks__/workerMock.ts

@@ -0,0 +1,5 @@
+export default jest.fn().mockImplementation(() => ({
+  postMessage: jest.fn(),
+  onmessage: jest.fn(),
+  onerror: jest.fn(),
+}));

+ 0 - 0
test/server/README.md → tests/server/README.md


+ 0 - 0
test/server/controller/FileController.ts → tests/server/controller/FileController.ts


+ 0 - 0
test/server/controller/UserController.ts → tests/server/controller/UserController.ts


+ 0 - 0
test/server/ecosystem.config.js → tests/server/ecosystem.config.js


+ 0 - 0
test/server/index.ts → tests/server/index.ts


+ 0 - 0
test/server/nodemon.json → tests/server/nodemon.json


+ 0 - 0
test/server/package.json → tests/server/package.json


+ 0 - 0
test/server/routes.ts → tests/server/routes.ts


+ 0 - 0
test/server/service/FileService.ts → tests/server/service/FileService.ts


+ 0 - 0
test/server/service/UserService.ts → tests/server/service/UserService.ts


BIN
tests/server/static/upload/11.jpg


BIN
tests/server/static/upload/5ab46a3cN616bdc41.jpg


BIN
tests/server/static/upload/5ac1bf5fN2522b9dc.jpg


BIN
tests/server/static/upload/5c9ccca8a27f0.png


BIN
tests/server/static/upload/5c9ccca8b27f1.jpg


BIN
tests/server/static/upload/5c9ccca8bc1e0.png


+ 0 - 0
test/server/tsconfig.json → tests/server/tsconfig.json


+ 0 - 0
test/server/utils.ts → tests/server/utils.ts


+ 0 - 0
test/server/yarn.lock → tests/server/yarn.lock


+ 16 - 0
tests/test.spec.ts

@@ -0,0 +1,16 @@
+// import { mount } from '@vue/test-utils';
+// import { Button } from '/@/components/Button';
+
+test('if jest is normal.', async () => {
+  expect('jest').toEqual('jest');
+});
+
+// TODO Vue component testing is not supported temporarily
+// test('is a Vue instance.', async () => {
+//   const wrapper = mount(Button, {
+//     slots: {
+//       default: 'Button text',
+//     },
+//   });
+//   expect(wrapper.html()).toContain('Button text');
+// });

+ 2 - 1
tsconfig.json

@@ -17,7 +17,7 @@
     "noUnusedParameters": true,
     "experimentalDecorators": true,
     "lib": ["dom", "esnext"],
-    "types": ["vite/client"],
+    "types": ["vite/client", "jest"],
     "typeRoots": ["./node_modules/@types/", "./types"],
     "noImplicitAny": false,
     "skipLibCheck": true,
@@ -27,6 +27,7 @@
     }
   },
   "include": [
+    "tests/**/*.ts",
     "src/**/*.ts",
     "src/**/*.d.ts",
     "src/**/*.tsx",

File diff suppressed because it is too large
+ 673 - 6
yarn.lock


Some files were not shown because too many files changed in this diff