diff --git a/.c8rc.json b/.c8rc.json new file mode 100644 index 00000000000..11549ad3fac --- /dev/null +++ b/.c8rc.json @@ -0,0 +1,13 @@ +{ + "all": true, + "reporter": [ + "lcov", + "text", + "html", + "text-summary" + ], + "include": [ + "lib/**/*.js", + "index.js" + ] +} diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 8d1f63e9398..9583567a00c 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,9 +1,9 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - - name: Node CI +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + on: push: branches: @@ -14,20 +14,63 @@ on: pull_request: jobs: - build: - name: Test - uses: pkgjs/action/.github/workflows/node-test.yaml@v0.1 - with: - runs-on: ubuntu-latest, windows-latest - test-command: npm run coverage:ci - timeout-minutes: 15 - post-test-steps: | - - name: Coverage Report - uses: codecov/codecov-action@v4 + test: + timeout-minutes: 15 + strategy: + fail-fast: false + max-parallel: 0 + matrix: + node-version: + - 18 + - 20 + - 21 + runs-on: + - ubuntu-latest + - windows-latest + + runs-on: ${{ matrix.runs-on }} + + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Setup Node.js@${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Print version information + run: | + echo OS: $(node -p "os.version()") + echo Node.js: $(node --version) + echo npm: $(npm --version) + echo git: $(git --version) + + - name: Install dependencies + run: npm install + + - name: Print installed dependencies + run: npm ls --all + continue-on-error: true + + - name: Run tests + run: npm run coverage:ci + env: + CI: true + NODE_V8_COVERAGE: ./coverage/tmp + + - name: Coverage Report + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + automerge: if: > github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]' - needs: build + needs: test runs-on: ubuntu-latest permissions: pull-requests: write diff --git a/.gitignore b/.gitignore index acd1b69eca2..0d8d333f83a 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,6 @@ fuzz-results-*.json # Bundle output undici-fetch.js /test/imports/undici-import.js + +# .npmrc has platform specific value for windows +.npmrc diff --git a/package.json b/package.json index 9cd9f7431cc..a4759d5221c 100644 --- a/package.json +++ b/package.json @@ -67,24 +67,28 @@ "build:wasm": "node build/wasm.js --docker", "lint": "standard | snazzy", "lint:fix": "standard --fix | snazzy", - "test": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:jest && npm run test:typescript && npm run test:node-test", - "test:cookies": "borp --coverage -p \"test/cookie/*.js\"", - "test:node-fetch": "borp --coverage -p \"test/node-fetch/**/*.js\"", - "test:eventsource": "npm run build:node && borp --expose-gc --coverage -p \"test/eventsource/*.js\"", - "test:fetch": "npm run build:node && borp --expose-gc --coverage -p \"test/fetch/*.js\" && borp --coverage -p \"test/webidl/*.js\"", - "test:jest": "jest", + "test": "npm run test:javascript && npm run test:typescript", + "test:javascript": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:node-test && npm run test:jest", + "test:cookies": "borp -p \"test/cookie/*.js\"", + "test:node-fetch": "borp -p \"test/node-fetch/**/*.js\"", + "test:eventsource": "npm run build:node && borp --expose-gc -p \"test/eventsource/*.js\"", + "test:fetch": "npm run build:node && borp --expose-gc -p \"test/fetch/*.js\" && borp -p \"test/webidl/*.js\"", + "test:jest": "cross-env NODE_V8_COVERAGE= jest", "test:unit": "borp --expose-gc -p \"test/*.js\"", - "test:node-test": "borp --coverage -p \"test/node-test/**/*.js\"", - "test:tdd": "borp --coverage --expose-gc -p \"test/*.js\"", + "test:node-test": "borp -p \"test/node-test/**/*.js\"", + "test:tdd": "borp --expose-gc -p \"test/*.js\"", "test:tdd:node-test": "borp -p \"test/node-test/**/*.js\" -w", - "test:typescript": "tsd && tsc --skipLibCheck test/imports/undici-import.ts", - "test:websocket": "borp --coverage -p \"test/websocket/*.js\"", + "test:typescript": "cross-env NODE_V8_COVERAGE= tsd && tsc --skipLibCheck test/imports/undici-import.ts", + "test:websocket": "borp -p \"test/websocket/*.js\"", "test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs", - "coverage": "nyc --reporter=text --reporter=html npm run test", - "coverage:ci": "nyc --reporter=lcov npm run test", + "coverage": "cross-env NODE_V8_COVERAGE=./coverage/tmp && npm run coverage:clean && npm run test && npm run coverage:report", + "coverage:ci": "npm run coverage:clean && npm run test && npm run coverage:report:ci", + "coverage:clean": "node ./scripts/clean-coverage.js", + "coverage:report": "cross-env NODE_V8_COVERAGE= c8 report", + "coverage:report:ci": "c8 report", "bench": "echo \"Error: Benchmarks have been moved to '\/benchmarks'\" && exit 1", "serve:website": "echo \"Error: Documentation has been moved to '\/docs'\" && exit 1", - "prepare": "husky install", + "prepare": "husky install && node ./scripts/platform-shell.js", "fuzz": "jsfuzz test/fuzzing/fuzz.js corpus" }, "devDependencies": { @@ -93,6 +97,8 @@ "@types/node": "^18.0.3", "abort-controller": "^3.0.0", "borp": "^0.9.1", + "c8": "^9.1.0", + "cross-env": "^7.0.3", "dns-packet": "^5.4.0", "form-data": "^4.0.0", "formdata-node": "^6.0.3", diff --git a/scripts/clean-coverage.js b/scripts/clean-coverage.js new file mode 100644 index 00000000000..23c30895241 --- /dev/null +++ b/scripts/clean-coverage.js @@ -0,0 +1,14 @@ +'use strict' + +const { rmSync } = require('node:fs') +const { resolve } = require('node:path') + +if (process.env.NODE_V8_COVERAGE) { + if (process.env.NODE_V8_COVERAGE.endsWith('/tmp')) { + rmSync(resolve(__dirname, process.env.NODE_V8_COVERAGE, '..'), { recursive: true, force: true }) + } else { + rmSync(resolve(__dirname, process.env.NODE_V8_COVERAGE), { recursive: true, force: true }) + } +} else { + rmSync(resolve(__dirname, 'coverage'), { recursive: true, force: true }) +} diff --git a/scripts/platform-shell.js b/scripts/platform-shell.js new file mode 100644 index 00000000000..093ce536a77 --- /dev/null +++ b/scripts/platform-shell.js @@ -0,0 +1,12 @@ +'use strict' + +const { platform } = require('node:os') +const { writeFileSync } = require('node:fs') +const { resolve } = require('node:path') + +if (platform() === 'win32') { + writeFileSync( + resolve(__dirname, '.npmrc'), + 'script-shell = "C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"\n' + ) +}