basic.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. var test = require("tap").test
  2. , LRU = require("../")
  3. test("basic", function (t) {
  4. var cache = new LRU({max: 10})
  5. cache.set("key", "value")
  6. t.equal(cache.get("key"), "value")
  7. t.equal(cache.get("nada"), undefined)
  8. t.equal(cache.length, 1)
  9. t.equal(cache.max, 10)
  10. t.end()
  11. })
  12. test("least recently set", function (t) {
  13. var cache = new LRU(2)
  14. cache.set("a", "A")
  15. cache.set("b", "B")
  16. cache.set("c", "C")
  17. t.equal(cache.get("c"), "C")
  18. t.equal(cache.get("b"), "B")
  19. t.equal(cache.get("a"), undefined)
  20. t.end()
  21. })
  22. test("lru recently gotten", function (t) {
  23. var cache = new LRU(2)
  24. cache.set("a", "A")
  25. cache.set("b", "B")
  26. cache.get("a")
  27. cache.set("c", "C")
  28. t.equal(cache.get("c"), "C")
  29. t.equal(cache.get("b"), undefined)
  30. t.equal(cache.get("a"), "A")
  31. t.end()
  32. })
  33. test("del", function (t) {
  34. var cache = new LRU(2)
  35. cache.set("a", "A")
  36. cache.del("a")
  37. t.equal(cache.get("a"), undefined)
  38. t.end()
  39. })
  40. test("max", function (t) {
  41. var cache = new LRU(3)
  42. // test changing the max, verify that the LRU items get dropped.
  43. cache.max = 100
  44. for (var i = 0; i < 100; i ++) cache.set(i, i)
  45. t.equal(cache.length, 100)
  46. for (var i = 0; i < 100; i ++) {
  47. t.equal(cache.get(i), i)
  48. }
  49. cache.max = 3
  50. t.equal(cache.length, 3)
  51. for (var i = 0; i < 97; i ++) {
  52. t.equal(cache.get(i), undefined)
  53. }
  54. for (var i = 98; i < 100; i ++) {
  55. t.equal(cache.get(i), i)
  56. }
  57. // now remove the max restriction, and try again.
  58. cache.max = "hello"
  59. for (var i = 0; i < 100; i ++) cache.set(i, i)
  60. t.equal(cache.length, 100)
  61. for (var i = 0; i < 100; i ++) {
  62. t.equal(cache.get(i), i)
  63. }
  64. // should trigger an immediate resize
  65. cache.max = 3
  66. t.equal(cache.length, 3)
  67. for (var i = 0; i < 97; i ++) {
  68. t.equal(cache.get(i), undefined)
  69. }
  70. for (var i = 98; i < 100; i ++) {
  71. t.equal(cache.get(i), i)
  72. }
  73. t.end()
  74. })
  75. test("reset", function (t) {
  76. var cache = new LRU(10)
  77. cache.set("a", "A")
  78. cache.set("b", "B")
  79. cache.reset()
  80. t.equal(cache.length, 0)
  81. t.equal(cache.max, 10)
  82. t.equal(cache.get("a"), undefined)
  83. t.equal(cache.get("b"), undefined)
  84. t.end()
  85. })
  86. test("basic with weighed length", function (t) {
  87. var cache = new LRU({
  88. max: 100,
  89. length: function (item) { return item.size }
  90. })
  91. cache.set("key", {val: "value", size: 50})
  92. t.equal(cache.get("key").val, "value")
  93. t.equal(cache.get("nada"), undefined)
  94. t.equal(cache.lengthCalculator(cache.get("key")), 50)
  95. t.equal(cache.length, 50)
  96. t.equal(cache.max, 100)
  97. t.end()
  98. })
  99. test("weighed length item too large", function (t) {
  100. var cache = new LRU({
  101. max: 10,
  102. length: function (item) { return item.size }
  103. })
  104. t.equal(cache.max, 10)
  105. // should fall out immediately
  106. cache.set("key", {val: "value", size: 50})
  107. t.equal(cache.length, 0)
  108. t.equal(cache.get("key"), undefined)
  109. t.end()
  110. })
  111. test("least recently set with weighed length", function (t) {
  112. var cache = new LRU({
  113. max:8,
  114. length: function (item) { return item.length }
  115. })
  116. cache.set("a", "A")
  117. cache.set("b", "BB")
  118. cache.set("c", "CCC")
  119. cache.set("d", "DDDD")
  120. t.equal(cache.get("d"), "DDDD")
  121. t.equal(cache.get("c"), "CCC")
  122. t.equal(cache.get("b"), undefined)
  123. t.equal(cache.get("a"), undefined)
  124. t.end()
  125. })
  126. test("lru recently gotten with weighed length", function (t) {
  127. var cache = new LRU({
  128. max: 8,
  129. length: function (item) { return item.length }
  130. })
  131. cache.set("a", "A")
  132. cache.set("b", "BB")
  133. cache.set("c", "CCC")
  134. cache.get("a")
  135. cache.get("b")
  136. cache.set("d", "DDDD")
  137. t.equal(cache.get("c"), undefined)
  138. t.equal(cache.get("d"), "DDDD")
  139. t.equal(cache.get("b"), "BB")
  140. t.equal(cache.get("a"), "A")
  141. t.end()
  142. })
  143. test("lru recently updated with weighed length", function (t) {
  144. var cache = new LRU({
  145. max: 8,
  146. length: function (item) { return item.length }
  147. })
  148. cache.set("a", "A")
  149. cache.set("b", "BB")
  150. cache.set("c", "CCC")
  151. t.equal(cache.length, 6) //CCC BB A
  152. cache.set("a", "+A")
  153. t.equal(cache.length, 7) //+A CCC BB
  154. cache.set("b", "++BB")
  155. t.equal(cache.length, 6) //++BB +A
  156. t.equal(cache.get("c"), undefined)
  157. cache.set("c", "oversized")
  158. t.equal(cache.length, 6) //++BB +A
  159. t.equal(cache.get("c"), undefined)
  160. cache.set("a", "oversized")
  161. t.equal(cache.length, 4) //++BB
  162. t.equal(cache.get("a"), undefined)
  163. t.equal(cache.get("b"), "++BB")
  164. t.end()
  165. })
  166. test("set returns proper booleans", function(t) {
  167. var cache = new LRU({
  168. max: 5,
  169. length: function (item) { return item.length }
  170. })
  171. t.equal(cache.set("a", "A"), true)
  172. // should return false for max exceeded
  173. t.equal(cache.set("b", "donuts"), false)
  174. t.equal(cache.set("b", "B"), true)
  175. t.equal(cache.set("c", "CCCC"), true)
  176. t.end()
  177. })
  178. test("drop the old items", function(t) {
  179. var cache = new LRU({
  180. max: 5,
  181. maxAge: 50
  182. })
  183. cache.set("a", "A")
  184. setTimeout(function () {
  185. cache.set("b", "b")
  186. t.equal(cache.get("a"), "A")
  187. }, 25)
  188. setTimeout(function () {
  189. cache.set("c", "C")
  190. // timed out
  191. t.notOk(cache.get("a"))
  192. }, 60 + 25)
  193. setTimeout(function () {
  194. t.notOk(cache.get("b"))
  195. t.equal(cache.get("c"), "C")
  196. }, 90)
  197. setTimeout(function () {
  198. t.notOk(cache.get("c"))
  199. t.end()
  200. }, 155)
  201. })
  202. test("individual item can have it's own maxAge", function(t) {
  203. var cache = new LRU({
  204. max: 5,
  205. maxAge: 50
  206. })
  207. cache.set("a", "A", 20)
  208. setTimeout(function () {
  209. t.notOk(cache.get("a"))
  210. t.end()
  211. }, 25)
  212. })
  213. test("individual item can have it's own maxAge > cache's", function(t) {
  214. var cache = new LRU({
  215. max: 5,
  216. maxAge: 20
  217. })
  218. cache.set("a", "A", 50)
  219. setTimeout(function () {
  220. t.equal(cache.get("a"), "A")
  221. t.end()
  222. }, 25)
  223. })
  224. test("disposal function", function(t) {
  225. var disposed = false
  226. var cache = new LRU({
  227. max: 1,
  228. dispose: function (k, n) {
  229. disposed = n
  230. }
  231. })
  232. cache.set(1, 1)
  233. cache.set(2, 2)
  234. t.equal(disposed, 1)
  235. cache.set(3, 3)
  236. t.equal(disposed, 2)
  237. cache.reset()
  238. t.equal(disposed, 3)
  239. t.end()
  240. })
  241. test("disposal function on too big of item", function(t) {
  242. var disposed = false
  243. var cache = new LRU({
  244. max: 1,
  245. length: function (k) {
  246. return k.length
  247. },
  248. dispose: function (k, n) {
  249. disposed = n
  250. }
  251. })
  252. var obj = [ 1, 2 ]
  253. t.equal(disposed, false)
  254. cache.set("obj", obj)
  255. t.equal(disposed, obj)
  256. t.end()
  257. })
  258. test("has()", function(t) {
  259. var cache = new LRU({
  260. max: 1,
  261. maxAge: 10
  262. })
  263. cache.set('foo', 'bar')
  264. t.equal(cache.has('foo'), true)
  265. cache.set('blu', 'baz')
  266. t.equal(cache.has('foo'), false)
  267. t.equal(cache.has('blu'), true)
  268. setTimeout(function() {
  269. t.equal(cache.has('blu'), false)
  270. t.end()
  271. }, 15)
  272. })
  273. test("stale", function(t) {
  274. var cache = new LRU({
  275. maxAge: 10,
  276. stale: true
  277. })
  278. cache.set('foo', 'bar')
  279. t.equal(cache.get('foo'), 'bar')
  280. t.equal(cache.has('foo'), true)
  281. setTimeout(function() {
  282. t.equal(cache.has('foo'), false)
  283. t.equal(cache.get('foo'), 'bar')
  284. t.equal(cache.get('foo'), undefined)
  285. t.end()
  286. }, 15)
  287. })
  288. test("lru update via set", function(t) {
  289. var cache = LRU({ max: 2 });
  290. cache.set('foo', 1);
  291. cache.set('bar', 2);
  292. cache.del('bar');
  293. cache.set('baz', 3);
  294. cache.set('qux', 4);
  295. t.equal(cache.get('foo'), undefined)
  296. t.equal(cache.get('bar'), undefined)
  297. t.equal(cache.get('baz'), 3)
  298. t.equal(cache.get('qux'), 4)
  299. t.end()
  300. })
  301. test("least recently set w/ peek", function (t) {
  302. var cache = new LRU(2)
  303. cache.set("a", "A")
  304. cache.set("b", "B")
  305. t.equal(cache.peek("a"), "A")
  306. cache.set("c", "C")
  307. t.equal(cache.get("c"), "C")
  308. t.equal(cache.get("b"), "B")
  309. t.equal(cache.get("a"), undefined)
  310. t.end()
  311. })
  312. test("pop the least used item", function (t) {
  313. var cache = new LRU(3)
  314. , last
  315. cache.set("a", "A")
  316. cache.set("b", "B")
  317. cache.set("c", "C")
  318. t.equal(cache.length, 3)
  319. t.equal(cache.max, 3)
  320. // Ensure we pop a, c, b
  321. cache.get("b", "B")
  322. last = cache.pop()
  323. t.equal(last.key, "a")
  324. t.equal(last.value, "A")
  325. t.equal(cache.length, 2)
  326. t.equal(cache.max, 3)
  327. last = cache.pop()
  328. t.equal(last.key, "c")
  329. t.equal(last.value, "C")
  330. t.equal(cache.length, 1)
  331. t.equal(cache.max, 3)
  332. last = cache.pop()
  333. t.equal(last.key, "b")
  334. t.equal(last.value, "B")
  335. t.equal(cache.length, 0)
  336. t.equal(cache.max, 3)
  337. last = cache.pop()
  338. t.equal(last, null)
  339. t.equal(cache.length, 0)
  340. t.equal(cache.max, 3)
  341. t.end()
  342. })