diff --git a/.gitignore b/.gitignore index 582845f5..0a17713c 100644 --- a/.gitignore +++ b/.gitignore @@ -94,7 +94,7 @@ openflexure_settings/ # Files created by test utilities /tests/unit_tests/utilities/*.pstats /tests/unit_tests/utilities/*.png - +coverage/ # Files created by simulator openflexure/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91592724..b6c46652 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -158,6 +158,14 @@ eslint: script: - npm run lint - npm run lint:style + # The test run if only + - npm run test:unit + artifacts: + name: "vitest-coverage-$CI_COMMIT_REF_SLUG" + when: always + expire_in: 1 week + paths: + - coverage/ # Build JS app build: diff --git a/webapp/eslint.config.mjs b/webapp/eslint.config.mjs index e7c8f7b4..6f931bfa 100644 --- a/webapp/eslint.config.mjs +++ b/webapp/eslint.config.mjs @@ -73,5 +73,22 @@ export default [ "pinia/require-setup-store-properties-export": "warn", }, }, + + { + files: ["src/tests/unit/**/*.spec.js"], + languageOptions: { + globals: { + describe: "readonly", + it: "readonly", + expect: "readonly", + vi: "readonly", + beforeEach: "readonly", + afterEach: "readonly", + mockLogData: "readonly", // Prevents unused global mock variable warnings + afterAll: "readonly", + }, + }, + }, + prettierConfig, ]; diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 3c37d602..3733d2de 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -30,8 +30,9 @@ "core-js": "^3.46.0", "cross-env": "^10.1.0", "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-pinia": "^0.4.2", - "eslint-plugin-prettier": "^5.1.0", + "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-vue": "^9.20.0", "happy-dom": "^20.9.0", "jsdom": "^29.1.1", @@ -1703,6 +1704,19 @@ "prettier": ">= 3.0.0" } }, + "node_modules/@vue/eslint-config-prettier/node_modules/eslint-config-prettier": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/@vue/reactivity": { "version": "3.5.33", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.33.tgz", @@ -2738,14 +2752,17 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", - "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } diff --git a/webapp/package.json b/webapp/package.json index 7b70c00e..b593ed8e 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -16,7 +16,7 @@ "lint:fix": "eslint . --fix --ignore-pattern .gitignore", "lint:style": "stylelint \"src/**/*.{vue,less,css}\" --max-warnings=0", "lint:style:fix": "stylelint \"src/**/*.{vue,less,css}\" --fix", - "unitest": "vitest src/tests/unit/LoggingContent.spec.js --no-cache --mode test --detectAsyncLeaks --coverage --isolate --silent --changed --logHeapUsage" + "test:unit": "NODE_OPTIONS=--expose-gc vitest run src/tests/unit/ --no-cache --mode test --detectAsyncLeaks --coverage --isolate=true --pool=forks --silent --logHeapUsage" }, "dependencies": { "@vueuse/core": "^14.1.0", @@ -40,8 +40,9 @@ "core-js": "^3.46.0", "cross-env": "^10.1.0", "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-pinia": "^0.4.2", - "eslint-plugin-prettier": "^5.1.0", + "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-vue": "^9.20.0", "happy-dom": "^20.9.0", "jsdom": "^29.1.1", diff --git a/webapp/src/components/tabContentComponents/loggingContent.vue b/webapp/src/components/tabContentComponents/loggingContent.vue index f621a734..21b0421d 100644 --- a/webapp/src/components/tabContentComponents/loggingContent.vue +++ b/webapp/src/components/tabContentComponents/loggingContent.vue @@ -16,8 +16,8 @@ diff --git a/webapp/src/tests/unit/LoggingContent.spec.js b/webapp/src/tests/unit/LoggingContent.spec.js index 7f4e0a66..0a57329c 100644 --- a/webapp/src/tests/unit/LoggingContent.spec.js +++ b/webapp/src/tests/unit/LoggingContent.spec.js @@ -1,7 +1,7 @@ import { shallowMount, flushPromises } from "@vue/test-utils"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { createTestingPinia } from "@pinia/testing"; -import { setActivePinia } from 'pinia'; +import { setActivePinia } from "pinia"; import axios from "axios"; import fs from "fs"; import path from "path"; @@ -38,7 +38,7 @@ describe("Test LoggingContent.vue", () => { // Things to do before each test beforeEach(async () => { - vi.useFakeTimers() + vi.useFakeTimers(); // Reset mocks before each test vi.resetAllMocks(); @@ -69,23 +69,23 @@ describe("Test LoggingContent.vue", () => { }); // flush so we avoid leaving uncompleted processes running on background await flushPromises(); - vi.advanceTimersByTime(1000) - vi.useRealTimers() + vi.advanceTimersByTime(1000); + vi.useRealTimers(); }); // Tear down wrapper, unmount testing component afterEach(() => { if (wrapper) { - wrapper.unmount() // Clean up virtual DOM and memory bindings + wrapper.unmount(); // Clean up virtual DOM and memory bindings } - setActivePinia(undefined) - document.body.innerHTML = '' + setActivePinia(undefined); + document.body.innerHTML = ""; if (global.gc) { - global.gc() // Forces V8 engine to immediately run Garbage Collection + global.gc(); // Forces V8 engine to immediately run Garbage Collection } - vi.clearAllTimers() - vi.useRealTimers() + vi.clearAllTimers(); + vi.useRealTimers(); }); // Test 1: Render check, if things do exist in the page as intended diff --git a/webapp/vitest.config.js b/webapp/vitest.config.js index 2c243456..a37912df 100644 --- a/webapp/vitest.config.js +++ b/webapp/vitest.config.js @@ -20,7 +20,7 @@ export default defineConfig({ test: { css: false, - pool: 'forks', + pool: "forks", singleThread: true, define: { @@ -28,16 +28,23 @@ export default defineConfig({ }, coverage: { - provider: 'v8', + provider: "v8", clean: true, cleanOnStart: true, - }, + reporter: ["text", "html"], + thresholds: { + lines: 70, + statements: 70, + functions: 50, + branches: 40, + }, + }, deps: { optimizer: { web: { enabled: true, - include: ['@mui/material', 'lucide-react'], // Add your largest component dependencies here + include: ["@mui/material", "lucide-react"], // Add your largest component dependencies here }, }, },