diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 46352f2..7f466f6 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node-version: [16] + node-version: [18] os: [ubuntu-latest] steps: @@ -31,6 +31,6 @@ jobs: env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} SLACK_TITLE: 'Node version' - SLACK_MESSAGE: ${{ matrix.node }} + SLACK_MESSAGE: ${{ matrix.node-version }} SLACK_COLOR: ${{ job.status == 'success' && 'good' || job.status == 'cancelled' && '#808080' || 'danger' }} diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 60078ad..6864425 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node-version: [14.x, 16.x] + node-version: [18.x, 20.x] os: [ubuntu-latest, windows-latest] steps: diff --git a/.github/workflows/on-push-publish-to-npm.yml b/.github/workflows/on-push-publish-to-npm.yml index 91f7943..56bf51a 100644 --- a/.github/workflows/on-push-publish-to-npm.yml +++ b/.github/workflows/on-push-publish-to-npm.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 18 - run: npm install - run: npm test - uses: JS-DevTools/npm-publish@v1 diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index ef91d0a..32e95a2 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -25,7 +25,7 @@ jobs: git config user.email github-actions@github.com - uses: actions/setup-node@v1 with: - node-version: 16 + node-version: 18 - run: | npm install npm test diff --git a/.github/workflows/version-bump-publish.yml b/.github/workflows/version-bump-publish.yml index 6eca10f..c253347 100644 --- a/.github/workflows/version-bump-publish.yml +++ b/.github/workflows/version-bump-publish.yml @@ -21,7 +21,7 @@ jobs: git config user.email github-actions@github.com - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 18 - run: | npm install npm test diff --git a/package.json b/package.json index 6a2c622..8b16ae3 100644 --- a/package.json +++ b/package.json @@ -48,15 +48,15 @@ "jest": "^29", "jest-fetch-mock": "^3.0.2", "jest-junit": "^16.0.0", - "jest-plugin-fs": "^2.9.0", "jsdoc": "^3.6.3", "jsdoc-to-markdown": "^5.0.0", + "memfs": "^4.6.0", "stdout-stderr": "^0.1.9", "tsd-jsdoc": "^2.4.0", "typescript": "^4.9.5" }, "engines": { - "node": "^14.18 || ^16.13 || >=18" + "node": ">=18" }, "scripts": { "e2e": "jest --config e2e/jest.config.js --runInBand", diff --git a/test/__mocks__/fs-extra.js b/test/__mocks__/fs-extra.js new file mode 100644 index 0000000..0d08526 --- /dev/null +++ b/test/__mocks__/fs-extra.js @@ -0,0 +1,9 @@ +const { fs } = require('memfs') + +module.exports = { + ...jest.requireActual('fs-extra'), + // fix for "TypeError: Class constructors cannot be invoked without 'new'" - fs-extra and memfs don't mix well + ...fs, + // fix for "(node:35530) [fs-extra-WARN0003] Warning: fs.realpath.native is not a function. Is fs being monkey-patched?" + realpath: jest.requireActual('fs').realpath +} diff --git a/test/__mocks__/fs.js b/test/__mocks__/fs.js new file mode 100644 index 0000000..bccca2e --- /dev/null +++ b/test/__mocks__/fs.js @@ -0,0 +1,7 @@ +const { fs } = require('memfs') + +module.exports = { + ...fs, + // fix for "(node:35530) [fs-extra-WARN0003] Warning: fs.realpath.native is not a function. Is fs being monkey-patched?" + realpath: jest.requireActual('fs').realpath // get rid of warnings +} diff --git a/test/__mocks__/fs/promises.js b/test/__mocks__/fs/promises.js new file mode 100644 index 0000000..149d2a4 --- /dev/null +++ b/test/__mocks__/fs/promises.js @@ -0,0 +1,2 @@ +const { fs } = require('memfs') +module.exports = fs.promises diff --git a/test/jest.setup.js b/test/jest.setup.js index f72fa3a..c0a538e 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -10,22 +10,15 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const { stdout } = require('stdout-stderr') +const { stdout, stderr } = require('stdout-stderr') const fs = jest.requireActual('fs') const eol = require('eol') +const { vol } = require('memfs') const fetch = require('jest-fetch-mock') -const fileSystem = require('jest-plugin-fs').default -// dont touch the real fs -const mockFs = require('jest-plugin-fs/mock') - -// jest-plugin-fs/mock is too old, and has no updates -// ... fs.rmSync is only available in node >= 14. -jest.mock('fs', () => ({ - ...mockFs, - rmSync: jest.fn() -})) +jest.mock('fs') +jest.mock('fs/promises') process.env.CI = true @@ -34,8 +27,13 @@ jest.setTimeout(30000) jest.setMock('node-fetch', fetch) // trap console log -beforeEach(() => { stdout.start() }) -afterEach(() => { stdout.stop() }) +beforeEach(() => { + stdout.start() + stderr.start() + // change this if you need to see logs from stdout + stdout.print = false +}) +afterEach(() => { stdout.stop(); stderr.stop() }) // helper for fixtures global.fixtureFile = (output) => { @@ -56,36 +54,36 @@ global.fixtureZip = (output) => { global.fakeFileSystem = { addJson: (json) => { // add to existing - fileSystem.mock(json) + vol.fromJSON(json, '/') }, addJsonFolder: (folderPath) => { - fileSystem.mock(getFilesRecursively(folderPath)) + vol.fromJSON(getFilesRecursively(folderPath), '/') }, removeKeys: (arr) => { // remove from existing - const files = fileSystem.files() + const files = vol.toJSON() for (const prop in files) { if (arr.includes(prop)) { delete files[prop] } } - fileSystem.restore() - fileSystem.mock(files) + vol.reset() + vol.fromJSON(files) }, clear: () => { // reset to empty - fileSystem.restore() + vol.reset() }, reset: () => { // reset file system - fileSystem.restore() + vol.reset() }, files: () => { - return fileSystem.files() + return vol.toJSON() } } // seed the fake filesystem -fakeFileSystem.reset() +vol.reset() // fixture matcher expect.extend({