79 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			79 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @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 * as ts from 'typescript';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import {createLanguageService} from '../src/language_service';
							 | 
						||
| 
								 | 
							
								import {TypeScriptServiceHost} from '../src/typescript_host';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import {MockTypescriptHost} from './test_utils';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const APP_COMPONENT = '/app/app.component.ts';
							 | 
						||
| 
								 | 
							
								const TEST_TEMPLATE = '/app/test.ng';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe('references', () => {
							 | 
						||
| 
								 | 
							
								  const mockHost = new MockTypescriptHost(['/app/main.ts']);
							 | 
						||
| 
								 | 
							
								  const tsLS = ts.createLanguageService(mockHost);
							 | 
						||
| 
								 | 
							
								  const ngHost = new TypeScriptServiceHost(mockHost, tsLS);
							 | 
						||
| 
								 | 
							
								  const ngLS = createLanguageService(ngHost);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  beforeEach(() => {
							 | 
						||
| 
								 | 
							
								    mockHost.reset();
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (const templateStrategy of ['inline', 'external'] as const) {
							 | 
						||
| 
								 | 
							
								    describe(`template: ${templateStrategy}`, () => {
							 | 
						||
| 
								 | 
							
								      describe('component members', () => {
							 | 
						||
| 
								 | 
							
								        it('should get TS references for a member in template', () => {
							 | 
						||
| 
								 | 
							
								          const fileName = overrideTemplate('{{«title»}}');
							 | 
						||
| 
								 | 
							
								          const marker = mockHost.getReferenceMarkerFor(fileName, 'title');
							 | 
						||
| 
								 | 
							
								          const references = ngLS.getReferencesAtPosition(fileName, marker.start)!;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          expect(references).toBeDefined();
							 | 
						||
| 
								 | 
							
								          expect(references.length).toBe(2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          for (let i = 0; i < references.length; ++i) {
							 | 
						||
| 
								 | 
							
								            // The first reference is declared as a class member.
							 | 
						||
| 
								 | 
							
								            // The second is in `setTitle`.
							 | 
						||
| 
								 | 
							
								            const ref = references[i];
							 | 
						||
| 
								 | 
							
								            expect(getSource(ref)).toBe('title');
							 | 
						||
| 
								 | 
							
								            if (i == 0) {
							 | 
						||
| 
								 | 
							
								              // The first reference is the member declaration, so it should
							 | 
						||
| 
								 | 
							
								              // have a context span pointing to the whole declaration.
							 | 
						||
| 
								 | 
							
								              expect(getSource(ref, 'contextSpan')).toBe('title = \'Tour of Heroes\';');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // TODO: override parsing-cases#TemplateReference for inline templates.
							 | 
						||
| 
								 | 
							
								    const overrideTemplate = (template: string): string => {
							 | 
						||
| 
								 | 
							
								      if (templateStrategy === 'inline') {
							 | 
						||
| 
								 | 
							
								        mockHost.overrideInlineTemplate(APP_COMPONENT, template);
							 | 
						||
| 
								 | 
							
								        return APP_COMPONENT;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        mockHost.override(TEST_TEMPLATE, template);
							 | 
						||
| 
								 | 
							
								        return TEST_TEMPLATE;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Gets the source code of a reference entry. By default the reference
							 | 
						||
| 
								 | 
							
								   * `textSpan` is checked, but this can be overridden by specifying `spanKind`.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  function getSource(
							 | 
						||
| 
								 | 
							
								      reference: ts.ReferenceEntry, spanKind: 'textSpan'|'contextSpan' = 'textSpan'): string {
							 | 
						||
| 
								 | 
							
								    const span = reference[spanKind]!;
							 | 
						||
| 
								 | 
							
								    const fileName = reference.fileName;
							 | 
						||
| 
								 | 
							
								    const content = mockHost.readFile(fileName)!;
							 | 
						||
| 
								 | 
							
								    return content.substring(span.start, span.start + span.length);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 |