Jasmine natively supports returning promises from spec functions for quite some time now. We don't need special async helpers. PR Close #30977
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google Inc. All Rights Reserved.
 | |
|  *
 | |
|  * Use of this source code is governed by an MIT-style license that can be
 | |
|  * found in the LICENSE file at https://angular.io/license
 | |
|  */
 | |
| 
 | |
| import {IdleScheduler} from '../src/idle';
 | |
| import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
 | |
| 
 | |
| (function() {
 | |
|   // Skip environments that don't support the minimum APIs needed to run the SW tests.
 | |
|   if (!SwTestHarness.envIsSupported()) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   describe('IdleScheduler', () => {
 | |
|     let scope: SwTestHarness;
 | |
|     let idle: IdleScheduler;
 | |
| 
 | |
|     beforeEach(() => {
 | |
|       scope = new SwTestHarnessBuilder().build();
 | |
|       idle = new IdleScheduler(scope, 1000, {
 | |
|         log: (v, context) => console.error(v, context),
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     // Validate that a single idle task executes when trigger()
 | |
|     // is called and the idle timeout passes.
 | |
|     it('executes scheduled work on time', async() => {
 | |
|       // Set up a single idle task to set the completed flag to true when it runs.
 | |
|       let completed: boolean = false;
 | |
|       idle.schedule('work', async() => { completed = true; });
 | |
| 
 | |
|       // Simply scheduling the task should not cause it to execute.
 | |
|       expect(completed).toEqual(false);
 | |
| 
 | |
|       // Trigger the idle mechanism. This returns a Promise that should resolve
 | |
|       // once the idle timeout has passed.
 | |
|       const trigger = idle.trigger();
 | |
| 
 | |
|       // Advance the clock beyond the idle timeout, causing the idle tasks to run.
 | |
|       scope.advance(1100);
 | |
| 
 | |
|       // It should now be possible to wait for the trigger, and for the idle queue
 | |
|       // to be empty.
 | |
|       await trigger;
 | |
|       await idle.empty;
 | |
| 
 | |
|       // The task should now have run.
 | |
|       expect(completed).toEqual(true);
 | |
|     });
 | |
| 
 | |
|     it('waits for multiple tasks to complete serially', async() => {
 | |
|       // Schedule several tasks that will increase a counter according to its
 | |
|       // current value. If these tasks execute in parallel, the writes to the counter
 | |
|       // will race, and the test will fail.
 | |
|       let counter: number = 2;
 | |
|       idle.schedule('double counter', async() => {
 | |
|         let local = counter;
 | |
|         await Promise.resolve();
 | |
|         local *= 2;
 | |
|         await Promise.resolve();
 | |
|         counter = local * 2;
 | |
|       });
 | |
|       idle.schedule('triple counter', async() => {
 | |
|         // If this expect fails, it comes out of the 'await trigger' below.
 | |
|         expect(counter).toEqual(8);
 | |
| 
 | |
|         // Multiply the counter by 3 twice.
 | |
|         let local = counter;
 | |
|         await Promise.resolve();
 | |
|         local *= 3;
 | |
|         await Promise.resolve();
 | |
|         counter = local * 3;
 | |
|       });
 | |
| 
 | |
|       // Trigger the idle mechanism once.
 | |
|       const trigger = idle.trigger();
 | |
| 
 | |
|       // Advance the clock beyond the idle timeout, causing the idle tasks to run, and
 | |
|       // wait for them to complete.
 | |
|       scope.advance(1100);
 | |
|       await trigger;
 | |
|       await idle.empty;
 | |
| 
 | |
|       // Assert that both tasks executed in the correct serial sequence by validating
 | |
|       // that the counter reached the correct value.
 | |
|       expect(counter).toEqual(2 * 2 * 2 * 3 * 3);
 | |
|     });
 | |
| 
 | |
|     // Validate that a single idle task does not execute until trigger() has been called
 | |
|     // and sufficient time passes without it being called again.
 | |
|     it('does not execute work until timeout passes with no triggers', async() => {
 | |
|       // Set up a single idle task to set the completed flag to true when it runs.
 | |
|       let completed: boolean = false;
 | |
|       idle.schedule('work', async() => { completed = true; });
 | |
| 
 | |
|       // Trigger the queue once. This trigger will start a timer for the idle timeout,
 | |
|       // but another trigger() will be called before that timeout passes.
 | |
|       const firstTrigger = idle.trigger();
 | |
| 
 | |
|       // Advance the clock a little, but not enough to actually cause tasks to execute.
 | |
|       scope.advance(500);
 | |
| 
 | |
|       // Assert that the task has not yet run.
 | |
|       expect(completed).toEqual(false);
 | |
| 
 | |
|       // Next, trigger the queue again.
 | |
|       const secondTrigger = idle.trigger();
 | |
| 
 | |
|       // Advance the clock beyond the timeout for the first trigger, but not the second.
 | |
|       // This should cause the first trigger to resolve, but without running the task.
 | |
|       scope.advance(600);
 | |
|       await firstTrigger;
 | |
|       expect(completed).toEqual(false);
 | |
| 
 | |
|       // Schedule a third trigger. This is the one that will eventually resolve the task.
 | |
|       const thirdTrigger = idle.trigger();
 | |
| 
 | |
|       // Again, advance beyond the second trigger and verify it didn't resolve the task.
 | |
|       scope.advance(500);
 | |
|       await secondTrigger;
 | |
|       expect(completed).toEqual(false);
 | |
| 
 | |
|       // Finally, advance beyond the third trigger, which should cause the task to be
 | |
|       // executed finally.
 | |
|       scope.advance(600);
 | |
|       await thirdTrigger;
 | |
|       await idle.empty;
 | |
| 
 | |
|       // The task should have executed.
 | |
|       expect(completed).toEqual(true);
 | |
|     });
 | |
|   });
 | |
| })();
 |