1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use rollupObject file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { expect } from 'chai'; 17import mocha from 'mocha'; 18import * as ts from 'typescript'; 19import path from 'path'; 20import { hasDecorator } from '../../../lib/utils'; 21import { hasArkDecorator } from '../../../lib/fast_build/ark_compiler/utils'; 22import { 23 processSendableClass, 24 processSendableFunction, 25 processSendableType 26} from '../../../lib/process_sendable'; 27import { COMPONENT_SENDABLE_DECORATOR } from '../../../lib/pre_define'; 28 29const SENDABLE_WITHOUT_CONSTRUCTOR_CODE: string = 30` 31@Sendable 32class sendableClass {} 33` 34 35const SENDABLE_WITHOUT_CONSTRUCTOR_CODE_EXPECT: string = 36'"use strict";\n' + 37'class sendableClass {\n' + 38' constructor() {\n' + 39' "use sendable";\n' + 40' }\n' + 41'}\n' + 42'//# sourceMappingURL=sendableTest.js.map' 43 44const SENDABLE_WITH_CONSTRUCTOR_CODE: string = 45` 46@Sendable 47class sendableClass { 48 constructor() {} 49} 50` 51 52const SENDABLE_WITH_CONSTRUCTOR_CODE_EXPECT: string = 53'"use strict";\n' + 54'class sendableClass {\n' + 55' constructor() {\n' + 56' "use sendable";\n' + 57' }\n' + 58'}\n' + 59'//# sourceMappingURL=sendableTest.js.map' 60 61const SENDABLE_WITH_SUPER_CLASS_CODE: string = 62`@Sendable 63class SuperClass {} 64 65@Sendable 66class SubClass extends SuperClass {}` 67 68const SENDABLE_WITH_SUPER_CLASS_CODE_EXPECT: string = 69'"use strict";\n' + 70'class SuperClass {\n' + 71' constructor() {\n' + 72' "use sendable";\n' + 73' }\n' + 74'}\n' + 75'class SubClass extends SuperClass {\n' + 76' constructor(...args) {\n' + 77' "use sendable";\n' + 78' super(...args);\n' + 79' }\n' + 80'}\n' + 81'//# sourceMappingURL=sendableTest.js.map' 82 83const SENDABLE_WITH_SUPER_CLASS_AND_CONSTRUCTOR_CODE: string = 84 ` @Sendable 85class SuperClass {} 86 87@Sendable 88class SubClass extends SuperClass { 89 constructor() { 90 super(); 91 } 92}` 93 94const SENDABLE_WITH_SUPER_CLASS_AND_CONSTRUCTOR_CODE_EXPECT: string = 95'"use strict";\n' + 96'class SuperClass {\n' + 97' constructor() {\n' + 98' "use sendable";\n' + 99' }\n' + 100'}\n' + 101'class SubClass extends SuperClass {\n' + 102' constructor() {\n' + 103' "use sendable";\n' + 104' super();\n' + 105' }\n' + 106'}\n' + 107'//# sourceMappingURL=sendableTest.js.map' 108 109const SENDABLE_WITH_OVERLOADED_CONSTRUCTOR_CODE: string = 110`@Sendable 111class SuperClass { 112 constructor(name) { 113 this.name = name; 114 } 115} 116 117@Sendable 118class SubClass extends SuperClass { 119 120}` 121 122const SENDABLE_WITH_OVERLOADED_CONSTRUCTOR_CODE_EXPECT: string = 123'"use strict";\n' + 124'class SuperClass {\n' + 125' constructor(name) {\n' + 126' "use sendable";\n' + 127' this.name = name;\n' + 128' }\n' + 129'}\n' + 130'class SubClass extends SuperClass {\n' + 131' constructor(...args) {\n' + 132' "use sendable";\n' + 133' super(...args);\n' + 134' }\n' + 135'}\n' + 136'//# sourceMappingURL=sendableTest.js.map'; 137 138const SENDABLE_WITH_NO_PARENT_CONSTRUCTOR_CODE: string = 139`@Sendable 140class SuperClass { 141} 142 143@Sendable 144class SubClass extends SuperClass { 145 age: number; 146 constructor() 147 constructor(age: number) 148 constructor(age?: number) { 149 super(); 150 this.age = age !== undefined ? age : 0; 151 } 152}` 153 154const SENDABLE_WITH_NO_PARENT_CONSTRUCTOR_CODE_EXPECT: string = 155'"use strict";\n' + 156'class SuperClass {\n' + 157' constructor() {\n' + 158' "use sendable";\n' + 159' }\n' + 160'}\n' + 161'class SubClass extends SuperClass {\n' + 162' constructor(age) {\n' + 163' "use sendable";\n' + 164' super();\n' + 165' this.age = age !== undefined ? age : 0;\n' + 166' }\n' + 167'}\n' + 168'//# sourceMappingURL=sendableTest.js.map' 169 170const SENDABLE_FUNCTION_WITH_BODY: string = 171` 172@Sendable 173function sendableFunction() {} 174` 175 176const SENDABLE_FUNCTION_WITH_BODY_EXPECT: string = 177`"use strict"; 178function sendableFunction() { 179 "use sendable"; 180} 181//# sourceMappingURL=sendableTest.js.map` 182 183const SENDABLE_FUNCTION_WITHOUT_BODY: string = 184` 185@Sendable 186function sendableFunction() 187` 188 189const SENDABLE_FUNCTION_WITHOUT_BODY_EXPECT: string = 190`"use strict"; 191//# sourceMappingURL=sendableTest.js.map` 192 193const SENDABLE_TYPE: string = 194` 195@Sendable 196type SendableFunctionType = () => void 197` 198 199const SENDABLE_TYPE_EXPECT: string = 200`"use strict"; 201//# sourceMappingURL=sendableTest.js.map` 202 203const compilerOptions = ts.readConfigFile( 204 path.resolve(__dirname, '../../../tsconfig.json'), ts.sys.readFile).config.compilerOptions; 205 206function processSendable(): Function { 207 return (context: ts.TransformationContext) => { 208 const visitor: ts.Visitor = node => { 209 if (ts.isClassDeclaration(node) && hasDecorator(node, COMPONENT_SENDABLE_DECORATOR)) { 210 return processSendableClass(node); 211 } 212 if (ts.isFunctionDeclaration(node) && hasArkDecorator(node, COMPONENT_SENDABLE_DECORATOR)) { 213 return processSendableFunction(node); 214 } 215 if (ts.isTypeAliasDeclaration(node) && hasArkDecorator(node, COMPONENT_SENDABLE_DECORATOR)) { 216 return processSendableType(node); 217 } 218 return node; 219 }; 220 221 return (node: ts.SourceFile) => { 222 return ts.visitEachChild(node, visitor, context); 223 }; 224 } 225} 226 227mocha.describe('process sendable decorator', function () { 228 mocha.it('1-1: process sendable class without constrcutor tests', function () { 229 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITHOUT_CONSTRUCTOR_CODE, { 230 compilerOptions: compilerOptions, 231 fileName: "sendableTest.ts", 232 transformers: { before: [ processSendable() ] } 233 }); 234 expect(result.outputText == SENDABLE_WITHOUT_CONSTRUCTOR_CODE_EXPECT).to.be.true; 235 }); 236 mocha.it('1-2: process sendable class with constrcutor tests', function () { 237 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_CONSTRUCTOR_CODE, { 238 compilerOptions: compilerOptions, 239 fileName: "sendableTest.ts", 240 transformers: { before: [ processSendable() ] } 241 }); 242 expect(result.outputText == SENDABLE_WITH_CONSTRUCTOR_CODE_EXPECT).to.be.true; 243 }); 244 mocha.it('1-3: process sendable subclass with super class tests', function () { 245 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_SUPER_CLASS_CODE, { 246 compilerOptions: compilerOptions, 247 fileName: "sendableTest.ts", 248 transformers: { before: [ processSendable() ] } 249 }); 250 expect(result.outputText == SENDABLE_WITH_SUPER_CLASS_CODE_EXPECT).to.be.true; 251 }); 252 mocha.it('1-4: process sendable subclass with super class and constructor tests', function () { 253 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_SUPER_CLASS_AND_CONSTRUCTOR_CODE, { 254 compilerOptions: compilerOptions, 255 fileName: "sendableTest.ts", 256 transformers: { before: [ processSendable() ] } 257 }); 258 expect(result.outputText == SENDABLE_WITH_SUPER_CLASS_AND_CONSTRUCTOR_CODE_EXPECT).to.be.true; 259 }); 260 mocha.it('1-5: process sendable subclass with super class and constructor tests', function () { 261 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_OVERLOADED_CONSTRUCTOR_CODE, { 262 compilerOptions: compilerOptions, 263 fileName: "sendableTest.ts", 264 transformers: { before: [ processSendable() ] } 265 }); 266 expect(result.outputText == SENDABLE_WITH_OVERLOADED_CONSTRUCTOR_CODE_EXPECT).to.be.true; 267 }); 268 mocha.it('1-6: process sendable subclass with no explicit constructor in super class tests', function () { 269 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_NO_PARENT_CONSTRUCTOR_CODE, { 270 compilerOptions: compilerOptions, 271 fileName: "sendableTest.ts", 272 transformers: { before: [ processSendable() ] } 273 }); 274 expect(result.outputText == SENDABLE_WITH_NO_PARENT_CONSTRUCTOR_CODE_EXPECT).to.be.true; 275 }); 276 mocha.it('2-1: process sendable function with body tests', function () { 277 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_FUNCTION_WITH_BODY, { 278 compilerOptions: compilerOptions, 279 fileName: "sendableTest.ts", 280 transformers: { before: [ processSendable() ] } 281 }); 282 expect(result.outputText == SENDABLE_FUNCTION_WITH_BODY_EXPECT).to.be.true; 283 }); 284 mocha.it('2-2: process sendable function without body tests', function () { 285 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_FUNCTION_WITHOUT_BODY, { 286 compilerOptions: compilerOptions, 287 fileName: "sendableTest.ts", 288 transformers: { before: [ processSendable() ] } 289 }); 290 expect(result.outputText == SENDABLE_FUNCTION_WITHOUT_BODY_EXPECT).to.be.true; 291 }); 292 mocha.it('3-1: process sendable type tests', function () { 293 const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_TYPE, { 294 compilerOptions: compilerOptions, 295 fileName: "sendableTest.ts", 296 transformers: { before: [ processSendable() ] } 297 }); 298 expect(result.outputText == SENDABLE_TYPE_EXPECT).to.be.true; 299 }); 300})