MCPcopy Create free account
hub / github.com/angular/angular / tcb

Function tcb

packages/compiler-cli/src/ngtsc/typecheck/testing/index.ts:361–481  ·  view source on GitHub ↗
(
  template: string,
  declarations: TestDeclaration[] = [],
  config?: Partial<TypeCheckingConfig>,
  options?: {emitSpans?: boolean},
  templateParserOptions?: ParseTemplateOptions,
  foreignComponents: string[] = [],
)

Source from the content-addressed store, hash-verified

359export type TestDeclaration = TestDirective | TestPipe;
360
361export function tcb(
362 template: string,
363 declarations: TestDeclaration[] = [],
364 config?: Partial<TypeCheckingConfig>,
365 options?: {emitSpans?: boolean},
366 templateParserOptions?: ParseTemplateOptions,
367 foreignComponents: string[] = [],
368): string {
369 const codeLines = [
370 'declare const ɵNgFieldDirective: unique symbol;',
371 `export class Test<T extends string> {}`,
372 ];
373
374 (function addCodeLines(currentDeclarations) {
375 for (const decl of currentDeclarations) {
376 if (decl.type === 'directive' && decl.hostDirectives) {
377 addCodeLines(decl.hostDirectives.map((hostDir) => hostDir.directive));
378 }
379
380 codeLines.push(
381 decl.code ??
382 `export class ${decl.name}${decl.type === 'directive' || decl.isGeneric ? '<T extends string>' : ''} { ${
383 (decl as TestDirective).hasNgFieldDirective === true ? '[ɵNgFieldDirective]: any;' : ''
384 } }`,
385 );
386 }
387 })(declarations);
388
389 const rootFilePath = absoluteFrom('/synthetic.ts');
390 const {program, host} = makeProgram([
391 {name: rootFilePath, contents: codeLines.join('\n'), isRoot: true},
392 ]);
393
394 const sf = getSourceFileOrError(program, rootFilePath);
395 const clazz = getClass(sf, 'Test');
396 const templateUrl = 'synthetic.html';
397 const {nodes, errors} = parseTemplate(template, templateUrl, templateParserOptions);
398 const selectorlessEnabled = templateParserOptions?.enableSelectorless ?? false;
399
400 if (errors !== null) {
401 throw new Error('Template parse errors: \n' + errors.join('\n'));
402 }
403
404 const {matcher, pipes, foreignMatcher} = prepareDeclarations(
405 declarations,
406 (decl) => getClass(sf, decl.name),
407 new Map(),
408 selectorlessEnabled,
409 foreignComponents,
410 );
411 const binder = new R3TargetBinder<DirectiveMeta>(matcher, foreignMatcher);
412 const boundTarget = binder.bind({template: nodes});
413
414 const id = 'tcb' as TypeCheckId;
415 const meta: TypeCheckBlockMetadata = {
416 id,
417 boundTarget,
418 pipes,

Callers 3

tcbWithSpansFunction · 0.90
selectorlessTcbFunction · 0.90

Calls 14

bindMethod · 0.95
addTypeCheckBlockMethod · 0.95
renderMethod · 0.95
absoluteFromFunction · 0.90
makeProgramFunction · 0.90
getSourceFileOrErrorFunction · 0.90
parseTemplateFunction · 0.90
prepareDeclarationsFunction · 0.85
mapMethod · 0.80
getTypeCheckerMethod · 0.80
getClassFunction · 0.70
joinMethod · 0.65

Tested by

no test coverage detected