|
| 1 | +import test from 'ava'; |
| 2 | +import { empty, set } from '../../src'; |
| 3 | +import { RedBlackTreeStructure, isNone } from '../../src/internals'; |
| 4 | + |
| 5 | +let tree: RedBlackTreeStructure<string, User>; |
| 6 | + |
| 7 | +type User = { |
| 8 | + name: string, |
| 9 | + id: string |
| 10 | +}; |
| 11 | + |
| 12 | +const testUser1: User = { |
| 13 | + name: 'Luke', |
| 14 | + id: '298' |
| 15 | +}; |
| 16 | + |
| 17 | +const testUser2: User = { |
| 18 | + name: 'Leia', |
| 19 | + id: '299' |
| 20 | +}; |
| 21 | + |
| 22 | +const testUser3: User = { |
| 23 | + name: 'Han', |
| 24 | + id: '300' |
| 25 | +}; |
| 26 | + |
| 27 | +const testUser4: User = { |
| 28 | + name: 'Chewbacca', |
| 29 | + id: '301' |
| 30 | +}; |
| 31 | + |
| 32 | +test.beforeEach(() => { |
| 33 | + tree = empty<string, User>((a, b) => a < b ? -1 : (a > b ? 1 : 0), true); |
| 34 | +}); |
| 35 | + |
| 36 | +test('should keep the tree balanced', t => { |
| 37 | + t.plan(13); |
| 38 | + |
| 39 | + // Set 298 and make sure it's the root and no other elements are there |
| 40 | + tree = set(testUser1.id, testUser1, tree); |
| 41 | + t.is(tree._root.key, testUser1.id); |
| 42 | + t.is(isNone(tree._root._left), true); |
| 43 | + t.is(isNone(tree._root._right), true); |
| 44 | + |
| 45 | + // Set 299, no rebalance. 299 should be on the right |
| 46 | + tree = set(testUser2.id, testUser2, tree); |
| 47 | + t.is(tree._root.key, testUser1.id); |
| 48 | + t.is(isNone(tree._root._left), true); |
| 49 | + t.is(tree._root._right.key, testUser2.id); |
| 50 | + |
| 51 | + // Set 300, this should cause a rebalance that puts 299 at the top |
| 52 | + tree = set(testUser3.id, testUser3, tree); |
| 53 | + t.is(tree._root.key, testUser2.id); // 299 is root |
| 54 | + t.is(tree._root._left.key, testUser1.id); // 298 goes left |
| 55 | + t.is(tree._root._right.key, testUser3.id); // 300 goes right |
| 56 | + |
| 57 | + // Set 301, no rebalance - will go on the right of 300 |
| 58 | + tree = set(testUser4.id, testUser4, tree); |
| 59 | + t.is(tree._root.key, testUser2.id); // 299 is root |
| 60 | + t.is(tree._root._left.key, testUser1.id); // 298 goes left |
| 61 | + t.is(tree._root._right.key, testUser3.id); // 300 goes right |
| 62 | + t.is(tree._root._right._right.key, testUser4.id); // 300 goes right |
| 63 | +}); |
| 64 | + |
| 65 | +test('should keep the tree balanced - many items synchronously', t => { |
| 66 | + // Add accounts to the tree which will trigger lots of rebalancing |
| 67 | + for (let i = 0; i < 1000; i++) { |
| 68 | + const user: User = { |
| 69 | + name: i.toString(), |
| 70 | + id: i.toString() |
| 71 | + }; |
| 72 | + tree = set(user.id, user, tree); |
| 73 | + } |
| 74 | + |
| 75 | + t.is(tree._root.key, '487'); |
| 76 | + t.is(tree._size, 1000); |
| 77 | +}); |
0 commit comments