UNPKG

sangja

Version:

JavaScript data structures library

285 lines (246 loc) 10.3 kB
/* 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); }); }); });