var chai = require('chai') var sinon = require('sinon') var expect = chai.expect chai.use(require('sinon-chai')) var TtlSet = require('../../lib/util/ttlset') describe('TtlSet', function() { it('should emit "drop" for entries with expired TTL', function(done) { var ttlset = new TtlSet(50) var spy = sinon.spy() ttlset.on('drop', spy) ttlset.bump(1, Date.now()) ttlset.bump(2, Date.now() + 100) ttlset.bump(3, Date.now() + 200) ttlset.bump(4, Date.now() + 1000) setTimeout(function() { expect(spy).to.have.been.calledThrice expect(spy).to.have.been.calledWith(1) expect(spy).to.have.been.calledWith(2) expect(spy).to.have.been.calledWith(3) expect(ttlset.head).to.equal(ttlset.tail) ttlset.stop() done() }, 300) }) describe('bump', function() { it('should emit "insert" for new entries', function(done) { var ttlset = new TtlSet(50) var spy = sinon.spy() ttlset.on('insert', spy) ttlset.bump(1) ttlset.bump(2) ttlset.bump(3) expect(spy).to.have.been.calledThrice expect(spy).to.have.been.calledWith(1) expect(spy).to.have.been.calledWith(2) expect(spy).to.have.been.calledWith(3) ttlset.stop() done() }) it('should not emit "insert" for new entries if SILENT', function(done) { var ttlset = new TtlSet(50) var spy = sinon.spy() ttlset.on('insert', spy) ttlset.bump(1, Date.now(), TtlSet.SILENT) ttlset.bump(2, Date.now()) ttlset.bump(3, Date.now(), TtlSet.SILENT) expect(spy).to.have.been.calledOnce expect(spy).to.have.been.calledWith(2) ttlset.stop() done() }) it('should create an item for the value if none exists', function(done) { var ttlset = new TtlSet(5000) ttlset.bump(5) expect(ttlset.head).to.equal(ttlset.tail) expect(ttlset.head.value).to.equal(5) done() }) it('should make the item the new tail', function(done) { var ttlset = new TtlSet(5000) ttlset.bump(5) expect(ttlset.tail.value).to.equal(5) ttlset.bump(6) expect(ttlset.tail.value).to.equal(6) done() }) it('should set head if none exists', function(done) { var ttlset = new TtlSet(5000) expect(ttlset.head).to.be.null ttlset.bump(5) expect(ttlset.head.value).to.equal(5) ttlset.bump(6) expect(ttlset.head.value).to.equal(5) done() }) it('should take old item out and make it the tail', function(done) { var ttlset = new TtlSet(5000) ttlset.bump(1) expect(ttlset.head.value).to.equal(1) expect(ttlset.tail.value).to.equal(1) expect(ttlset.head.next).to.be.null expect(ttlset.head.prev).to.be.null expect(ttlset.tail.next).to.be.null expect(ttlset.tail.prev).to.be.null ttlset.bump(2) expect(ttlset.head.value).to.equal(1) expect(ttlset.tail.value).to.equal(2) expect(ttlset.head.next).to.equal(ttlset.tail) expect(ttlset.head.prev).to.be.null expect(ttlset.tail.next).to.be.null expect(ttlset.tail.prev).to.equal(ttlset.head) ttlset.bump(1) expect(ttlset.head.value).to.equal(2) expect(ttlset.tail.value).to.equal(1) expect(ttlset.head.next).to.equal(ttlset.tail) expect(ttlset.head.prev).to.be.null expect(ttlset.tail.next).to.be.null expect(ttlset.tail.prev).to.equal(ttlset.head) ttlset.bump(1) expect(ttlset.head.value).to.equal(2) expect(ttlset.tail.value).to.equal(1) expect(ttlset.head.next).to.equal(ttlset.tail) expect(ttlset.head.prev).to.be.null expect(ttlset.tail.next).to.be.null expect(ttlset.tail.prev).to.equal(ttlset.head) done() }) }) describe('drop', function() { it('should emit "drop" for the dropped entry', function(done) { var ttlset = new TtlSet(50) var spy = sinon.spy() ttlset.on('drop', spy) ttlset.bump(1) ttlset.bump(2) ttlset.bump(3) ttlset.drop(1) ttlset.drop(3) expect(spy).to.have.been.calledTwice expect(spy).to.have.been.calledWith(1) expect(spy).to.have.been.calledWith(3) ttlset.stop() done() }) it('should not emit "drop" for the dropped entry if SILENT', function(done) { var ttlset = new TtlSet(50) var spy = sinon.spy() ttlset.on('drop', spy) ttlset.bump(1) ttlset.bump(2) ttlset.bump(3) ttlset.drop(1, TtlSet.SILENT) ttlset.drop(3) expect(spy).to.have.been.calledOnce expect(spy).to.have.been.calledWith(3) ttlset.stop() done() }) it('should silently ignore unknown values', function(done) { var ttlset = new TtlSet(5000) ttlset.drop(5) done() }) it('should remove the value from the set', function(done) { var ttlset = new TtlSet(5000) ttlset.bump(5) ttlset.drop(5) expect(ttlset.tail).to.be.null expect(ttlset.head).to.be.null ttlset.bump(1) ttlset.bump(2) ttlset.drop(1) expect(ttlset.tail).to.equal(ttlset.head) expect(ttlset.tail.value).to.equal(2) ttlset.bump(3) ttlset.drop(3) expect(ttlset.tail).to.equal(ttlset.head) expect(ttlset.tail.value).to.equal(2) done() }) }) })