diff --git a/package.json b/package.json index 9b4b98d..4afb875 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "types": "index.d.ts", "scripts": { - "test": "standard | snazzy && tap test/*test.js && tsd", + "test": "standard | snazzy && c8 --100 node --test test/*test.js && tsd", "test:browser": "node test/browser/helpers/runner-browser.mjs", "lint:fix": "standard --fix", "redis": "docker run --rm -p 6379:6379 redis redis-server" @@ -31,11 +31,13 @@ "license": "MIT", "devDependencies": { "@fastify/pre-commit": "^2.0.2", + "@matteo.collina/tspl": "^0.1.0", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-inject": "^5.0.3", "@rollup/plugin-node-resolve": "^15.2.1", "browserify": "^17.0.0", "buffer": "^6.0.3", + "c8": "^8.0.1", "esbuild": "^0.19.4", "esbuild-plugin-alias": "^0.2.1", "events": "^3.3.0", @@ -49,7 +51,6 @@ "snazzy": "^9.0.0", "standard": "^17.1.0", "stream-browserify": "^3.0.0", - "tap": "^18.4", "tap-mocha-reporter": "^5.0.4", "tap-parser": "^15.2.0", "tape": "^5.7.0", diff --git a/test/base.test.js b/test/base.test.js index 1506a56..4a90daa 100644 --- a/test/base.test.js +++ b/test/base.test.js @@ -1,6 +1,8 @@ 'use strict' -const { test, before, teardown } = require('tap') +const { describe, test, before, after } = require('node:test') +const assert = require('node:assert') +const { tspl } = require('@matteo.collina/tspl') const Redis = require('ioredis') const stringify = require('safe-stable-stringify') @@ -18,610 +20,613 @@ const dummyStorage = { } let redisClient -before(async (t) => { - redisClient = new Redis() -}) - -teardown(async (t) => { - await redisClient.quit() -}) - -test('create a Cache that dedupes', async (t) => { - t.plan(6) - let dedupes = 0 - const cache = new Cache({ - storage: dummyStorage, - onDedupe () { - dedupes++ - } +describe('base', async () => { + before(async () => { + redisClient = new Redis() }) - const expected = [42, 24] - - cache.define('fetchSomething', async (value, key) => { - t.equal(value, expected.shift()) - t.equal(stringify(value), key) - return { k: value } + after(async () => { + await redisClient.quit() }) - const p1 = cache.fetchSomething(42) - const p2 = cache.fetchSomething(24) - const p3 = cache.fetchSomething(42) + test('create a Cache that dedupes', async (t) => { + const { deepStrictEqual, equal } = tspl(t, { plan: 6 }) - const res = await Promise.all([p1, p2, p3]) + let dedupes = 0 + const cache = new Cache({ + storage: dummyStorage, + onDedupe () { + dedupes++ + } + }) - t.same(res, [ - { k: 42 }, - { k: 24 }, - { k: 42 } - ]) - t.equal(dedupes, 1) -}) + const expected = [42, 24] -test('create a Cache that dedupes full signature', async (t) => { - t.plan(3) + cache.define('fetchSomething', async (value, key) => { + equal(value, expected.shift()) + equal(stringify(value), key) + return { k: value } + }) - const cache = new Cache({ storage: dummyStorage }) + const p1 = cache.fetchSomething(42) + const p2 = cache.fetchSomething(24) + const p3 = cache.fetchSomething(42) - const expected = [42, 24] + const res = await Promise.all([p1, p2, p3]) - cache.define('fetchSomething', undefined, async (query) => { - t.equal(query, expected.shift()) - return { k: query } + deepStrictEqual(res, [ + { k: 42 }, + { k: 24 }, + { k: 42 } + ]) + equal(dedupes, 1) }) - const p1 = cache.fetchSomething(42) - const p2 = cache.fetchSomething(24) - const p3 = cache.fetchSomething(42) + test('create a Cache that dedupes full signature', async (t) => { + const { deepStrictEqual, equal } = tspl(t, { plan: 3 }) - const res = await Promise.all([p1, p2, p3]) - - t.same(res, [ - { k: 42 }, - { k: 24 }, - { k: 42 } - ]) -}) + const cache = new Cache({ storage: dummyStorage }) -test('create a cache with the factory function, default options', async t => { - const cache = createCache() + const expected = [42, 24] - t.ok(cache[kStorage]) + cache.define('fetchSomething', undefined, async (query) => { + equal(query, expected.shift()) + return { k: query } + }) - cache.define('plusOne', async (value, key) => value + 1) + const p1 = cache.fetchSomething(42) + const p2 = cache.fetchSomething(24) + const p3 = cache.fetchSomething(42) - t.equal(await cache.plusOne(42), 43) - t.equal(await cache.plusOne(24), 25) - t.equal(await cache.plusOne(42), 43) -}) + const res = await Promise.all([p1, p2, p3]) -test('create a cache with the factory function, with default storage', async t => { - let hits = 0 - const cache = createCache({ - ttl: 1, - onHit () { hits++ } + deepStrictEqual(res, [ + { k: 42 }, + { k: 24 }, + { k: 42 } + ]) }) - t.ok(cache[kStorage].get) - t.ok(cache[kStorage].set) + test('create a cache with the factory function, default options', async t => { + const cache = createCache() - cache.define('plusOne', async (value, key) => value + 1) + assert.ok(cache[kStorage]) - t.equal(await cache.plusOne(42), 43) - t.equal(await cache.plusOne(24), 25) - t.equal(await cache.plusOne(42), 43) + cache.define('plusOne', async (value, key) => value + 1) - t.equal(hits, 1) -}) - -test('create a cache with the factory function, with storage', async t => { - let hits = 0 - const cache = createCache({ - ttl: 1, - storage: { type: 'memory', options: { size: 9 } }, - onHit () { hits++ } + assert.equal(await cache.plusOne(42), 43) + assert.equal(await cache.plusOne(24), 25) + assert.equal(await cache.plusOne(42), 43) }) - t.equal(cache[kStorage].size, 9) + test('create a cache with the factory function, with default storage', async t => { + let hits = 0 + const cache = createCache({ + ttl: 1, + onHit () { hits++ } + }) - cache.define('plusOne', async (value, key) => value + 1) + assert.ok(cache[kStorage].get) + assert.ok(cache[kStorage].set) - t.equal(await cache.plusOne(42), 43) - t.equal(await cache.plusOne(24), 25) - t.equal(await cache.plusOne(42), 43) + cache.define('plusOne', async (value, key) => value + 1) - t.equal(hits, 1) -}) + assert.equal(await cache.plusOne(42), 43) + assert.equal(await cache.plusOne(24), 25) + assert.equal(await cache.plusOne(42), 43) -test('missing function', async (t) => { - const cache = new Cache({ storage: createStorage() }) - t.throws(function () { - cache.define('something', null) - }) - t.throws(function () { - cache.define('something', 42) + assert.equal(hits, 1) }) - t.throws(function () { - cache.define('something', 'a string') - }) -}) -test('works with custom serialize', async (t) => { - t.plan(3) + test('create a cache with the factory function, with storage', async t => { + let hits = 0 + const cache = createCache({ + ttl: 1, + storage: { type: 'memory', options: { size: 9 } }, + onHit () { hits++ } + }) - const cache = new Cache({ storage: createStorage() }) + assert.equal(cache[kStorage].size, 9) - cache.define( - 'fetchSomething', - { - serialize (args) { return args.k } - }, - async (queries) => { - return queries - } - ) + cache.define('plusOne', async (value, key) => value + 1) - const p1 = cache.fetchSomething({ k: 42 }) - const p2 = cache.fetchSomething({ k: 24 }) + assert.equal(await cache.plusOne(42), 43) + assert.equal(await cache.plusOne(24), 25) + assert.equal(await cache.plusOne(42), 43) - t.same([...cache[kValues].fetchSomething.dedupes.keys()], ['42', '24']) - const res = await Promise.all([p1, p2]) + assert.equal(hits, 1) + }) - t.same(res, [ - { k: 42 }, - { k: 24 } - ]) + test('missing function', async (t) => { + const cache = new Cache({ storage: createStorage() }) + assert.throws(function () { + cache.define('something', null) + }) + assert.throws(function () { + cache.define('something', 42) + }) + assert.throws(function () { + cache.define('something', 'a string') + }) + }) - // Ensure we clean up dedupes - t.same([...cache[kValues].fetchSomething.dedupes.keys()], []) -}) + test('works with custom serialize', async (t) => { + const { deepStrictEqual } = tspl(t, { plan: 3 }) -test('constructor - options', async (t) => { - test('missing storage', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache() - }) + const cache = new Cache({ storage: createStorage() }) + + cache.define( + 'fetchSomething', + { + serialize (args) { return args.k } + }, + async (queries) => { + return queries + } + ) + + const p1 = cache.fetchSomething({ k: 42 }) + const p2 = cache.fetchSomething({ k: 24 }) + + deepStrictEqual([...cache[kValues].fetchSomething.dedupes.keys()], ['42', '24']) + const res = await Promise.all([p1, p2]) + + deepStrictEqual(res, [ + { k: 42 }, + { k: 24 } + ]) + + // Ensure we clean up dedupes + deepStrictEqual([...cache[kValues].fetchSomething.dedupes.keys()], []) }) - test('invalid ttl', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache({ storage: createStorage(), ttl: -1 }) + describe('constructor - options', async () => { + test('missing storage', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache() + }) }) - }) - test('invalid onDedupe', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache({ storage: createStorage(), onDedupe: -1 }) + test('invalid ttl', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache({ storage: createStorage(), ttl: -1 }) + }) }) - }) - test('invalid onError', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache({ storage: createStorage(), onError: {} }) + test('invalid onDedupe', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache({ storage: createStorage(), onDedupe: -1 }) + }) }) - }) - test('invalid onHit', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache({ storage: createStorage(), onHit: -1 }) + test('invalid onError', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache({ storage: createStorage(), onError: {} }) + }) }) - }) - test('invalid onMiss', async (t) => { - t.throws(function () { - // eslint-disable-next-line no-new - new Cache({ storage: createStorage(), onMiss: -1 }) + test('invalid onHit', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache({ storage: createStorage(), onHit: -1 }) + }) }) - }) -}) -test('define - options', async (t) => { - test('wrong serialize', async (t) => { - const cache = new Cache({ storage: createStorage() }) - t.throws(function () { - cache.define('something', { - serialize: 42 - }, async () => { }) + test('invalid onMiss', async () => { + assert.throws(function () { + // eslint-disable-next-line no-new + new Cache({ storage: createStorage(), onMiss: -1 }) + }) }) }) - test('wrong references', async (t) => { - const cache = new Cache({ storage: createStorage() }) - t.throws(function () { - cache.define('something', { - references: 42 - }, async () => { }) + describe('define - options', async () => { + test('wrong serialize', async () => { + const cache = new Cache({ storage: createStorage() }) + assert.throws(function () { + cache.define('something', { + serialize: 42 + }, async () => { }) + }) + }) + + test('wrong references', async () => { + const cache = new Cache({ storage: createStorage() }) + assert.throws(function () { + cache.define('something', { + references: 42 + }, async () => { }) + }) + }) + + test('custom storage', async () => { + const cache = new Cache({ storage: createStorage() }) + cache.define('foo', { + storage: { type: 'memory', options: { size: 9 } } + }, () => true) + + assert.ok(cache.foo()) }) }) - test('custom storage', async (t) => { + test('safe stable serialize', async (t) => { + const { deepStrictEqual, equal } = tspl(t, { plan: 5 }) + const cache = new Cache({ storage: createStorage() }) - cache.define('foo', { - storage: { type: 'memory', options: { size: 9 } } - }, () => true) - t.ok(cache.foo()) - }) -}) + const expected = [ + { foo: 'bar', bar: 'foo' }, + { hello: 'world' } + ] -test('safe stable serialize', async (t) => { - t.plan(5) + cache.define('fetchSomething', async (query, cacheKey) => { + deepStrictEqual(query, expected.shift()) + equal(stringify(query), cacheKey) - const cache = new Cache({ storage: createStorage() }) + return { k: query } + }) - const expected = [ - { foo: 'bar', bar: 'foo' }, - { hello: 'world' } - ] + const p1 = cache.fetchSomething({ foo: 'bar', bar: 'foo' }) + const p2 = cache.fetchSomething({ hello: 'world' }) + const p3 = cache.fetchSomething({ bar: 'foo', foo: 'bar' }) - cache.define('fetchSomething', async (query, cacheKey) => { - t.same(query, expected.shift()) - t.equal(stringify(query), cacheKey) + const res = await Promise.all([p1, p2, p3]) - return { k: query } + deepStrictEqual(res, [ + { k: { foo: 'bar', bar: 'foo' } }, + { k: { hello: 'world' } }, + { k: { foo: 'bar', bar: 'foo' } } + ]) }) - const p1 = cache.fetchSomething({ foo: 'bar', bar: 'foo' }) - const p2 = cache.fetchSomething({ hello: 'world' }) - const p3 = cache.fetchSomething({ bar: 'foo', foo: 'bar' }) + test('strings', async (t) => { + const { deepStrictEqual, equal } = tspl(t, { plan: 3 }) - const res = await Promise.all([p1, p2, p3]) + const cache = new Cache({ storage: createStorage() }) - t.same(res, [ - { k: { foo: 'bar', bar: 'foo' } }, - { k: { hello: 'world' } }, - { k: { foo: 'bar', bar: 'foo' } } - ]) -}) + const expected = ['42', '24'] -test('strings', async (t) => { - t.plan(3) + cache.define('fetchSomething', async (query) => { + equal(query, expected.shift()) + return { k: query } + }) - const cache = new Cache({ storage: createStorage() }) + const p1 = cache.fetchSomething('42') + const p2 = cache.fetchSomething('24') + const p3 = cache.fetchSomething('42') - const expected = ['42', '24'] + const res = await Promise.all([p1, p2, p3]) - cache.define('fetchSomething', async (query) => { - t.equal(query, expected.shift()) - return { k: query } + deepStrictEqual(res, [ + { k: '42' }, + { k: '24' }, + { k: '42' } + ]) }) - const p1 = cache.fetchSomething('42') - const p2 = cache.fetchSomething('24') - const p3 = cache.fetchSomething('42') - - const res = await Promise.all([p1, p2, p3]) + test('do not cache failures', async (t) => { + const { deepStrictEqual, ok, rejects } = tspl(t, { plan: 4 }) - t.same(res, [ - { k: '42' }, - { k: '24' }, - { k: '42' } - ]) -}) - -test('do not cache failures', async (t) => { - t.plan(4) + const cache = new Cache({ storage: createStorage() }) - const cache = new Cache({ storage: createStorage() }) + let called = false + cache.define('fetchSomething', async (query) => { + ok('called') + if (!called) { + called = true + throw new Error('kaboom') + } + return { k: query } + }) - let called = false - cache.define('fetchSomething', async (query) => { - t.pass('called') - if (!called) { - called = true - throw new Error('kaboom') - } - return { k: query } + await rejects(cache.fetchSomething(42)) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) - await t.rejects(cache.fetchSomething(42)) - t.same(await cache.fetchSomething(42), { k: 42 }) -}) + test('do not cache failures async', async (t) => { + const { ok, rejects, deepStrictEqual } = tspl(t, { plan: 5 }) -test('do not cache failures async', async (t) => { - t.plan(5) - - const storage = createStorage() - storage.remove = async () => { - t.pass('async remove called') - throw new Error('kaboom') - } - const cache = new Cache({ storage }) - - let called = false - cache.define('fetchSomething', async (query) => { - t.pass('called') - if (!called) { - called = true + const storage = createStorage() + storage.remove = async () => { + ok('async remove called') throw new Error('kaboom') } - return { k: query } + const cache = new Cache({ storage }) + + let called = false + cache.define('fetchSomething', async (query) => { + ok('called') + if (!called) { + called = true + throw new Error('kaboom') + } + return { k: query } + }) + + await rejects(cache.fetchSomething(42)) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) - await t.rejects(cache.fetchSomething(42)) - t.same(await cache.fetchSomething(42), { k: 42 }) -}) + test('clear the full cache', async (t) => { + const { ok, deepStrictEqual } = tspl(t, { plan: 7 }) -test('clear the full cache', async (t) => { - t.plan(7) + const cache = new Cache({ ttl: 1, storage: createStorage() }) - const cache = new Cache({ ttl: 1, storage: createStorage() }) + cache.define('fetchA', async (query) => { + ok('a called') + return { k: query } + }) - cache.define('fetchA', async (query) => { - t.pass('a called') - return { k: query } - }) + cache.define('fetchB', async (query) => { + ok('b called') + return { j: query } + }) - cache.define('fetchB', async (query) => { - t.pass('b called') - return { j: query } + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) + + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) + + await cache.clear() + + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) }) - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) - - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) - - await cache.clear() - - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) -}) + test('clears only one method', async (t) => { + const { ok, deepStrictEqual } = tspl(t, { plan: 6 }) -test('clears only one method', async (t) => { - t.plan(6) + const cache = new Cache({ ttl: 1, storage: createStorage() }) - const cache = new Cache({ ttl: 1, storage: createStorage() }) + cache.define('fetchA', async (query) => { + ok('a called') + return { k: query } + }) - cache.define('fetchA', async (query) => { - t.pass('a called') - return { k: query } - }) + cache.define('fetchB', async (query) => { + ok('b called') + return { j: query } + }) - cache.define('fetchB', async (query) => { - t.pass('b called') - return { j: query } + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) + + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) + + await cache.clear('fetchA') + + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchB(24) + ]), [ + { k: 42 }, + { j: 24 } + ]) }) - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) - - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) - - await cache.clear('fetchA') - - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchB(24) - ]), [ - { k: 42 }, - { j: 24 } - ]) -}) + test('clears only one method with one value', async (t) => { + const { ok, deepStrictEqual } = tspl(t, { plan: 5 }) -test('clears only one method with one value', async (t) => { - t.plan(5) + const cache = new Cache({ ttl: 10, storage: createStorage() }) - const cache = new Cache({ ttl: 10, storage: createStorage() }) + cache.define('fetchA', async (query) => { + ok('a called') + return { k: query } + }) - cache.define('fetchA', async (query) => { - t.pass('a called') - return { k: query } + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchA(24) + ]), [ + { k: 42 }, + { k: 24 } + ]) + + await cache.clear('fetchA', 42) + + deepStrictEqual(await Promise.all([ + cache.fetchA(42), + cache.fetchA(24) + ]), [ + { k: 42 }, + { k: 24 } + ]) }) - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchA(24) - ]), [ - { k: 42 }, - { k: 24 } - ]) - - await cache.clear('fetchA', 42) - - t.same(await Promise.all([ - cache.fetchA(42), - cache.fetchA(24) - ]), [ - { k: 42 }, - { k: 24 } - ]) -}) + test('throws for methods in the property chain', async function (t) { + const cache = new Cache({ storage: createStorage() }) -test('throws for methods in the property chain', async function (t) { - const cache = new Cache({ storage: createStorage() }) + const keys = [ + 'toString', + 'hasOwnProperty', + 'define', + 'clear' + ] + + for (const key of keys) { + assert.throws(() => { + cache.define(key, () => { }) + }) + } + }) - const keys = [ - 'toString', - 'hasOwnProperty', - 'define', - 'clear' - ] + test('should cache with references', async function (t) { + const { ok } = tspl(t, { plan: 1 }) - for (const key of keys) { - t.throws(() => { - cache.define(key, () => { }) - }) - } -}) + const cache = new Cache({ ttl: 60, storage: createStorage() }) -test('should cache with references', async function (t) { - t.plan(1) + cache.define('run', { + references: (args, key, result) => { + ok('references called') + return ['some-reference'] + } + }, () => 'something') - const cache = new Cache({ ttl: 60, storage: createStorage() }) + await cache.run(1) + }) - cache.define('run', { - references: (args, key, result) => { - t.pass('references called') - return ['some-reference'] - } - }, () => 'something') + test('should handle references function (sync) throwing an error', async function (t) { + const { equal } = tspl(t, { plan: 4 }) - await cache.run(1) -}) + const cache = new Cache({ ttl: 60, storage: createStorage() }) -test('should handle references function (sync) throwing an error', async function (t) { - t.plan(4) + cache.define('references', { + onError: (err) => { equal(err.message, 'boom') }, + references: (args, key, result) => { throw new Error('boom') } + }, () => 'the-result') - const cache = new Cache({ ttl: 60, storage: createStorage() }) + equal(await cache.references(1), 'the-result') + equal(await cache.references(1), 'the-result') + }) - cache.define('references', { - onError: (err) => { t.equal(err.message, 'boom') }, - references: (args, key, result) => { throw new Error('boom') } - }, () => 'the-result') + test('should handle references function (async) throwing an error', async function (t) { + const { equal } = tspl(t, { plan: 4 }) - t.equal(await cache.references(1), 'the-result') - t.equal(await cache.references(1), 'the-result') -}) + const cache = new Cache({ ttl: 60, storage: createStorage() }) -test('should handle references function (async) throwing an error', async function (t) { - t.plan(4) + cache.define('references', { + onError: (err) => { equal(err.message, 'boom') }, + references: async (args, key, result) => { throw new Error('boom') } + }, () => 'the-result') - const cache = new Cache({ ttl: 60, storage: createStorage() }) + equal(await cache.references(1), 'the-result') + equal(await cache.references(1), 'the-result') + }) - cache.define('references', { - onError: (err) => { t.equal(err.message, 'boom') }, - references: async (args, key, result) => { throw new Error('boom') } - }, () => 'the-result') + test('should cache with async references', async function (t) { + const { ok } = tspl(t, { plan: 1 }) - t.equal(await cache.references(1), 'the-result') - t.equal(await cache.references(1), 'the-result') -}) + const cache = new Cache({ ttl: 60, storage: createStorage() }) -test('should cache with async references', async function (t) { - t.plan(1) + cache.define('run', { + references: async (args, key, result) => { + ok('references called') + return ['some-reference'] + } + }, () => 'something') - const cache = new Cache({ ttl: 60, storage: createStorage() }) + await cache.run(1) + }) - cache.define('run', { - references: async (args, key, result) => { - t.pass('references called') - return ['some-reference'] - } - }, () => 'something') + test('should cache with async storage (redis)', async function () { + const cache = new Cache({ ttl: 60, storage: createStorage('redis', { client: redisClient }) }) + cache.define('run', () => 'something') + await cache.run(1) - await cache.run(1) -}) + assert.deepStrictEqual(await cache.run(2), 'something') + }) -test('should cache with async storage (redis)', async function (t) { - const cache = new Cache({ ttl: 60, storage: createStorage('redis', { client: redisClient }) }) - cache.define('run', () => 'something') - await cache.run(1) + test('automatically expires with no TTL', async (t) => { + // plan verifies that fetchSomething is called only once + const { deepStrictEqual, equal } = tspl(t, { plan: 10 }) - t.equal(await cache.run(2), 'something') -}) + let dedupes = 0 + const cache = new Cache({ + storage: createStorage(), + onDedupe () { + dedupes++ + } + }) -test('automatically expires with no TTL', async (t) => { - // plan verifies that fetchSomething is called only once - t.plan(10) + const expected = [42, 24, 42] - let dedupes = 0 - const cache = new Cache({ - storage: createStorage(), - onDedupe () { - dedupes++ - } - }) + cache.define('fetchSomething', async (query, cacheKey) => { + deepStrictEqual(query, expected.shift()) + equal(stringify(query), cacheKey) + return { k: query } + }) - const expected = [42, 24, 42] + const p1 = cache.fetchSomething(42) + const p2 = cache.fetchSomething(24) + const p3 = cache.fetchSomething(42) - cache.define('fetchSomething', async (query, cacheKey) => { - t.equal(query, expected.shift()) - t.equal(stringify(query), cacheKey) - return { k: query } - }) + const res = await Promise.all([p1, p2, p3]) - const p1 = cache.fetchSomething(42) - const p2 = cache.fetchSomething(24) - const p3 = cache.fetchSomething(42) + deepStrictEqual(res, [ + { k: 42 }, + { k: 24 }, + { k: 42 } + ]) + equal(dedupes, 1) - const res = await Promise.all([p1, p2, p3]) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + equal(dedupes, 1) + }) - t.same(res, [ - { k: 42 }, - { k: 24 }, - { k: 42 } - ]) - t.equal(dedupes, 1) + test('calls onError listener', async (t) => { + const { equal } = tspl(t, { plan: 2 }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.equal(dedupes, 1) -}) + let onError -test('calls onError listener', async (t) => { - t.plan(2) + const promise = new Promise((resolve, reject) => { + onError = reject + }) - let onError + const cache = new Cache({ storage: createStorage(), onError }) - const promise = new Promise((resolve, reject) => { - onError = reject - }) + cache.define('willDefinitelyWork', async (query, cacheKey) => { + throw new Error('whoops') + }) - const cache = new Cache({ storage: createStorage(), onError }) + try { + await cache.willDefinitelyWork(42) + throw new Error('Should throw') + } catch (err) { + equal(err.message, 'whoops') + } - cache.define('willDefinitelyWork', async (query, cacheKey) => { - throw new Error('whoops') + try { + await promise + throw new Error('Should throw') + } catch (err) { + equal(err.message, 'whoops') + } }) - try { - await cache.willDefinitelyWork(42) - throw new Error('Should throw') - } catch (err) { - t.equal(err.message, 'whoops') - } - - try { - await promise - throw new Error('Should throw') - } catch (err) { - t.equal(err.message, 'whoops') - } -}) - -test('should call onError when serialize throws exception', async (t) => { - t.plan(1) + test('should call onError when serialize throws exception', async (t) => { + const { equal } = tspl(t, { plan: 1 }) - const serialize = () => { - throw new Error('error serializing') - } + const serialize = () => { + throw new Error('error serializing') + } - const onError = err => t.equal(err.message, 'error serializing') + const onError = err => equal(err.message, 'error serializing') - const cache = new Cache({ storage: createStorage(), onError }) - cache.define('serializeWithError', { serialize }, async k => k) + const cache = new Cache({ storage: createStorage(), onError }) + cache.define('serializeWithError', { serialize }, async k => k) - await cache.serializeWithError(1) + await cache.serializeWithError(1) + }) }) diff --git a/test/cache.test.js b/test/cache.test.js index 12841f1..d05f8b4 100644 --- a/test/cache.test.js +++ b/test/cache.test.js @@ -1,39 +1,39 @@ 'use strict' -const t = require('tap') +const { describe, test } = require('node:test') +const assert = require('node:assert') +const { tspl } = require('@matteo.collina/tspl') const { Cache } = require('../src/cache') const createStorage = require('../src/storage') const { kStorage, kStorages } = require('../src/symbol') -const { test } = t - -test('Cache', async (t) => { - test('should get an instance with default options', async (t) => { +describe('Cache', async (t) => { + test('should get an instance with default options', async () => { const cache = new Cache({ storage: createStorage() }) - t.ok(typeof cache.define === 'function') - t.ok(typeof cache.clear === 'function') - t.ok(typeof cache.get === 'function') - t.ok(typeof cache.set === 'function') - t.ok(typeof cache.invalidate === 'function') + assert.ok(typeof cache.define === 'function') + assert.ok(typeof cache.clear === 'function') + assert.ok(typeof cache.get === 'function') + assert.ok(typeof cache.set === 'function') + assert.ok(typeof cache.invalidate === 'function') }) - test('define', async (t) => { - test('should define an instance with storage options', async (t) => { + describe('define', async () => { + test('should define an instance with storage options', async () => { const cache = new Cache({ storage: createStorage() }) cache.define('different-storage', { storage: createStorage('memory', { invalidation: true }) }, () => {}) - t.equal(cache[kStorages].get('different-storage').invalidation, true) + assert.equal(cache[kStorages].get('different-storage').invalidation, true) }) }) - test('get', async (t) => { + describe('get', async () => { test('should use storage to get a value', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const cache = new Cache({ storage: { async get (key) { - t.equal(key, 'foo') + equal(key, 'foo') } } }) @@ -43,26 +43,26 @@ test('Cache', async (t) => { }) test('should get an error trying to use get of not defined name', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const cache = new Cache({ storage: createStorage() }) cache.define('f', () => 'the-value') cache.get('fiiii', 'key').catch((err) => { - t.equal(err.message, 'fiiii is not defined in the cache') + equal(err.message, 'fiiii is not defined in the cache') }) }) test('should bypass storage when ttl is 0', async (t) => { - t.plan(1) + const { equal, fail } = tspl(t, { plan: 1 }) const cache = new Cache({ storage: createStorage() }) cache[kStorage].get = () => { - t.fail('should bypass storage') + fail('should bypass storage') } cache[kStorage].set = () => { - t.fail('should bypass storage') + fail('should bypass storage') } cache.define('f', { ttl: 0 }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -72,13 +72,14 @@ test('Cache', async (t) => { }) test('should bypass setting value in storage if ttl function returns 0', async (t) => { - t.plan(1) + const { equal, fail } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: createStorage() }) cache[kStorage].set = () => { - t.fail('should bypass storage') + fail('should bypass storage') } cache.define('f', { ttl: (_data) => { return 0 } }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -87,15 +88,16 @@ test('Cache', async (t) => { }) test('should set value in storage if ttl function returns > 0', async (t) => { - t.plan(4) + const { equal } = tspl(t, { plan: 4 }) + const cache = new Cache({ storage: createStorage() }) cache[kStorage].set = (key, value, ttl) => { - t.equal(key, 'f~foo') - t.equal(value.k, 'foo') - t.equal(ttl, 1) + equal(key, 'f~foo') + equal(value.k, 'foo') + equal(ttl, 1) } cache.define('f', { ttl: (data) => { return 1 } }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -104,16 +106,17 @@ test('Cache', async (t) => { }) test('should call onError and bypass storage if ttl fn returns non-integer', async (t) => { - t.plan(2) + const { equal, fail } = tspl(t, { plan: 2 }) + const cache = new Cache({ storage: createStorage() }) cache[kStorage].set = () => { - t.fail('should bypass storage') + fail('should bypass storage') } const onError = (err) => { - t.equal(err.message, 'ttl must be an integer') + equal(err.message, 'ttl must be an integer') } cache.define('f', { ttl: (data) => { return 3.14 }, onError }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -122,16 +125,17 @@ test('Cache', async (t) => { }) test('should call onError and bypass storage if ttl fn returns undefined', async (t) => { - t.plan(2) + const { equal, fail } = tspl(t, { plan: 2 }) + const cache = new Cache({ storage: createStorage() }) cache[kStorage].set = () => { - t.fail('should bypass storage') + fail('should bypass storage') } const onError = (err) => { - t.equal(err.message, 'ttl must be an integer') + equal(err.message, 'ttl must be an integer') } cache.define('f', { ttl: (data) => { return undefined }, onError }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -140,16 +144,17 @@ test('Cache', async (t) => { }) test('should call onError and bypass storage if ttl fn returns non-number', async (t) => { - t.plan(2) + const { equal, fail } = tspl(t, { plan: 2 }) + const cache = new Cache({ storage: createStorage() }) cache[kStorage].set = () => { - t.fail('should bypass storage') + fail('should bypass storage') } const onError = (err) => { - t.equal(err.message, 'ttl must be an integer') + equal(err.message, 'ttl must be an integer') } cache.define('f', { ttl: (data) => { return '3' }, onError }, async (k) => { - t.equal(k, 'foo') + equal(k, 'foo') return { k } }) @@ -157,16 +162,17 @@ test('Cache', async (t) => { await cache.f('foo') }) - test('set', async (t) => { + describe('set', async (t) => { test('should use storage to set a value', async (t) => { - t.plan(4) + const { equal, deepStrictEqual } = tspl(t, { plan: 4 }) + const cache = new Cache({ storage: { async set (key, value, ttl, references) { - t.equal(key, 'foo') - t.equal(value, 'bar') - t.equal(ttl, 9) - t.same(references, ['fooers']) + equal(key, 'foo') + equal(value, 'bar') + equal(ttl, 9) + deepStrictEqual(references, ['fooers']) } } }) @@ -176,23 +182,25 @@ test('Cache', async (t) => { }) test('should get an error trying to use set of not defined name', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: createStorage() }) cache.define('f', () => 'the-value') cache.set('fiiii', 'key', 'value').catch((err) => { - t.equal(err.message, 'fiiii is not defined in the cache') + equal(err.message, 'fiiii is not defined in the cache') }) }) }) - test('invalidate', async (t) => { + describe('invalidate', async (t) => { test('should use storage to get a value', async (t) => { - t.plan(1) + const { deepStrictEqual } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: { async invalidate (references) { - t.same(references, ['foo']) + deepStrictEqual(references, ['foo']) } } }) @@ -202,23 +210,25 @@ test('Cache', async (t) => { }) test('should get an error trying to invalidate of not defined name', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: createStorage() }) cache.define('f', () => 'the-value') cache.invalidate('fiiii', ['references']).catch((err) => { - t.equal(err.message, 'fiiii is not defined in the cache') + equal(err.message, 'fiiii is not defined in the cache') }) }) }) - test('invalidateAll', async (t) => { + describe('invalidateAll', async (t) => { test('should call invalidate on default storage', async (t) => { - t.plan(1) + const { deepStrictEqual } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: { async invalidate (references) { - t.same(references, ['foo']) + deepStrictEqual(references, ['foo']) } } }) @@ -228,7 +238,8 @@ test('Cache', async (t) => { }) test('should call invalidate on specific storage', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: { async invalidate () { @@ -239,17 +250,17 @@ test('Cache', async (t) => { cache.define('f', { storage: {} }, () => 'the-value') cache[kStorages].get('f').invalidate = async (references) => { - t.equal(references, 'foo') + equal(references, 'foo') } await cache.invalidateAll('foo', 'f') }) - test('should rejects invalidating on non-existing storage', async (t) => { + test('should rejects invalidating on non-existing storage', async () => { const cache = new Cache({ storage: { async invalidate () { - t.fail('should not call default storage') + assert.fail('should not call default storage') } } }) @@ -258,17 +269,20 @@ test('Cache', async (t) => { { storage: { type: 'memory', options: { size: 1 } } }, () => 'the-value') - await t.rejects(cache.invalidateAll('foo', 'not-a-storage'), 'not-a-storage storage is not defined in the cache') + await assert.rejects(cache.invalidateAll('foo', 'not-a-storage'), { + message: 'not-a-storage storage is not defined in the cache' + }) }) }) - test('clear', async (t) => { + describe('clear', async (t) => { test('should use storage to clear a value by name', async (t) => { - t.plan(1) + const { deepStrictEqual } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: { async remove (value) { - t.same(value, 'f~foo') + deepStrictEqual(value, 'f~foo') } } }) @@ -278,12 +292,13 @@ test('Cache', async (t) => { }) test('should get an error trying to clear of not defined name', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const cache = new Cache({ storage: createStorage() }) cache.define('f', () => 'the-value') cache.clear('fiiii').catch((err) => { - t.equal(err.message, 'fiiii is not defined in the cache') + equal(err.message, 'fiiii is not defined in the cache') }) }) }) diff --git a/test/clear.test.js b/test/clear.test.js index f9ec17e..274049a 100644 --- a/test/clear.test.js +++ b/test/clear.test.js @@ -1,29 +1,26 @@ 'use strict' -const t = require('tap') +const { test } = require('node:test') +const { tspl } = require('@matteo.collina/tspl') const { Cache } = require('../src/cache') const createStorage = require('../src/storage') -const { test } = t - -t.jobs = 3 - test('clear the full cache', async (t) => { - t.plan(7) + const { ok, deepStrictEqual } = tspl(t, { plan: 7 }) const cache = new Cache({ ttl: 42, storage: createStorage() }) cache.define('fetchA', async (query) => { - t.pass('a called') + ok('a called') return { k: query } }) cache.define('fetchB', async (query) => { - t.pass('b called') + ok('b called') return { j: query } }) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -31,7 +28,7 @@ test('clear the full cache', async (t) => { { j: 24 } ]) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -41,7 +38,7 @@ test('clear the full cache', async (t) => { cache.clear() - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -51,21 +48,21 @@ test('clear the full cache', async (t) => { }) test('clears only one method', async (t) => { - t.plan(6) + const { ok, deepStrictEqual } = tspl(t, { plan: 6 }) const cache = new Cache({ ttl: 42, storage: createStorage() }) cache.define('fetchA', async (query) => { - t.pass('a called') + ok('a called') return { k: query } }) cache.define('fetchB', async (query) => { - t.pass('b called') + ok('b called') return { j: query } }) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -73,7 +70,7 @@ test('clears only one method', async (t) => { { j: 24 } ]) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -83,7 +80,7 @@ test('clears only one method', async (t) => { cache.clear('fetchA') - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchB(24) ]), [ @@ -93,16 +90,16 @@ test('clears only one method', async (t) => { }) test('clears only one method with one value', async (t) => { - t.plan(5) + const { ok, deepStrictEqual } = tspl(t, { plan: 5 }) const cache = new Cache({ ttl: 42, storage: createStorage() }) cache.define('fetchA', async (query) => { - t.pass('a called') + ok('a called') return { k: query } }) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchA(24) ]), [ @@ -112,7 +109,7 @@ test('clears only one method with one value', async (t) => { cache.clear('fetchA', 42) - t.same(await Promise.all([ + deepStrictEqual(await Promise.all([ cache.fetchA(42), cache.fetchA(24) ]), [ diff --git a/test/stale.test.js b/test/stale.test.js index 87fd72d..ec9e85c 100644 --- a/test/stale.test.js +++ b/test/stale.test.js @@ -1,18 +1,15 @@ 'use strict' -const t = require('tap') +const { test } = require('node:test') +const { tspl } = require('@matteo.collina/tspl') const { promisify } = require('util') const { Cache } = require('../src/cache') const createStorage = require('../src/storage') const sleep = promisify(setTimeout) -const { test } = t - -t.jobs = 3 - test('stale', async (t) => { - t.plan(11) + const { equal, deepStrictEqual } = tspl(t, { plan: 11 }) const storage = createStorage() @@ -25,43 +22,43 @@ test('stale', async (t) => { let toReturn = 42 cache.define('fetchSomething', async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: toReturn } }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + equal(storage.getTTL('fetchSomething~42'), 10) await sleep(2500) - t.equal(storage.getTTL('fetchSomething~42') < 10, true) + equal(storage.getTTL('fetchSomething~42') < 10, true) // This value will be revalidated toReturn++ - t.same(await cache.fetchSomething(42), { k: 42 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + equal(storage.getTTL('fetchSomething~42'), 10) await sleep(500) - t.same(await cache.fetchSomething(42), { k: 43 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 43 }) - t.same(await cache.fetchSomething(42), { k: 43 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + deepStrictEqual(await cache.fetchSomething(42), { k: 43 }) + equal(storage.getTTL('fetchSomething~42'), 10) }) test('global stale is a positive integer', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) try { // eslint-disable-next-line no-new new Cache({ ttl: 42, stale: 3.14, storage: createStorage() }) } catch (err) { - t.equal(err.message, 'stale must be an integer greater or equal to 0') + equal(err.message, 'stale must be an integer greater or equal to 0') } }) test('stale as parameter', async (t) => { - t.plan(6) + const { equal, deepStrictEqual } = tspl(t, { plan: 6 }) const cache = new Cache({ storage: createStorage(), @@ -69,24 +66,24 @@ test('stale as parameter', async (t) => { }) cache.define('fetchSomething', { stale: 9 }, async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: query } }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(2500) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(500) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) test('stale as a function', async (t) => { - t.plan(11) + const { equal, deepStrictEqual } = tspl(t, { plan: 11 }) const storage = createStorage() @@ -99,32 +96,32 @@ test('stale as a function', async (t) => { let toReturn = 42 cache.define('fetchSomething', async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: toReturn, stale: 9 } }) - t.same(await cache.fetchSomething(42), { k: 42, stale: 9 }) - t.same(await cache.fetchSomething(42), { k: 42, stale: 9 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42, stale: 9 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42, stale: 9 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + equal(storage.getTTL('fetchSomething~42'), 10) await sleep(2500) - t.equal(storage.getTTL('fetchSomething~42') < 10, true) + equal(storage.getTTL('fetchSomething~42') < 10, true) // This value will be revalidated toReturn++ - t.same(await cache.fetchSomething(42), { k: 42, stale: 9 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + deepStrictEqual(await cache.fetchSomething(42), { k: 42, stale: 9 }) + equal(storage.getTTL('fetchSomething~42'), 10) await sleep(500) - t.same(await cache.fetchSomething(42), { k: 43, stale: 9 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 43, stale: 9 }) - t.same(await cache.fetchSomething(42), { k: 43, stale: 9 }) - t.equal(storage.getTTL('fetchSomething~42'), 10) + deepStrictEqual(await cache.fetchSomething(42), { k: 43, stale: 9 }) + equal(storage.getTTL('fetchSomething~42'), 10) }) test('stale as a function parameter', async (t) => { - t.plan(6) + const { equal, deepStrictEqual } = tspl(t, { plan: 6 }) const cache = new Cache({ storage: createStorage(), @@ -132,18 +129,18 @@ test('stale as a function parameter', async (t) => { }) cache.define('fetchSomething', { stale: () => 9 }, async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: query } }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(2500) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(500) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) diff --git a/test/storage-base.test.js b/test/storage-base.test.js index 1e62aeb..b81937b 100644 --- a/test/storage-base.test.js +++ b/test/storage-base.test.js @@ -1,20 +1,19 @@ 'use strict' -const t = require('tap') +const { test, describe } = require('node:test') +const assert = require('assert') const createStorage = require('../src/storage') const StorageInterface = require('../src/storage/interface') -const { test } = t - -test('storage', async (t) => { +describe('storage', async (t) => { test('should get an instance with default options', async (t) => { const storage = createStorage() - t.ok(typeof storage.get === 'function') - t.ok(typeof storage.set === 'function') - t.ok(typeof storage.remove === 'function') - t.ok(typeof storage.invalidate === 'function') - t.ok(typeof storage.refresh === 'function') + assert.ok(typeof storage.get === 'function') + assert.ok(typeof storage.set === 'function') + assert.ok(typeof storage.remove === 'function') + assert.ok(typeof storage.invalidate === 'function') + assert.ok(typeof storage.refresh === 'function') }) test('should get an error implementing storage interfaces without get method', async (t) => { @@ -25,9 +24,9 @@ test('storage', async (t) => { for (const method of ['get', 'set', 'remove', 'invalidate', 'clear', 'refresh']) { try { await badStorage[method]() - t.fail(`should throw an error on method ${method}`) + assert.fail(`should throw an error on method ${method}`) } catch (err) { - t.equal(err.message, `storage ${method} method not implemented`) + assert.equal(err.message, `storage ${method} method not implemented`) } } }) diff --git a/test/storage-memory.test.js b/test/storage-memory.test.js index ec2081d..e81407d 100644 --- a/test/storage-memory.test.js +++ b/test/storage-memory.test.js @@ -1,171 +1,171 @@ 'use strict' -const t = require('tap') +const { test, describe } = require('node:test') +const assert = require('node:assert') +const { tspl } = require('@matteo.collina/tspl') const createStorage = require('../src/storage') const { promisify } = require('util') const sleep = promisify(setTimeout) -const { test } = t - -test('storage memory', async (t) => { - test('should get an instance with default options', async (t) => { +describe('storage memory', async () => { + test('should get an instance with default options', async () => { const storage = createStorage('memory') - t.ok(typeof storage.get === 'function') - t.ok(typeof storage.set === 'function') - t.ok(typeof storage.remove === 'function') - t.ok(typeof storage.invalidate === 'function') - t.ok(typeof storage.refresh === 'function') + assert.ok(typeof storage.get === 'function') + assert.ok(typeof storage.set === 'function') + assert.ok(typeof storage.remove === 'function') + assert.ok(typeof storage.invalidate === 'function') + assert.ok(typeof storage.refresh === 'function') - t.equal(storage.store.capacity, 1024) + assert.equal(storage.store.capacity, 1024) }) - test('should get an error on invalid options', async (t) => { - t.throws(() => createStorage('memory', { size: -1 }), /size must be a positive integer greater than 0/) + test('should get an error on invalid options', async () => { + assert.throws(() => createStorage('memory', { size: -1 }), /size must be a positive integer greater than 0/) }) - test('should not initialize references containeres on invalidation disabled', async (t) => { + test('should not initialize references containeres on invalidation disabled', async () => { const storage = createStorage('memory') - t.equal(storage.keysReferences, undefined) - t.equal(storage.referencesKeys, undefined) + assert.equal(storage.keysReferences, undefined) + assert.equal(storage.referencesKeys, undefined) }) - test('should initialize references containeres on invalidation enabled', async (t) => { + test('should initialize references containeres on invalidation enabled', async () => { const storage = createStorage('memory', { invalidation: true }) - t.ok(typeof storage.keysReferences === 'object') - t.ok(typeof storage.referencesKeys === 'object') + assert.ok(typeof storage.keysReferences === 'object') + assert.ok(typeof storage.referencesKeys === 'object') }) - test('get', async (t) => { - test('should get a value by a key previously stored', async (t) => { + describe('get', async () => { + test('should get a value by a key previously stored', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 100) - t.equal(storage.get('foo'), 'bar') + assert.equal(storage.get('foo'), 'bar') }) - test('should get undefined retrieving a non stored key', async (t) => { + test('should get undefined retrieving a non stored key', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 100) - t.equal(storage.get('no-foo'), undefined) + assert.equal(storage.get('no-foo'), undefined) }) - test('should get undefined retrieving an expired value', async (t) => { + test('should get undefined retrieving an expired value', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 1) await sleep(2000) - t.equal(storage.get('foo'), undefined) + assert.equal(storage.get('foo'), undefined) }) }) - test('getTTL', async (t) => { - test('should get the TTL of a previously key stored', async (t) => { + describe('getTTL', async () => { + test('should get the TTL of a previously key stored', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 100) - t.equal(storage.getTTL('foo'), 100) + assert.equal(storage.getTTL('foo'), 100) await sleep(1000) - t.equal(storage.getTTL('foo'), 99) + assert.equal(storage.getTTL('foo'), 99) }) - test('should get the TTL of a a key without TTL', async (t) => { + test('should get the TTL of a a key without TTL', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 0) - t.equal(storage.getTTL('foo'), 0) + assert.equal(storage.getTTL('foo'), 0) }) - test('should get the TTL of a previously key stored', async (t) => { + test('should get the TTL of a previously key stored', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 1) - t.equal(storage.getTTL('foo'), 1) + assert.equal(storage.getTTL('foo'), 1) await sleep(1000) - t.equal(storage.getTTL('foo'), 0) + assert.equal(storage.getTTL('foo'), 0) }) - test('no key', async (t) => { + test('no key', async () => { const storage = createStorage('memory') - t.equal(storage.getTTL('foo'), 0) + assert.equal(storage.getTTL('foo'), 0) }) - test('should get the TTL of a previously key stored', async (t) => { + test('should get the TTL of a previously key stored', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 1) await sleep(2000) - t.equal(storage.getTTL('foo'), 0) + assert.equal(storage.getTTL('foo'), 0) }) }) - test('set', async (t) => { - test('should set a value, with ttl', async (t) => { + describe('set', async () => { + test('should set a value, with ttl', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 1) const stored = storage.store.get('foo') - t.equal(stored.value, 'bar') - t.equal(stored.ttl, 1) - t.ok(stored.start < Date.now()) + assert.equal(stored.value, 'bar') + assert.equal(stored.ttl, 1) + assert.ok(stored.start < Date.now()) }) - test('should not set a value with ttl < 1', async (t) => { + test('should not set a value with ttl < 1', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 0) - t.equal(storage.get('foo'), undefined) + assert.equal(storage.get('foo'), undefined) }) - test('should set a value with references', async (t) => { + test('should set a value with references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 100, ['fooers']) const stored = storage.store.get('foo') - t.equal(stored.value, 'bar') - t.same(storage.referencesKeys.get('fooers'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['fooers']) + assert.equal(stored.value, 'bar') + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), ['foo']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['fooers']) }) - test('should not set an empty references', async (t) => { + test('should not set an empty references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 100, []) const stored = storage.store.get('foo') - t.equal(stored.value, 'bar') - t.same(storage.referencesKeys.size, 0) - t.same(storage.keysReferences.size, 0) + assert.equal(stored.value, 'bar') + assert.deepStrictEqual(storage.referencesKeys.size, 0) + assert.deepStrictEqual(storage.keysReferences.size, 0) }) test('should get a warning setting references with invalidation disabled', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const storage = createStorage('memory', { log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/memory.set, invalidation is disabled, references are useless') + equal(error.msg, 'acd/storage/memory.set, invalidation is disabled, references are useless') } } }) @@ -173,98 +173,98 @@ test('storage memory', async (t) => { storage.set('foo', 'bar', 1, ['fooers']) }) - test('should not set a references twice', async (t) => { + test('should not set a references twice', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 1, ['fooers']) storage.set('foo', 'new-bar', 1, ['fooers']) const stored = storage.store.get('foo') - t.equal(stored.value, 'new-bar') - t.same(storage.referencesKeys.get('fooers'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['fooers']) + assert.equal(stored.value, 'new-bar') + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), ['foo']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['fooers']) }) - test('should add a key to an existing reference', async (t) => { + test('should add a key to an existing reference', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo1', 'bar1', 1, ['fooers']) storage.set('foo2', 'bar2', 1, ['fooers']) - t.same(storage.referencesKeys.get('fooers'), ['foo1', 'foo2']) - t.same(storage.keysReferences.get('foo1'), ['fooers']) - t.same(storage.keysReferences.get('foo2'), ['fooers']) + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), ['foo1', 'foo2']) + assert.deepStrictEqual(storage.keysReferences.get('foo1'), ['fooers']) + assert.deepStrictEqual(storage.keysReferences.get('foo2'), ['fooers']) }) - test('should update the key references, full replace', async (t) => { + test('should update the key references, full replace', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar1', 100, ['fooers', 'mooers']) storage.set('foo', 'bar2', 100, ['booers', 'tooers']) - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.equal(storage.referencesKeys.get('mooers'), undefined) - t.same(storage.referencesKeys.get('booers'), ['foo']) - t.same(storage.referencesKeys.get('tooers'), ['foo']) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.equal(storage.referencesKeys.get('mooers'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('booers'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('tooers'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['booers', 'tooers']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['booers', 'tooers']) }) - test('should update the key references, partial replace', async (t) => { + test('should update the key references, partial replace', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar1', 100, ['fooers', 'mooers']) storage.set('foo', 'bar2', 100, ['mooers', 'tooers']) - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.same(storage.referencesKeys.get('mooers'), ['foo']) - t.same(storage.referencesKeys.get('tooers'), ['foo']) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('mooers'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('tooers'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['mooers', 'tooers']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['mooers', 'tooers']) }) - test('should update the key references, partial replace adding more references', async (t) => { + test('should update the key references, partial replace adding more references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar1', 100, ['a', 'b']) storage.set('foo', 'bar2', 100, ['z', 'b', 'd']) - t.equal(storage.referencesKeys.get('a'), undefined) - t.same(storage.referencesKeys.get('b'), ['foo']) - t.same(storage.referencesKeys.get('d'), ['foo']) - t.same(storage.referencesKeys.get('z'), ['foo']) + assert.equal(storage.referencesKeys.get('a'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('b'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('d'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('z'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['b', 'd', 'z']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['b', 'd', 'z']) }) - test('should update the key references, partial replace with shared reference', async (t) => { + test('should update the key references, partial replace with shared reference', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('boo', 'bar1', 100, ['a', 'b']) storage.set('foo', 'bar1', 100, ['a', 'b']) storage.set('foo', 'bar2', 100, ['z', 'b', 'd']) - t.same(storage.referencesKeys.get('a'), ['boo']) - t.same(storage.referencesKeys.get('b'), ['boo', 'foo']) - t.same(storage.referencesKeys.get('d'), ['foo']) - t.same(storage.referencesKeys.get('z'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('a'), ['boo']) + assert.deepStrictEqual(storage.referencesKeys.get('b'), ['boo', 'foo']) + assert.deepStrictEqual(storage.referencesKeys.get('d'), ['foo']) + assert.deepStrictEqual(storage.referencesKeys.get('z'), ['foo']) - t.same(storage.keysReferences.get('foo'), ['b', 'd', 'z']) + assert.deepStrictEqual(storage.keysReferences.get('foo'), ['b', 'd', 'z']) }) - test('should update the key references, add reference to existing key without them', async (t) => { + test('should update the key references, add reference to existing key without them', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('key1', {}, 2) storage.set('key1', 'another value', 2, ['a', 'b', 'c']) - t.same(storage.referencesKeys.get('a'), ['key1']) - t.same(storage.referencesKeys.get('b'), ['key1']) - t.same(storage.referencesKeys.get('c'), ['key1']) + assert.deepStrictEqual(storage.referencesKeys.get('a'), ['key1']) + assert.deepStrictEqual(storage.referencesKeys.get('b'), ['key1']) + assert.deepStrictEqual(storage.referencesKeys.get('c'), ['key1']) - t.same(storage.keysReferences.get('key1'), ['a', 'b', 'c']) + assert.deepStrictEqual(storage.keysReferences.get('key1'), ['a', 'b', 'c']) }) - test('should update references of evicted keys (removed by size)', async (t) => { + test('should update references of evicted keys (removed by size)', async () => { const storage = createStorage('memory', { size: 2, invalidation: true }) storage.set('foo1', 'a', 100, ['foo:1', 'fooers']) @@ -272,60 +272,60 @@ test('storage memory', async (t) => { storage.set('foo3', 'c', 100, ['foo:3', 'fooers']) storage.set('foo4', 'd', 100, ['foo:4', 'fooers']) - t.equal(storage.store.get('foo1'), undefined) - t.equal(storage.store.get('foo2'), undefined) - t.equal(storage.store.get('foo3').value, 'c') - t.equal(storage.store.get('foo4').value, 'd') + assert.equal(storage.store.get('foo1'), undefined) + assert.equal(storage.store.get('foo2'), undefined) + assert.equal(storage.store.get('foo3').value, 'c') + assert.equal(storage.store.get('foo4').value, 'd') - t.same(storage.referencesKeys.get('fooers'), ['foo3', 'foo4']) + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), ['foo3', 'foo4']) - t.same(storage.keysReferences.get('foo1'), undefined) - t.same(storage.keysReferences.get('foo2'), undefined) - t.same(storage.keysReferences.get('foo3'), ['foo:3', 'fooers']) - t.same(storage.keysReferences.get('foo4'), ['foo:4', 'fooers']) + assert.deepStrictEqual(storage.keysReferences.get('foo1'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('foo2'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('foo3'), ['foo:3', 'fooers']) + assert.deepStrictEqual(storage.keysReferences.get('foo4'), ['foo:4', 'fooers']) }) }) - test('remove', async (t) => { - test('should remove an existing key', async (t) => { + describe('remove', async () => { + test('should remove an existing key', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 10) - t.equal(storage.remove('foo'), true) + assert.equal(storage.remove('foo'), true) - t.equal(storage.get('foo'), undefined) + assert.equal(storage.get('foo'), undefined) }) - test('should remove an non existing key', async (t) => { + test('should remove an non existing key', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 10) - t.equal(storage.remove('fooz'), false) + assert.equal(storage.remove('fooz'), false) - t.equal(storage.get('foo'), 'bar') - t.equal(storage.get('fooz'), undefined) + assert.equal(storage.get('foo'), 'bar') + assert.equal(storage.get('fooz'), undefined) }) - test('should remove an existing key and references', async (t) => { + test('should remove an existing key and references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 10, ['fooers']) - t.equal(storage.remove('foo'), true) + assert.equal(storage.remove('foo'), true) - t.equal(storage.get('foo'), undefined) + assert.equal(storage.get('foo'), undefined) }) - test('should remove an non existing key (and references)', async (t) => { + test('should remove an non existing key (and references)', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 10, ['fooers']) - t.equal(storage.remove('fooz'), false) + assert.equal(storage.remove('fooz'), false) - t.equal(storage.get('foo'), 'bar') - t.equal(storage.get('fooz'), undefined) + assert.equal(storage.get('foo'), 'bar') + assert.equal(storage.get('fooz'), undefined) }) - test('should remove a key but not references if still active', async (t) => { + test('should remove a key but not references if still active', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('a', 1, 10, ['fooers', 'vowels']) storage.set('b', 1, 10, ['fooers', 'consonantes']) @@ -333,28 +333,28 @@ test('storage memory', async (t) => { storage.set('d', 1, 10, ['consonantes']) storage.set('e', 1, 10, ['vowels']) - t.equal(storage.remove('a'), true) + assert.equal(storage.remove('a'), true) - t.equal(storage.get('a'), undefined) - t.equal(storage.get('b'), 1) - t.equal(storage.get('c'), 1) - t.equal(storage.get('d'), 1) - t.equal(storage.get('e'), 1) + assert.equal(storage.get('a'), undefined) + assert.equal(storage.get('b'), 1) + assert.equal(storage.get('c'), 1) + assert.equal(storage.get('d'), 1) + assert.equal(storage.get('e'), 1) - t.same(storage.referencesKeys.get('fooers'), ['b', 'c']) - t.same(storage.referencesKeys.get('consonantes'), ['b', 'c', 'd']) - t.same(storage.referencesKeys.get('vowels'), ['e']) + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), ['b', 'c']) + assert.deepStrictEqual(storage.referencesKeys.get('consonantes'), ['b', 'c', 'd']) + assert.deepStrictEqual(storage.referencesKeys.get('vowels'), ['e']) - t.same(storage.keysReferences.get('a'), undefined) - t.same(storage.keysReferences.get('b'), ['fooers', 'consonantes']) - t.same(storage.keysReferences.get('c'), ['fooers', 'consonantes']) - t.same(storage.keysReferences.get('d'), ['consonantes']) - t.same(storage.keysReferences.get('e'), ['vowels']) + assert.deepStrictEqual(storage.keysReferences.get('a'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('b'), ['fooers', 'consonantes']) + assert.deepStrictEqual(storage.keysReferences.get('c'), ['fooers', 'consonantes']) + assert.deepStrictEqual(storage.keysReferences.get('d'), ['consonantes']) + assert.deepStrictEqual(storage.keysReferences.get('e'), ['vowels']) }) }) - test('invalidate', async (t) => { - test('should remove storage keys by references', async (t) => { + describe('invalidate', async () => { + test('should remove storage keys by references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 1, ['fooers', 'foo:2']) @@ -362,23 +362,23 @@ test('storage memory', async (t) => { const removed = storage.invalidate(['fooers']) - t.same(removed, ['foo~1', 'foo~2']) + assert.deepStrictEqual(removed, ['foo~1', 'foo~2']) - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.equal(storage.referencesKeys.get('foo:1'), undefined) - t.equal(storage.referencesKeys.get('foo:2'), undefined) - t.same(storage.referencesKeys.get('booers'), ['boo~1']) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.equal(storage.referencesKeys.get('foo:1'), undefined) + assert.equal(storage.referencesKeys.get('foo:2'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('booers'), ['boo~1']) - t.equal(storage.keysReferences.get('foo~1'), undefined) - t.equal(storage.keysReferences.get('foo~2'), undefined) - t.same(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) + assert.equal(storage.keysReferences.get('foo~1'), undefined) + assert.equal(storage.keysReferences.get('foo~2'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) }) - test('should not remove storage keys by not existing reference', async (t) => { + test('should not remove storage keys by not existing reference', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 1, ['fooers', 'foo:2']) @@ -386,14 +386,14 @@ test('storage memory', async (t) => { const removed = storage.invalidate(['buzzers']) - t.same(removed, []) + assert.deepStrictEqual(removed, []) - t.equal(storage.get('foo~1'), 'bar') - t.equal(storage.get('foo~2'), 'baz') - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~1'), 'bar') + assert.equal(storage.get('foo~2'), 'baz') + assert.equal(storage.get('boo~1'), 'fiz') }) - test('should invalide more than one reference at once', async (t) => { + test('should invalide more than one reference at once', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 1, ['fooers', 'foo:2']) @@ -401,14 +401,14 @@ test('storage memory', async (t) => { const removed = storage.invalidate(['fooers', 'booers']) - t.same(removed, ['foo~1', 'foo~2', 'boo~1']) + assert.deepStrictEqual(removed, ['foo~1', 'foo~2', 'boo~1']) - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), undefined) + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), undefined) }) - test('should remove storage keys by references, but not the ones still alive', async (t) => { + test('should remove storage keys by references, but not the ones still alive', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~boo', 'baz', 1, ['fooers', 'booers']) @@ -416,22 +416,22 @@ test('storage memory', async (t) => { const removed = storage.invalidate(['fooers']) - t.same(removed, ['foo~1', 'foo~boo']) + assert.deepStrictEqual(removed, ['foo~1', 'foo~boo']) - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('boo~1'), 'fiz') - t.equal(storage.get('foo~boo'), undefined) + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~boo'), undefined) - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.equal(storage.referencesKeys.get('foo:1'), undefined) - t.same(storage.referencesKeys.get('booers'), ['boo~1']) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.equal(storage.referencesKeys.get('foo:1'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('booers'), ['boo~1']) - t.equal(storage.keysReferences.get('foo~1'), undefined) - t.equal(storage.keysReferences.get('foo~boo'), undefined) - t.same(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) + assert.equal(storage.keysReferences.get('foo~1'), undefined) + assert.equal(storage.keysReferences.get('foo~boo'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) }) - test('should remove a keys and references and also linked ones', async (t) => { + test('should remove a keys and references and also linked ones', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('a', 1, 10, ['fooers', 'vowels', 'empty']) storage.set('b', 1, 10, ['fooers', 'consonantes']) @@ -441,25 +441,25 @@ test('storage memory', async (t) => { storage.invalidate(['fooers']) - t.equal(storage.get('a'), undefined) - t.equal(storage.get('b'), undefined) - t.equal(storage.get('c'), undefined) - t.equal(storage.get('d'), 1) - t.equal(storage.get('e'), 1) + assert.equal(storage.get('a'), undefined) + assert.equal(storage.get('b'), undefined) + assert.equal(storage.get('c'), undefined) + assert.equal(storage.get('d'), 1) + assert.equal(storage.get('e'), 1) - t.same(storage.referencesKeys.get('fooers'), undefined) - t.same(storage.referencesKeys.get('empty'), undefined) - t.same(storage.referencesKeys.get('consonantes'), ['d']) - t.same(storage.referencesKeys.get('vowels'), ['e']) + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('empty'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('consonantes'), ['d']) + assert.deepStrictEqual(storage.referencesKeys.get('vowels'), ['e']) - t.same(storage.keysReferences.get('a'), undefined) - t.same(storage.keysReferences.get('b'), undefined) - t.same(storage.keysReferences.get('c'), undefined) - t.same(storage.keysReferences.get('d'), ['consonantes']) - t.same(storage.keysReferences.get('e'), ['vowels']) + assert.deepStrictEqual(storage.keysReferences.get('a'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('b'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('c'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('d'), ['consonantes']) + assert.deepStrictEqual(storage.keysReferences.get('e'), ['vowels']) }) - test('should invalidate by a string', async (t) => { + test('should invalidate by a string', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 1, ['fooers', 'foo:2']) @@ -467,23 +467,23 @@ test('storage memory', async (t) => { const removed = storage.invalidate('fooers') - t.same(removed, ['foo~1', 'foo~2']) + assert.deepStrictEqual(removed, ['foo~1', 'foo~2']) - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.equal(storage.referencesKeys.get('foo:1'), undefined) - t.equal(storage.referencesKeys.get('foo:2'), undefined) - t.same(storage.referencesKeys.get('booers'), ['boo~1']) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.equal(storage.referencesKeys.get('foo:1'), undefined) + assert.equal(storage.referencesKeys.get('foo:2'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('booers'), ['boo~1']) - t.equal(storage.keysReferences.get('foo~1'), undefined) - t.equal(storage.keysReferences.get('foo~2'), undefined) - t.same(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) + assert.equal(storage.keysReferences.get('foo~1'), undefined) + assert.equal(storage.keysReferences.get('foo~2'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('boo~1'), ['booers', 'boo:1']) }) - test('should invalidate by an array of strings', async (t) => { + test('should invalidate by an array of strings', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 1, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 1, ['fooers', 'foo:2']) @@ -491,23 +491,23 @@ test('storage memory', async (t) => { const removed = storage.invalidate(['fooers', 'booers']) - t.same(removed, ['foo~1', 'foo~2', 'boo~1']) + assert.deepStrictEqual(removed, ['foo~1', 'foo~2', 'boo~1']) - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), undefined) + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), undefined) - t.equal(storage.referencesKeys.get('fooers'), undefined) - t.equal(storage.referencesKeys.get('foo:1'), undefined) - t.equal(storage.referencesKeys.get('foo:2'), undefined) - t.same(storage.referencesKeys.get('booers'), undefined) + assert.equal(storage.referencesKeys.get('fooers'), undefined) + assert.equal(storage.referencesKeys.get('foo:1'), undefined) + assert.equal(storage.referencesKeys.get('foo:2'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('booers'), undefined) - t.equal(storage.keysReferences.get('foo~1'), undefined) - t.equal(storage.keysReferences.get('foo~2'), undefined) - t.same(storage.keysReferences.get('boo~1'), undefined) + assert.equal(storage.keysReferences.get('foo~1'), undefined) + assert.equal(storage.keysReferences.get('foo~2'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('boo~1'), undefined) }) - test('should invalidate with wildcard one asterisk', async (t) => { + test('should invalidate with wildcard one asterisk', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~1', 'bar', 9, ['fooers', 'foo:1']) storage.set('foo~2', 'baz', 9, ['fooers', 'foo:2']) @@ -515,12 +515,12 @@ test('storage memory', async (t) => { storage.invalidate('foo:*') - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') }) - test('should invalidate with wildcard two asterisk', async (t) => { + test('should invalidate with wildcard two asterisk', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo~01', '0', 1, ['group', 'foo:0x']) storage.set('foo~02', '0', 1, ['group', 'foo:0x']) @@ -530,14 +530,14 @@ test('storage memory', async (t) => { storage.invalidate('f*1*') - t.equal(storage.get('foo~01'), '0') - t.equal(storage.get('foo~02'), '0') - t.equal(storage.get('foo~11'), undefined) - t.equal(storage.get('foo~12'), undefined) - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~01'), '0') + assert.equal(storage.get('foo~02'), '0') + assert.equal(storage.get('foo~11'), undefined) + assert.equal(storage.get('foo~12'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') }) - test('should invalidate all with wildcard', async (t) => { + test('should invalidate all with wildcard', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('a', '0', 1, ['a', 'a:01']) storage.set('b', '0', 1, ['b', 'b:01']) @@ -548,15 +548,15 @@ test('storage memory', async (t) => { storage.invalidate('*') - t.equal(storage.get('a'), undefined) - t.equal(storage.get('b'), undefined) - t.equal(storage.get('c'), undefined) - t.equal(storage.get('d'), undefined) - t.equal(storage.get('e'), undefined) - t.equal(storage.get('f'), undefined) + assert.equal(storage.get('a'), undefined) + assert.equal(storage.get('b'), undefined) + assert.equal(storage.get('c'), undefined) + assert.equal(storage.get('d'), undefined) + assert.equal(storage.get('e'), undefined) + assert.equal(storage.get('f'), undefined) }) - test('should not invalidate anything with a non-existing reference', async (t) => { + test('should not invalidate anything with a non-existing reference', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('a', '0', 1, ['a', 'a:01']) storage.set('b', '0', 1, ['b', 'b:01']) @@ -565,49 +565,49 @@ test('storage memory', async (t) => { storage.set('e', '0', 1, ['e', 'e:01']) storage.set('f', '0', 1, ['f', 'f:01']) - t.same(storage.invalidate('zzz'), []) + assert.deepStrictEqual(storage.invalidate('zzz'), []) }) test('should get a warning with invalidation disabled', async (t) => { - t.plan(2) + const { equal, deepStrictEqual } = tspl(t, { plan: 2 }) const storage = createStorage('memory', { log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/memory.invalidate, exit due invalidation is disabled') + equal(error.msg, 'acd/storage/memory.invalidate, exit due invalidation is disabled') } } }) - t.same(storage.invalidate(['something']), []) + deepStrictEqual(storage.invalidate(['something']), []) }) }) - test('clear', async (t) => { - test('should clear the whole storage (invalidation disabled)', async (t) => { + describe('clear', async () => { + test('should clear the whole storage (invalidation disabled)', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 10) storage.set('baz', 'buz', 10) storage.clear() - t.equal(storage.store.size, 0) + assert.equal(storage.store.size, 0) }) - test('should clear the whole storage (invalidation enabled)', async (t) => { + test('should clear the whole storage (invalidation enabled)', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 10, ['fooers']) storage.set('baz', 'buz', 10, ['bazers']) storage.clear() - t.equal(storage.store.size, 0) - t.equal(storage.referencesKeys.size, 0) - t.equal(storage.keysReferences.size, 0) + assert.equal(storage.store.size, 0) + assert.equal(storage.referencesKeys.size, 0) + assert.equal(storage.keysReferences.size, 0) }) - test('should clear only keys with common name', async (t) => { + test('should clear only keys with common name', async () => { const storage = createStorage('memory') storage.set('foo~1', 'bar', 10) storage.set('foo~2', 'baz', 10) @@ -615,12 +615,12 @@ test('storage memory', async (t) => { storage.clear('foo~') - t.equal(storage.get('foo~1'), undefined) - t.equal(storage.get('foo~2'), undefined) - t.equal(storage.get('boo~1'), 'fiz') + assert.equal(storage.get('foo~1'), undefined) + assert.equal(storage.get('foo~2'), undefined) + assert.equal(storage.get('boo~1'), 'fiz') }) - test('should clear a keys and their references', async (t) => { + test('should clear a keys and their references', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('a-a', 1, 10, ['fooers', 'vowels', 'empty']) storage.set('a-b', 1, 10, ['fooers', 'consonantes']) @@ -630,42 +630,42 @@ test('storage memory', async (t) => { storage.clear('a-') - t.equal(storage.get('a-a'), undefined) - t.equal(storage.get('a-b'), undefined) - t.equal(storage.get('a-c'), undefined) - t.equal(storage.get('b-d'), 1) - t.equal(storage.get('b-e'), 1) + assert.equal(storage.get('a-a'), undefined) + assert.equal(storage.get('a-b'), undefined) + assert.equal(storage.get('a-c'), undefined) + assert.equal(storage.get('b-d'), 1) + assert.equal(storage.get('b-e'), 1) - t.same(storage.referencesKeys.get('fooers'), undefined) - t.same(storage.referencesKeys.get('empty'), undefined) - t.same(storage.referencesKeys.get('consonantes'), ['b-d']) - t.same(storage.referencesKeys.get('vowels'), ['b-e']) + assert.deepStrictEqual(storage.referencesKeys.get('fooers'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('empty'), undefined) + assert.deepStrictEqual(storage.referencesKeys.get('consonantes'), ['b-d']) + assert.deepStrictEqual(storage.referencesKeys.get('vowels'), ['b-e']) - t.same(storage.keysReferences.get('a-a'), undefined) - t.same(storage.keysReferences.get('a-b'), undefined) - t.same(storage.keysReferences.get('a-c'), undefined) - t.same(storage.keysReferences.get('b-d'), ['consonantes']) - t.same(storage.keysReferences.get('b-e'), ['vowels']) + assert.deepStrictEqual(storage.keysReferences.get('a-a'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('a-b'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('a-c'), undefined) + assert.deepStrictEqual(storage.keysReferences.get('b-d'), ['consonantes']) + assert.deepStrictEqual(storage.keysReferences.get('b-e'), ['vowels']) }) }) - test('refresh', async (t) => { - test('should start a new storage', async (t) => { + describe('refresh', async () => { + test('should start a new storage', async () => { const storage = createStorage('memory') storage.set('foo', 'bar', 10) storage.refresh() - t.equal(storage.store.size, 0) + assert.equal(storage.store.size, 0) }) - test('should start a new storage (invalidation enabled)', async (t) => { + test('should start a new storage (invalidation enabled)', async () => { const storage = createStorage('memory', { invalidation: true }) storage.set('foo', 'bar', 10, ['fooers']) storage.refresh() - t.equal(storage.store.size, 0) - t.equal(storage.referencesKeys.size, 0) - t.equal(storage.referencesKeys.size, 0) + assert.equal(storage.store.size, 0) + assert.equal(storage.referencesKeys.size, 0) + assert.equal(storage.referencesKeys.size, 0) }) }) }) diff --git a/test/storage-redis.test.js b/test/storage-redis.test.js index 118514e..edd07fd 100644 --- a/test/storage-redis.test.js +++ b/test/storage-redis.test.js @@ -1,6 +1,8 @@ 'use strict' -const t = require('tap') +const { test, describe, before, beforeEach, after } = require('node:test') +const assert = require('node:assert') +const { tspl } = require('@matteo.collina/tspl') const { promisify } = require('util') const Redis = require('ioredis') const proxyquire = require('proxyquire') @@ -15,47 +17,45 @@ const sleep = promisify(setTimeout) const redisClient = new Redis() -const { test, before, beforeEach, teardown } = t - function assertInclude (t, array0, array1) { - t.equal(array0.length, array1.length) + assert.deepStrictEqual(array0.length, array1.length) for (const a of array0) { - t.ok(array1.includes(a), `${a} should be in ${array1}`) + assert.ok(array1.includes(a), `${a} should be in ${array1}`) } } -before(async () => { - await redisClient.flushall() -}) +describe('storage redis', async () => { + before(async () => { + await redisClient.flushall() + }) -teardown(async () => { - await redisClient.quit() -}) + after(async () => { + redisClient.quit() + }) -test('storage redis', async (t) => { test('should get an instance with default options', async (t) => { const storage = createStorage('redis', { client: redisClient }) - t.ok(typeof storage.get === 'function') - t.ok(typeof storage.set === 'function') - t.ok(typeof storage.remove === 'function') - t.ok(typeof storage.invalidate === 'function') - t.ok(typeof storage.refresh === 'function') + assert.ok(typeof storage.get === 'function') + assert.ok(typeof storage.set === 'function') + assert.ok(typeof storage.remove === 'function') + assert.ok(typeof storage.invalidate === 'function') + assert.ok(typeof storage.refresh === 'function') }) test('should throw on missing options', async (t) => { - t.throws(() => createStorage('redis')) + assert.throws(() => createStorage('redis')) }) test('should throw on invalid options, missing client', async (t) => { - t.throws(() => createStorage('redis', { client: -1 })) + assert.throws(() => createStorage('redis', { client: -1 })) }) test('should throw on invalid options, invalid referenceTTL', async (t) => { - t.throws(() => createStorage('redis', { client: {}, invalidation: { referencesTTL: -1 } })) + assert.throws(() => createStorage('redis', { client: {}, invalidation: { referencesTTL: -1 } })) }) - test('get', async (t) => { + describe('get', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -65,7 +65,7 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100) - t.equal(await storage.get('foo'), 'bar') + assert.equal(await storage.get('foo'), 'bar') }) test('should get undefined retrieving a non stored key', async (t) => { @@ -73,7 +73,7 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100) - t.equal(await storage.get('no-foo'), undefined) + assert.equal(await storage.get('no-foo'), undefined) }) test('should get undefined retrieving an expired value', async (t) => { @@ -82,27 +82,28 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 1) await sleep(2000) - t.equal(await storage.get('foo'), undefined) + assert.equal(await storage.get('foo'), undefined) }) test('should not throw on error', async (t) => { - t.plan(3) + const { equal } = tspl(t, { plan: 3 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.get error') - t.equal(error.key, 'foo') + equal(error.msg, 'acd/storage/redis.get error') + equal(error.key, 'foo') } } }) - t.equal(await storage.get('foo'), undefined) + equal(await storage.get('foo'), undefined) }) }) - test('set', async (t) => { + describe('set', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -112,10 +113,10 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100) const value = await storage.store.get('foo') - t.equal(JSON.parse(value), 'bar') + assert.equal(JSON.parse(value), 'bar') const ttl = await storage.store.ttl('foo') - t.equal(ttl, 100) + assert.equal(ttl, 100) }) test('should not set a value with ttl < 1', async (t) => { @@ -123,7 +124,7 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 0) - t.equal(await storage.get('foo'), undefined) + assert.equal(await storage.get('foo'), undefined) }) test('should set a value with references', async (t) => { @@ -131,9 +132,9 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100, ['fooers']) const value = await storage.store.get('foo') - t.equal(JSON.parse(value), 'bar') + assert.equal(JSON.parse(value), 'bar') - t.same(await storage.store.smembers('r:fooers'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:fooers'), ['foo']) }) test('should not set an empty references', async (t) => { @@ -141,9 +142,9 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100, []) const value = await storage.store.get('foo') - t.equal(JSON.parse(value), 'bar') + assert.equal(JSON.parse(value), 'bar') - t.same((await storage.store.keys('r:*')).length, 0) + assert.deepStrictEqual((await storage.store.keys('r:*')).length, 0) }) test('should set a custom references ttl', async (t) => { @@ -151,21 +152,21 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar', 100, ['fooers']) const value = await storage.store.get('foo') - t.equal(JSON.parse(value), 'bar') + assert.equal(JSON.parse(value), 'bar') - t.same(await storage.store.smembers('r:fooers'), ['foo']) - t.same(await storage.store.ttl('r:fooers'), 10) + assert.deepStrictEqual(await storage.store.smembers('r:fooers'), ['foo']) + assert.deepStrictEqual(await storage.store.ttl('r:fooers'), 10) }) test('should get a warning setting references with invalidation disabled', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const storage = createStorage('redis', { client: redisClient, log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/redis.set, invalidation is disabled, references are useless') + equal(error.msg, 'acd/storage/redis.set, invalidation is disabled, references are useless') } } }) @@ -179,10 +180,10 @@ test('storage redis', async (t) => { await storage.set('foo', 'new-bar', 100, ['fooers']) const value = await storage.store.get('foo') - t.equal(JSON.parse(value), 'new-bar') + assert.equal(JSON.parse(value), 'new-bar') const references = await storage.store.smembers('r:fooers') - t.same(references, ['foo']) + assert.deepStrictEqual(references, ['foo']) }) test('should add a key to an existing reference', async (t) => { @@ -192,9 +193,9 @@ test('storage redis', async (t) => { await storage.set('foo2', 'bar2', 100, ['fooers']) const references = await storage.store.smembers('r:fooers') - t.equal(references.length, 2) - t.ok(references.includes('foo1')) - t.ok(references.includes('foo2')) + assert.equal(references.length, 2) + assert.ok(references.includes('foo1')) + assert.ok(references.includes('foo2')) }) test('should update the key references, full replace', async (t) => { @@ -203,10 +204,10 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar1', 100, ['fooers', 'mooers']) await storage.set('foo', 'bar2', 100, ['booers', 'tooers']) - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.equal((await storage.store.smembers('r:mooers')).length, 0) - t.same(await storage.store.smembers('r:booers'), ['foo']) - t.same(await storage.store.smembers('r:tooers'), ['foo']) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.equal((await storage.store.smembers('r:mooers')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:booers'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:tooers'), ['foo']) }) test('should update the key references, partial replace', async (t) => { @@ -215,9 +216,9 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar1', 100, ['fooers', 'mooers']) await storage.set('foo', 'bar2', 100, ['mooers', 'tooers']) - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.same(await storage.store.smembers('r:mooers'), ['foo']) - t.same(await storage.store.smembers('r:tooers'), ['foo']) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:mooers'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:tooers'), ['foo']) assertInclude(t, await storage.store.smembers('k:foo'), ['mooers', 'tooers']) }) @@ -227,10 +228,10 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar1', 100, ['a', 'b']) await storage.set('foo', 'bar2', 100, ['z', 'b', 'd']) - t.equal((await storage.store.smembers('r:a')).length, 0) - t.same(await storage.store.smembers('r:b'), ['foo']) - t.same(await storage.store.smembers('r:d'), ['foo']) - t.same(await storage.store.smembers('r:z'), ['foo']) + assert.equal((await storage.store.smembers('r:a')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:b'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:d'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:z'), ['foo']) assertInclude(t, await storage.store.smembers('k:foo'), ['b', 'd', 'z']) }) @@ -241,32 +242,33 @@ test('storage redis', async (t) => { await storage.set('foo', 'bar1', 100, ['a', 'b']) await storage.set('foo', 'bar2', 100, ['z', 'b', 'd']) - t.same(await storage.store.smembers('r:a'), ['boo']) + assert.deepStrictEqual(await storage.store.smembers('r:a'), ['boo']) assertInclude(t, await storage.store.smembers('r:b'), ['foo', 'boo']) - t.same(await storage.store.smembers('r:d'), ['foo']) - t.same(await storage.store.smembers('r:z'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:d'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('r:z'), ['foo']) assertInclude(t, await storage.store.smembers('k:foo'), ['z', 'd', 'b']) }) test('should not throw on error', async (t) => { - t.plan(3) + const { equal, doesNotThrow } = tspl(t, { plan: 3 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.set error') - t.equal(error.key, 'foo') + equal(error.msg, 'acd/storage/redis.set error') + equal(error.key, 'foo') } } }) - t.doesNotThrow(() => storage.set('foo', 'bar', 1)) + doesNotThrow(() => storage.set('foo', 'bar', 1)) }) }) - test('remove', async (t) => { + describe('remove', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -277,7 +279,7 @@ test('storage redis', async (t) => { await storage.remove('foo') - t.equal(await storage.get('foo'), undefined) + assert.equal(await storage.get('foo'), undefined) }) test('should remove an non existing key', async (t) => { @@ -286,8 +288,8 @@ test('storage redis', async (t) => { await storage.remove('fooz') - t.equal(await storage.get('foo'), 'bar') - t.equal(await storage.get('fooz'), undefined) + assert.equal(await storage.get('foo'), 'bar') + assert.equal(await storage.get('fooz'), undefined) }) test('should remove an existing key and references', async (t) => { @@ -296,10 +298,10 @@ test('storage redis', async (t) => { await storage.remove('foo') - t.equal(await storage.get('foo'), undefined) + assert.equal(await storage.get('foo'), undefined) - t.same((await storage.store.smembers('r:fooers')).length, 0) - t.same((await storage.store.smembers('k:foo')).length, 0) + assert.deepStrictEqual((await storage.store.smembers('r:fooers')).length, 0) + assert.deepStrictEqual((await storage.store.smembers('k:foo')).length, 0) }) test('should remove an non existing key (and references)', async (t) => { @@ -308,11 +310,11 @@ test('storage redis', async (t) => { await storage.remove('fooz') - t.equal(await storage.get('foo'), 'bar') - t.equal(await storage.get('fooz'), undefined) + assert.equal(await storage.get('foo'), 'bar') + assert.equal(await storage.get('fooz'), undefined) - t.same(await storage.store.smembers('k:foo'), ['fooers']) - t.same(await storage.store.smembers('r:fooers'), ['foo']) + assert.deepStrictEqual(await storage.store.smembers('k:foo'), ['fooers']) + assert.deepStrictEqual(await storage.store.smembers('r:fooers'), ['foo']) }) test('should remove a key but not references if still active', async (t) => { @@ -325,41 +327,42 @@ test('storage redis', async (t) => { await storage.remove('a') - t.equal(await storage.get('a'), undefined) - t.equal(await storage.get('b'), 1) - t.equal(await storage.get('c'), 1) - t.equal(await storage.get('d'), 1) - t.equal(await storage.get('e'), 1) + assert.equal(await storage.get('a'), undefined) + assert.equal(await storage.get('b'), 1) + assert.equal(await storage.get('c'), 1) + assert.equal(await storage.get('d'), 1) + assert.equal(await storage.get('e'), 1) assertInclude(t, await storage.store.smembers('r:fooers'), ['b', 'c']) assertInclude(t, await storage.store.smembers('r:consonantes'), ['b', 'c', 'd']) - t.same(await storage.store.smembers('r:vowels'), ['e']) + assert.deepStrictEqual(await storage.store.smembers('r:vowels'), ['e']) - t.equal((await storage.store.smembers('k:a')).length, 0) + assert.equal((await storage.store.smembers('k:a')).length, 0) assertInclude(t, await storage.store.smembers('k:b'), ['fooers', 'consonantes']) assertInclude(t, await storage.store.smembers('k:c'), ['fooers', 'consonantes']) assertInclude(t, await storage.store.smembers('k:d'), ['consonantes']) - t.same(await storage.store.smembers('k:e'), ['vowels']) + assert.deepStrictEqual(await storage.store.smembers('k:e'), ['vowels']) }) test('should not throw on error', async (t) => { - t.plan(3) + const { equal, doesNotThrow } = tspl(t, { plan: 3 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.remove error') - t.equal(error.key, 'foo') + equal(error.msg, 'acd/storage/redis.remove error') + equal(error.key, 'foo') } } }) - t.doesNotThrow(() => storage.remove('foo')) + doesNotThrow(() => storage.remove('foo')) }) }) - test('invalidate', async (t) => { + describe('invalidate', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -372,9 +375,9 @@ test('storage redis', async (t) => { await storage.invalidate(['fooers']) - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should not remove storage keys by not existing reference', async (t) => { @@ -385,9 +388,9 @@ test('storage redis', async (t) => { await storage.invalidate(['buzzers']) - t.equal(await storage.get('foo~1'), 'bar') - t.equal(await storage.get('foo~2'), 'baz') - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), 'bar') + assert.equal(await storage.get('foo~2'), 'baz') + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should invalide more than one reference at once', async (t) => { @@ -398,9 +401,9 @@ test('storage redis', async (t) => { await storage.invalidate(['fooers', 'booers']) - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), undefined) + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), undefined) }) test('should remove storage keys by references, but not the ones still alive', async (t) => { @@ -413,16 +416,16 @@ test('storage redis', async (t) => { assertInclude(t, removed, ['foo~1', 'foo~boo']) - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~boo'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~boo'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.equal((await storage.store.smembers('r:foo:1')).length, 0) - t.same(await storage.store.smembers('r:booers'), ['boo~1']) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.equal((await storage.store.smembers('r:foo:1')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:booers'), ['boo~1']) - t.equal((await storage.store.smembers('k:foo~1')).length, 0) - t.equal((await storage.store.smembers('k:foo~boo')).length, 0) + assert.equal((await storage.store.smembers('k:foo~1')).length, 0) + assert.equal((await storage.store.smembers('k:foo~boo')).length, 0) assertInclude(t, await storage.store.smembers('k:boo~1'), ['booers', 'boo:1']) }) @@ -436,22 +439,22 @@ test('storage redis', async (t) => { await storage.invalidate(['fooers']) - t.equal(await storage.get('a'), undefined) - t.equal(await storage.get('b'), undefined) - t.equal(await storage.get('c'), undefined) - t.equal(await storage.get('d'), 1) - t.equal(await storage.get('e'), 1) + assert.equal(await storage.get('a'), undefined) + assert.equal(await storage.get('b'), undefined) + assert.equal(await storage.get('c'), undefined) + assert.equal(await storage.get('d'), 1) + assert.equal(await storage.get('e'), 1) - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.equal((await storage.store.smembers('r:empty')).length, 0) - t.same(await storage.store.smembers('r:consonantes'), ['d']) - t.same(await storage.store.smembers('r:vowels'), ['e']) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.equal((await storage.store.smembers('r:empty')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:consonantes'), ['d']) + assert.deepStrictEqual(await storage.store.smembers('r:vowels'), ['e']) - t.equal((await storage.store.smembers('k:a')).length, 0) - t.equal((await storage.store.smembers('k:b')).length, 0) - t.equal((await storage.store.smembers('k:c')).length, 0) - t.same(await storage.store.smembers('k:d'), ['consonantes']) - t.same(await storage.store.smembers('k:e'), ['vowels']) + assert.equal((await storage.store.smembers('k:a')).length, 0) + assert.equal((await storage.store.smembers('k:b')).length, 0) + assert.equal((await storage.store.smembers('k:c')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('k:d'), ['consonantes']) + assert.deepStrictEqual(await storage.store.smembers('k:e'), ['vowels']) }) test('should invalidate by a string', async (t) => { @@ -462,9 +465,9 @@ test('storage redis', async (t) => { await storage.invalidate('fooers') - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should invalidate by an array of strings', async (t) => { @@ -475,9 +478,9 @@ test('storage redis', async (t) => { await storage.invalidate(['fooers', 'booers']) - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), undefined) + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), undefined) }) test('should invalidate with wildcard one asterisk', async (t) => { @@ -488,9 +491,9 @@ test('storage redis', async (t) => { await storage.invalidate('foo:*') - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should invalidate with wildcard two asterisk', async (t) => { @@ -503,11 +506,11 @@ test('storage redis', async (t) => { await storage.invalidate('f*1*') - t.equal(await storage.get('foo~01'), '0') - t.equal(await storage.get('foo~02'), '0') - t.equal(await storage.get('foo~11'), undefined) - t.equal(await storage.get('foo~12'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~01'), '0') + assert.equal(await storage.get('foo~02'), '0') + assert.equal(await storage.get('foo~11'), undefined) + assert.equal(await storage.get('foo~12'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should invalidate all with wildcard', async (t) => { @@ -521,56 +524,57 @@ test('storage redis', async (t) => { await storage.invalidate('*') - t.equal(await storage.get('a'), undefined) - t.equal(await storage.get('b'), undefined) - t.equal(await storage.get('c'), undefined) - t.equal(await storage.get('d'), undefined) - t.equal(await storage.get('e'), undefined) - t.equal(await storage.get('f'), undefined) + assert.equal(await storage.get('a'), undefined) + assert.equal(await storage.get('b'), undefined) + assert.equal(await storage.get('c'), undefined) + assert.equal(await storage.get('d'), undefined) + assert.equal(await storage.get('e'), undefined) + assert.equal(await storage.get('f'), undefined) }) test('should get a warning with invalidation disabled', async (t) => { - t.plan(2) + const { equal, deepStrictEqual } = tspl(t, { plan: 2 }) const storage = createStorage('redis', { client: {}, log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/redis.invalidate, exit due invalidation is disabled') + equal(error.msg, 'acd/storage/redis.invalidate, exit due invalidation is disabled') } } }) - t.same(await storage.invalidate(['something']), []) + deepStrictEqual(await storage.invalidate(['something']), []) }) test('should not throw on error', async (t) => { - t.plan(3) + const { equal, deepStrictEqual, doesNotThrow } = tspl(t, { plan: 3 }) + const storage = createStorage('redis', { client: {}, invalidation: true, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.invalidate error') - t.same(error.references, ['pizzers']) + equal(error.msg, 'acd/storage/redis.invalidate error') + deepStrictEqual(error.references, ['pizzers']) } } }) - t.doesNotThrow(() => storage.invalidate(['pizzers'])) + doesNotThrow(() => storage.invalidate(['pizzers'])) }) test('should not throw invalidating non-existing references', async (t) => { const storage = createStorage('redis', { client: redisClient, invalidation: true }) await redisClient.set('r:model:1', 'value') - t.doesNotThrow(() => storage.invalidate(['model:1', 'model:2'])) + assert.doesNotThrow(() => storage.invalidate(['model:1', 'model:2'])) }) }) - test('clear', async (t) => { + describe('clear', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -582,7 +586,7 @@ test('storage redis', async (t) => { await storage.clear() - t.equal(await storage.store.dbsize(), 0) + assert.equal(await storage.store.dbsize(), 0) }) test('should clear the whole storage (invalidation enabled)', async (t) => { @@ -592,7 +596,7 @@ test('storage redis', async (t) => { await storage.clear() - t.equal(await storage.store.dbsize(), 0) + assert.equal(await storage.store.dbsize(), 0) }) test('should clear only keys with common name', async (t) => { @@ -603,9 +607,9 @@ test('storage redis', async (t) => { await storage.clear('foo~') - t.equal(await storage.get('foo~1'), undefined) - t.equal(await storage.get('foo~2'), undefined) - t.equal(await storage.get('boo~1'), 'fiz') + assert.equal(await storage.get('foo~1'), undefined) + assert.equal(await storage.get('foo~2'), undefined) + assert.equal(await storage.get('boo~1'), 'fiz') }) test('should clear a keys and their references', async (t) => { @@ -618,42 +622,43 @@ test('storage redis', async (t) => { await storage.clear('a-') - t.equal(await storage.get('a-a'), undefined) - t.equal(await storage.get('a-b'), undefined) - t.equal(await storage.get('a-c'), undefined) - t.equal(await storage.get('b-d'), 1) - t.equal(await storage.get('b-e'), 1) + assert.equal(await storage.get('a-a'), undefined) + assert.equal(await storage.get('a-b'), undefined) + assert.equal(await storage.get('a-c'), undefined) + assert.equal(await storage.get('b-d'), 1) + assert.equal(await storage.get('b-e'), 1) - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.equal((await storage.store.smembers('r:empty')).length, 0) - t.same(await storage.store.smembers('r:consonantes'), ['b-d']) - t.same(await storage.store.smembers('r:vowels'), ['b-e']) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.equal((await storage.store.smembers('r:empty')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('r:consonantes'), ['b-d']) + assert.deepStrictEqual(await storage.store.smembers('r:vowels'), ['b-e']) - t.equal((await storage.store.smembers('k:a-a')).length, 0) - t.equal((await storage.store.smembers('k:a-b')).length, 0) - t.equal((await storage.store.smembers('k:a-c')).length, 0) - t.same(await storage.store.smembers('k:b-d'), ['consonantes']) - t.same(await storage.store.smembers('k:b-e'), ['vowels']) + assert.equal((await storage.store.smembers('k:a-a')).length, 0) + assert.equal((await storage.store.smembers('k:a-b')).length, 0) + assert.equal((await storage.store.smembers('k:a-c')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('k:b-d'), ['consonantes']) + assert.deepStrictEqual(await storage.store.smembers('k:b-e'), ['vowels']) }) test('should not throw on error', async (t) => { - t.plan(3) + const { equal, doesNotThrow } = tspl(t, { plan: 3 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.clear error') - t.equal(error.name, 'foo') + equal(error.msg, 'acd/storage/redis.clear error') + equal(error.name, 'foo') } } }) - t.doesNotThrow(() => storage.clear('foo')) + doesNotThrow(() => storage.clear('foo')) }) }) - test('refresh', async (t) => { + describe('refresh', async () => { beforeEach(async () => { await redisClient.flushall() }) @@ -664,26 +669,27 @@ test('storage redis', async (t) => { await storage.refresh() - t.equal(await storage.store.dbsize(), 0) + assert.equal(await storage.store.dbsize(), 0) }) test('should not throw on error', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.refresh error') + equal(error.msg, 'acd/storage/redis.refresh error') } } }) - t.doesNotThrow(() => storage.refresh()) + doesNotThrow(() => storage.refresh()) }) }) - test('clearReferences', async (t) => { + describe('clearReferences', async () => { test('should clear keys references', async (t) => { const storage = createStorage('redis', { client: redisClient }) await storage.set('a', 1, 10, ['fooers', 'vowels', 'empty']) @@ -694,10 +700,10 @@ test('storage redis', async (t) => { await storage.clearReferences(['a', 'b', 'c', 'd', 'e']) - t.equal((await storage.store.smembers('r:fooers')).length, 0) - t.equal((await storage.store.smembers('r:empty')).length, 0) - t.equal((await storage.store.smembers('r:vowels')).length, 0) - t.equal((await storage.store.smembers('r:consonantes')).length, 0) + assert.equal((await storage.store.smembers('r:fooers')).length, 0) + assert.equal((await storage.store.smembers('r:empty')).length, 0) + assert.equal((await storage.store.smembers('r:vowels')).length, 0) + assert.equal((await storage.store.smembers('r:consonantes')).length, 0) }) test('should clear a key references when expires', async (t) => { @@ -711,20 +717,21 @@ test('storage redis', async (t) => { await sleep(ttl * 1000 + 500) - t.equal((await storage.store.smembers('r:1')).length, 0) - t.equal((await storage.store.smembers('r:2')).length, 0) - t.equal((await storage.store.smembers('r:3')).length, 0) - t.equal((await storage.store.smembers('r:4')).length, 0) + assert.equal((await storage.store.smembers('r:1')).length, 0) + assert.equal((await storage.store.smembers('r:2')).length, 0) + assert.equal((await storage.store.smembers('r:3')).length, 0) + assert.equal((await storage.store.smembers('r:4')).length, 0) }) test('should get a warning calling with empty key', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/redis.clearReferences invalid call due to empty key') + equal(error.msg, 'acd/storage/redis.clearReferences invalid call due to empty key') } } }) @@ -733,30 +740,32 @@ test('storage redis', async (t) => { }) test('should not throw on error', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.clearReferences error') + equal(error.msg, 'acd/storage/redis.clearReferences error') } } }) - t.doesNotThrow(() => storage.clearReferences('the-key')) + doesNotThrow(() => storage.clearReferences('the-key')) }) }) - test('gc', async (t) => { + describe('gc', async () => { test('should get a warning calling on disabled invalidation', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) + const storage = createStorage('redis', { client: {}, log: { debug: () => { }, warn: (error) => { - t.equal(error.msg, 'acd/storage/redis.gc does not run due to invalidation is disabled') + equal(error.msg, 'acd/storage/redis.gc does not run due to invalidation is disabled') } } }) @@ -765,7 +774,8 @@ test('storage redis', async (t) => { }) test('should not throw on error', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, invalidation: true, @@ -773,41 +783,44 @@ test('storage redis', async (t) => { debug: () => { }, warn: () => { }, error: (error) => { - t.equal(error.msg, 'acd/storage/redis.gc error') + equal(error.msg, 'acd/storage/redis.gc error') } } }) - t.doesNotThrow(() => storage.gc()) + doesNotThrow(() => storage.gc()) }) test('should not throw on invalid options, chunk', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, invalidation: true }) - t.doesNotThrow(async () => { + doesNotThrow(async () => { const report = await storage.gc('zzz', { chunk: -1 }) - t.equal(report.error.message, 'chunk must be a positive integer greater than 1') + equal(report.error.message, 'chunk must be a positive integer greater than 1') }) }) test('should not throw on invalid options, lazy.chunk', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, invalidation: true }) - t.doesNotThrow(async () => { + doesNotThrow(async () => { const report = await storage.gc('zzz', { lazy: { chunk: -1 } }) - t.equal(report.error.message, 'lazy.chunk must be a positive integer greater than 1') + equal(report.error.message, 'lazy.chunk must be a positive integer greater than 1') }) }) test('should not throw on invalid options, lazy.cursor', async (t) => { - t.plan(2) + const { equal, doesNotThrow } = tspl(t, { plan: 2 }) + const storage = createStorage('redis', { client: {}, invalidation: true }) - t.doesNotThrow(async () => { + doesNotThrow(async () => { const report = await storage.gc('zzz', { lazy: { cursor: -1 } }) - t.equal(report.error.message, 'lazy.cursor must be a positive integer greater than 0') + equal(report.error.message, 'lazy.cursor must be a positive integer greater than 0') }) }) @@ -817,11 +830,11 @@ test('storage redis', async (t) => { invalidation: true }) - t.ok((await storage.gc()).error instanceof Error) + assert.ok((await storage.gc()).error instanceof Error) }) - test('strict mode', async (t) => { - t.beforeEach(async () => { + describe('strict mode', async () => { + beforeEach(async () => { await redisClient.flushall() }) @@ -837,16 +850,16 @@ test('storage redis', async (t) => { await storage.gc('strict') - t.same(await storage.store.smembers('k:e'), ['vowels']) - t.equal((await storage.store.smembers('k:a')).length, 0) - t.equal((await storage.store.smembers('k:b')).length, 0) - t.equal((await storage.store.smembers('k:c')).length, 0) - t.equal((await storage.store.smembers('k:d')).length, 0) + assert.deepStrictEqual(await storage.store.smembers('k:e'), ['vowels']) + assert.equal((await storage.store.smembers('k:a')).length, 0) + assert.equal((await storage.store.smembers('k:b')).length, 0) + assert.equal((await storage.store.smembers('k:c')).length, 0) + assert.equal((await storage.store.smembers('k:d')).length, 0) - t.same((await storage.store.smembers('r:vowels')), ['e']) - t.equal(await storage.store.exists('r:fooers'), 0) - t.equal(await storage.store.exists('r:empty'), 0) - t.equal(await storage.store.exists('r:consonantes'), 0) + assert.deepStrictEqual((await storage.store.smembers('r:vowels')), ['e']) + assert.equal(await storage.store.exists('r:fooers'), 0) + assert.equal(await storage.store.exists('r:empty'), 0) + assert.equal(await storage.store.exists('r:consonantes'), 0) }) test('should run a gc without cleaning', async (t) => { @@ -864,13 +877,13 @@ test('storage redis', async (t) => { assertInclude(t, await storage.store.smembers('k:a'), ['fooers', 'vowels', 'empty']) assertInclude(t, await storage.store.smembers('k:b'), ['fooers', 'consonantes']) assertInclude(t, await storage.store.smembers('k:c'), ['fooers', 'consonantes']) - t.same(await storage.store.smembers('k:d'), ['consonantes']) - t.same(await storage.store.smembers('k:e'), ['vowels']) + assert.deepStrictEqual(await storage.store.smembers('k:d'), ['consonantes']) + assert.deepStrictEqual(await storage.store.smembers('k:e'), ['vowels']) assertInclude(t, await storage.store.smembers('r:vowels'), ['a', 'e']) assertInclude(t, await storage.store.smembers('r:fooers'), ['a', 'b', 'c']) assertInclude(t, await storage.store.smembers('r:consonantes'), ['b', 'c', 'd']) - t.same(await storage.store.smembers('r:empty'), ['a']) + assert.deepStrictEqual(await storage.store.smembers('r:empty'), ['a']) }) test('should get stats on full gc', async (t) => { @@ -889,13 +902,13 @@ test('storage redis', async (t) => { const report = await storage.gc('strict', { chunk: 10 }) - t.equal(report.references.scanned.length, 103) - t.equal(report.references.removed.length, 103) - t.equal(report.keys.scanned.length, 100) - t.equal(report.keys.removed.length, 100) - t.equal(report.cursor, 0) - t.ok(report.loops > 2) - t.equal(report.error, null) + assert.equal(report.references.scanned.length, 103) + assert.equal(report.references.removed.length, 103) + assert.equal(report.keys.scanned.length, 100) + assert.equal(report.keys.removed.length, 100) + assert.equal(report.cursor, 0) + assert.ok(report.loops > 2) + assert.equal(report.error, null) }) test('should run on an empty storage', async (t) => { @@ -903,18 +916,18 @@ test('storage redis', async (t) => { const report = await storage.gc('strict', { chunk: 10 }) - t.equal(report.references.scanned.length, 0) - t.equal(report.references.removed.length, 0) - t.equal(report.keys.scanned.length, 0) - t.equal(report.keys.removed.length, 0) - t.equal(report.cursor, 0) - t.ok(report.loops > 0) - t.equal(report.error, null) + assert.equal(report.references.scanned.length, 0) + assert.equal(report.references.removed.length, 0) + assert.equal(report.keys.scanned.length, 0) + assert.equal(report.keys.removed.length, 0) + assert.equal(report.cursor, 0) + assert.ok(report.loops > 0) + assert.equal(report.error, null) }) }) - test('lazy mode', async (t) => { - t.beforeEach(async () => { + describe('lazy mode', async () => { + beforeEach(async () => { await redisClient.flushall() }) @@ -923,13 +936,13 @@ test('storage redis', async (t) => { const report = await storage.gc('lazy') - t.equal(report.references.scanned.length, 0) - t.equal(report.references.removed.length, 0) - t.equal(report.keys.scanned.length, 0) - t.equal(report.keys.removed.length, 0) - t.equal(report.cursor, 0) - t.ok(report.loops > 0) - t.equal(report.error, null) + assert.equal(report.references.scanned.length, 0) + assert.equal(report.references.removed.length, 0) + assert.equal(report.keys.scanned.length, 0) + assert.equal(report.keys.removed.length, 0) + assert.equal(report.cursor, 0) + assert.ok(report.loops > 0) + assert.equal(report.error, null) }) test('should get stats on lazy run', async (t) => { @@ -950,13 +963,13 @@ test('storage redis', async (t) => { const report = await storage.gc('lazy', { lazy: { chunk } }) - t.ok(report.references.scanned.length > 1) - t.ok(report.references.removed.length > 1) - t.ok(report.keys.scanned.length > 1) - t.ok(report.keys.removed.length > 1) - t.ok(report.cursor > 1) - t.ok(report.loops > 0) - t.equal(report.error, null) + assert.ok(report.references.scanned.length > 1) + assert.ok(report.references.removed.length > 1) + assert.ok(report.keys.scanned.length > 1) + assert.ok(report.keys.removed.length > 1) + assert.ok(report.cursor > 1) + assert.ok(report.loops > 0) + assert.equal(report.error, null) }) test('should clean the whole storage in some cycles', async (t) => { @@ -980,58 +993,70 @@ test('storage redis', async (t) => { cursor = report.cursor } - t.equal((await storage.store.keys('*')).length, 0) + assert.equal((await storage.store.keys('*')).length, 0) }) }) }) - test('getTTL', async (t) => { + describe('getTTL', async () => { test('should get the TTL of a previously key stored', async (t) => { + t.after(async () => { + await redisClient.flushall() + }) + const storage = new StorageRedis({ client: redisClient, invalidation: false }) storage.set('foo', 'bar', 100) - t.equal(await storage.getTTL('foo'), 100) + assert.equal(await storage.getTTL('foo'), 100) await sleep(1000) - t.equal(await storage.getTTL('foo'), 99) + assert.equal(await storage.getTTL('foo'), 99) }) test('should get the TTL of a a key without TTL', async (t) => { + t.after(async () => { + await redisClient.flushall() + }) + const storage = new StorageRedis({ client: redisClient, invalidation: false }) storage.set('foo', 'bar', 0) - t.equal(await storage.getTTL('foo'), 0) + assert.equal(await storage.getTTL('foo'), 0) }) test('should get the TTL of a previously key stored', async (t) => { + t.after(async () => { + await redisClient.flushall() + }) + const storage = new StorageRedis({ client: redisClient, invalidation: false }) storage.set('foo', 'bar', 1) - t.equal(await storage.getTTL('foo'), 1) + assert.equal(await storage.getTTL('foo'), 1) await sleep(1000) - t.equal(await storage.getTTL('foo'), 0) + assert.equal(await storage.getTTL('foo'), 0) }) test('no key', async (t) => { const storage = new StorageRedis({ client: redisClient, invalidation: false }) - t.equal(await storage.getTTL('foo'), 0) + assert.equal(await storage.getTTL('foo'), 0) }) }) test('should throw if is not server side and storage is redis', async (t) => { - const createStorageMock = t.mockRequire('../src/storage/index.js', { - '../src/util.js': module.exports = { - isServerSide: false - } + const createStorage = proxyquire('../src/storage/index.js', { + '../util': { isServerSide: false } }) - t.throws(() => createStorageMock('redis', { client: redisClient }), 'Redis storage is not supported in the browser') + assert.throws(() => createStorage('redis', { client: redisClient }), { + message: 'Redis storage is not supported in the browser' + }) }) }) diff --git a/test/transformer.test.js b/test/transformer.test.js index 0afef99..5a87c6b 100644 --- a/test/transformer.test.js +++ b/test/transformer.test.js @@ -1,123 +1,127 @@ 'use strict' -const { test, before, teardown } = require('tap') +const { test, describe, after, before } = require('node:test') +const assert = require('assert') const Redis = require('ioredis') const createStorage = require('../src/storage') const { Cache } = require('../') let redisClient -before(async (t) => { - redisClient = new Redis() -}) - -teardown(async (t) => { - await redisClient.quit() -}) -test('should handle a custom transformer to store and get data per cache', async function (t) { - const cache = new Cache({ - ttl: 1000, - storage: createStorage(), - transformer: { - serialize: (value) => { - t.pass('serialize called') - return JSON.stringify(value) - }, - deserialize: (value) => { - t.pass('deserialize called') - return JSON.parse(value) - } - } +describe('transformer', async function () { + before(async () => { + redisClient = new Redis() }) - cache.define('fetchSomething', async (query, cacheKey) => { - return { k: query } + after(async () => { + await redisClient.quit() }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) -}) + test('should handle a custom transformer to store and get data per cache', async function (t) { + const cache = new Cache({ + ttl: 1000, + storage: createStorage(), + transformer: { + serialize: (value) => { + assert.ok('serialize called') + return JSON.stringify(value) + }, + deserialize: (value) => { + assert.ok('deserialize called') + return JSON.parse(value) + } + } + }) + + cache.define('fetchSomething', async (query, cacheKey) => { + return { k: query } + }) -test('should handle a custom transformer to store and get data per define', async function (t) { - const cache = new Cache({ - storage: createStorage() + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) - cache.define('fetchSomething', { - ttl: 1000, - transformer: { - serialize: (value) => { - t.pass('serialize called') - return JSON.stringify(value) - }, - deserialize: (value) => { - t.pass('deserialize called') - return JSON.parse(value) + test('should handle a custom transformer to store and get data per define', async function (t) { + const cache = new Cache({ + storage: createStorage() + }) + + cache.define('fetchSomething', { + ttl: 1000, + transformer: { + serialize: (value) => { + assert.ok('serialize called') + return JSON.stringify(value) + }, + deserialize: (value) => { + assert.ok('deserialize called') + return JSON.parse(value) + } } - } - }, async (query, cacheKey) => { - return { k: query } + }, async (query, cacheKey) => { + return { k: query } + }) + + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) -}) + test('should handle a custom transformer and references function to store and get data per cache', async function (t) { + const cache = new Cache({ + ttl: 1000, + storage: createStorage(), + transformer: { + serialize: (value) => { + assert.ok('serialize called') + return JSON.stringify(value) + }, + deserialize: (value) => { + assert.ok('deserialize called') + return JSON.parse(value) + } + } + }) -test('should handle a custom transformer and references function to store and get data per cache', async function (t) { - const cache = new Cache({ - ttl: 1000, - storage: createStorage(), - transformer: { - serialize: (value) => { - t.pass('serialize called') - return JSON.stringify(value) - }, - deserialize: (value) => { - t.pass('deserialize called') - return JSON.parse(value) + cache.define('fetchSomething', { + references: (args, key, result) => { + assert.ok('references called') + return ['some-reference'] } - } - }) + }, async (query, cacheKey) => { + return { k: query } + }) - cache.define('fetchSomething', { - references: (args, key, result) => { - t.pass('references called') - return ['some-reference'] - } - }, async (query, cacheKey) => { - return { k: query } + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) -}) + test('should handle a custom transformer and references function to store and get data per define', async function (t) { + const cache = new Cache({ + storage: createStorage() + }) -test('should handle a custom transformer and references function to store and get data per define', async function (t) { - const cache = new Cache({ - storage: createStorage() - }) - - cache.define('fetchSomething', { - ttl: 1000, - references: (args, key, result) => { - t.pass('references called') - return ['some-reference'] - }, - transformer: { - serialize: (value) => { - t.pass('serialize called') - return JSON.stringify(value) + cache.define('fetchSomething', { + ttl: 1000, + references: (args, key, result) => { + assert.ok('references called') + return ['some-reference'] }, - deserialize: (value) => { - t.pass('deserialize called') - return JSON.parse(value) + transformer: { + serialize: (value) => { + assert.ok('serialize called') + return JSON.stringify(value) + }, + deserialize: (value) => { + assert.ok('deserialize called') + return JSON.parse(value) + } } - } - }, async (query, cacheKey) => { - return { k: query } - }) + }, async (query, cacheKey) => { + return { k: query } + }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + assert.deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + }) }) diff --git a/test/ttl.test.js b/test/ttl.test.js index b89d96d..60afe56 100644 --- a/test/ttl.test.js +++ b/test/ttl.test.js @@ -1,18 +1,15 @@ 'use strict' -const t = require('tap') +const { test } = require('node:test') +const { tspl } = require('@matteo.collina/tspl') const { promisify } = require('util') const { Cache } = require('../src/cache') const createStorage = require('../src/storage') const sleep = promisify(setTimeout) -const { test } = t - -t.jobs = 3 - test('ttl', async (t) => { - t.plan(5) + const { equal, deepStrictEqual } = tspl(t, { plan: 5 }) const cache = new Cache({ storage: createStorage(), @@ -20,42 +17,42 @@ test('ttl', async (t) => { }) cache.define('fetchSomething', async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: query } }) - t.same(await cache.fetchSomething(42), { k: 42 }) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(2500) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) test('global ttl is a positive integer', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) try { // eslint-disable-next-line no-new new Cache({ ttl: 3.14, storage: createStorage() }) } catch (err) { - t.equal(err.message, 'ttl must be a positive integer greater than 0') + equal(err.message, 'ttl must be a positive integer greater than 0') } }) test('function ttl is a positive integer', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const cache = new Cache({ storage: createStorage() }) try { cache.define('fetchSomething', { ttl: 3.14 }, async (k) => ({ k })) } catch (err) { - t.equal(err.message, 'ttl must be a positive integer greater than 0') + equal(err.message, 'ttl must be a positive integer greater than 0') } }) test('ttl expires', async (t) => { - t.plan(5) + const { equal, deepStrictEqual } = tspl(t, { plan: 5 }) const cache = new Cache({ storage: createStorage(), @@ -63,29 +60,29 @@ test('ttl expires', async (t) => { }) cache.define('fetchSomething', async (query) => { - t.equal(query, 42) + equal(query, 42) return { k: query } }) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(1000) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) await sleep(3000) - t.same(await cache.fetchSomething(42), { k: 42 }) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) test('do not cache failures', async (t) => { - t.plan(4) + const { ok, deepStrictEqual, rejects } = tspl(t, { plan: 4 }) const cache = new Cache({ ttl: 42, storage: createStorage() }) let called = false cache.define('fetchSomething', async (query) => { - t.pass('called') + ok('called') if (!called) { called = true throw new Error('kaboom') @@ -93,12 +90,12 @@ test('do not cache failures', async (t) => { return { k: query } }) - await t.rejects(cache.fetchSomething(42)) - t.same(await cache.fetchSomething(42), { k: 42 }) + await rejects(cache.fetchSomething(42)) + deepStrictEqual(await cache.fetchSomething(42), { k: 42 }) }) test('function ttl has precedence over global ttl', async (t) => { - t.plan(1) + const { equal } = tspl(t, { plan: 1 }) const cache = new Cache({ ttl: 42, storage: createStorage() }) @@ -111,11 +108,11 @@ test('function ttl has precedence over global ttl', async (t) => { await cache.fetchSomething(42) await cache.fetchSomething(42) - t.same(callCount, 2) + equal(callCount, 2) }) test('ttl as a function', async (t) => { - t.plan(2) + const { equal } = tspl(t, { plan: 2 }) const cache = new Cache({ storage: createStorage() }) @@ -128,9 +125,9 @@ test('ttl as a function', async (t) => { await cache.fetchSomething(42) await cache.fetchSomething(42) await cache.fetchSomething(42) - t.same(callCount, 1) + equal(callCount, 1) await sleep(3000) await cache.fetchSomething(42) - t.same(callCount, 2) + equal(callCount, 2) }) diff --git a/test/util.test.js b/test/util.test.js index 32a0eb1..4cf0c3c 100644 --- a/test/util.test.js +++ b/test/util.test.js @@ -1,6 +1,7 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') +const assert = require('node:assert') const { bsearchIndex, randomSubset, wildcardMatch } = require('../src/util') test('bsearchIndex', async t => { @@ -17,7 +18,7 @@ test('bsearchIndex', async t => { for (const case_ of cases) { const result = bsearchIndex(...case_.input) - t.equal(result, case_.output) + assert.equal(result, case_.output) } }) @@ -32,8 +33,8 @@ test('randomSubset', async t => { for (const case_ of cases) { const result = randomSubset(case_.array, case_.size) - t.ok(result.length > 0) - t.ok(result.length <= case_.size) + assert.ok(result.length > 0) + assert.ok(result.length <= case_.size) } cases = [ @@ -43,7 +44,7 @@ test('randomSubset', async t => { for (const case_ of cases) { const result = randomSubset(case_.array, case_.size) - t.equal(result.length, case_.resultLength) + assert.equal(result.length, case_.resultLength) } }) @@ -67,6 +68,6 @@ test('wildcardMatch', async t => { ] for (const case_ of cases) { - t.equal(wildcardMatch(case_.value, case_.content), case_.result, `${case_.value} ${case_.content} => ${case_.result}`) + assert.equal(wildcardMatch(case_.value, case_.content), case_.result, `${case_.value} ${case_.content} => ${case_.result}`) } })