| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google LLC 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 {FileSystem} from '../../../src/ngtsc/file_system'; | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {getBuildOutputDirectory, getRootDirectory} from './compile_test'; | 
					
						
							| 
									
										
										
										
											2020-11-26 23:41:01 +01:00
										 |  |  | import {verifyUniqueFactory} from './di_checks'; | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  | import {expectEmit} from './expect_emit'; | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | import {replaceMacros} from './expected_file_macros'; | 
					
						
							| 
									
										
										
										
											2020-12-01 16:52:39 +01:00
										 |  |  | import {verifyUniqueFunctions} from './function_checks'; | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | import {ExpectedFile, ExtraCheck} from './get_compliance_tests'; | 
					
						
							|  |  |  | import {verifyPlaceholdersIntegrity, verifyUniqueConsts} from './i18n_checks'; | 
					
						
							| 
									
										
										
										
											2020-12-02 21:40:44 +00:00
										 |  |  | import {checkMappings} from './sourcemap_helpers'; | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | type ExtraCheckFunction = (generated: string, ...extraArgs: any[]) => boolean; | 
					
						
							|  |  |  | const EXTRA_CHECK_FUNCTIONS: Record<string, ExtraCheckFunction> = { | 
					
						
							|  |  |  |   verifyPlaceholdersIntegrity, | 
					
						
							|  |  |  |   verifyUniqueConsts, | 
					
						
							| 
									
										
										
										
											2020-11-26 23:41:01 +01:00
										 |  |  |   verifyUniqueFactory, | 
					
						
							| 
									
										
										
										
											2020-12-01 16:52:39 +01:00
										 |  |  |   verifyUniqueFunctions, | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Check that each of the generated files matches the expected files. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param fs The mock file-system that holds the expected and generated files to compare. | 
					
						
							|  |  |  |  * @param testPath Path to the current test case (relative to the basePath). | 
					
						
							|  |  |  |  * @param failureMessage The message to display if the expectation fails. | 
					
						
							|  |  |  |  * @param expectedFiles The list of expected-generated pairs to compare. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export function checkExpectations( | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  |     fs: FileSystem, testPath: string, failureMessage: string, expectedFiles: ExpectedFile[], | 
					
						
							|  |  |  |     extraChecks: ExtraCheck[]): void { | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  |   const builtDirectory = getBuildOutputDirectory(fs); | 
					
						
							|  |  |  |   for (const expectedFile of expectedFiles) { | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  |     const expectedPath = fs.resolve(getRootDirectory(fs), expectedFile.expected); | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  |     if (!fs.exists(expectedPath)) { | 
					
						
							|  |  |  |       throw new Error(`The expected file at ${ | 
					
						
							|  |  |  |           expectedPath} does not exist. Please check the TEST_CASES.json file for this test case.`);
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatedPath = fs.resolve(builtDirectory, expectedFile.generated); | 
					
						
							|  |  |  |     if (!fs.exists(generatedPath)) { | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  |       const error = new Error( | 
					
						
							|  |  |  |           `The generated file at ${generatedPath} does not exist.\n` + | 
					
						
							|  |  |  |           'Perhaps there is no matching input source file in the TEST_CASES.json file for this test case.\n' + | 
					
						
							|  |  |  |           'Or maybe you need to regenerate the GOLDEN_PARTIAL.js file by running:\n\n' + | 
					
						
							|  |  |  |           `    bazel run //packages/compiler-cli/test/compliance/test_cases:${ | 
					
						
							|  |  |  |               testPath}.golden.update`);
 | 
					
						
							|  |  |  |       // Clear the stack so that we get a nice error message
 | 
					
						
							|  |  |  |       error.stack = ''; | 
					
						
							|  |  |  |       throw error; | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     const generated = fs.readFile(generatedPath); | 
					
						
							| 
									
										
										
										
											2020-12-02 21:40:44 +00:00
										 |  |  |     let expected = fs.readFile(expectedPath); | 
					
						
							|  |  |  |     expected = replaceMacros(expected); | 
					
						
							|  |  |  |     expected = checkMappings(fs, generated, generatedPath, expected); | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     expectEmit( | 
					
						
							|  |  |  |         generated, expected, | 
					
						
							|  |  |  |         `When checking against expected file "${testPath}/${expectedFile.expected}"\n` + | 
					
						
							|  |  |  |             failureMessage); | 
					
						
							| 
									
										
										
										
											2020-11-12 19:43:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     runExtraChecks(testPath, generated, extraChecks); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function runExtraChecks( | 
					
						
							|  |  |  |     testPath: string, generated: string, extraChecks: (string|[string, ...any])[]): void { | 
					
						
							|  |  |  |   for (const check of extraChecks) { | 
					
						
							|  |  |  |     let fnName: string; | 
					
						
							|  |  |  |     let args: any[]; | 
					
						
							|  |  |  |     if (Array.isArray(check)) { | 
					
						
							|  |  |  |       [fnName, ...args] = check; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       fnName = check; | 
					
						
							|  |  |  |       args = []; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const fn = EXTRA_CHECK_FUNCTIONS[fnName]; | 
					
						
							|  |  |  |     if (fn === undefined) { | 
					
						
							|  |  |  |       throw new Error( | 
					
						
							|  |  |  |           `Unknown extra-check function: "${fnName}" in ${testPath}.\n` + | 
					
						
							|  |  |  |           `Possible choices are: ${Object.keys(EXTRA_CHECK_FUNCTIONS).map(f => `\n - ${f}`)}.`); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-26 23:38:08 +01:00
										 |  |  |     if (!fn(generated, ...args)) { | 
					
						
							|  |  |  |       throw new Error( | 
					
						
							|  |  |  |           `Extra check ${fnName}(${args.map(arg => JSON.stringify(arg)).join(',')}) in ${ | 
					
						
							|  |  |  |               testPath} failed for generated code:\n\n${generated}`);
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-11 15:29:43 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } |