From f55a4bab602d748d9c0adab85dce993fba87a985 Mon Sep 17 00:00:00 2001 From: Pupix Date: Wed, 29 Jan 2025 18:33:52 +0100 Subject: [PATCH 1/4] chore(tests): replace tap with node:test --- .github/workflows/ci.yml | 2 +- .taprc | 2 - package.json | 6 +- test/build-plugin.test.js | 140 +++++++++++++++--------------- test/fastify-secrets-core.test.js | 7 +- 5 files changed, 78 insertions(+), 79 deletions(-) delete mode 100644 .taprc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9757f01..dca1ee2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: node-version: ${{ matrix.node-version }} - run: npm install - run: npm run lint - - run: npm run test:ci + - run: npm run test automerge: needs: build runs-on: ubuntu-latest diff --git a/.taprc b/.taprc deleted file mode 100644 index 6ecd25a..0000000 --- a/.taprc +++ /dev/null @@ -1,2 +0,0 @@ -100: true -reporter: spec diff --git a/package.json b/package.json index cbf529c..3402ea4 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,7 @@ "lint": "eslint lib/**/*.js test/**/*.js", "lint:fix": "npm run lint -- --fix", "lint:staged": "lint-staged", - "test": "tap --no-browser --coverage-report=html --coverage-report=text test", - "test:ci": "tap --no-color --coverage-report=json --coverage-report=text test" + "test": "node --test --experimental-test-coverage --test-coverage-exclude=test/** --test-coverage-branches=100 --test-coverage-lines=100 --test-coverage-functions=100" }, "repository": { "type": "git", @@ -47,8 +46,7 @@ "lint-staged": "^15.0.1", "prettier": "^3.0.1", "proxyquire": "^2.1.3", - "sinon": "^19.0.2", - "tap": "^16.0.0" + "sinon": "^19.0.2" }, "lint-staged": { "*.js": [ diff --git a/test/build-plugin.test.js b/test/build-plugin.test.js index 2c335fd..af57136 100644 --- a/test/build-plugin.test.js +++ b/test/build-plugin.test.js @@ -1,6 +1,8 @@ 'use strict' -const { test, beforeEach } = require('tap') +const { test, beforeEach } = require('node:test') +const assert = require('node:assert/strict') + const sinon = require('sinon') const proxyquire = require('proxyquire') @@ -23,19 +25,19 @@ beforeEach(async () => { fp.returns({}) }) -test('builds a fastify plugin', async (t) => { +test('builds a fastify plugin', () => { const plugin = buildPlugin(Client, { option: 'option1' }) - t.ok(fp.called, 'calls fastify-plugin') + assert.ok(fp.called, 'calls fastify-plugin') const opts = fp.firstCall.args[1] - t.equal(opts.fastify, '5.x', 'adds option for fastify support') - t.equal(opts.option, 'option1', 'forward provided options') + assert.strictEqual(opts.fastify, '5.x', 'adds option for fastify support') + assert.strictEqual(opts.option, 'option1', 'forward provided options') - t.equal(plugin.Client, Client, 'also exports client') + assert.strictEqual(plugin.Client, Client, 'also exports client') }) test('plugin', async (t) => { @@ -44,7 +46,7 @@ test('plugin', async (t) => { }) const plugin = fp.firstCall.args[0] - t.test('no namespace', async (t) => { + await test('no namespace', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -59,7 +61,7 @@ test('plugin', async (t) => { } }) - t.ok(typeof fastifyMock.secrets.refresh === 'function', 'refresh is defined as expected') + assert.ok(typeof fastifyMock.secrets.refresh === 'function', 'refresh is defined as expected') sinon.assert.calledWith(decorate, 'secrets', { secret1: 'content for secret1-name', secret2: 'content for secret2-name', @@ -67,7 +69,7 @@ test('plugin', async (t) => { }) }) - t.test('no namespace - secrets array', async (t) => { + await test('no namespace - secrets array', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -79,7 +81,7 @@ test('plugin', async (t) => { secrets: ['secret1-name', 'secret2-name'] }) - t.ok(typeof fastifyMock.secrets.refresh === 'function', 'refresh is defined as expected') + assert.ok(typeof fastifyMock.secrets.refresh === 'function', 'refresh is defined as expected') sinon.assert.calledWith(decorate, 'secrets', { 'secret1-name': 'content for secret1-name', 'secret2-name': 'content for secret2-name', @@ -87,7 +89,7 @@ test('plugin', async (t) => { }) }) - t.test('no namespace - secrets exists', async (t) => { + await test('no namespace - secrets exists', async (t) => { const decorate = sinon.spy() const promise = plugin( @@ -100,11 +102,11 @@ test('plugin', async (t) => { } ) - await t.rejects(promise, new Error('fastify-secrets has already been registered'), 'registration fails') - t.notOk(decorate.called, 'does not decorate fastify') + await assert.rejects(promise, new Error('fastify-secrets has already been registered'), 'registration fails') + assert.strictEqual(decorate.called, false, 'does not decorate fastify') }) - t.test('namespace', async (t) => { + await test('namespace', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -120,7 +122,7 @@ test('plugin', async (t) => { } }) - t.ok(typeof fastifyMock.secrets.namespace1.refresh === 'function', 'refresh is defined as expected') + assert.ok(typeof fastifyMock.secrets.namespace1.refresh === 'function', 'refresh is defined as expected') sinon.assert.calledWith(decorate, 'secrets', { namespace1: { secret1: 'content for secret1-name', @@ -130,7 +132,7 @@ test('plugin', async (t) => { }) }) - t.test('namespace - secrets exists', async (t) => { + await test('namespace - secrets exists', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -148,9 +150,9 @@ test('plugin', async (t) => { } }) - t.ok(typeof fastifyMock.secrets.namespace1.refresh === 'function', 'refresh is defined as expected') - t.notOk(decorate.calledWith('secrets'), 'does not decorate fastify with secrets') - t.same( + assert.ok(typeof fastifyMock.secrets.namespace1.refresh === 'function', 'refresh is defined as expected') + assert.strictEqual(decorate.calledWith('secrets'), false, 'does not decorate fastify with secrets') + assert.deepStrictEqual( expectedSecrets, { namespace1: { @@ -163,7 +165,7 @@ test('plugin', async (t) => { ) }) - t.test('namespace - namespace exists', async (t) => { + await test('namespace - namespace exists', async (t) => { const decorate = sinon.spy() const secrets = { namespace1: {} @@ -180,13 +182,13 @@ test('plugin', async (t) => { } ) - await t.rejects( + await assert.rejects( promise, new Error(`fastify-secrets 'namespace1' instance name has already been registered`), 'registration fails' ) - t.notOk(decorate.called, 'does not decorate fastify') - t.notSame( + assert.strictEqual(decorate.called, false, 'does not decorate fastify') + assert.notDeepStrictEqual( secrets, { namespace1: { @@ -198,26 +200,26 @@ test('plugin', async (t) => { ) }) - t.test('no options', async (t) => { + await test('no options', async (t) => { const decorate = sinon.spy() const promise = plugin({ decorate }) - await t.rejects(promise, new Error(`fastify-secrets: no secrets requested`), 'registration fails') - t.notOk(decorate.called, 'does not decorate fastify') + await assert.rejects(promise, new Error(`fastify-secrets: no secrets requested`), 'registration fails') + assert.strictEqual(decorate.called, false, 'does not decorate fastify') }) - t.test('no secrets', async (t) => { + await test('no secrets', async (t) => { const decorate = sinon.spy() const emptyOpts = {} const promise = plugin({ decorate }, emptyOpts) - await t.rejects(promise, new Error(`fastify-secrets: no secrets requested`), 'registration fails') - t.notOk(decorate.called, 'does not decorate fastify') + await assert.rejects(promise, new Error(`fastify-secrets: no secrets requested`), 'registration fails') + assert.strictEqual(decorate.called, false, 'does not decorate fastify') }) }) test('client integration', async (t) => { - t.test('clientOptions are provided to client when instantiated', async (t) => { + await test('clientOptions are provided to client when instantiated', async (t) => { const constructorStub = sinon.stub() class Client { @@ -247,7 +249,7 @@ test('client integration', async (t) => { sinon.assert.calledOnceWithExactly(constructorStub, clientOptions) }) - t.test('client with close method', async (t) => { + await test('client with close method', async (t) => { let closeCalled = false class Client { @@ -275,10 +277,10 @@ test('client integration', async (t) => { } ) - t.ok(closeCalled, 'calls client.close if present') + assert.ok(closeCalled, 'calls client.close if present') }) - t.test('client without close method', async (t) => { + await test('client without close method', async (t) => { class Client { async get(key) { return key @@ -299,7 +301,7 @@ test('client integration', async (t) => { } ) - await t.resolves(promise, 'does not fail') + await assert.doesNotReject(promise, 'does not fail') }) }) @@ -307,7 +309,7 @@ test('client wrapper', async (t) => { buildPlugin(Client) const plugin = fp.firstCall.args[0] - t.test("is exposed as 'refresh' at the root with no namespace", async (t) => { + await test("is exposed as 'refresh' at the root with no namespace", async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -321,11 +323,11 @@ test('client wrapper', async (t) => { } }) - t.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') - t.ok(fastifyMock.secrets.refresh, 'populates secrets with a refresh method') + assert.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') + assert.ok(fastifyMock.secrets.refresh, 'populates secrets with a refresh method') }) - t.test("is exposed as 'refresh' on the namespace scope when provided", async (t) => { + test("is exposed as 'refresh' on the namespace scope when provided", async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -340,11 +342,11 @@ test('client wrapper', async (t) => { } }) - t.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') - t.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') + assert.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') + assert.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') }) - t.test('can be aliased using the refreshAlias option', async (t) => { + await test('can be aliased using the refreshAlias option', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -360,11 +362,11 @@ test('client wrapper', async (t) => { } }) - t.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') - t.ok(fastifyMock.secrets.test.update, 'populates secrets namespace with an "update" method') + assert.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') + assert.ok(fastifyMock.secrets.test.update, 'populates secrets namespace with an "update" method') }) - t.test('persists across refresh invocations', async (t) => { + await test('persists across refresh invocations', async (t) => { const decorate = sinon.stub().callsFake((key, value) => { fastifyMock[key] = value }) @@ -379,13 +381,13 @@ test('client wrapper', async (t) => { } }) - t.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') - t.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') + assert.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') + assert.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') await fastifyMock.secrets.test.refresh() - t.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') - t.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') + assert.ok(decorate.calledWith('secrets'), 'decorates fastify with secrets') + assert.ok(fastifyMock.secrets.test.refresh, 'populates secrets namespace with a refresh method') }) class MockClient { @@ -403,7 +405,7 @@ test('client wrapper', async (t) => { } } - t.test('allows for specific secrets to be refreshed', async (t) => { + await test('allows for specific secrets to be refreshed', async (t) => { buildPlugin(MockClient) const plugin = fp.firstCall.args[0] @@ -421,11 +423,11 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.refresh('test') - t.equal(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test2, 'value for test2 - 1', 'un-refreshed secret has been called once') + assert.strictEqual(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test2, 'value for test2 - 1', 'un-refreshed secret has been called once') }) - t.test('refreshes all secrets by default', async (t) => { + await test('refreshes all secrets by default', async (t) => { buildPlugin(MockClient) const plugin = fp.firstCall.args[0] @@ -443,11 +445,11 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.refresh() - t.equal(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test2, 'value for test2 - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test2, 'value for test2 - 2', 'refreshed secret has been called twice') }) - t.test('refreshes a specified set of secrets with array notation', async (t) => { + await test('refreshes a specified set of secrets with array notation', async (t) => { buildPlugin(MockClient) const plugin = fp.firstCall.args[0] @@ -465,12 +467,12 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.refresh(['test', 'test2']) - t.equal(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test2, 'value for test2 - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test3, 'value for test3 - 1', 'un-refreshed secret has been called once') + assert.strictEqual(fastifyMock.secrets.test, 'value for test - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test2, 'value for test2 - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test3, 'value for test3 - 1', 'un-refreshed secret has been called once') }) - t.test('refreshes a specified set of secrets with object notation', async (t) => { + await test('refreshes a specified set of secrets with object notation', async (t) => { buildPlugin(MockClient) const plugin = fp.firstCall.args[0] @@ -493,12 +495,12 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.refresh() - t.equal(fastifyMock.secrets.test, 'value for secretAlias - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test2, 'value for secretAlias2 - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.test3, 'value for secretAlias3 - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test, 'value for secretAlias - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test2, 'value for secretAlias2 - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.test3, 'value for secretAlias3 - 2', 'refreshed secret has been called twice') }) - t.test('respects namespaces when refreshing', async (t) => { + await test('respects namespaces when refreshing', async (t) => { buildPlugin(MockClient) const plugin = fp.firstCall.args[0] @@ -518,11 +520,11 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.testns.refresh('test') - t.equal(fastifyMock.secrets.testns.test, 'value for test - 2', 'refreshed secret has been called twice') - t.equal(fastifyMock.secrets.testns.test2, 'value for test2 - 1', 'un-refreshed secret has been called once') + assert.strictEqual(fastifyMock.secrets.testns.test, 'value for test - 2', 'refreshed secret has been called twice') + assert.strictEqual(fastifyMock.secrets.testns.test2, 'value for test2 - 1', 'un-refreshed secret has been called once') }) - t.test('will instantiate a fresh client if there is a provided close method', async (t) => { + await test('will instantiate a fresh client if there is a provided close method', async (t) => { const constructionStub = sinon.stub() const closeStub = sinon.stub() class MockCloseClient { @@ -554,11 +556,11 @@ test('client wrapper', async (t) => { secrets: ['test'] }) - t.ok(closeStub.calledOnce, 'close is invoked after initial secret setup') + assert.ok(closeStub.calledOnce, 'close is invoked after initial secret setup') await fastifyMock.secrets.refresh() - t.ok(constructionStub.calledTwice, 'constructor has been called twice') - t.ok(closeStub.calledTwice, 'close method has been called twice') + assert.ok(constructionStub.calledTwice, 'constructor has been called twice') + assert.ok(closeStub.calledTwice, 'close method has been called twice') }) }) diff --git a/test/fastify-secrets-core.test.js b/test/fastify-secrets-core.test.js index 177dc85..a3c9513 100644 --- a/test/fastify-secrets-core.test.js +++ b/test/fastify-secrets-core.test.js @@ -1,9 +1,10 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') +const assert = require('node:assert/strict') const { buildPlugin } = require('../lib/fastify-secrets-core') -test('buildPlugin should be defined', async (t) => { - t.ok(buildPlugin) +test('buildPlugin should be defined', () => { + assert.ok(buildPlugin) }) From 7036fbf6cd67ff3c3bb3a7eab601f8801878337f Mon Sep 17 00:00:00 2001 From: Pupix Date: Wed, 29 Jan 2025 18:47:40 +0100 Subject: [PATCH 2/4] chore(tests): fix lint issues --- test/build-plugin.test.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/build-plugin.test.js b/test/build-plugin.test.js index af57136..b5bea5b 100644 --- a/test/build-plugin.test.js +++ b/test/build-plugin.test.js @@ -496,8 +496,16 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.refresh() assert.strictEqual(fastifyMock.secrets.test, 'value for secretAlias - 2', 'refreshed secret has been called twice') - assert.strictEqual(fastifyMock.secrets.test2, 'value for secretAlias2 - 2', 'refreshed secret has been called twice') - assert.strictEqual(fastifyMock.secrets.test3, 'value for secretAlias3 - 2', 'refreshed secret has been called twice') + assert.strictEqual( + fastifyMock.secrets.test2, + 'value for secretAlias2 - 2', + 'refreshed secret has been called twice' + ) + assert.strictEqual( + fastifyMock.secrets.test3, + 'value for secretAlias3 - 2', + 'refreshed secret has been called twice' + ) }) await test('respects namespaces when refreshing', async (t) => { @@ -521,7 +529,11 @@ test('client wrapper', async (t) => { await fastifyMock.secrets.testns.refresh('test') assert.strictEqual(fastifyMock.secrets.testns.test, 'value for test - 2', 'refreshed secret has been called twice') - assert.strictEqual(fastifyMock.secrets.testns.test2, 'value for test2 - 1', 'un-refreshed secret has been called once') + assert.strictEqual( + fastifyMock.secrets.testns.test2, + 'value for test2 - 1', + 'un-refreshed secret has been called once' + ) }) await test('will instantiate a fresh client if there is a provided close method', async (t) => { From 9c9807075de4765c66db49229bc8886eda09864d Mon Sep 17 00:00:00 2001 From: Pupix Date: Wed, 29 Jan 2025 19:04:33 +0100 Subject: [PATCH 3/4] chore(tests): update ci node versions --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dca1ee2..c0d9e8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,9 +10,8 @@ jobs: strategy: matrix: node-version: - - 16 - - 18 - 20 + - 22 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From 3c1431d436c98a7bc04bfc0dfb47dc452170b90a Mon Sep 17 00:00:00 2001 From: Pupix Date: Wed, 29 Jan 2025 19:12:23 +0100 Subject: [PATCH 4/4] chore(tests): make CI use nvmrc --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0d9e8f..db91885 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,16 +7,11 @@ on: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: - - 20 - - 22 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version-file: .nvmrc - run: npm install - run: npm run lint - run: npm run test