selectNearestFrame.spec.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {FlamegraphFrame} from '../flamegraphFrame';
  2. import {selectNearestFrame} from './selectNearestFrame';
  3. function createFlamegraphFrame(frame?: Partial<FlamegraphFrame>) {
  4. const {depth = 0, parent = null, children = []} = frame ?? {};
  5. return {
  6. depth,
  7. parent,
  8. children,
  9. } as FlamegraphFrame;
  10. }
  11. function addChild(frame: FlamegraphFrame) {
  12. const child = createFlamegraphFrame({
  13. parent: frame,
  14. depth: frame.depth + 1,
  15. children: [],
  16. });
  17. frame.children.push(child);
  18. return child;
  19. }
  20. function addChildrenToDepth(frame: FlamegraphFrame, n: number) {
  21. let node = frame;
  22. Array.from(Array(n)).forEach(() => {
  23. node = addChild(node);
  24. });
  25. return node;
  26. }
  27. describe('selectNearestFrame', () => {
  28. it('selects a first child frame when walking down', () => {
  29. const root = createFlamegraphFrame();
  30. const firstChild = addChild(root);
  31. const next = selectNearestFrame(root as any, 'down');
  32. expect(next).toBe(firstChild);
  33. });
  34. it('selects parent when walking up', () => {
  35. const root = createFlamegraphFrame();
  36. const firstChild = addChild(root);
  37. const next = selectNearestFrame(firstChild as any, 'up');
  38. expect(next).toBe(root);
  39. });
  40. it('selects nearest right node with same target depth', () => {
  41. const root = createFlamegraphFrame();
  42. const leftGrandChild = addChildrenToDepth(root, 2);
  43. const rightGrandChild = addChildrenToDepth(root, 2);
  44. const next = selectNearestFrame(leftGrandChild as any, 'right');
  45. expect(next).toBe(rightGrandChild);
  46. expect(next!.depth).toBe(rightGrandChild.depth);
  47. });
  48. it('selects nearest right node to its max depth', () => {
  49. const root = createFlamegraphFrame();
  50. const leftGrandChild = addChildrenToDepth(root, 4);
  51. const rightGrandChild = addChildrenToDepth(root, 2);
  52. const next = selectNearestFrame(leftGrandChild as any, 'right');
  53. expect(next).toBe(rightGrandChild);
  54. expect(next!.depth).not.toBe(leftGrandChild.depth);
  55. });
  56. it('selects nearest left node with same target depth', () => {
  57. const root = createFlamegraphFrame();
  58. const leftGrandChild = addChildrenToDepth(root, 2);
  59. const rightGrandChild = addChildrenToDepth(root, 2);
  60. const next = selectNearestFrame(rightGrandChild as any, 'left');
  61. expect(next).toBe(leftGrandChild);
  62. expect(next!.depth).toBe(rightGrandChild.depth);
  63. });
  64. it('selects nearest left node to its max depth', () => {
  65. const root = createFlamegraphFrame();
  66. const leftGrandChild = addChildrenToDepth(root, 2);
  67. const rightGrandChild = addChildrenToDepth(root, 4);
  68. const next = selectNearestFrame(rightGrandChild as any, 'left');
  69. expect(next).toBe(leftGrandChild);
  70. expect(next!.depth).not.toBe(rightGrandChild.depth);
  71. });
  72. it('returns current node when moving up from root', () => {
  73. const root = createFlamegraphFrame();
  74. const next = selectNearestFrame(root as any, 'up');
  75. expect(next).toBe(root);
  76. });
  77. it('returns current node when at max depth at bottom boundary and no adjacent stack', () => {
  78. const root = createFlamegraphFrame();
  79. const grandChild = addChildrenToDepth(root, 2);
  80. const next = selectNearestFrame(grandChild as any, 'down');
  81. expect(next).toBe(grandChild);
  82. });
  83. it('moves to top of next stack when moving down at bottom boundary', () => {
  84. const root = createFlamegraphFrame();
  85. const leftGrandChild = addChildrenToDepth(root, 2);
  86. const rightGrandChild = addChildrenToDepth(root, 2);
  87. const next = selectNearestFrame(leftGrandChild as any, 'down');
  88. expect(next).toBe(rightGrandChild.parent);
  89. });
  90. });