| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 {DirectorySizeEntry, FileSizeData, getChildEntryNames} from './file_size_data'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface SizeDifference { | 
					
						
							|  |  |  |   filePath?: string; | 
					
						
							|  |  |  |   message: string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  | export interface Threshold { | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Maximum difference percentage. Exceeding this causes a reported size | 
					
						
							|  |  |  |    * difference. Percentage difference is helpful for small files where | 
					
						
							|  |  |  |    * the byte threshold is not exceeded but the change is relatively large | 
					
						
							|  |  |  |    * for the small file and should be reported. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   maxPercentageDiff: number; | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Maximum byte difference. Exceeding this causes a reported size difference. | 
					
						
							|  |  |  |    * The max byte threshold works good for large files where change is relatively | 
					
						
							|  |  |  |    * small but still needs to reported as it causes an overall size regression. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   maxByteDiff: number; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  | /** Compares two file size data objects and returns an array of size differences. */ | 
					
						
							|  |  |  | export function compareFileSizeData( | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |     actual: FileSizeData, expected: FileSizeData, threshold: Threshold) { | 
					
						
							|  |  |  |   return [ | 
					
						
							|  |  |  |     ...compareSizeEntry(actual.files, expected.files, '/', threshold), | 
					
						
							|  |  |  |     ...compareActualSizeToExpected(actual.unmapped, expected.unmapped, '<unmapped>', threshold) | 
					
						
							|  |  |  |   ]; | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Compares two file size entries and returns an array of size differences. */ | 
					
						
							|  |  |  | function compareSizeEntry( | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     actual: DirectorySizeEntry|number, expected: DirectorySizeEntry|number, filePath: string, | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |     threshold: Threshold) { | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |   if (typeof actual !== 'number' && typeof expected !== 'number') { | 
					
						
							| 
									
										
										
										
											2019-10-09 17:17:52 +02:00
										 |  |  |     return compareDirectorySizeEntry(actual, expected, filePath, threshold); | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     return compareActualSizeToExpected(<number>actual, <number>expected, filePath, threshold); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |  * Compares two size numbers and returns a size difference if the difference | 
					
						
							|  |  |  |  * percentage exceeds the specified maximum percentage or the byte size | 
					
						
							|  |  |  |  * difference exceeds the maximum byte difference. | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | function compareActualSizeToExpected( | 
					
						
							|  |  |  |     actualSize: number, expectedSize: number, filePath: string, | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |     threshold: Threshold): SizeDifference[] { | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |   const diffPercentage = getDifferencePercentage(actualSize, expectedSize); | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |   const byteDiff = Math.abs(expectedSize - actualSize); | 
					
						
							|  |  |  |   const diffs: SizeDifference[] = []; | 
					
						
							|  |  |  |   if (diffPercentage > threshold.maxPercentageDiff) { | 
					
						
							|  |  |  |     diffs.push({ | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |       filePath: filePath, | 
					
						
							|  |  |  |       message: `Differs by ${diffPercentage.toFixed(2)}% from the expected size ` + | 
					
						
							|  |  |  |           `(actual = ${actualSize}, expected = ${expectedSize})` | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |   if (byteDiff > threshold.maxByteDiff) { | 
					
						
							|  |  |  |     diffs.push({ | 
					
						
							|  |  |  |       filePath: filePath, | 
					
						
							|  |  |  |       message: `Differs by ${byteDiff}B from the expected size ` + | 
					
						
							|  |  |  |           `(actual = ${actualSize}, expected = ${expectedSize})` | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return diffs; | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Compares two size directory size entries and returns an array of found size | 
					
						
							|  |  |  |  * differences within that directory. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function compareDirectorySizeEntry( | 
					
						
							|  |  |  |     actual: DirectorySizeEntry, expected: DirectorySizeEntry, filePath: string, | 
					
						
							| 
									
										
										
										
											2019-05-03 15:48:23 +02:00
										 |  |  |     threshold: Threshold): SizeDifference[] { | 
					
						
							| 
									
										
										
										
											2019-04-23 20:50:11 +02:00
										 |  |  |   const diffs: SizeDifference[] = | 
					
						
							|  |  |  |       [...compareActualSizeToExpected(actual.size, expected.size, filePath, threshold)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getChildEntryNames(expected).forEach(childName => { | 
					
						
							|  |  |  |     if (actual[childName] === undefined) { | 
					
						
							|  |  |  |       diffs.push( | 
					
						
							|  |  |  |           {filePath: filePath + childName, message: 'Expected file/directory is not included.'}); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     diffs.push(...compareSizeEntry( | 
					
						
							|  |  |  |         actual[childName], expected[childName], filePath + childName, threshold)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getChildEntryNames(actual).forEach(childName => { | 
					
						
							|  |  |  |     if (expected[childName] === undefined) { | 
					
						
							|  |  |  |       diffs.push({ | 
					
						
							|  |  |  |         filePath: filePath + childName, | 
					
						
							|  |  |  |         message: 'Unexpected file/directory included (not part of golden).' | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return diffs; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Gets the difference of the two size values in percentage. */ | 
					
						
							|  |  |  | function getDifferencePercentage(actualSize: number, expectedSize: number) { | 
					
						
							|  |  |  |   return (Math.abs(actualSize - expectedSize) / ((expectedSize + actualSize) / 2)) * 100; | 
					
						
							|  |  |  | } |