bitlist
Version:
A bit-set/bit-array/bit-vector implementation which allows inserting and removing values
193 lines (174 loc) • 6.11 kB
JavaScript
/*globals it, describe, afterEach */
var BitList = require('../index');
var expect = require('expect.js');
describe('BitList', function () {
describe('#initialize', function () {
it('adds provided data', function () {
var list = new BitList([ 1, 0, 1, 0 ]);
expect(list.size).to.be(4);
});
it('handles no data', function () {
var list = new BitList();
expect(list.size).to.be(0);
});
});
describe('#get', function () {
it('reads values from the list', function () {
var list = new BitList([ 1, 0, 1 ]);
expect(list.get(0)).to.be(true);
expect(list.get(1)).to.be(false);
expect(list.get(2)).to.be(true);
});
});
describe('#set', function () {
it('can set values', function () {
var list = new BitList([ 1, 1, 0, 0 ]);
list.set(0, 1);
list.set(1, 0);
list.set(2, 1);
list.set(3, 0);
expectValues(list, [1, 0, 1, 0]);
});
it('ignores out-of-bounds indexes', function () {
var list = new BitList([ 1, 1, 1 ]);
list.set(3, 0);
list.set(-1, 0);
expectValues(list, [1, 1, 1]);
});
});
describe('#insert', function () {
it('inserts values at the start of the list', function () {
var list = new BitList([ 1, 1, 1 ]);
list.insert(0, 0);
expectValues(list, [0, 1, 1, 1]);
});
it('inserts values at the end of the list', function () {
var list = new BitList([ 1, 1, 1 ]);
list.insert(3, 0);
expectValues(list, [1, 1, 1, 0]);
});
it('inserts values in the middle of the list', function () {
var list = new BitList([ 1, 1, 1 ]);
list.insert(1, 0);
expectValues(list, [1, 0, 1, 1]);
});
it('ignores out-of-bounds indexes', function () {
var list = new BitList([ 1, 1, 1 ]);
list.insert(5, 0);
list.insert(-1, 0);
expectValues(list, [1, 1, 1]);
});
});
describe('#remove', function () {
it('removes values from the start of the list', function (){
var list = new BitList([ 1, 0, 1, 0, 1]);
list.remove(0);
expectValues(list, [0, 1, 0, 1]);
});
it('removes values from the end of the list', function (){
var list = new BitList([ 1, 0, 1, 0, 1]);
list.remove(4);
expectValues(list, [1, 0, 1, 0]);
});
it('removes values from the middle of the list', function (){
var list = new BitList([ 1, 0, 1, 0, 1]);
list.remove(2);
expectValues(list, [1, 0, 0, 1]);
});
it('ignores out-of-bounds indexes', function () {
var list = new BitList([ 1, 1, 1 ]);
list.remove(5);
list.remove(-1);
expectValues(list, [1, 1, 1]);
});
});
describe('#applyAnd', function () {
it('applies lists using AND', function () {
var list1 = new BitList([ 1, 1, 1, 1, 0, 0, 0, 0 ]);
var list2 = new BitList([ 1, 1, 0, 0, 1, 1, 0, 0 ]);
var list3 = new BitList([ 1, 0, 1, 0, 1, 0, 1, 0 ]);
list1.applyAnd([list2, list3]);
expectValues(list1, [ 1, 0, 0, 0, 0, 0, 0, 0 ]);
});
});
describe('#clearRange', function () {
it('will clear the given range of bits', function () {
var list = new BitList([ 1, 1, 1, 1, 1, 1, 1, 1 ]);
list.clearRange(2, 4);
expectValues(list, [ 1, 1, 0, 0, 0, 1, 1, 1 ]);
});
});
describe('#clone', function () {
it('creates a copy of a BitList', function () {
var list1 = new BitList([ 1, 0, 1 ]);
var list2 = list1.clone();
list1.set(1, 1);
expectValues(list2, [1, 0, 1]); // checking that the data is separate
});
});
describe('#getIndexes', function () {
it('gets the indexes of matching values', function () {
var list = new BitList([ 1, 0, 1, 1, 0, 0, 1 ]);
expect(list.getIndexes(true)).to.eql([0, 2, 3, 6]);
expect(list.getIndexes(false)).to.eql([1, 4, 5]);
});
});
describe('#countValuesInRange', function () {
it('counts the matching values in a given range', function () {
var list = new BitList([ 1, 1, 1, 0, 0, 1, 0, 1, 0 ]);
expect(list.countValuesInRange(true)).to.be(5);
expect(list.countValuesInRange(false)).to.be(4);
expect(list.countValuesInRange(true, 1, 5)).to.be(3);
})
});
describe('#combine', function () {
var list1 = new BitList([ 1, 1, 0, 0 ]);
var list2 = new BitList([ 1, 0, 1, 0 ]);
expectValues(BitList.combine([list1, list2]), [1, 0, 0, 0]);
});
describe('BitLists longer than one word', function () {
describe('#insert', function () {
it('will expand the data object', function () {
var list = new BitList(arrayOfBools(32, true));
// list = 11111111111111111111111111111111
list.insert(0, 0);
// list = 00000000000000000000000000000001 11111111111111111111111111111110
expect(list.get(32)).to.be(true);
expect(list.get(0)).to.be(false);
});
});
describe('#remove', function () {
it('will shrink the data object', function () {
var list = new BitList(arrayOfBools(32, true).concat([false, true]));
// list = 00000000000000000000000000000010 11111111111111111111111111111111
list.remove(0);
// list = 00000000000000000000000000000001 01111111111111111111111111111111
expect(list.get(31)).to.be(false);
list.remove(0);
// list = 10111111111111111111111111111111
expect(list.get(31)).to.be(true);
expect(list.get(30)).to.be(false);
});
});
describe('#countValuesInRange', function () {
it('works across buffer sizes', function () {
var list = new BitList(arrayOfBools(96, true));
expect(list.countValuesInRange(true)).to.be(96);
});
});
});
});
function arrayOfBools(length, value) {
var arr = new Array(length);
var i;
for (i = 0; i < length; ++i) {
arr[i] = !!value;
}
return arr;
}
function expectValues(list, values) {
expect(list.size).to.be(values.length);
for (var i = 0; i < values.length; ++i) {
expect(list.get(i)).to.be(!!values[i]);
}
}