| 
									
										
										
										
											2020-03-14 22:09:46 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @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 {DepGraph} from 'dependency-graph'; | 
					
						
							|  |  |  | import {PartiallyOrderedTasks, Task} from '../../src/execution/tasks/api'; | 
					
						
							|  |  |  | import {EntryPoint} from '../../src/packages/entry_point'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Create a set of tasks and a graph of their interdependencies. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NOTE 1: The first task for each entry-point generates typings (which is similar to what happens | 
					
						
							|  |  |  |  *         in the actual code). | 
					
						
							| 
									
										
										
										
											2020-04-06 08:30:08 +01:00
										 |  |  |  * NOTE 2: The `computeTaskDependencies()` implementation relies on the fact that tasks are sorted | 
					
						
							|  |  |  |  * in such a way that a task can only depend upon earlier tasks (i.e. dependencies always come | 
					
						
							| 
									
										
										
										
											2020-03-14 22:09:46 +00:00
										 |  |  |  *         before dependents in the list of tasks). | 
					
						
							|  |  |  |  *         To preserve this attribute, you need to ensure that entry-points will only depend on | 
					
						
							|  |  |  |  *         entry-points with a lower index. Take this into account when defining `entryPointDeps`. | 
					
						
							|  |  |  |  *         (Failing to do so, will result in an error.) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param entryPointCount The number of different entry-points to mock. | 
					
						
							|  |  |  |  * @param tasksPerEntryPointCount The number of tasks to generate per entry-point (i.e. simulating | 
					
						
							|  |  |  |  *                                processing multiple format properties). | 
					
						
							|  |  |  |  * @param entryPointDeps An object mapping an entry-point to its dependencies. Keys are | 
					
						
							|  |  |  |  *                       entry-point indices and values are arrays of entry-point indices that the | 
					
						
							|  |  |  |  *                       entry-point corresponding to the key depends on. | 
					
						
							|  |  |  |  *                       For example, if entry-point #2 depends on entry-points #0 and #1, | 
					
						
							|  |  |  |  *                       `entryPointDeps` would be `{2: [0, 1]}`. | 
					
						
							|  |  |  |  * @return An object with the following properties: | 
					
						
							|  |  |  |  *         - `tasks`: The (partially ordered) list of generated mock tasks. | 
					
						
							|  |  |  |  *         - `graph`: The dependency graph for the generated mock entry-point. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export function createTasksAndGraph( | 
					
						
							|  |  |  |     entryPointCount: number, tasksPerEntryPointCount = 1, | 
					
						
							|  |  |  |     entryPointDeps: {[entryPointIndex: string]: number[]} = {}): | 
					
						
							|  |  |  |     {tasks: PartiallyOrderedTasks, graph: DepGraph<EntryPoint>} { | 
					
						
							|  |  |  |   const entryPoints: EntryPoint[] = []; | 
					
						
							|  |  |  |   const tasks: PartiallyOrderedTasks = [] as any; | 
					
						
							|  |  |  |   const graph = new DepGraph<EntryPoint>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create the entry-points and the associated tasks.
 | 
					
						
							|  |  |  |   for (let epIdx = 0; epIdx < entryPointCount; epIdx++) { | 
					
						
							|  |  |  |     const entryPoint = { | 
					
						
							|  |  |  |       name: `entry-point-${epIdx}`, | 
					
						
							|  |  |  |       path: `/path/to/entry/point/${epIdx}`, | 
					
						
							|  |  |  |     } as EntryPoint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     entryPoints.push(entryPoint); | 
					
						
							|  |  |  |     graph.addNode(entryPoint.path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (let tIdx = 0; tIdx < tasksPerEntryPointCount; tIdx++) { | 
					
						
							| 
									
										
										
										
											2020-04-06 08:30:08 +01:00
										 |  |  |       tasks.push({entryPoint, formatProperty: `prop-${tIdx}`, processDts: tIdx === 0} as Task); | 
					
						
							| 
									
										
										
										
											2020-03-14 22:09:46 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Define entry-point interdependencies.
 | 
					
						
							|  |  |  |   for (const epIdx of Object.keys(entryPointDeps).map(strIdx => +strIdx)) { | 
					
						
							|  |  |  |     const fromPath = entryPoints[epIdx].path; | 
					
						
							|  |  |  |     for (const depIdx of entryPointDeps[epIdx]) { | 
					
						
							|  |  |  |       // Ensure that each entry-point only depends on entry-points at a lower index.
 | 
					
						
							|  |  |  |       if (depIdx >= epIdx) { | 
					
						
							|  |  |  |         throw Error( | 
					
						
							|  |  |  |             'Invalid `entryPointDeps`: Entry-points can only depend on entry-points at a lower ' + | 
					
						
							|  |  |  |             `index, but entry-point #${epIdx} depends on #${depIdx} in: ` + | 
					
						
							|  |  |  |             JSON.stringify(entryPointDeps, null, 2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const toPath = entryPoints[depIdx].path; | 
					
						
							|  |  |  |       graph.addDependency(fromPath, toPath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return {tasks, graph}; | 
					
						
							|  |  |  | } |