PriorityQueue.test.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import { PriorityQueue } from '../src/utilities/PriorityQueue.js';
  2. const nextFrame = () => new Promise( resolve => requestAnimationFrame( resolve ) );
  3. const nextTick = () => new Promise( resolve => process.nextTick( resolve ) );
  4. describe( 'PriorityQueue', () => {
  5. it( 'should run jobs automatically in the correct order.', async () => {
  6. const queue = new PriorityQueue();
  7. queue.maxJobs = 6;
  8. queue.priorityCallback = item => item.priority;
  9. queue.add( { priority : 6 }, () => new Promise( () => {} ) );
  10. queue.add( { priority : 3 }, () => new Promise( () => {} ) );
  11. queue.add( { priority : 4 }, () => new Promise( () => {} ) );
  12. queue.add( { priority : 0 }, () => new Promise( () => {} ) );
  13. queue.add( { priority : 8 }, () => new Promise( () => {} ) );
  14. queue.add( { priority : 2 }, () => new Promise( () => {} ) );
  15. queue.add( { priority : 1 }, () => new Promise( () => {} ) );
  16. await nextFrame();
  17. expect( queue.items.map( item => item.priority ) ).toEqual( [ 0 ] );
  18. expect( queue.currJobs ).toEqual( 6 );
  19. } );
  20. it( 'should run jobs in the correct order.', async () => {
  21. const result = [];
  22. const cb = item => new Promise( resolve => {
  23. result.push( item.priority );
  24. resolve();
  25. } );
  26. const queue = new PriorityQueue();
  27. queue.maxJobs = 1;
  28. queue.priorityCallback = item => item.priority;
  29. queue.add( { priority : 6 }, cb );
  30. queue.add( { priority : 3 }, cb );
  31. queue.add( { priority : 4 }, cb );
  32. queue.add( { priority : 0 }, cb );
  33. queue.add( { priority : 8 }, cb );
  34. queue.add( { priority : 2 }, cb );
  35. queue.add( { priority : 1 }, cb );
  36. expect( queue.items.length ).toEqual( queue.callbacks.size );
  37. await nextTick();
  38. expect( result ).toEqual( [ 8, 6, 4, 3, 2, 1, 0 ] );
  39. expect( queue.items.length ).toEqual( queue.callbacks.size );
  40. } );
  41. it( 'should remove an item from the queue correctly.', () => {
  42. const A = { priority : 0 };
  43. const B = { priority : 1 };
  44. const C = { priority : 2 };
  45. const D = { priority : 3 };
  46. const queue = new PriorityQueue();
  47. queue.priorityCallback = item => item.priority;
  48. queue.add( A, () => new Promise( () => {} ) );
  49. queue.add( B, () => new Promise( () => {} ) );
  50. queue.add( C, () => new Promise( () => {} ) );
  51. queue.add( D, () => new Promise( () => {} ) );
  52. queue.sort();
  53. expect( queue.items ).toEqual( [ A, B, C, D ] );
  54. queue.remove( C );
  55. expect( queue.items ).toEqual( [ A, B, D ] );
  56. queue.remove( A );
  57. expect( queue.items ).toEqual( [ B, D ] );
  58. queue.remove( B );
  59. expect( queue.items ).toEqual( [ D ] );
  60. queue.remove( D );
  61. expect( queue.items ).toEqual( [] );
  62. expect( queue.items.length ).toEqual( queue.callbacks.size );
  63. } );
  64. it( 'should automatically run new jobs when one is finished.', async () => {
  65. let called = 0;
  66. let resolveFunc = null;
  67. const queue = new PriorityQueue();
  68. queue.maxJobs = 1;
  69. queue.priorityCallback = item => item.priority;
  70. queue.add( { priority : 1 }, () => new Promise( resolve => {
  71. resolveFunc = resolve;
  72. called ++;
  73. } ) );
  74. queue.add( { priority : 0 }, () => new Promise( () => {
  75. called ++;
  76. } ) );
  77. expect( queue.currJobs ).toEqual( 0 );
  78. await nextFrame();
  79. expect( queue.currJobs ).toEqual( 1 );
  80. expect( resolveFunc ).not.toEqual( null );
  81. expect( called ).toEqual( 1 );
  82. resolveFunc();
  83. await nextFrame();
  84. expect( queue.currJobs ).toEqual( 1 );
  85. expect( called ).toEqual( 2 );
  86. } );
  87. it( 'should fire the callback with the item and priority.', async () => {
  88. const A = { priority : 100 };
  89. const queue = new PriorityQueue();
  90. queue.priorityCallback = item => item.priority;
  91. queue.add( A, item => new Promise( () => {
  92. expect( item ).toEqual( A );
  93. } ) );
  94. await nextFrame();
  95. } );
  96. it( 'should return a promise that resolves from the add function.', async () => {
  97. const queue = new PriorityQueue();
  98. queue.priorityCallback = item => item.priority;
  99. let result = null;
  100. queue.add( { priority : 0 }, item => Promise.resolve( 1000 ) ).then( res => result = res );
  101. expect( result ).toEqual( null );
  102. await nextFrame();
  103. expect( result ).toEqual( 1000 );
  104. } );
  105. it( 'should not automatically run if autoUpdate is false.', async () => {
  106. const queue = new PriorityQueue();
  107. queue.priorityCallback = () => 0;
  108. queue.autoUpdate = false;
  109. queue.maxJobs = 1;
  110. queue.add( {}, async () => {} );
  111. queue.add( {}, async () => {} );
  112. expect( queue.items ).toHaveLength( 2 );
  113. await nextTick();
  114. expect( queue.items ).toHaveLength( 2 );
  115. queue.scheduleJobRun();
  116. await nextTick();
  117. expect( queue.items ).toHaveLength( 1 );
  118. await nextTick();
  119. expect( queue.items ).toHaveLength( 1 );
  120. queue.scheduleJobRun();
  121. await nextTick();
  122. expect( queue.items ).toHaveLength( 0 );
  123. });
  124. } );