import { assert, expect } from 'chai'; import { describe } from 'mocha'; import { compareObjs } from './helpers/compare-objs.js'; import { LlRbTree } from '../src/index.js'; import { insert1to7Objs } from './helpers/insert-1-to-7-objs.js'; import { isBlackHeightCorrect, isNoRedEdge } from './helpers/constraints.js'; import { vals1to7Objs } from './helpers/vals-1-to-7-objs.js'; import { countValues } from './helpers/count-values.js'; describe('remove', function() { it('it should remove items in the tree based on value', function() { { const tree = new LlRbTree(compareObjs); expect(tree.remove({ val: 112 })).to.not.throw; insert1to7Objs(tree); tree.remove({ val: 2 }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([1,3,3,4,5,6,7]); tree.remove({ val: 5, name: 'apple pear' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([1,3,3,4,6,7]); expect(tree.remove({ val: 112 })).to.not.throw; tree.remove({ val: 1, name: 'apple pear' }); tree.remove({ val: 3, name: 'apple pear' }); tree.remove({ val: 3, name: 'apple pear' }); tree.remove({ val: 4, name: 'apple pear' }); tree.remove({ val: 6, name: 'apple pear' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([7]); tree.remove({ val: 7, name: 'apple pear' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([]); tree.insert({ val: 7, name: 'apple pear' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([7]); tree.remove({ val: 7, name: 'pear apple' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql([]); expect(tree.root).to.be.undefined; } }); it('it should remove multiple items in the tree based if requested', function() { const tree = new LlRbTree(compareObjs); let vals: number[]; insert1to7Objs(tree); const vals1to7Objs2 = vals1to7Objs.slice(); vals1to7Objs2.splice(1,1); for (let val of vals1to7Objs2) { tree.insert(val); } tree.insert({ val: 3.5 }); //tree.insertMulti([1,1,2,2,3,3,3,3.5,4,4,5,5,6,6,7,7].map(v => ({ val: v }))); // treeToString(tree, nodeObjToString); assert(isBlackHeightCorrect(tree), 'tree does not pass \'black height\' constraint'); assert(isNoRedEdge(tree), 'tree does not pass \'no red edge\' constraint') vals = tree.toArrayInOrder().map(o => o.val); expect(vals).to.eql([1,1,2,2,3,3,3,3.5,4,4,5,5,6,6,7,7]); tree.remove({ val: 3 }, true); // treeToString(tree, nodeObjToString); vals = tree.toArrayInOrder().map(o => o.val); expect(vals).to.eql([1,1,2,2,3.5,4,4,5,5,6,6,7,7]); }); it('it should remove multiple items in the tree based if requested', function() { const vals = [1,2,3,3,3,3,3,4,5,6].map(v => ({ val: v, name: v.toString() })); const tree = new LlRbTree(compareObjs, true, vals); // const vCount = countValues(tree); expect(tree.toArrayInOrder().map(o => o.val)).to.eql( [1,2,3,3,3,3,3,4,5,6] ); tree.remove({ val: 3, name: 'apple' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql( [1,2,3,3,3,3,4,5,6] ); tree.remove({ val: 3, name: 'pear' }); expect(tree.toArrayInOrder().map(o => o.val)).to.eql( [1,2,3,3,3,4,5,6] ); tree.remove( { val: 3, name: 'guava' }, false, (a,b) => (a.val - b.val === 0) && (a.name === b.name) ); expect(tree.toArrayInOrder().map(o => o.val)).to.eql( [1,2,3,3,3,4,5,6] // should not have removed ); tree.remove( { val: 3, name: '322' }, false, (a,b) => (a.val - b.val === 0) && (a.name === b.name) ); expect(tree.toArrayInOrder().map(o => o.val)).to.eql( [1,2,3,3,3,4,5,6] ); }); });