Skip to content

Commit 5ad76c0

Browse files
pvogel1967Peter Vogel
and
Peter Vogel
authored
ttl may be a function, handle appropriately (#38)
Co-authored-by: Peter Vogel <[email protected]>
1 parent a90109e commit 5ad76c0

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

src/cache.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ class Cache {
1919
throw new Error('storage is required')
2020
}
2121

22-
if (options.ttl && (typeof options.ttl !== 'number' || options.ttl < 0 || !Number.isInteger(options.ttl))) {
22+
// ttl _may_ be a function to defer the ttl decision until later
23+
if (options.ttl && typeof options.ttl === 'number' && (options.ttl < 0 || !Number.isInteger(options.ttl))) {
2324
throw new Error('ttl must be a positive integer greater than 0')
2425
}
2526

@@ -250,12 +251,14 @@ class Wrapper {
250251
}
251252

252253
const result = await this.func(args, key)
253-
254-
if (this.ttl < 1) {
254+
const ttl = typeof this.ttl === 'function' ? this.ttl(result) : this.ttl
255+
if (ttl === undefined || ttl === null || (typeof ttl !== 'number' || !Number.isInteger(ttl))) {
256+
this.onError(new Error('ttl must be an integer'))
257+
return result
258+
}
259+
if (ttl < 1) {
255260
return result
256261
}
257-
258-
const ttl = typeof this.ttl === 'function' ? this.ttl(result) : this.ttl
259262

260263
if (!this.references) {
261264
let p = this.storage.set(storageKey, result, ttl)

test/cache.test.js

+86
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,92 @@ test('Cache', async (t) => {
7171
})
7272
})
7373

74+
test('should bypass setting value in storage if ttl function returns 0', async (t) => {
75+
t.plan(1)
76+
const cache = new Cache({ storage: createStorage() })
77+
cache[kStorage].set = () => {
78+
t.fail('should bypass storage')
79+
}
80+
cache.define('f', { ttl: (_data) => { return 0 } }, async (k) => {
81+
t.equal(k, 'foo')
82+
83+
return { k }
84+
})
85+
86+
await cache.f('foo')
87+
})
88+
89+
test('should set value in storage if ttl function returns > 0', async (t) => {
90+
t.plan(4)
91+
const cache = new Cache({ storage: createStorage() })
92+
cache[kStorage].set = (key, value, ttl) => {
93+
t.equal(key, 'f~foo')
94+
t.equal(value.k, 'foo')
95+
t.equal(ttl, 1)
96+
}
97+
cache.define('f', { ttl: (data) => { return 1 } }, async (k) => {
98+
t.equal(k, 'foo')
99+
100+
return { k }
101+
})
102+
103+
await cache.f('foo')
104+
})
105+
106+
test('should call onError and bypass storage if ttl fn returns non-integer', async (t) => {
107+
t.plan(2)
108+
const cache = new Cache({ storage: createStorage() })
109+
cache[kStorage].set = () => {
110+
t.fail('should bypass storage')
111+
}
112+
const onError = (err) => {
113+
t.equal(err.message, 'ttl must be an integer')
114+
}
115+
cache.define('f', { ttl: (data) => { return 3.14 }, onError }, async (k) => {
116+
t.equal(k, 'foo')
117+
118+
return { k }
119+
})
120+
121+
await cache.f('foo')
122+
})
123+
124+
test('should call onError and bypass storage if ttl fn returns undefined', async (t) => {
125+
t.plan(2)
126+
const cache = new Cache({ storage: createStorage() })
127+
cache[kStorage].set = () => {
128+
t.fail('should bypass storage')
129+
}
130+
const onError = (err) => {
131+
t.equal(err.message, 'ttl must be an integer')
132+
}
133+
cache.define('f', { ttl: (data) => { return undefined }, onError }, async (k) => {
134+
t.equal(k, 'foo')
135+
136+
return { k }
137+
})
138+
139+
await cache.f('foo')
140+
})
141+
142+
test('should call onError and bypass storage if ttl fn returns non-number', async (t) => {
143+
t.plan(2)
144+
const cache = new Cache({ storage: createStorage() })
145+
cache[kStorage].set = () => {
146+
t.fail('should bypass storage')
147+
}
148+
const onError = (err) => {
149+
t.equal(err.message, 'ttl must be an integer')
150+
}
151+
cache.define('f', { ttl: (data) => { return '3' }, onError }, async (k) => {
152+
t.equal(k, 'foo')
153+
154+
return { k }
155+
})
156+
157+
await cache.f('foo')
158+
})
159+
74160
test('set', async (t) => {
75161
test('should use storage to set a value', async (t) => {
76162
t.plan(4)

0 commit comments

Comments
 (0)