397 lines
8.2 KiB
JavaScript
397 lines
8.2 KiB
JavaScript
|
var test = require("tap").test
|
||
|
, LRU = require("../")
|
||
|
|
||
|
test("basic", function (t) {
|
||
|
var cache = new LRU({max: 10})
|
||
|
cache.set("key", "value")
|
||
|
t.equal(cache.get("key"), "value")
|
||
|
t.equal(cache.get("nada"), undefined)
|
||
|
t.equal(cache.length, 1)
|
||
|
t.equal(cache.max, 10)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("least recently set", function (t) {
|
||
|
var cache = new LRU(2)
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "B")
|
||
|
cache.set("c", "C")
|
||
|
t.equal(cache.get("c"), "C")
|
||
|
t.equal(cache.get("b"), "B")
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("lru recently gotten", function (t) {
|
||
|
var cache = new LRU(2)
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "B")
|
||
|
cache.get("a")
|
||
|
cache.set("c", "C")
|
||
|
t.equal(cache.get("c"), "C")
|
||
|
t.equal(cache.get("b"), undefined)
|
||
|
t.equal(cache.get("a"), "A")
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("del", function (t) {
|
||
|
var cache = new LRU(2)
|
||
|
cache.set("a", "A")
|
||
|
cache.del("a")
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("max", function (t) {
|
||
|
var cache = new LRU(3)
|
||
|
|
||
|
// test changing the max, verify that the LRU items get dropped.
|
||
|
cache.max = 100
|
||
|
for (var i = 0; i < 100; i ++) cache.set(i, i)
|
||
|
t.equal(cache.length, 100)
|
||
|
for (var i = 0; i < 100; i ++) {
|
||
|
t.equal(cache.get(i), i)
|
||
|
}
|
||
|
cache.max = 3
|
||
|
t.equal(cache.length, 3)
|
||
|
for (var i = 0; i < 97; i ++) {
|
||
|
t.equal(cache.get(i), undefined)
|
||
|
}
|
||
|
for (var i = 98; i < 100; i ++) {
|
||
|
t.equal(cache.get(i), i)
|
||
|
}
|
||
|
|
||
|
// now remove the max restriction, and try again.
|
||
|
cache.max = "hello"
|
||
|
for (var i = 0; i < 100; i ++) cache.set(i, i)
|
||
|
t.equal(cache.length, 100)
|
||
|
for (var i = 0; i < 100; i ++) {
|
||
|
t.equal(cache.get(i), i)
|
||
|
}
|
||
|
// should trigger an immediate resize
|
||
|
cache.max = 3
|
||
|
t.equal(cache.length, 3)
|
||
|
for (var i = 0; i < 97; i ++) {
|
||
|
t.equal(cache.get(i), undefined)
|
||
|
}
|
||
|
for (var i = 98; i < 100; i ++) {
|
||
|
t.equal(cache.get(i), i)
|
||
|
}
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("reset", function (t) {
|
||
|
var cache = new LRU(10)
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "B")
|
||
|
cache.reset()
|
||
|
t.equal(cache.length, 0)
|
||
|
t.equal(cache.max, 10)
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.equal(cache.get("b"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
|
||
|
test("basic with weighed length", function (t) {
|
||
|
var cache = new LRU({
|
||
|
max: 100,
|
||
|
length: function (item) { return item.size }
|
||
|
})
|
||
|
cache.set("key", {val: "value", size: 50})
|
||
|
t.equal(cache.get("key").val, "value")
|
||
|
t.equal(cache.get("nada"), undefined)
|
||
|
t.equal(cache.lengthCalculator(cache.get("key")), 50)
|
||
|
t.equal(cache.length, 50)
|
||
|
t.equal(cache.max, 100)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
|
||
|
test("weighed length item too large", function (t) {
|
||
|
var cache = new LRU({
|
||
|
max: 10,
|
||
|
length: function (item) { return item.size }
|
||
|
})
|
||
|
t.equal(cache.max, 10)
|
||
|
|
||
|
// should fall out immediately
|
||
|
cache.set("key", {val: "value", size: 50})
|
||
|
|
||
|
t.equal(cache.length, 0)
|
||
|
t.equal(cache.get("key"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("least recently set with weighed length", function (t) {
|
||
|
var cache = new LRU({
|
||
|
max:8,
|
||
|
length: function (item) { return item.length }
|
||
|
})
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "BB")
|
||
|
cache.set("c", "CCC")
|
||
|
cache.set("d", "DDDD")
|
||
|
t.equal(cache.get("d"), "DDDD")
|
||
|
t.equal(cache.get("c"), "CCC")
|
||
|
t.equal(cache.get("b"), undefined)
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("lru recently gotten with weighed length", function (t) {
|
||
|
var cache = new LRU({
|
||
|
max: 8,
|
||
|
length: function (item) { return item.length }
|
||
|
})
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "BB")
|
||
|
cache.set("c", "CCC")
|
||
|
cache.get("a")
|
||
|
cache.get("b")
|
||
|
cache.set("d", "DDDD")
|
||
|
t.equal(cache.get("c"), undefined)
|
||
|
t.equal(cache.get("d"), "DDDD")
|
||
|
t.equal(cache.get("b"), "BB")
|
||
|
t.equal(cache.get("a"), "A")
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("lru recently updated with weighed length", function (t) {
|
||
|
var cache = new LRU({
|
||
|
max: 8,
|
||
|
length: function (item) { return item.length }
|
||
|
})
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "BB")
|
||
|
cache.set("c", "CCC")
|
||
|
t.equal(cache.length, 6) //CCC BB A
|
||
|
cache.set("a", "+A")
|
||
|
t.equal(cache.length, 7) //+A CCC BB
|
||
|
cache.set("b", "++BB")
|
||
|
t.equal(cache.length, 6) //++BB +A
|
||
|
t.equal(cache.get("c"), undefined)
|
||
|
|
||
|
cache.set("c", "oversized")
|
||
|
t.equal(cache.length, 6) //++BB +A
|
||
|
t.equal(cache.get("c"), undefined)
|
||
|
|
||
|
cache.set("a", "oversized")
|
||
|
t.equal(cache.length, 4) //++BB
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.equal(cache.get("b"), "++BB")
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("set returns proper booleans", function(t) {
|
||
|
var cache = new LRU({
|
||
|
max: 5,
|
||
|
length: function (item) { return item.length }
|
||
|
})
|
||
|
|
||
|
t.equal(cache.set("a", "A"), true)
|
||
|
|
||
|
// should return false for max exceeded
|
||
|
t.equal(cache.set("b", "donuts"), false)
|
||
|
|
||
|
t.equal(cache.set("b", "B"), true)
|
||
|
t.equal(cache.set("c", "CCCC"), true)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("drop the old items", function(t) {
|
||
|
var cache = new LRU({
|
||
|
max: 5,
|
||
|
maxAge: 50
|
||
|
})
|
||
|
|
||
|
cache.set("a", "A")
|
||
|
|
||
|
setTimeout(function () {
|
||
|
cache.set("b", "b")
|
||
|
t.equal(cache.get("a"), "A")
|
||
|
}, 25)
|
||
|
|
||
|
setTimeout(function () {
|
||
|
cache.set("c", "C")
|
||
|
// timed out
|
||
|
t.notOk(cache.get("a"))
|
||
|
}, 60 + 25)
|
||
|
|
||
|
setTimeout(function () {
|
||
|
t.notOk(cache.get("b"))
|
||
|
t.equal(cache.get("c"), "C")
|
||
|
}, 90)
|
||
|
|
||
|
setTimeout(function () {
|
||
|
t.notOk(cache.get("c"))
|
||
|
t.end()
|
||
|
}, 155)
|
||
|
})
|
||
|
|
||
|
test("individual item can have it's own maxAge", function(t) {
|
||
|
var cache = new LRU({
|
||
|
max: 5,
|
||
|
maxAge: 50
|
||
|
})
|
||
|
|
||
|
cache.set("a", "A", 20)
|
||
|
setTimeout(function () {
|
||
|
t.notOk(cache.get("a"))
|
||
|
t.end()
|
||
|
}, 25)
|
||
|
})
|
||
|
|
||
|
test("individual item can have it's own maxAge > cache's", function(t) {
|
||
|
var cache = new LRU({
|
||
|
max: 5,
|
||
|
maxAge: 20
|
||
|
})
|
||
|
|
||
|
cache.set("a", "A", 50)
|
||
|
setTimeout(function () {
|
||
|
t.equal(cache.get("a"), "A")
|
||
|
t.end()
|
||
|
}, 25)
|
||
|
})
|
||
|
|
||
|
test("disposal function", function(t) {
|
||
|
var disposed = false
|
||
|
var cache = new LRU({
|
||
|
max: 1,
|
||
|
dispose: function (k, n) {
|
||
|
disposed = n
|
||
|
}
|
||
|
})
|
||
|
|
||
|
cache.set(1, 1)
|
||
|
cache.set(2, 2)
|
||
|
t.equal(disposed, 1)
|
||
|
cache.set(3, 3)
|
||
|
t.equal(disposed, 2)
|
||
|
cache.reset()
|
||
|
t.equal(disposed, 3)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("disposal function on too big of item", function(t) {
|
||
|
var disposed = false
|
||
|
var cache = new LRU({
|
||
|
max: 1,
|
||
|
length: function (k) {
|
||
|
return k.length
|
||
|
},
|
||
|
dispose: function (k, n) {
|
||
|
disposed = n
|
||
|
}
|
||
|
})
|
||
|
var obj = [ 1, 2 ]
|
||
|
|
||
|
t.equal(disposed, false)
|
||
|
cache.set("obj", obj)
|
||
|
t.equal(disposed, obj)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("has()", function(t) {
|
||
|
var cache = new LRU({
|
||
|
max: 1,
|
||
|
maxAge: 10
|
||
|
})
|
||
|
|
||
|
cache.set('foo', 'bar')
|
||
|
t.equal(cache.has('foo'), true)
|
||
|
cache.set('blu', 'baz')
|
||
|
t.equal(cache.has('foo'), false)
|
||
|
t.equal(cache.has('blu'), true)
|
||
|
setTimeout(function() {
|
||
|
t.equal(cache.has('blu'), false)
|
||
|
t.end()
|
||
|
}, 15)
|
||
|
})
|
||
|
|
||
|
test("stale", function(t) {
|
||
|
var cache = new LRU({
|
||
|
maxAge: 10,
|
||
|
stale: true
|
||
|
})
|
||
|
|
||
|
cache.set('foo', 'bar')
|
||
|
t.equal(cache.get('foo'), 'bar')
|
||
|
t.equal(cache.has('foo'), true)
|
||
|
setTimeout(function() {
|
||
|
t.equal(cache.has('foo'), false)
|
||
|
t.equal(cache.get('foo'), 'bar')
|
||
|
t.equal(cache.get('foo'), undefined)
|
||
|
t.end()
|
||
|
}, 15)
|
||
|
})
|
||
|
|
||
|
test("lru update via set", function(t) {
|
||
|
var cache = LRU({ max: 2 });
|
||
|
|
||
|
cache.set('foo', 1);
|
||
|
cache.set('bar', 2);
|
||
|
cache.del('bar');
|
||
|
cache.set('baz', 3);
|
||
|
cache.set('qux', 4);
|
||
|
|
||
|
t.equal(cache.get('foo'), undefined)
|
||
|
t.equal(cache.get('bar'), undefined)
|
||
|
t.equal(cache.get('baz'), 3)
|
||
|
t.equal(cache.get('qux'), 4)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("least recently set w/ peek", function (t) {
|
||
|
var cache = new LRU(2)
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "B")
|
||
|
t.equal(cache.peek("a"), "A")
|
||
|
cache.set("c", "C")
|
||
|
t.equal(cache.get("c"), "C")
|
||
|
t.equal(cache.get("b"), "B")
|
||
|
t.equal(cache.get("a"), undefined)
|
||
|
t.end()
|
||
|
})
|
||
|
|
||
|
test("pop the least used item", function (t) {
|
||
|
var cache = new LRU(3)
|
||
|
, last
|
||
|
|
||
|
cache.set("a", "A")
|
||
|
cache.set("b", "B")
|
||
|
cache.set("c", "C")
|
||
|
|
||
|
t.equal(cache.length, 3)
|
||
|
t.equal(cache.max, 3)
|
||
|
|
||
|
// Ensure we pop a, c, b
|
||
|
cache.get("b", "B")
|
||
|
|
||
|
last = cache.pop()
|
||
|
t.equal(last.key, "a")
|
||
|
t.equal(last.value, "A")
|
||
|
t.equal(cache.length, 2)
|
||
|
t.equal(cache.max, 3)
|
||
|
|
||
|
last = cache.pop()
|
||
|
t.equal(last.key, "c")
|
||
|
t.equal(last.value, "C")
|
||
|
t.equal(cache.length, 1)
|
||
|
t.equal(cache.max, 3)
|
||
|
|
||
|
last = cache.pop()
|
||
|
t.equal(last.key, "b")
|
||
|
t.equal(last.value, "B")
|
||
|
t.equal(cache.length, 0)
|
||
|
t.equal(cache.max, 3)
|
||
|
|
||
|
last = cache.pop()
|
||
|
t.equal(last, null)
|
||
|
t.equal(cache.length, 0)
|
||
|
t.equal(cache.max, 3)
|
||
|
|
||
|
t.end()
|
||
|
})
|