dag.test.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Graph } from './dag';
  2. describe('Directed acyclic graph', () => {
  3. describe('Given a graph with nodes with different links in between them', () => {
  4. const dag = new Graph();
  5. const nodeA = dag.createNode('A');
  6. const nodeB = dag.createNode('B');
  7. const nodeC = dag.createNode('C');
  8. const nodeD = dag.createNode('D');
  9. const nodeE = dag.createNode('E');
  10. const nodeF = dag.createNode('F');
  11. const nodeG = dag.createNode('G');
  12. const nodeH = dag.createNode('H');
  13. const nodeI = dag.createNode('I');
  14. dag.link([nodeB, nodeC, nodeD, nodeE, nodeF, nodeG, nodeH], nodeA);
  15. dag.link([nodeC, nodeD, nodeE, nodeF, nodeI], nodeB);
  16. dag.link([nodeD, nodeE, nodeF, nodeG], nodeC);
  17. dag.link([nodeE, nodeF], nodeD);
  18. dag.link([nodeF, nodeG], nodeE);
  19. //printGraph(dag);
  20. it('nodes in graph should have expected edges', () => {
  21. expect(nodeA.inputEdges).toHaveLength(7);
  22. expect(nodeA.outputEdges).toHaveLength(0);
  23. expect(nodeA.edges).toHaveLength(7);
  24. expect(nodeB.inputEdges).toHaveLength(5);
  25. expect(nodeB.outputEdges).toHaveLength(1);
  26. expect(nodeB.edges).toHaveLength(6);
  27. expect(nodeC.inputEdges).toHaveLength(4);
  28. expect(nodeC.outputEdges).toHaveLength(2);
  29. expect(nodeC.edges).toHaveLength(6);
  30. expect(nodeD.inputEdges).toHaveLength(2);
  31. expect(nodeD.outputEdges).toHaveLength(3);
  32. expect(nodeD.edges).toHaveLength(5);
  33. expect(nodeE.inputEdges).toHaveLength(2);
  34. expect(nodeE.outputEdges).toHaveLength(4);
  35. expect(nodeE.edges).toHaveLength(6);
  36. expect(nodeF.inputEdges).toHaveLength(0);
  37. expect(nodeF.outputEdges).toHaveLength(5);
  38. expect(nodeF.edges).toHaveLength(5);
  39. expect(nodeG.inputEdges).toHaveLength(0);
  40. expect(nodeG.outputEdges).toHaveLength(3);
  41. expect(nodeG.edges).toHaveLength(3);
  42. expect(nodeH.inputEdges).toHaveLength(0);
  43. expect(nodeH.outputEdges).toHaveLength(1);
  44. expect(nodeH.edges).toHaveLength(1);
  45. expect(nodeI.inputEdges).toHaveLength(0);
  46. expect(nodeI.outputEdges).toHaveLength(1);
  47. expect(nodeI.edges).toHaveLength(1);
  48. expect(nodeA.getEdgeFrom(nodeB)).not.toBeUndefined();
  49. expect(nodeB.getEdgeTo(nodeA)).not.toBeUndefined();
  50. });
  51. it('when optimizing input edges for node A should return node B and H', () => {
  52. const actual = nodeA.getOptimizedInputEdges().map((e) => e.inputNode);
  53. expect(actual).toHaveLength(2);
  54. expect(actual).toEqual(expect.arrayContaining([nodeB, nodeH]));
  55. });
  56. it('when optimizing input edges for node B should return node C', () => {
  57. const actual = nodeB.getOptimizedInputEdges().map((e) => e.inputNode);
  58. expect(actual).toHaveLength(2);
  59. expect(actual).toEqual(expect.arrayContaining([nodeC, nodeI]));
  60. });
  61. it('when optimizing input edges for node C should return node D', () => {
  62. const actual = nodeC.getOptimizedInputEdges().map((e) => e.inputNode);
  63. expect(actual).toHaveLength(1);
  64. expect(actual).toEqual(expect.arrayContaining([nodeD]));
  65. });
  66. it('when optimizing input edges for node D should return node E', () => {
  67. const actual = nodeD.getOptimizedInputEdges().map((e) => e.inputNode);
  68. expect(actual).toHaveLength(1);
  69. expect(actual).toEqual(expect.arrayContaining([nodeE]));
  70. });
  71. it('when optimizing input edges for node E should return node F and G', () => {
  72. const actual = nodeE.getOptimizedInputEdges().map((e) => e.inputNode);
  73. expect(actual).toHaveLength(2);
  74. expect(actual).toEqual(expect.arrayContaining([nodeF, nodeG]));
  75. });
  76. it('when optimizing input edges for node F should return zero nodes', () => {
  77. const actual = nodeF.getOptimizedInputEdges();
  78. expect(actual).toHaveLength(0);
  79. });
  80. it('when optimizing input edges for node G should return zero nodes', () => {
  81. const actual = nodeG.getOptimizedInputEdges();
  82. expect(actual).toHaveLength(0);
  83. });
  84. it('when optimizing input edges for node H should return zero nodes', () => {
  85. const actual = nodeH.getOptimizedInputEdges();
  86. expect(actual).toHaveLength(0);
  87. });
  88. it('when linking non-existing input node with existing output node should throw error', () => {
  89. expect(() => {
  90. dag.link('non-existing', 'A');
  91. }).toThrowError("cannot link input node named non-existing since it doesn't exist in graph");
  92. });
  93. it('when linking existing input node with non-existing output node should throw error', () => {
  94. expect(() => {
  95. dag.link('A', 'non-existing');
  96. }).toThrowError("cannot link output node named non-existing since it doesn't exist in graph");
  97. });
  98. });
  99. });