2024-09-20 13:40:01 +00:00
|
|
|
import { Eltro as t, assert, spy } from 'eltro'
|
|
|
|
import path from 'path'
|
|
|
|
import crypto from 'crypto'
|
|
|
|
import os from 'os'
|
|
|
|
import fsSyncOriginal from 'fs'
|
|
|
|
import fsPromisesOriginal from 'fs/promises'
|
|
|
|
import Cache from '../index.mjs'
|
|
|
|
import { fakeFs, fakeFsPromises, fakeFsSync } from './helper.mjs'
|
|
|
|
|
|
|
|
let fsSync
|
|
|
|
let fsPromises
|
|
|
|
|
|
|
|
t.beforeEach(function() {
|
|
|
|
fsSync = fakeFsSync()
|
|
|
|
fsPromises = fakeFsPromises()
|
|
|
|
})
|
|
|
|
|
|
|
|
function createCache(opts) {
|
|
|
|
return new Cache(opts, fsSync, fsPromises)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.describe('#constructor()', function() {
|
|
|
|
t.test('uses default fs', function() {
|
|
|
|
let cache = new Cache({})
|
|
|
|
assert.strictEqual(cache.fsSync, fsSyncOriginal)
|
|
|
|
assert.strictEqual(cache.fsPromises, fsPromisesOriginal)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should be able to override the fs', function() {
|
|
|
|
let cache = createCache({})
|
|
|
|
assert.strictEqual(cache.fsSync, fsSync)
|
|
|
|
assert.strictEqual(cache.fsPromises, fsPromises)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('comes with default options', function() {
|
|
|
|
let cache = createCache({})
|
|
|
|
assert.ok(cache.id)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache.ttl, 0)
|
|
|
|
assert.strictEqual(cache.prefix, '-')
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(cache.hash_alg, 'md5')
|
|
|
|
assert.strictEqual(cache.cache_dir, path.join(os.tmpdir(), cache.id))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('can overwrite options', function() {
|
|
|
|
const assertHash = 'sha256'
|
|
|
|
const assertDir = '/something/else'
|
|
|
|
const assertPrefix = 'blabla'
|
2024-09-20 23:14:22 +00:00
|
|
|
const assertTtl = 60
|
2024-09-20 13:40:01 +00:00
|
|
|
|
|
|
|
let cache = createCache({
|
|
|
|
prefix: assertPrefix,
|
|
|
|
hash_alg: assertHash,
|
|
|
|
cache_dir: assertDir,
|
2024-09-20 23:14:22 +00:00
|
|
|
ttl: assertTtl,
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
assert.ok(cache.id)
|
|
|
|
assert.strictEqual(cache.prefix, assertPrefix + '-')
|
|
|
|
assert.strictEqual(cache.hash_alg, assertHash)
|
|
|
|
assert.strictEqual(cache.cache_dir, assertDir)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache.ttl, assertTtl)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should create the directory by default', function() {
|
|
|
|
assert.notOk(fsSync.mkdirSync.called)
|
|
|
|
let cache = createCache({})
|
|
|
|
assert.ok(fsSync.mkdirSync.called)
|
|
|
|
assert.strictEqual(fsSync.mkdirSync.firstCall[0], cache.cache_dir)
|
|
|
|
assert.strictEqual(fsSync.mkdirSync.firstCall[1]?.recursive, true)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should check if hash_alg is valid', function() {
|
|
|
|
assert.throws(function() {
|
|
|
|
createCache({ hash_alg: 'dafdsagasdgwa4e' })
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('FSCache', function() {
|
|
|
|
t.describe('#hash()', function() {
|
|
|
|
t.test('should use cache hasher to hash string', function() {
|
|
|
|
let cache = createCache({ hash_alg: 'sha256' })
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache.hash('asdf'), path.join(cache.cache_dir, '-' + crypto.hash('sha256', 'asdf')))
|
2024-09-20 13:40:01 +00:00
|
|
|
|
|
|
|
cache = createCache({ hash_alg: 'md5' })
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache.hash('asdf'), path.join(cache.cache_dir, '-' + crypto.hash('md5', 'asdf')))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should add prefix if prefix is defined', function() {
|
|
|
|
let cache = createCache({ prefix: 'asdfg', hash_alg: 'md5' })
|
|
|
|
assert.strictEqual(cache.hash('asdf'), path.join(cache.cache_dir, 'asdfg-' + crypto.hash('md5', 'asdf')))
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#_parseCacheData()', function() {
|
|
|
|
t.test('should default parse as json', function() {
|
|
|
|
let cache = createCache()
|
2024-09-20 23:14:22 +00:00
|
|
|
let output = cache._parseCacheData('{"content":{"hello":"world"}}')
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(typeof output, 'object')
|
|
|
|
assert.strictEqual(output.hello, 'world')
|
|
|
|
})
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
t.test('should return content if not expired', function() {
|
|
|
|
let expiredTime = new Date().getTime() + 1000
|
|
|
|
let cache = createCache()
|
|
|
|
let output = cache._parseCacheData(`{"content":{"hello":"world"},"ttl":${expiredTime}}`)
|
|
|
|
assert.strictEqual(typeof output, 'object')
|
|
|
|
assert.strictEqual(output.hello, 'world')
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
t.test('should return null if ttl expired', function() {
|
|
|
|
let expiredTime = new Date().getTime() - 1
|
2024-09-20 13:40:01 +00:00
|
|
|
let cache = createCache()
|
2024-09-20 23:14:22 +00:00
|
|
|
let output = cache._parseCacheData(`{"content":{"hello":"world"},"ttl":${expiredTime}}`)
|
|
|
|
assert.strictEqual(output, null)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should fall back to fallback if ttl expired', function() {
|
|
|
|
const fallback = { a: 1 }
|
|
|
|
let cache = createCache()
|
|
|
|
let output = cache._parseCacheData('{"content":{"hello":"world"},"ttl":0}', fallback)
|
|
|
|
assert.strictEqual(output, fallback)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#_parseSetData()', function() {
|
|
|
|
t.test('should default stringify to json', function() {
|
2024-09-20 23:14:22 +00:00
|
|
|
const assertKey = 'mytestkey-1234'
|
|
|
|
|
2024-09-20 13:40:01 +00:00
|
|
|
let cache = createCache()
|
2024-09-20 23:14:22 +00:00
|
|
|
let output = cache._parseSetData(assertKey, { hello: 'world' })
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(typeof output, 'string')
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(output, `{"key":"${assertKey}","content":{"hello":"world"}}`)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
t.test('should include ttl if specified in options', function() {
|
|
|
|
const assertData = { a: 1 }
|
|
|
|
|
|
|
|
let cache = createCache({ ttl: 60 })
|
|
|
|
let output = cache._parseSetData('a', assertData)
|
|
|
|
let back = JSON.parse(output)
|
|
|
|
assert.ok(back.ttl)
|
|
|
|
assert.deepStrictEqual(back.content, assertData)
|
|
|
|
assert.equalWithMargin(new Date().getTime() + 60 * 1000, back.ttl, 1000)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
t.test('should include ttl if specified in parameters', function() {
|
|
|
|
const assertData = { a: 1 }
|
|
|
|
const assertKey = 'mytestkey-1234'
|
|
|
|
|
2024-09-20 13:40:01 +00:00
|
|
|
let cache = createCache()
|
2024-09-20 23:14:22 +00:00
|
|
|
let output = cache._parseSetData(assertKey, assertData, { ttl: 60 })
|
|
|
|
let back = JSON.parse(output)
|
|
|
|
assert.ok(back.ttl)
|
|
|
|
assert.strictEqual(back.key, assertKey)
|
|
|
|
assert.deepStrictEqual(back.content, assertData)
|
|
|
|
assert.equalWithMargin(new Date().getTime() + 60 * 1000, back.ttl, 1000)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('ttl in parameter should overwrite options', function() {
|
|
|
|
const assertData = { a: 1 }
|
|
|
|
|
|
|
|
let cache = createCache({ ttl: 30 })
|
|
|
|
let output = cache._parseSetData('a', assertData, { ttl: 60 })
|
|
|
|
let back = JSON.parse(output)
|
|
|
|
assert.ok(back.ttl)
|
|
|
|
assert.deepStrictEqual(back.content, assertData)
|
|
|
|
assert.equalWithMargin(new Date().getTime() + 60 * 1000, back.ttl, 1000)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('ttl in parameter with 0 should overwrite options with no ttl', function() {
|
|
|
|
const assertData = { a: 1 }
|
|
|
|
|
|
|
|
let cache = createCache({ ttl: 30 })
|
|
|
|
let output = cache._parseSetData('a', assertData, { ttl: 0 })
|
|
|
|
let back = JSON.parse(output)
|
|
|
|
assert.notOk(back.ttl)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#get()', function() {
|
|
|
|
t.test('should call promise readFile and parse result', async function() {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
const assertContent = '{"hello":"world"}'
|
|
|
|
const assertResult = { hello: 'world' }
|
|
|
|
let cache = createCache()
|
|
|
|
fsPromises.readFile.resolves(assertContent)
|
|
|
|
cache._parseCacheData = spy().returns(assertResult)
|
|
|
|
|
|
|
|
let output = await cache.get(assertKey)
|
|
|
|
assert.strictEqual(output, assertResult)
|
|
|
|
assert.ok(fsPromises.readFile.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(fsPromises.readFile.firstCall[0], cache.hash(assertKey))
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(fsPromises.readFile.firstCall[1]?.encoding, 'utf8')
|
|
|
|
assert.ok(cache._parseCacheData.called)
|
|
|
|
assert.ok(cache._parseCacheData.firstCall[0], assertContent)
|
|
|
|
})
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
t.test('should pass extra options and fallback to the parser', async function() {
|
2024-09-20 13:40:01 +00:00
|
|
|
const assertOptions = { a: 1 }
|
2024-09-20 23:14:22 +00:00
|
|
|
const assertFallback = { b: 2 }
|
2024-09-20 13:40:01 +00:00
|
|
|
let cache = createCache()
|
|
|
|
cache._parseCacheData = spy()
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
await cache.get('asdf', assertFallback, assertOptions)
|
2024-09-20 13:40:01 +00:00
|
|
|
|
|
|
|
assert.ok(cache._parseCacheData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.ok(cache._parseCacheData.firstCall[1], assertFallback)
|
|
|
|
assert.ok(cache._parseCacheData.firstCall[2], assertOptions)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should support fallback value if file does not exist', async function() {
|
|
|
|
const assertFallback = { a: 1 }
|
|
|
|
let cache = createCache()
|
|
|
|
fsPromises.readFile.rejects(new Error('asdf'))
|
|
|
|
cache._parseCacheData = spy()
|
|
|
|
|
|
|
|
let output = await cache.get('bla', assertFallback)
|
|
|
|
assert.strictEqual(output, assertFallback)
|
|
|
|
assert.notOk(cache._parseCacheData.called)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('parser error should propogate', async function() {
|
|
|
|
const assertError = new Error('Hello')
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseCacheData = spy().throws(assertError)
|
|
|
|
|
|
|
|
let err = await assert.isRejected(cache.get('asdf'))
|
|
|
|
|
|
|
|
assert.strictEqual(err, assertError)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#getSync()', function() {
|
|
|
|
t.test('should call sync readFile and parse result', function() {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
const assertContent = '{"hello":"world"}'
|
|
|
|
const assertResult = { hello: 'world' }
|
|
|
|
let cache = createCache()
|
|
|
|
fsSync.readFileSync.returns(assertContent)
|
|
|
|
cache._parseCacheData = spy().returns(assertResult)
|
|
|
|
|
|
|
|
let output = cache.getSync(assertKey)
|
|
|
|
assert.strictEqual(output, assertResult)
|
|
|
|
assert.ok(fsSync.readFileSync.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(fsSync.readFileSync.firstCall[0], cache.hash(assertKey))
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(fsSync.readFileSync.firstCall[1]?.encoding, 'utf8')
|
|
|
|
assert.ok(cache._parseCacheData.called)
|
|
|
|
assert.ok(cache._parseCacheData.firstCall[0], assertContent)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass extra options to the parser', function() {
|
|
|
|
const assertOptions = { a: 1 }
|
2024-09-20 23:14:22 +00:00
|
|
|
const assertFallback = { b: 2 }
|
2024-09-20 13:40:01 +00:00
|
|
|
let cache = createCache()
|
|
|
|
cache._parseCacheData = spy()
|
|
|
|
|
2024-09-20 23:14:22 +00:00
|
|
|
cache.getSync('asdf', assertFallback, assertOptions)
|
2024-09-20 13:40:01 +00:00
|
|
|
|
|
|
|
assert.ok(cache._parseCacheData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.ok(cache._parseCacheData.firstCall[1], assertFallback)
|
|
|
|
assert.ok(cache._parseCacheData.firstCall[2], assertOptions)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should support fallback value if file does not exist', function() {
|
|
|
|
const assertFallback = { a: 1 }
|
|
|
|
let cache = createCache()
|
|
|
|
fsSync.readFileSync.throws(new Error('asdf'))
|
|
|
|
cache._parseCacheData = spy()
|
|
|
|
|
|
|
|
let output = cache.getSync('bla', assertFallback)
|
|
|
|
assert.strictEqual(output, assertFallback)
|
|
|
|
assert.notOk(cache._parseCacheData.called)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('parser error should propogate', async function() {
|
|
|
|
const assertError = new Error('Hello')
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseCacheData = spy().throws(assertError)
|
|
|
|
|
|
|
|
assert.throws(function() {
|
|
|
|
cache.getSync('asdf')
|
|
|
|
}, assertError)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#set()', function() {
|
|
|
|
t.test('should call promise writeFile', async function() {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
const assertInput = { hello: 'world' }
|
|
|
|
const assertContent = JSON.stringify(assertInput)
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy().returns(assertContent)
|
|
|
|
await cache.set(assertKey, assertInput)
|
|
|
|
|
|
|
|
assert.ok(fsPromises.writeFile.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(fsPromises.writeFile.firstCall[0], cache.hash(assertKey))
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(fsPromises.writeFile.firstCall[1], assertContent)
|
|
|
|
assert.strictEqual(fsPromises.writeFile.firstCall[2]?.encoding, 'utf8')
|
|
|
|
assert.ok(cache._parseSetData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[0], assertKey)
|
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[1], assertInput)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass extra options to the parser', async function() {
|
|
|
|
const assertOptions = { a: 1 }
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy()
|
|
|
|
|
|
|
|
await cache.set('asdf', null, assertOptions)
|
|
|
|
|
|
|
|
assert.ok(cache._parseSetData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[2], assertOptions)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass options if number as ttl to the parser', async function() {
|
|
|
|
const assertTtl = 1234
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy()
|
|
|
|
|
|
|
|
await cache.set('asdf', null, assertTtl)
|
|
|
|
|
|
|
|
assert.ok(cache._parseSetData.called)
|
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[2].ttl, assertTtl)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass extra options to the parser', async function() {
|
|
|
|
const assertEncoding = 'asdf'
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
await cache.set('asdf', null, { encoding: assertEncoding })
|
|
|
|
|
|
|
|
assert.strictEqual(fsPromises.writeFile.firstCall[2]?.encoding, assertEncoding)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('parse error should reject properly', async function() {
|
|
|
|
const assertError = new Error('what is up')
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy().throws(assertError)
|
|
|
|
|
|
|
|
// make sure it's properly promise wrapped
|
|
|
|
let inbetween = cache.set('asdf')
|
|
|
|
let err = await assert.isRejected(inbetween)
|
|
|
|
|
|
|
|
assert.strictEqual(err, assertError)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#setSync()', function() {
|
|
|
|
t.test('should call sync writeFileSync', function() {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
const assertInput = { hello: 'world' }
|
|
|
|
const assertContent = JSON.stringify(assertInput)
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy().returns(assertContent)
|
|
|
|
cache.setSync(assertKey, assertInput)
|
|
|
|
|
|
|
|
assert.ok(fsSync.writeFileSync.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(fsSync.writeFileSync.firstCall[0], cache.hash(assertKey))
|
2024-09-20 13:40:01 +00:00
|
|
|
assert.strictEqual(fsSync.writeFileSync.firstCall[1], assertContent)
|
|
|
|
assert.strictEqual(fsSync.writeFileSync.firstCall[2]?.encoding, 'utf8')
|
|
|
|
assert.ok(cache._parseSetData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[0], assertKey)
|
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[1], assertInput)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass extra options to the parser', function() {
|
|
|
|
const assertOptions = { a: 1 }
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy()
|
|
|
|
|
|
|
|
cache.setSync('asdf', null, assertOptions)
|
|
|
|
|
|
|
|
assert.ok(cache._parseSetData.called)
|
2024-09-20 23:14:22 +00:00
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[2], assertOptions)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass options if number as ttl to the parser', function() {
|
|
|
|
const assertTtl = 1234
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy()
|
|
|
|
|
|
|
|
cache.setSync('asdf', null, assertTtl)
|
|
|
|
|
|
|
|
assert.ok(cache._parseSetData.called)
|
|
|
|
assert.strictEqual(cache._parseSetData.firstCall[2].ttl, assertTtl)
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.test('should pass extra options to the parser', function() {
|
|
|
|
const assertEncoding = 'asdf'
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache.setSync('asdf', null, { encoding: assertEncoding })
|
|
|
|
|
|
|
|
assert.strictEqual(fsSync.writeFileSync.firstCall[2]?.encoding, assertEncoding)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.test('parse error should throw', function() {
|
|
|
|
const assertError = new Error('what is up')
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache._parseSetData = spy().throws(assertError)
|
|
|
|
|
|
|
|
assert.throws(function() {
|
|
|
|
cache.setSync('asdf')
|
|
|
|
}, assertError)
|
|
|
|
})
|
|
|
|
})
|
2024-09-20 23:14:22 +00:00
|
|
|
|
|
|
|
const setManyFunctions = ['setMany', 'save']
|
|
|
|
|
|
|
|
setManyFunctions.forEach(function (fnName) {
|
|
|
|
t.describe(`#${fnName}()`, function () {
|
|
|
|
t.test('should set many at once', async function() {
|
|
|
|
const assertItem1 = { a: 1 }
|
|
|
|
const assertItem2 = { b: 2 }
|
|
|
|
const assertOptions = { opt: true }
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache.set = spy().resolves()
|
|
|
|
|
|
|
|
await cache[fnName]([
|
|
|
|
{ key: 'item1', value: assertItem1 },
|
|
|
|
{ key: 'item2', content: assertItem2 },
|
|
|
|
], assertOptions)
|
|
|
|
|
|
|
|
assert.strictEqual(cache.set.callCount, 2)
|
|
|
|
assert.strictEqual(cache.set.getCallN(1)[0], 'item1')
|
|
|
|
assert.strictEqual(cache.set.getCallN(1)[1], assertItem1)
|
|
|
|
assert.strictEqual(cache.set.getCallN(1)[2], assertOptions)
|
|
|
|
assert.strictEqual(cache.set.getCallN(2)[0], 'item2')
|
|
|
|
assert.strictEqual(cache.set.getCallN(2)[1], assertItem2)
|
|
|
|
assert.strictEqual(cache.set.getCallN(2)[2], assertOptions)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
const setManySyncFunctions = ['setManySync', 'saveSync']
|
|
|
|
|
|
|
|
setManySyncFunctions.forEach(function (fnName) {
|
|
|
|
t.describe(`#${fnName}()`, function () {
|
|
|
|
t.test('should setSync many at once', function() {
|
|
|
|
const assertItem1 = { a: 1 }
|
|
|
|
const assertItem2 = { b: 2 }
|
|
|
|
const assertOptions = { opt: true }
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache.setSync = spy().resolves()
|
|
|
|
|
|
|
|
cache[fnName]([
|
|
|
|
{ key: 'item1', value: assertItem1 },
|
|
|
|
{ key: 'item2', content: assertItem2 },
|
|
|
|
], assertOptions)
|
|
|
|
|
|
|
|
assert.strictEqual(cache.setSync.callCount, 2)
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(1)[0], 'item1')
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(1)[1], assertItem1)
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(1)[2], assertOptions)
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(2)[0], 'item2')
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(2)[1], assertItem2)
|
|
|
|
assert.strictEqual(cache.setSync.getCallN(2)[2], assertOptions)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#remove()', function() {
|
|
|
|
t.test('it should call promise rm', async function () {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
await cache.remove(assertKey)
|
|
|
|
|
|
|
|
assert.ok(fsPromises.rm.called)
|
|
|
|
assert.strictEqual(fsPromises.rm.firstCall[0], cache.hash(assertKey))
|
|
|
|
assert.deepStrictEqual(fsPromises.rm.firstCall[1], { force: true })
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#removeSync()', function() {
|
|
|
|
t.test('it should call sync rm', async function () {
|
|
|
|
const assertKey = 'asdf1234'
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
await cache.removeSync(assertKey)
|
|
|
|
|
|
|
|
assert.ok(fsSync.rmSync.called)
|
|
|
|
assert.strictEqual(fsSync.rmSync.firstCall[0], cache.hash(assertKey))
|
|
|
|
assert.deepStrictEqual(fsSync.rmSync.firstCall[1], { force: true })
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#clear()', function() {
|
|
|
|
t.test('it should call promises readdir and rm on every item with same prefix', async function () {
|
|
|
|
let files = ['.gitkeep', '-asdf', '-temp', 'hello.world']
|
|
|
|
fsPromises.readdir.resolves(files)
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
await cache.clear()
|
|
|
|
|
|
|
|
assert.ok(fsPromises.readdir.called)
|
|
|
|
assert.strictEqual(fsPromises.readdir.firstCall[0], cache.cache_dir)
|
|
|
|
assert.strictEqual(fsPromises.rm.callCount, 2)
|
|
|
|
assert.strictEqual(fsPromises.rm.getCallN(1)[0], path.join(cache.cache_dir, '-asdf'))
|
|
|
|
assert.deepStrictEqual(fsPromises.rm.getCallN(1)[1], { force: true })
|
|
|
|
assert.strictEqual(fsPromises.rm.getCallN(2)[0], path.join(cache.cache_dir, '-temp'))
|
|
|
|
assert.deepStrictEqual(fsPromises.rm.getCallN(2)[1], { force: true })
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.describe('#clearSync()', function() {
|
|
|
|
t.test('it should call sync readdirSync and rmSync on every item with same prefix', function () {
|
|
|
|
let files = ['.gitkeep', '-asdf', '-temp', 'hello.world']
|
|
|
|
fsSync.readdirSync.returns(files)
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
cache.clearSync()
|
|
|
|
|
|
|
|
assert.ok(fsSync.readdirSync.called)
|
|
|
|
assert.strictEqual(fsSync.readdirSync.firstCall[0], cache.cache_dir)
|
|
|
|
assert.strictEqual(fsSync.rmSync.callCount, 2)
|
|
|
|
assert.strictEqual(fsSync.rmSync.getCallN(1)[0], path.join(cache.cache_dir, '-asdf'))
|
|
|
|
assert.deepStrictEqual(fsSync.rmSync.getCallN(1)[1], { force: true })
|
|
|
|
assert.strictEqual(fsSync.rmSync.getCallN(2)[0], path.join(cache.cache_dir, '-temp'))
|
|
|
|
assert.deepStrictEqual(fsSync.rmSync.getCallN(2)[1], { force: true })
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
const getManyFunctions = ['getAll', 'load']
|
|
|
|
|
|
|
|
getManyFunctions.forEach(function (fnName) {
|
|
|
|
t.describe(`#${fnName}()`, function () {
|
|
|
|
t.test('should read each file in folder and return results', async function() {
|
|
|
|
let files = ['.gitkeep', '-asdf', '-temp', '-derp', 'hello.world']
|
|
|
|
let expired = new Date().getTime() - 1
|
|
|
|
fsPromises.readdir.resolves(files)
|
|
|
|
fsPromises.readFile.onCallN(1).resolves(JSON.stringify({ key: 'a', content: { a: 1 } }))
|
|
|
|
fsPromises.readFile.onCallN(2).resolves(JSON.stringify({ key: 'b', content: { b: 2 } }))
|
|
|
|
fsPromises.readFile.onCallN(3).resolves(JSON.stringify({ key: 'c', content: { c: 3 }, ttl: expired }))
|
|
|
|
|
|
|
|
let cache = createCache()
|
|
|
|
let data = await cache[fnName]()
|
|
|
|
|
|
|
|
if (fnName === 'getAll') {
|
|
|
|
assert.strictEqual(data.length, 2)
|
|
|
|
assert.strictEqual(data[0].key, 'a')
|
|
|
|
assert.deepStrictEqual(data[0].content, { a: 1 })
|
|
|
|
assert.strictEqual(data[1].key, 'b')
|
|
|
|
assert.deepStrictEqual(data[1].content, { b: 2 })
|
|
|
|
} else {
|
|
|
|
assert.strictEqual(data.files.length, 2)
|
|
|
|
assert.strictEqual(data.files[0].path, cache.hash('a'))
|
|
|
|
assert.strictEqual(data.files[0].key, 'a')
|
|
|
|
assert.deepStrictEqual(data.files[0].value, { a: 1 })
|
|
|
|
assert.strictEqual(data.files[1].path, cache.hash('b'))
|
|
|
|
assert.strictEqual(data.files[1].key, 'b')
|
|
|
|
assert.deepStrictEqual(data.files[1].value, { b: 2 })
|
|
|
|
}
|
|
|
|
assert.strictEqual(fsPromises.readFile.getCallN(1)[0], path.join(cache.cache_dir, '-asdf'))
|
|
|
|
assert.strictEqual(fsPromises.readFile.getCallN(2)[0], path.join(cache.cache_dir, '-temp'))
|
|
|
|
assert.strictEqual(fsPromises.readFile.getCallN(3)[0], path.join(cache.cache_dir, '-derp'))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2024-09-20 13:40:01 +00:00
|
|
|
})
|