priorityqueuejs
Version:
a simple priority queue data structure
225 lines (193 loc) • 6.75 kB
JavaScript
var expect = require('expect.js');
var PriorityQueue = require('..')
describe('PriorityQueue()', function() {
it('returns an new PriorityQueue', function() {
expect(new PriorityQueue()).to.be.a(PriorityQueue);
});
it('accepts a comparator function', function() {
var queue = new PriorityQueue(function(a, b) {
return a - b;
});
expect(queue).to.be.a(PriorityQueue);
});
describe('.DEFAULT_COMPARATOR()', function() {
context('given strings', function() {
it('returns a negative number when a < b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR('jano', 'valentina')).to.be.
below(0);
});
it('returns 0 number when a == b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR('jano', 'jano')).to.be(0);
});
it('returns a positive number when a > b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR('jano', 'fran')).to.be.
above(0);
});
});
context('given numbers', function() {
it('returns a negative number when a < b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR(10, 1000)).to.be.below(0);
});
it('returns 0 number when a == b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR(10, 10)).to.be(0);
});
it('returns a positive number when a > b', function() {
expect(PriorityQueue.DEFAULT_COMPARATOR(10, 1)).to.be.above(0);
});
it('works with `Number` objects', function() {
var a = Number(10)
var b = Number(1000)
expect(PriorityQueue.DEFAULT_COMPARATOR(a, b)).to.be.below(0);
});
});
});
describe('#isEmpty()', function() {
it('returns true when the queue is empty', function() {
var queue = new PriorityQueue();
expect(queue.isEmpty()).to.be(true);
});
it('returns false when the queue is not empty', function() {
var queue = new PriorityQueue();
queue.enq('jano');
expect(queue.isEmpty()).to.be(false);
});
});
describe('#peek()', function() {
it('fails when the queue is empty', function() {
var queue = new PriorityQueue();
expect(function() {
queue.peek();
}).to.throwException('PriorityQueue is empty');
});
it('returns the top element of the queue', function() {
var queue = new PriorityQueue();
queue.enq('jano');
queue.enq('valentina');
queue.enq('zombie');
queue.enq('fran');
queue.enq('albert');
queue.enq('albert');
queue.enq('frank');
expect(queue.peek()).to.be('zombie');
});
});
describe('#deq()', function() {
it('fails when the queue is empty', function() {
var queue = new PriorityQueue();
expect(function() {
queue.deq();
}).to.throwException('PriorityQueue is empty');
});
it('dequeues the top element of the queue', function() {
var queue = new PriorityQueue();
queue.enq('jano');
queue.enq('valentina');
queue.enq('zombie');
queue.enq('fran');
queue.enq('albert');
queue.enq('albert');
queue.enq('frank');
queue.enq('jano');
queue.enq('valentina');
queue.enq('zombie');
expect(queue.deq()).to.be('zombie');
expect(queue.deq()).to.be('zombie');
expect(queue.deq()).to.be('valentina');
expect(queue.deq()).to.be('valentina');
expect(queue.deq()).to.be('jano');
expect(queue.deq()).to.be('jano');
expect(queue.deq()).to.be('frank');
expect(queue.deq()).to.be('fran');
expect(queue.deq()).to.be('albert');
expect(queue.deq()).to.be('albert');
expect(queue.isEmpty()).to.be(true);
});
it('not fails with only one element', function() {
var queue = new PriorityQueue();
queue.enq('jano');
expect(queue.deq()).to.be('jano');
expect(queue.size()).to.be(0);
});
it('works with custom comparators', function() {
var queue = new PriorityQueue(function(a, b) {
return b.priority - a.priority;
});
queue.enq({ priority: 100 });
queue.enq({ priority: -1 });
queue.enq({ priority: 0 });
queue.enq({ priority: 5 });
expect(queue.deq()).to.be.eql({ priority: -1 });
expect(queue.deq()).to.be.eql({ priority: 0 });
expect(queue.deq()).to.be.eql({ priority: 5 });
expect(queue.deq()).to.be.eql({ priority: 100 });
expect(queue.isEmpty()).to.be(true);
});
});
describe('#enq()', function() {
it('enqueues an element at the end of the queue', function() {
var queue = new PriorityQueue();
queue.enq('jano');
queue.enq('valentina');
queue.enq('fran');
expect(queue.peek()).to.be('valentina');
expect(queue.size()).to.be(3);
});
it('returns the new size of the queue', function() {
var queue = new PriorityQueue();
expect(queue.enq('jano')).to.be(1);
});
it('works with custom comparators', function() {
var queue = new PriorityQueue(function(a, b) {
return b.priority - a.priority;
});
queue.enq({ priority: 100 });
queue.enq({ priority: -1 });
queue.enq({ priority: 0 });
queue.enq({ priority: 5 });
expect(queue.peek()).to.be.eql({ priority: -1 });
expect(queue.size()).to.be(4);
});
});
describe('#size()', function() {
it('returns 0 when the queue is empty', function() {
var queue = new PriorityQueue();
expect(queue.size()).to.be(0);
});
it('returns the size of the queue', function() {
var queue = new PriorityQueue();
queue.enq('jano');
queue.enq('valentina');
expect(queue.size()).to.be(2);
});
});
describe('#forEach()', function() {
it('iterates over all queue elements', function () {
var queue = new PriorityQueue();
queue.enq('a');
queue.enq('b');
var iteration = [];
queue.forEach(function(element, index) {
iteration.push([element, index]);
});
expect(iteration.length).to.be(2);
expect(iteration[0][0]).to.be.eql('b');
expect(iteration[0][1]).to.be.eql(0);
expect(iteration[1][0]).to.be.eql('a');
expect(iteration[1][1]).to.be.eql(1);
});
});
describe('when there are elements with the same priority', function() {
it('retains the queue behavior', function () {
var queue = new PriorityQueue(function (a, b) { return b.pri - a.pri; });
var a = { pri: 1, val: 1 }
var b = { pri: 1, val: 2 }
var c = { pri: 1, val: 3 }
queue.enq(a);
queue.enq(b);
queue.enq(c);
expect(queue.deq()).to.be(a);
expect(queue.deq()).to.be(b);
expect(queue.deq()).to.be(c);
});
});
});