diff --git a/.eslintrc.js b/.eslintrc.js index 14c73fcdc0f6..c03cb3df46f8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -25,11 +25,12 @@ module.exports = { 'prettier', 'eslint:recommended', 'plugin:vue/recommended', + 'plugin:jest/recommended', 'standard' ], // https://eslint.org/docs/user-guide/configuring#configuring-plugins - plugins: ['vue'], + plugins: ['vue', 'jest', 'simple-import-sort', 'import'], rules: { 'space-before-function-paren': 0, @@ -38,6 +39,11 @@ module.exports = { 'no-console': 0, 'no-unused-vars': 1, 'no-undef': 1, - 'vue/no-template-key': 1 + 'vue/no-template-key': 1, + 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', + 'import/first': 'error', + 'import/newline-after-import': 'error', + 'import/no-duplicates': 'error' } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000000..282a99523c7c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,133 @@ +name: ci + +on: + pull_request: + branches: + - master + - development + +env: + NODE_VERSIONS: [14.x] + +jobs: + lint: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ${{ env.NODE_VERSIONS }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache node modules + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package.json', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Node ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm run ci + + - name: Execute eslint checks + run: npm run lint + + format: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ${{ env.NODE_VERSIONS }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache node modules + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package.json', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Node ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm run ci + + - name: Execute prettier checks + run: npm run prettier + + unittests: + runs-on: ubuntu-18.04 + needs: [lint, format] + + strategy: + matrix: + node-version: ${{ env.NODE_VERSIONS }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache node modules + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package.json', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Node ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm run ci + + - name: Execute unit tests + run: npm run test:unit + + e2e: + runs-on: ubuntu-latest + needs: [lint, format, unittests] + + strategy: + matrix: + node-version: ${{ env.NODE_VERSIONS }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache node modules + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package.json', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Node ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm run ci + + - name: Execute e2e tests + run: npm run test:e2e-headless diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml deleted file mode 100644 index 7d74006c6456..000000000000 --- a/.github/workflows/linter.yml +++ /dev/null @@ -1,27 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Linter - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -on: - pull_request: - branches: [ master, development ] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - lint: - # The type of runner that the job will run on - runs-on: ubuntu-20.04 - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 14.x - uses: actions/setup-node@v2 - with: - node-version: 14.x - cache: "yarn" - - run: npm run ci - - run: npm run lint diff --git a/.gitignore b/.gitignore index 79dfea94c23f..abdae8a771cd 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ data/tmp/ .tmp/ tmp/ .cache +.eslintcache dist coverage __coverage__ diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 000000000000..9313055d57fc --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,4 @@ +{ + "*.{js,ts,vue}": "eslint --cache", + "{src,_scripts}/**/*.{js,ts,vue}": "prettier --check" +} diff --git a/.prettierrc b/.prettierrc index b96994ddd09a..28a3206b19a3 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,6 +2,6 @@ "semi": false, "singleQuote": true, "tabWidth": 2, - "trailingComma": false, + "trailingComma": none, "useTabs": false } diff --git a/.simple-git-hooks.json b/.simple-git-hooks.json new file mode 100644 index 000000000000..7e870f157ee1 --- /dev/null +++ b/.simple-git-hooks.json @@ -0,0 +1,4 @@ +{ + "pre-commit": "npx lint-staged", + "pre-push": "npm run test" +} diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000000..99f3df474806 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,15 @@ +module.exports = { + verbose: true, + setupFiles: ['./tests/setup.js'], + moduleFileExtensions: ['js', 'json', 'vue'], + transform: { + '.*\\.(vue)$': 'vue-jest', + '^.+\\.js$': 'babel-jest' + }, + collectCoverage: true, + collectCoverageFrom: [ + 'src/renderer/components/**/*.{js,ts,vue}', + '!**/node_modules/**' + ], + coverageReporters: ['html', 'text-summary'] +} diff --git a/package.json b/package.json index cbbf6817d828..d24d5d3c7534 100644 --- a/package.json +++ b/package.json @@ -31,23 +31,34 @@ "dev": "run-s rebuild:electron dev-runner", "dev-runner": "node _scripts/dev-runner.js", "jest": "jest", + "jest:unit": "jest tests/unit", + "jest:e2e": "run-s pack:silent \"jest tests/e2e\" --silent", "jest:coverage": "jest --collect-coverage", "jest:watch": "jest --watch", - "lint-fix": "eslint --fix --ext .js,.ts,.vue ./", "lint": "eslint --ext .js,.ts,.vue ./", + "lint-fix": "eslint --fix --ext .js,.ts,.vue ./", "pack": "run-p pack:main pack:renderer pack:workers", + "pack:silent": "run-p pack:main-silent pack:renderer-silent pack:workers-silent --silent", "pack:main": "webpack --mode=production --node-env=production --config _scripts/webpack.main.config.js", + "pack:main-silent": "webpack --no-stats --mode=production --node-env=production --config _scripts/webpack.main.config.js", "pack:renderer": "webpack --mode=production --node-env=production --config _scripts/webpack.renderer.config.js", + "pack:renderer-silent": "webpack --no-stats --mode=production --node-env=production --config _scripts/webpack.renderer.config.js", "pack:web": "webpack --mode=production --node-env=production --config _scripts/webpack.web.config.js", + "pack:web-silent": "webpack --no-stats --mode=production --node-env=production --config _scripts/webpack.web.config.js", "pack:workers": "webpack --mode=production --node-env=production --config _scripts/webpack.workers.config.js", + "pack:workers-silent": "webpack --no-stats --mode=production --node-env=production --config _scripts/webpack.workers.config.js", "postinstall": "npm run rebuild:electron", "prettier": "prettier --write \"{src,_scripts}/**/*.{js,ts,vue}\"", + "prettier:fix": "prettier --write \"{src,_scripts}/**/*.{js,ts,vue}\"", + "prettier:local": "npx pretty-quick --pattern \"{src,_scripts}/**/*.{js,ts,vue}\" --no-restage", "rebuild:electron": "electron-builder install-app-deps", "rebuild:node": "npm rebuild", "release": "run-s test build", - "test": "run-s rebuild:node pack:workers jest", - "test:watch": "run-s rebuild:node pack:workers jest:watch", - + "test": "run-s pack:silent jest --silent", + "test:unit": "run-s jest:unit --silent", + "test:e2e": "run-s jest:e2e --silent", + "test:e2e-headless": "npm run pack:silent && xvfb-maybe --server-args=\"-screen 0 1024x768x24\" -- jest tests/e2e", + "test:watch": "run-s pack:silent jest:watch --silent", "ci": "yarn install --frozen-lockfile" }, "dependencies": { @@ -103,9 +114,13 @@ "@babel/plugin-proposal-object-rest-spread": "^7.14.7", "@babel/preset-env": "^7.15.0", "@babel/preset-typescript": "^7.15.0", + "@testing-library/jest-dom": "^5.11.9", + "@testing-library/vue": "^5.6.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", + "babel-core": "^7.0.0-bridge.0", "babel-eslint": "^10.1.0", + "babel-jest": "^27.2.2", "babel-loader": "^8.2.2", "copy-webpack-plugin": "^9.0.1", "css-loader": "5.2.6", @@ -117,34 +132,42 @@ "eslint-config-prettier": "^8.3.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-import": "^2.24.2", + "eslint-plugin-jest": "^24.2.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-simple-import-sort": "^7.0.0", "eslint-plugin-standard": "^5.0.0", "eslint-plugin-vue": "^7.17.0", "fast-glob": "^3.2.7", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.3.2", "jest": "^27.1.0", + "lint-staged": "^10.5.4", "mini-css-extract-plugin": "^2.2.2", "node-abi": "^2.30.1", "node-loader": "^2.0.0", "npm-run-all": "^4.1.5", "prettier": "^2.3.2", + "pretty-quick": "^3.1.0", "rimraf": "^3.0.2", "sass": "^1.38.2", "sass-loader": "^12.1.0", + "simple-git-hooks": "^2.3.1", + "spectron": "^14.0.0", "style-loader": "^3.2.1", "tree-kill": "1.2.2", "typescript": "^4.4.2", "url-loader": "^4.1.1", "vue-devtools": "^5.1.4", "vue-eslint-parser": "^7.10.0", + "vue-jest": "^3.0.7", "vue-loader": "^15.9.8", "vue-style-loader": "^4.1.3", "vue-template-compiler": "^2.6.14", "webpack": "^5.51.1", "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.1.0" + "webpack-dev-server": "^4.1.0", + "xvfb-maybe": "^0.2.1" } } diff --git a/src/renderer/components/ft-channel-bubble/ft-channel-bubble.vue b/src/renderer/components/ft-channel-bubble/ft-channel-bubble.vue index 795a00c76db0..44f8c5f1ab8f 100644 --- a/src/renderer/components/ft-channel-bubble/ft-channel-bubble.vue +++ b/src/renderer/components/ft-channel-bubble/ft-channel-bubble.vue @@ -1,20 +1,8 @@