13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ciimport {ListUtil} from '../../../src/utils/ListUtil'; 173af6ab5fSopenharmony_ciimport {describe, it} from 'mocha'; 183af6ab5fSopenharmony_ciimport {assert} from 'chai'; 193af6ab5fSopenharmony_ciimport * as fs from 'fs'; 203af6ab5fSopenharmony_ciimport sinon from 'sinon'; 213af6ab5fSopenharmony_ciimport {TypeUtils} from '../../../src/utils/TypeUtils'; 223af6ab5fSopenharmony_ciimport { 233af6ab5fSopenharmony_ci Label, 243af6ab5fSopenharmony_ci Scope, 253af6ab5fSopenharmony_ci ScopeKind, 263af6ab5fSopenharmony_ci ScopeManager, 273af6ab5fSopenharmony_ci createLabel, 283af6ab5fSopenharmony_ci createScopeManager, 293af6ab5fSopenharmony_ci isClassScope, 303af6ab5fSopenharmony_ci isEnumScope, 313af6ab5fSopenharmony_ci isFunctionScope, 323af6ab5fSopenharmony_ci isGlobalScope, 333af6ab5fSopenharmony_ci isInterfaceScope, 343af6ab5fSopenharmony_ci isObjectLiteralScope 353af6ab5fSopenharmony_ci} from '../../../src/utils/ScopeAnalyzer'; 363af6ab5fSopenharmony_ciimport { ScriptTarget, SourceFile, createSourceFile, isSourceFile, Symbol, __String, Declaration, JSDocTagInfo, 373af6ab5fSopenharmony_ci SymbolDisplayPart, SymbolFlags, TypeChecker, LabeledStatement, Identifier, SyntaxKind, 383af6ab5fSopenharmony_ci isIdentifier, 393af6ab5fSopenharmony_ci factory, 403af6ab5fSopenharmony_ci VariableStatement} from 'typescript'; 413af6ab5fSopenharmony_ci 423af6ab5fSopenharmony_cidescribe('ScopeAnalyzer ut', function () { 433af6ab5fSopenharmony_ci let sourceFile: SourceFile; 443af6ab5fSopenharmony_ci 453af6ab5fSopenharmony_ci before('init parameters', function () { 463af6ab5fSopenharmony_ci const sourceFileContent = ` 473af6ab5fSopenharmony_ci //This is a comment 483af6ab5fSopenharmony_ci class Demo{ 493af6ab5fSopenharmony_ci constructor(public title: string, public content: string, public mark: number) { 503af6ab5fSopenharmony_ci this.title = title 513af6ab5fSopenharmony_ci this.content = content 523af6ab5fSopenharmony_ci this.mark = mark 533af6ab5fSopenharmony_ci } 543af6ab5fSopenharmony_ci } 553af6ab5fSopenharmony_ci `; 563af6ab5fSopenharmony_ci 573af6ab5fSopenharmony_ci sourceFile = createSourceFile('sourceFile.ts', sourceFileContent, ScriptTarget.ES2015, true); 583af6ab5fSopenharmony_ci }); 593af6ab5fSopenharmony_ci 603af6ab5fSopenharmony_ci describe('unit test for isGlobalScope', function () { 613af6ab5fSopenharmony_ci it('is Global Scope', function () { 623af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 633af6ab5fSopenharmony_ci assert.isTrue(isGlobalScope(curScope)); 643af6ab5fSopenharmony_ci }); 653af6ab5fSopenharmony_ci 663af6ab5fSopenharmony_ci it('is not Global Scope', function () { 673af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.MODULE); 683af6ab5fSopenharmony_ci assert.isFalse(isGlobalScope(curScope)); 693af6ab5fSopenharmony_ci }); 703af6ab5fSopenharmony_ci }); 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ci describe('unit test for isFunctionScope', function () { 733af6ab5fSopenharmony_ci it('is Function Scope', function () { 743af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.FUNCTION); 753af6ab5fSopenharmony_ci assert.isTrue(isFunctionScope(curScope)); 763af6ab5fSopenharmony_ci }); 773af6ab5fSopenharmony_ci 783af6ab5fSopenharmony_ci it('is not Function Scope', function () { 793af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.MODULE); 803af6ab5fSopenharmony_ci assert.isFalse(isFunctionScope(curScope)); 813af6ab5fSopenharmony_ci }); 823af6ab5fSopenharmony_ci }); 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci describe('unit test for isClassScope', function () { 853af6ab5fSopenharmony_ci it('is Class Scope', function () { 863af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.CLASS); 873af6ab5fSopenharmony_ci assert.isTrue(isClassScope(curScope)); 883af6ab5fSopenharmony_ci }); 893af6ab5fSopenharmony_ci 903af6ab5fSopenharmony_ci it('is not Class Scope', function () { 913af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.MODULE); 923af6ab5fSopenharmony_ci assert.isFalse(isClassScope(curScope)); 933af6ab5fSopenharmony_ci }); 943af6ab5fSopenharmony_ci }); 953af6ab5fSopenharmony_ci 963af6ab5fSopenharmony_ci describe('unit test for isInterfaceScope', function () { 973af6ab5fSopenharmony_ci it('is Interface Scope', function () { 983af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.INTERFACE); 993af6ab5fSopenharmony_ci assert.isTrue(isInterfaceScope(curScope)); 1003af6ab5fSopenharmony_ci }); 1013af6ab5fSopenharmony_ci 1023af6ab5fSopenharmony_ci it('is not Interface Scope', function () { 1033af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.MODULE); 1043af6ab5fSopenharmony_ci assert.isFalse(isInterfaceScope(curScope)); 1053af6ab5fSopenharmony_ci }); 1063af6ab5fSopenharmony_ci }); 1073af6ab5fSopenharmony_ci 1083af6ab5fSopenharmony_ci describe('unit test for isEnumScope', function () { 1093af6ab5fSopenharmony_ci it('is Enum Scope', function () { 1103af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.ENUM); 1113af6ab5fSopenharmony_ci assert.isTrue(isEnumScope(curScope)); 1123af6ab5fSopenharmony_ci }); 1133af6ab5fSopenharmony_ci 1143af6ab5fSopenharmony_ci it('is not Enum Scope', function () { 1153af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.MODULE); 1163af6ab5fSopenharmony_ci assert.isFalse(isEnumScope(curScope)); 1173af6ab5fSopenharmony_ci }); 1183af6ab5fSopenharmony_ci }); 1193af6ab5fSopenharmony_ci 1203af6ab5fSopenharmony_ci describe('unit test for isObjectLiteralScope', function () { 1213af6ab5fSopenharmony_ci it('is ObjectLiteral Scope', function () { 1223af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.OBJECT_LITERAL); 1233af6ab5fSopenharmony_ci assert.isTrue(isObjectLiteralScope(curScope)); 1243af6ab5fSopenharmony_ci }); 1253af6ab5fSopenharmony_ci 1263af6ab5fSopenharmony_ci it('is not ObjectLiteral Scope', function () { 1273af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile , ScopeKind.MODULE); 1283af6ab5fSopenharmony_ci assert.isFalse(isObjectLiteralScope(curScope)); 1293af6ab5fSopenharmony_ci }); 1303af6ab5fSopenharmony_ci }); 1313af6ab5fSopenharmony_ci 1323af6ab5fSopenharmony_ci describe('unit test for Scope', function () { 1333af6ab5fSopenharmony_ci describe('constructor', function () { 1343af6ab5fSopenharmony_ci it('init', function () { 1353af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 1363af6ab5fSopenharmony_ci assert.equal(curScope.name, 'curScope'); 1373af6ab5fSopenharmony_ci assert.equal(curScope.kind, ScopeKind.GLOBAL); 1383af6ab5fSopenharmony_ci assert.equal(curScope.block, sourceFile); 1393af6ab5fSopenharmony_ci assert.equal(curScope.parent, undefined); 1403af6ab5fSopenharmony_ci assert.deepEqual(curScope.children, []); 1413af6ab5fSopenharmony_ci assert.deepEqual(curScope.defs, new Set()); 1423af6ab5fSopenharmony_ci assert.deepEqual(curScope.labels, []); 1433af6ab5fSopenharmony_ci assert.deepEqual(curScope.importNames, new Set()); 1443af6ab5fSopenharmony_ci assert.deepEqual(curScope.exportNames, new Set()); 1453af6ab5fSopenharmony_ci assert.deepEqual(curScope.mangledNames, new Set()); 1463af6ab5fSopenharmony_ci assert.equal(curScope.loc, 'curScope'); 1473af6ab5fSopenharmony_ci }); 1483af6ab5fSopenharmony_ci }); 1493af6ab5fSopenharmony_ci 1503af6ab5fSopenharmony_ci describe('addChild', function () { 1513af6ab5fSopenharmony_ci it('push', function () { 1523af6ab5fSopenharmony_ci let parentScope = new Scope('parentScope', sourceFile, ScopeKind.FUNCTION); 1533af6ab5fSopenharmony_ci let childScope = new Scope('childScope', sourceFile, ScopeKind.BLOCK, false, parentScope); 1543af6ab5fSopenharmony_ci assert.include(parentScope.children, childScope); 1553af6ab5fSopenharmony_ci }); 1563af6ab5fSopenharmony_ci }); 1573af6ab5fSopenharmony_ci 1583af6ab5fSopenharmony_ci describe('addDefinition', function () { 1593af6ab5fSopenharmony_ci it('should add definition symbol to the current scope', function () { 1603af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 1613af6ab5fSopenharmony_ci let symbol: Symbol = Object(Symbol('testSymbol')); 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci curScope.addDefinition(symbol, false); 1643af6ab5fSopenharmony_ci assert.isTrue(curScope.defs.has(symbol)); 1653af6ab5fSopenharmony_ci }); 1663af6ab5fSopenharmony_ci 1673af6ab5fSopenharmony_ci it('should mark symbol as obfuscateAsProperty if required', function () { 1683af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 1693af6ab5fSopenharmony_ci let symbol: Symbol = Object(Symbol('testSymbol')); 1703af6ab5fSopenharmony_ci 1713af6ab5fSopenharmony_ci curScope.addDefinition(symbol, true); 1723af6ab5fSopenharmony_ci assert.isTrue(Reflect.get(symbol, 'obfuscateAsProperty')); 1733af6ab5fSopenharmony_ci }); 1743af6ab5fSopenharmony_ci }); 1753af6ab5fSopenharmony_ci 1763af6ab5fSopenharmony_ci describe('addLabel', function () { 1773af6ab5fSopenharmony_ci it('should add a label to the current scope', function () { 1783af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 1793af6ab5fSopenharmony_ci let label: Label = {name: 'testLabel', locInfo: 'locInfo', refs: [], parent: undefined, children: [], scope: curScope}; 1803af6ab5fSopenharmony_ci 1813af6ab5fSopenharmony_ci curScope.addLabel(label); 1823af6ab5fSopenharmony_ci assert.include(curScope.labels, label); 1833af6ab5fSopenharmony_ci }); 1843af6ab5fSopenharmony_ci }); 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ci describe('getSymbolLocation', function () { 1873af6ab5fSopenharmony_ci it('should return the correct location if symbol exists', function () { 1883af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 1893af6ab5fSopenharmony_ci let symbol: Symbol = { 1903af6ab5fSopenharmony_ci flags: 0, 1913af6ab5fSopenharmony_ci escapedName: 'testSymbol' as __String, 1923af6ab5fSopenharmony_ci declarations: [], 1933af6ab5fSopenharmony_ci valueDeclaration: undefined, 1943af6ab5fSopenharmony_ci members: undefined, 1953af6ab5fSopenharmony_ci exports: undefined, 1963af6ab5fSopenharmony_ci globalExports: undefined, 1973af6ab5fSopenharmony_ci exportSymbol: undefined, 1983af6ab5fSopenharmony_ci name: 'testSymbol', 1993af6ab5fSopenharmony_ci getFlags: function (): SymbolFlags { 2003af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2013af6ab5fSopenharmony_ci }, 2023af6ab5fSopenharmony_ci getEscapedName: function (): __String { 2033af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2043af6ab5fSopenharmony_ci }, 2053af6ab5fSopenharmony_ci getName: function (): string { 2063af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2073af6ab5fSopenharmony_ci }, 2083af6ab5fSopenharmony_ci getDeclarations: function (): Declaration[] | undefined { 2093af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2103af6ab5fSopenharmony_ci }, 2113af6ab5fSopenharmony_ci getDocumentationComment: function (typeChecker: TypeChecker | undefined): SymbolDisplayPart[] { 2123af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2133af6ab5fSopenharmony_ci }, 2143af6ab5fSopenharmony_ci getJsDocTags: function (checker?: TypeChecker): JSDocTagInfo[] { 2153af6ab5fSopenharmony_ci throw new Error('Function not implemented.'); 2163af6ab5fSopenharmony_ci } 2173af6ab5fSopenharmony_ci }; 2183af6ab5fSopenharmony_ci curScope.addDefinition(symbol); 2193af6ab5fSopenharmony_ci assert.equal(curScope.getSymbolLocation(symbol), 'testSymbol'); 2203af6ab5fSopenharmony_ci }); 2213af6ab5fSopenharmony_ci 2223af6ab5fSopenharmony_ci it('should return an empty string if symbol does not exist', function () { 2233af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 2243af6ab5fSopenharmony_ci let symbol: Symbol = Object(Symbol('nonExistentSymbol')); 2253af6ab5fSopenharmony_ci 2263af6ab5fSopenharmony_ci assert.equal(curScope.getSymbolLocation(symbol), ''); 2273af6ab5fSopenharmony_ci }); 2283af6ab5fSopenharmony_ci }); 2293af6ab5fSopenharmony_ci 2303af6ab5fSopenharmony_ci describe('getLabelLocation', function () { 2313af6ab5fSopenharmony_ci it('should return the correct location if label exists', function () { 2323af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 2333af6ab5fSopenharmony_ci let label: Label = {name: 'testLabel', locInfo: 'locInfo', refs: [], parent: undefined, children: [], scope: curScope}; 2343af6ab5fSopenharmony_ci 2353af6ab5fSopenharmony_ci curScope.addLabel(label); 2363af6ab5fSopenharmony_ci assert.equal(curScope.getLabelLocation(label), 'testLabel'); 2373af6ab5fSopenharmony_ci }); 2383af6ab5fSopenharmony_ci 2393af6ab5fSopenharmony_ci it('should return an empty string if label does not exist', function () { 2403af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 2413af6ab5fSopenharmony_ci let label: Label = {name: 'nonExistentLabel', locInfo: 'locInfo', refs: [], parent: undefined, children: [], scope: curScope}; 2423af6ab5fSopenharmony_ci 2433af6ab5fSopenharmony_ci assert.equal(curScope.getLabelLocation(label), ''); 2443af6ab5fSopenharmony_ci }); 2453af6ab5fSopenharmony_ci }); 2463af6ab5fSopenharmony_ci }); 2473af6ab5fSopenharmony_ci 2483af6ab5fSopenharmony_ci describe('unit test for createLabel', function () { 2493af6ab5fSopenharmony_ci const sourceFileContent = ` 2503af6ab5fSopenharmony_ci label: console.log('This is a labeled statement'); 2513af6ab5fSopenharmony_ci `; 2523af6ab5fSopenharmony_ci sourceFile = createSourceFile('test.ts', sourceFileContent, ScriptTarget.ES2015, true); 2533af6ab5fSopenharmony_ci let labeledStatement: LabeledStatement = sourceFile.statements[0] as LabeledStatement; 2543af6ab5fSopenharmony_ci let curScope = new Scope('curScope', sourceFile, ScopeKind.GLOBAL); 2553af6ab5fSopenharmony_ci 2563af6ab5fSopenharmony_ci it('should create a label and add it to the scope', function () { 2573af6ab5fSopenharmony_ci const label = createLabel(labeledStatement, curScope); 2583af6ab5fSopenharmony_ci 2593af6ab5fSopenharmony_ci assert.equal(label.name, labeledStatement.label.text); 2603af6ab5fSopenharmony_ci assert.equal(label.locInfo, `$0_${labeledStatement.label.text}`); 2613af6ab5fSopenharmony_ci assert.deepEqual(label.refs, [labeledStatement.label]); 2623af6ab5fSopenharmony_ci assert.equal(label.parent, undefined); 2633af6ab5fSopenharmony_ci assert.deepEqual(label.children, []); 2643af6ab5fSopenharmony_ci assert.equal(label.scope, curScope); 2653af6ab5fSopenharmony_ci assert.include(curScope.labels, label); 2663af6ab5fSopenharmony_ci }); 2673af6ab5fSopenharmony_ci 2683af6ab5fSopenharmony_ci it('should create a label with a parent and add it to the parent\'s children', function () { 2693af6ab5fSopenharmony_ci const parentLabel: Label = { 2703af6ab5fSopenharmony_ci name: 'parentLabel', 2713af6ab5fSopenharmony_ci locInfo: 'parentLocInfo', 2723af6ab5fSopenharmony_ci refs: [], 2733af6ab5fSopenharmony_ci parent: undefined, 2743af6ab5fSopenharmony_ci children: [], 2753af6ab5fSopenharmony_ci scope: curScope 2763af6ab5fSopenharmony_ci }; 2773af6ab5fSopenharmony_ci const label = createLabel(labeledStatement, curScope, parentLabel); 2783af6ab5fSopenharmony_ci 2793af6ab5fSopenharmony_ci assert.equal(label.name, labeledStatement.label.text); 2803af6ab5fSopenharmony_ci assert.equal(label.locInfo, `$1_${labeledStatement.label.text}`); 2813af6ab5fSopenharmony_ci assert.deepEqual(label.refs, [labeledStatement.label]); 2823af6ab5fSopenharmony_ci assert.equal(label.parent, parentLabel); 2833af6ab5fSopenharmony_ci assert.deepEqual(label.children, []); 2843af6ab5fSopenharmony_ci assert.equal(label.scope, curScope); 2853af6ab5fSopenharmony_ci assert.include(curScope.labels, label); 2863af6ab5fSopenharmony_ci assert.include(parentLabel.children, label); 2873af6ab5fSopenharmony_ci }); 2883af6ab5fSopenharmony_ci }); 2893af6ab5fSopenharmony_ci 2903af6ab5fSopenharmony_ci describe('unit test for createScopeManager', function () { 2913af6ab5fSopenharmony_ci let scopeManager: ScopeManager; 2923af6ab5fSopenharmony_ci let sourceFile: SourceFile; 2933af6ab5fSopenharmony_ci let checker: TypeChecker; 2943af6ab5fSopenharmony_ci 2953af6ab5fSopenharmony_ci function InitScopeManager(newFilePath: string): void { 2963af6ab5fSopenharmony_ci const fileContent = fs.readFileSync(newFilePath, 'utf8'); 2973af6ab5fSopenharmony_ci sourceFile = createSourceFile(newFilePath, fileContent, ScriptTarget.ES2015, true); 2983af6ab5fSopenharmony_ci checker = TypeUtils.createChecker(sourceFile); 2993af6ab5fSopenharmony_ci scopeManager = createScopeManager(); 3003af6ab5fSopenharmony_ci scopeManager.analyze(sourceFile, checker, false); 3013af6ab5fSopenharmony_ci } 3023af6ab5fSopenharmony_ci 3033af6ab5fSopenharmony_ci describe('analyze', function () { 3043af6ab5fSopenharmony_ci describe('analyzeModule', function () { 3053af6ab5fSopenharmony_ci let filePath = 'test/ut/utils/ScopeAnalyzer/analyzeModule.ts'; 3063af6ab5fSopenharmony_ci InitScopeManager(filePath); 3073af6ab5fSopenharmony_ci it('getReservedNames', function () { 3083af6ab5fSopenharmony_ci const reservedNames = scopeManager.getReservedNames(); 3093af6ab5fSopenharmony_ci assert.strictEqual(reservedNames.size === 0, true); 3103af6ab5fSopenharmony_ci }); 3113af6ab5fSopenharmony_ci it('getRootScope', function () { 3123af6ab5fSopenharmony_ci const rootScope = scopeManager.getRootScope(); 3133af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.size !== 0, true); 3143af6ab5fSopenharmony_ci }); 3153af6ab5fSopenharmony_ci describe('getScopeOfNode', function () { 3163af6ab5fSopenharmony_ci it('node is not identifier', function () { 3173af6ab5fSopenharmony_ci const node: SourceFile = sourceFile; 3183af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3193af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3203af6ab5fSopenharmony_ci }); 3213af6ab5fSopenharmony_ci 3223af6ab5fSopenharmony_ci it('node with no symbol', function () { 3233af6ab5fSopenharmony_ci const node: Identifier = factory.createIdentifier('noSymbolIdentifier'); 3243af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3253af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3263af6ab5fSopenharmony_ci }); 3273af6ab5fSopenharmony_ci 3283af6ab5fSopenharmony_ci it('get the scope of node', function () { 3293af6ab5fSopenharmony_ci const classDeclaration = sourceFile.statements.find(node => node && node.kind === SyntaxKind.ClassDeclaration); 3303af6ab5fSopenharmony_ci if (!classDeclaration) throw new Error('ClassDeclaration not found'); 3313af6ab5fSopenharmony_ci const node: Identifier = (classDeclaration as any)?.name; 3323af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3333af6ab5fSopenharmony_ci assert.strictEqual(scope?.name, ''); 3343af6ab5fSopenharmony_ci }); 3353af6ab5fSopenharmony_ci 3363af6ab5fSopenharmony_ci it('get no scope of node', function () { 3373af6ab5fSopenharmony_ci const anotherSourceFile = createSourceFile('another.ts', 'let y = 2;', ScriptTarget.ES2015, true); 3383af6ab5fSopenharmony_ci const node = (anotherSourceFile.statements[0] as VariableStatement).declarationList.declarations[0].name; 3393af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3403af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3413af6ab5fSopenharmony_ci }); 3423af6ab5fSopenharmony_ci }); 3433af6ab5fSopenharmony_ci }); 3443af6ab5fSopenharmony_ci 3453af6ab5fSopenharmony_ci describe('analyzeFunctionLike', function () { 3463af6ab5fSopenharmony_ci let filePath = 'test/ut/utils/ScopeAnalyzer/analyzeFunctionLike.ts'; 3473af6ab5fSopenharmony_ci InitScopeManager(filePath); 3483af6ab5fSopenharmony_ci it('getReservedNames', function () { 3493af6ab5fSopenharmony_ci const reservedNames = scopeManager.getReservedNames(); 3503af6ab5fSopenharmony_ci assert.strictEqual(reservedNames.size === 0, true); 3513af6ab5fSopenharmony_ci }); 3523af6ab5fSopenharmony_ci it('getRootScope', function () { 3533af6ab5fSopenharmony_ci const rootScope = scopeManager.getRootScope(); 3543af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.size !== 0, true); 3553af6ab5fSopenharmony_ci }); 3563af6ab5fSopenharmony_ci describe('getScopeOfNode', function () { 3573af6ab5fSopenharmony_ci it('node is not identifier', function () { 3583af6ab5fSopenharmony_ci const node: SourceFile = sourceFile; 3593af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3603af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3613af6ab5fSopenharmony_ci }); 3623af6ab5fSopenharmony_ci 3633af6ab5fSopenharmony_ci it('node with no symbol', function () { 3643af6ab5fSopenharmony_ci const node: Identifier = factory.createIdentifier('noSymbolIdentifier'); 3653af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3663af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3673af6ab5fSopenharmony_ci }); 3683af6ab5fSopenharmony_ci 3693af6ab5fSopenharmony_ci it('get the scope of node', function () { 3703af6ab5fSopenharmony_ci const functionDeclaration = sourceFile.statements.find(node => node && node.kind === SyntaxKind.FunctionDeclaration); 3713af6ab5fSopenharmony_ci if (!functionDeclaration) throw new Error('FunctionDeclaration not found'); 3723af6ab5fSopenharmony_ci const node: Identifier = (functionDeclaration as any)?.name; 3733af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3743af6ab5fSopenharmony_ci assert.strictEqual(scope?.name, ''); 3753af6ab5fSopenharmony_ci }); 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci it('get no scope of node', function () { 3783af6ab5fSopenharmony_ci const anotherSourceFile = createSourceFile('another.ts', 'let y = 2;', ScriptTarget.ES2015, true); 3793af6ab5fSopenharmony_ci const node = (anotherSourceFile.statements[0] as VariableStatement).declarationList.declarations[0].name; 3803af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 3813af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 3823af6ab5fSopenharmony_ci }); 3833af6ab5fSopenharmony_ci }); 3843af6ab5fSopenharmony_ci }); 3853af6ab5fSopenharmony_ci 3863af6ab5fSopenharmony_ci describe('analyzeExportNames', function () { 3873af6ab5fSopenharmony_ci let filePath = 'test/ut/utils/ScopeAnalyzer/analyzeExportNames.ts'; 3883af6ab5fSopenharmony_ci InitScopeManager(filePath); 3893af6ab5fSopenharmony_ci it('getReservedNames', function () { 3903af6ab5fSopenharmony_ci const reservedNames = scopeManager.getReservedNames(); 3913af6ab5fSopenharmony_ci assert.strictEqual(reservedNames.size === 0, true); 3923af6ab5fSopenharmony_ci }); 3933af6ab5fSopenharmony_ci it('getRootScope', function () { 3943af6ab5fSopenharmony_ci const rootScope = scopeManager.getRootScope(); 3953af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.size !== 0, true); 3963af6ab5fSopenharmony_ci }); 3973af6ab5fSopenharmony_ci describe('getScopeOfNode', function () { 3983af6ab5fSopenharmony_ci it('node is not identifier', function () { 3993af6ab5fSopenharmony_ci const node: SourceFile = sourceFile; 4003af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4013af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4023af6ab5fSopenharmony_ci }); 4033af6ab5fSopenharmony_ci 4043af6ab5fSopenharmony_ci it('node with no symbol', function () { 4053af6ab5fSopenharmony_ci const node: Identifier = factory.createIdentifier('noSymbolIdentifier'); 4063af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4073af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4083af6ab5fSopenharmony_ci }); 4093af6ab5fSopenharmony_ci 4103af6ab5fSopenharmony_ci it('get the scope of node', function () { 4113af6ab5fSopenharmony_ci const exportDeclaration = sourceFile.statements.find(node => node && node.kind === SyntaxKind.ExportDeclaration); 4123af6ab5fSopenharmony_ci if (!exportDeclaration) throw new Error('ExportDeclaration not found'); 4133af6ab5fSopenharmony_ci 4143af6ab5fSopenharmony_ci const exportClause = (exportDeclaration as any).exportClause; 4153af6ab5fSopenharmony_ci if (!exportClause || !exportClause.elements) throw new Error('ExportSpecifier not found'); 4163af6ab5fSopenharmony_ci 4173af6ab5fSopenharmony_ci const exportSpecifier = exportClause.elements[0]; 4183af6ab5fSopenharmony_ci const node: Identifier = exportSpecifier.name; 4193af6ab5fSopenharmony_ci 4203af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4213af6ab5fSopenharmony_ci assert.strictEqual(scope?.name, ''); 4223af6ab5fSopenharmony_ci }); 4233af6ab5fSopenharmony_ci 4243af6ab5fSopenharmony_ci it('get no scope of node', function () { 4253af6ab5fSopenharmony_ci const anotherSourceFile = createSourceFile('another.ts', 'let y = 2;', ScriptTarget.ES2015, true); 4263af6ab5fSopenharmony_ci const node = (anotherSourceFile.statements[0] as VariableStatement).declarationList.declarations[0].name; 4273af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4283af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4293af6ab5fSopenharmony_ci }); 4303af6ab5fSopenharmony_ci }); 4313af6ab5fSopenharmony_ci }); 4323af6ab5fSopenharmony_ci 4333af6ab5fSopenharmony_ci describe('analyzeImportEqualsDeclaration', function () { 4343af6ab5fSopenharmony_ci let filePath = 'test/ut/utils/ScopeAnalyzer/analyzeImportEqualsDeclaration.ts'; 4353af6ab5fSopenharmony_ci const fileContent = fs.readFileSync(filePath, 'utf8'); 4363af6ab5fSopenharmony_ci let sourceFile = createSourceFile(filePath, fileContent, ScriptTarget.ES2015, true); 4373af6ab5fSopenharmony_ci let checker = TypeUtils.createChecker(sourceFile); 4383af6ab5fSopenharmony_ci let scopeManager = createScopeManager(); 4393af6ab5fSopenharmony_ci scopeManager.analyze(sourceFile, checker, false); 4403af6ab5fSopenharmony_ci it('getReservedNames', function () { 4413af6ab5fSopenharmony_ci const reservedNames = scopeManager.getReservedNames(); 4423af6ab5fSopenharmony_ci assert.strictEqual(reservedNames.size === 0, true); 4433af6ab5fSopenharmony_ci }); 4443af6ab5fSopenharmony_ci it('getRootScope', function () { 4453af6ab5fSopenharmony_ci const rootScope = scopeManager.getRootScope(); 4463af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.size === 2, true); 4473af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.has("a"), true); 4483af6ab5fSopenharmony_ci assert.strictEqual(rootScope.fileExportNames?.has("b"), true); 4493af6ab5fSopenharmony_ci }); 4503af6ab5fSopenharmony_ci describe('getScopeOfNode', function () { 4513af6ab5fSopenharmony_ci it('node is not identifier', function () { 4523af6ab5fSopenharmony_ci const node: SourceFile = sourceFile; 4533af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4543af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4553af6ab5fSopenharmony_ci }); 4563af6ab5fSopenharmony_ci 4573af6ab5fSopenharmony_ci it('node with no symbol', function () { 4583af6ab5fSopenharmony_ci const node: Identifier = factory.createIdentifier('noSymbolIdentifier'); 4593af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4603af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4613af6ab5fSopenharmony_ci }); 4623af6ab5fSopenharmony_ci 4633af6ab5fSopenharmony_ci it('get the scope of node', function () { 4643af6ab5fSopenharmony_ci const moduleDeclaration = sourceFile.statements.find(node => node && node.kind === SyntaxKind.ModuleDeclaration); 4653af6ab5fSopenharmony_ci if (!moduleDeclaration) throw new Error('ModuleDeclaration not found'); 4663af6ab5fSopenharmony_ci const moduleBlock = (moduleDeclaration as any).body; 4673af6ab5fSopenharmony_ci if (!moduleBlock) throw new Error('ModuleBlock not found'); 4683af6ab5fSopenharmony_ci const importEqualsDeclaration = moduleBlock.statements.find(node => node && node.kind === SyntaxKind.ImportEqualsDeclaration); 4693af6ab5fSopenharmony_ci if (!importEqualsDeclaration) throw new Error('ImportEqualsDeclaration not found'); 4703af6ab5fSopenharmony_ci const node: Identifier = (importEqualsDeclaration as any)?.name; 4713af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4723af6ab5fSopenharmony_ci assert.strictEqual(scope?.name, 'ns111'); 4733af6ab5fSopenharmony_ci }); 4743af6ab5fSopenharmony_ci 4753af6ab5fSopenharmony_ci it('get no scope of node', function () { 4763af6ab5fSopenharmony_ci const anotherSourceFile = createSourceFile('another.ts', 'let y = 2;', ScriptTarget.ES2015, true); 4773af6ab5fSopenharmony_ci const node = (anotherSourceFile.statements[0] as VariableStatement).declarationList.declarations[0].name; 4783af6ab5fSopenharmony_ci const scope = scopeManager.getScopeOfNode(node); 4793af6ab5fSopenharmony_ci assert.strictEqual(scope, undefined); 4803af6ab5fSopenharmony_ci }); 4813af6ab5fSopenharmony_ci }); 4823af6ab5fSopenharmony_ci }); 4833af6ab5fSopenharmony_ci }); 4843af6ab5fSopenharmony_ci }); 4853af6ab5fSopenharmony_ci}); 4863af6ab5fSopenharmony_ci 4873af6ab5fSopenharmony_ci 488