sangja
Version:
JavaScript data structures library
285 lines (246 loc) • 10.3 kB
JavaScript
/* eslint-env node, mocha */
const { assert } = require('chai');
const { BinarySearchTree } = require('../src/index');
describe('BinarySearchTree', () => {
describe('Constructor', () => {
it('Fails without new', () => {
assert.throws(() => BinarySearchTree(), TypeError);
});
it('Constructor with iterable', () => {
assert.deepEqual([...new BinarySearchTree([6, 3, 9])], [3, 6, 9]);
});
it('Constructor with key', () => {
const binarySearchTree = new BinarySearchTree({ key: (x => x.id) });
binarySearchTree.add({ id: 22 });
binarySearchTree.add({ id: 33 });
binarySearchTree.add({ id: 11 });
assert.equal(binarySearchTree.pop().id, 11);
assert.equal(binarySearchTree.pop().id, 22);
assert.equal(binarySearchTree.pop().id, 33);
});
it('Constructor with compare', () => {
const bst = new BinarySearchTree({ compare: ((x, y) => y.val - x.val) });
bst.add({ val: 22 });
bst.add({ val: 33 });
bst.add({ val: 11 });
assert.equal(bst.pop().val, 33);
assert.equal(bst.pop().val, 22);
assert.equal(bst.pop().val, 11);
});
it('Constructor with reverse', () => {
const bst = new BinarySearchTree({ reverse: true });
bst.addAll([6, 3, 7, 9, 1]);
assert.deepEqual([...bst], [9, 7, 6, 3, 1]);
});
});
describe('Basic Methods', () => {
it('add', () => {
const binarySearchTree = new BinarySearchTree();
assert.equal(binarySearchTree.size(), 0);
binarySearchTree.add(3);
assert.equal(binarySearchTree.size(), 1);
binarySearchTree.add(6);
assert.equal(binarySearchTree.size(), 2);
binarySearchTree.add(9);
assert.equal(binarySearchTree.size(), 3);
});
it('addAll', () => {
const binarySearchTree = new BinarySearchTree();
assert.equal(binarySearchTree.size(), 0);
binarySearchTree.addAll([3, 6, 9, 2, 8]);
assert.equal(binarySearchTree.size(), 5);
assert.deepEqual([...binarySearchTree], [2, 3, 6, 8, 9]);
});
it('pop', () => {
const binarySearchTree = new BinarySearchTree();
binarySearchTree.add(3);
binarySearchTree.add(6);
binarySearchTree.add(9);
assert.equal(binarySearchTree.size(), 3);
assert.equal(binarySearchTree.pop(), 3);
assert.equal(binarySearchTree.size(), 2);
assert.equal(binarySearchTree.pop(), 6);
assert.equal(binarySearchTree.size(), 1);
assert.equal(binarySearchTree.pop(), 9);
assert.equal(binarySearchTree.size(), 0);
assert.equal(binarySearchTree.pop(), undefined);
assert.equal(binarySearchTree.size(), 0);
});
it('remove', () => {
const binarySearchTree = new BinarySearchTree();
binarySearchTree.addAll([4, 2, 1, 3, 6, 5, 7]);
assert.deepEqual([...binarySearchTree], [1, 2, 3, 4, 5, 6, 7]);
assert.deepEqual([...binarySearchTree.preorder()], [4, 2, 1, 3, 6, 5, 7]);
assert.equal(binarySearchTree.remove(4), 4);
assert.deepEqual([...binarySearchTree], [1, 2, 3, 5, 6, 7]);
assert.equal(binarySearchTree.remove(6), 6);
assert.equal(binarySearchTree.remove(8), undefined);
assert.equal(binarySearchTree.size(), 5);
assert.deepEqual([...binarySearchTree], [1, 2, 3, 5, 7]);
assert.equal(binarySearchTree.remove(2), 2);
assert.deepEqual([...binarySearchTree], [1, 3, 5, 7]);
assert.equal(binarySearchTree.remove(7), 7);
assert.deepEqual([...binarySearchTree], [1, 3, 5]);
assert.equal(binarySearchTree.size(), 3);
assert.equal(binarySearchTree.remove(3), 3);
assert.deepEqual([...binarySearchTree], [1, 5]);
assert.equal(binarySearchTree.remove(1), 1);
assert.deepEqual([...binarySearchTree], [5]);
assert.equal(binarySearchTree.remove(5), 5);
assert.deepEqual([...binarySearchTree], []);
assert.equal(binarySearchTree.size(), 0);
});
it('removeMatch', () => {
const bst = new BinarySearchTree();
bst.addAll([4, 2, 1, 3, 6, 5, 7]);
assert.equal(bst.removeMatch(v => v === 3), 3);
assert.deepEqual([...bst], [1, 2, 4, 5, 6, 7]);
assert.equal(bst.size(), 6);
bst.removeMatch(v => v % 2);
bst.removeMatch(v => v % 2);
bst.removeMatch(v => v % 2); // remove 1, 5, 7
assert.deepEqual([...bst], [2, 4, 6]);
assert.equal(bst.size(), 3);
bst.removeMatch(v => !(v % 2));
bst.removeMatch(v => !(v % 2));
bst.removeMatch(v => !(v % 2)); // remove 2, 4, 6
assert.deepEqual([...bst], []);
assert.equal(bst.size(), 0);
});
it('clear', () => {
const binarySearchTree = new BinarySearchTree();
assert.equal(binarySearchTree.size(), 0);
binarySearchTree.add(3);
binarySearchTree.add(6);
binarySearchTree.add(9);
assert.equal(binarySearchTree.size(), 3);
binarySearchTree.clear();
assert.equal(binarySearchTree.size(), 0);
});
it('find', () => {
const binarySearchTree = new BinarySearchTree();
binarySearchTree.addAll([9, 7, 4, 8, 1]);
assert.equal(binarySearchTree.find(v => v === 3), undefined);
assert.equal(binarySearchTree.find(v => v === 7), 7);
assert.equal(binarySearchTree.size(), 5);
});
it('reversed', () => {
const bst = new BinarySearchTree();
bst.addAll([9, 7, 4, 8, 1]);
assert.deepEqual([...bst], [1, 4, 7, 8, 9]);
assert.deepEqual([...bst.reversed()], [9, 8, 7, 4, 1]);
});
});
describe('Iterator', () => {
it('Iterate without value', () => {
const binarySearchTree = new BinarySearchTree();
assert.deepEqual([...binarySearchTree], []);
assert.deepEqual([...binarySearchTree.inorder()], []);
assert.deepEqual([...binarySearchTree.preorder()], []);
assert.deepEqual([...binarySearchTree.postorder()], []);
assert.deepEqual([...binarySearchTree.breadthFirst()], []);
});
it('Iterate one value', () => {
const binarySearchTree = new BinarySearchTree();
binarySearchTree.add(3);
assert.deepEqual([...binarySearchTree], [3]);
assert.deepEqual([...binarySearchTree.inorder()], [3]);
assert.deepEqual([...binarySearchTree.preorder()], [3]);
assert.deepEqual([...binarySearchTree.postorder()], [3]);
assert.deepEqual([...binarySearchTree.breadthFirst()], [3]);
});
it('Iterate some values', () => {
const binarySearchTree = new BinarySearchTree();
binarySearchTree.add(6);
binarySearchTree.add(3);
binarySearchTree.add(9);
binarySearchTree.add(1);
binarySearchTree.add(4);
assert.deepEqual([...binarySearchTree], [1, 3, 4, 6, 9]); // Default inorder
assert.deepEqual([...binarySearchTree.inorder()], [1, 3, 4, 6, 9]);
assert.deepEqual([...binarySearchTree.preorder()], [6, 3, 1, 4, 9]);
assert.deepEqual([...binarySearchTree.postorder()], [1, 4, 3, 9, 6]);
assert.deepEqual([...binarySearchTree.breadthFirst()], [6, 3, 9, 1, 4]);
});
it('Iterate some values with given function', () => {
const binarySearchTree = new BinarySearchTree();
let arr = [];
const accmulate = (x) => { arr.push(x); };
assert.deepEqual(arr, []);
binarySearchTree.inorder(accmulate);
assert.deepEqual(arr, []);
binarySearchTree.preorder(accmulate);
assert.deepEqual(arr, []);
binarySearchTree.postorder(accmulate);
assert.deepEqual(arr, []);
binarySearchTree.breadthFirst(accmulate);
assert.deepEqual(arr, []);
binarySearchTree.addAll([2, 1, 3]);
binarySearchTree.inorder(accmulate);
assert.deepEqual(arr, [1, 2, 3]);
arr = [];
binarySearchTree.preorder(accmulate);
assert.deepEqual(arr, [2, 1, 3]);
arr = [];
binarySearchTree.postorder(accmulate);
assert.deepEqual(arr, [1, 3, 2]);
arr = [];
binarySearchTree.breadthFirst(accmulate);
assert.deepEqual(arr, [2, 1, 3]);
});
});
describe('Functional tools', () => {
it('forEach', () => {
const bst = new BinarySearchTree();
let acc = 0;
const accmulate = (x) => { acc += x; };
assert.equal(acc, 0);
bst.forEach(accmulate);
assert.equal(acc, 0);
bst.addAll([11, 22, 33]);
bst.forEach(accmulate);
assert.equal(acc, 66);
});
it('map', () => {
const bst = new BinarySearchTree();
assert.deepEqual([...bst.map(x => x + 3)], []);
bst.addAll([11, 22, 33]);
assert.deepEqual([...bst.map(x => x + 3)], [14, 25, 36]);
assert.deepEqual([...bst], [11, 22, 33]);
});
it('flatMap', () => {
const bst = new BinarySearchTree();
assert.deepEqual([...bst.flatMap(x => [x, x + 3])], []);
bst.addAll([11, 22, 33]);
assert.deepEqual([...bst.flatMap(x => [x, x + 3])], [11, 14, 22, 25, 33, 36]);
assert.deepEqual([...bst], [11, 22, 33]);
});
it('filter', () => {
const bst = new BinarySearchTree();
assert.deepEqual([...bst.filter(x => x % 2)], []);
bst.addAll([1, 2, 3, 4, 5]);
assert.deepEqual([...bst.filter(x => x % 2)], [1, 3, 5]);
assert.deepEqual([...bst], [1, 2, 3, 4, 5]);
});
});
describe('Checking tools', () => {
it('some', () => {
assert.equal(new BinarySearchTree().some(x => x > 5), false);
assert.equal(new BinarySearchTree([1, 2, 3]).some(x => x > 5), false);
assert.equal(new BinarySearchTree([4, 5, 6]).some(x => x > 5), true);
assert.equal(new BinarySearchTree([7, 8, 9]).some(x => x > 5), true);
});
it('every', () => {
assert.equal(new BinarySearchTree().every(x => x > 5), true);
assert.equal(new BinarySearchTree([1, 2, 3]).every(x => x > 5), false);
assert.equal(new BinarySearchTree([4, 5, 6]).every(x => x > 5), false);
assert.equal(new BinarySearchTree([7, 8, 9]).every(x => x > 5), true);
});
it('includes', () => {
assert.equal(new BinarySearchTree().includes(5), false);
assert.equal(new BinarySearchTree([1, 2, 3]).includes(5), false);
assert.equal(new BinarySearchTree([4, 5, 6]).includes(5), true);
assert.equal(new BinarySearchTree([5]).includes(5), true);
});
});
});