diff --git a/compiler/src/process_kit_import.ts b/compiler/src/process_kit_import.ts index 3dfa9e9a4ec241a94a4222a38fbb910757e8dd63..433d6b35e2b7cb6a212a5b559ca559818732ca34 100644 --- a/compiler/src/process_kit_import.ts +++ b/compiler/src/process_kit_import.ts @@ -179,7 +179,7 @@ class SpecificerInfo { } } -class KitInfo { +export class KitInfo { private static currentKitInfo: KitInfo = undefined; private static currentFileType: FileType = FileType.ETS; private static currentKitName: string = ''; diff --git a/compiler/test/ark_compiler_ut/common/ark_utils.test.ts b/compiler/test/ark_compiler_ut/ark_utils.test.ts similarity index 82% rename from compiler/test/ark_compiler_ut/common/ark_utils.test.ts rename to compiler/test/ark_compiler_ut/ark_utils.test.ts index 5252ab989e1987467f4d92529fb8a22525349ecd..b4d3a2c5d10e165db71f57c2d90bcb92b92ffe9b 100644 --- a/compiler/test/ark_compiler_ut/common/ark_utils.test.ts +++ b/compiler/test/ark_compiler_ut/ark_utils.test.ts @@ -13,11 +13,14 @@ * limitations under the License. */ +// Execute this file first to avoid circular dependency problems + import { expect } from 'chai'; import mocha from 'mocha'; import fs from "fs"; import path from "path"; import MagicString from 'magic-string'; +import sinon from 'sinon'; import { getBuildModeInLowerCase, @@ -25,8 +28,10 @@ import { genSourceMapFileName, isOhModules, isEs2Abc, + writeArkguardObfuscatedSourceCode, + writeMinimizedSourceCode, writeTerserObfuscatedSourceCode -} from '../../../lib/ark_utils'; +} from '../../lib/ark_utils'; import { DEBUG, RELEASE, @@ -35,35 +40,36 @@ import { EXTNAME_JS, EXTNAME_ETS, OBFUSCATION_TOOL -} from '../../../lib/fast_build/ark_compiler/common/ark_define'; -import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock'; +} from '../../lib/fast_build/ark_compiler/common/ark_define'; +import RollUpPluginMock from './mock/rollup_mock/rollup_plugin_mock'; import { BUNDLE_NAME_DEFAULT, ENTRY_MODULE_NAME_DEFAULT, EXTNAME_MAP, ENTRYABILITY_JS -} from '../mock/rollup_mock/common'; -import projectConfig from '../utils/processProjectConfig'; +} from './mock/rollup_mock/common'; +import projectConfig from './utils/processProjectConfig'; import { ES2ABC, TS2ABC -} from '../../../lib/pre_define'; -import { changeFileExtension } from '../../../lib/fast_build/ark_compiler/utils'; -import ModuleSourceFileMock from '../mock/class_mock/module_source_files_mock'; +} from '../../lib/pre_define'; +import { changeFileExtension } from '../../lib/fast_build/ark_compiler/utils'; +import ModuleSourceFileMock from './mock/class_mock/module_source_files_mock'; import { genTemporaryPath, toUnixPath -} from '../../../lib/utils'; +} from '../../lib/utils'; import { ObConfigResolver, MergedConfig -} from '../../../lib/fast_build/ark_compiler/common/ob_config_resolver'; +} from '../../lib/fast_build/ark_compiler/common/ob_config_resolver'; import { utProcessArkConfig -} from '../../../lib/fast_build/ark_compiler/common/process_ark_config'; -import { ModuleSourceFile } from '../../../lib/fast_build/ark_compiler/module/module_source_file'; -import { newSourceMaps } from '../../../lib/fast_build/ark_compiler/transform'; -import { TERSER_PROCESSED_EXPECTED_CODE } from '../mock/rollup_mock/path_config'; +} from '../../lib/fast_build/ark_compiler/common/process_ark_config'; +import { ModuleSourceFile } from '../../lib/fast_build/ark_compiler/module/module_source_file'; +import { newSourceMaps } from '../../lib/fast_build/ark_compiler/transform'; +import { TERSER_PROCESSED_EXPECTED_CODE } from './mock/rollup_mock/path_config'; +import { GEN_ABC_PLUGIN_NAME } from '../../lib/fast_build/ark_compiler/common/ark_define'; mocha.describe('test ark_utils file api', function () { mocha.before(function () { @@ -340,4 +346,50 @@ mocha.describe('test ark_utils file api', function () { delete newSourceMaps[key]; } }); + + mocha.it('6-2: test the error message of writeTerserObfuscatedSourceCode', async function () { + this.rollup.build(RELEASE); + const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME); + const stub = sinon.stub(logger, 'error'); + const red: string = '\x1B[31m'; + try { + await writeTerserObfuscatedSourceCode(undefined, '', logger, undefined); + } catch (e) { + } + expect(stub.calledWith(red, + 'ArkTS:INTERNAL ERROR: Failed to obfuscate file with terser: ' + )).to.be.true; + stub.restore(); + }); + + mocha.it('7-1: test the error message of writeArkguardObfuscatedSourceCode', async function () { + this.rollup.build(RELEASE); + const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME); + const stub = sinon.stub(logger, 'error'); + const red: string = '\x1B[31m'; + try { + await writeArkguardObfuscatedSourceCode(undefined, '', logger, this.rollup.share.projectConfig, '', {}, ''); + } catch (e) { + } + expect(stub.calledWith(red, + 'ArkTS:INTERNAL ERROR: Failed to obfuscate file with arkguard: ' + )).to.be.true; + stub.restore(); + }); + + mocha.it('8-1: test the error message of writeMinimizedSourceCode', async function () { + this.rollup.build(RELEASE); + const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME); + const stub = sinon.stub(logger, 'error'); + const red: string = '\x1B[31m'; + const reset: string = '\x1B[39m'; + try { + await writeMinimizedSourceCode(undefined, '', logger); + } catch (e) { + } + expect(stub.calledWith(red, + 'ArkTS:INTERNAL ERROR: Failed to obfuscate source code for ', reset + )).to.be.true; + stub.restore(); + }); }); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/bundle/bundle_mode.test.ts b/compiler/test/ark_compiler_ut/bundle/bundle_mode.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8e4b82a19ddc9f01aad7f9597250b0be6a3c948 --- /dev/null +++ b/compiler/test/ark_compiler_ut/bundle/bundle_mode.test.ts @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use rollupObject file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import mocha from 'mocha'; +import sinon from 'sinon'; +import fs from 'fs'; +import cluster from 'cluster'; + +import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock'; +import { BundleMode } from '../../../lib/fast_build/ark_compiler/bundle/bundle_mode'; + + +mocha.describe('test bundle_mode file api', function () { + mocha.before(function () { + this.rollup = new RollUpPluginMock(); + }); + + mocha.after(() => { + delete this.rollup; + }); + + mocha.it('1-1: test error message of executeCompiler', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + bundleMode.projectConfig.pandaMode = 'invalid value'; + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + bundleMode.executeArkCompiler(); + expect(stub.calledWith('ArkTS:INTERNAL ERROR: Invalid compilation mode.')).to.be.true; + stub.restore(); + }); + + mocha.it('2-1: test the error message of executeEs2AbcCmd handler error', async function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + const triggerAsyncStub = sinon.stub(bundleMode, 'triggerAsync').throws(new Error('Execution failed')); + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + try { + bundleMode.executeEs2AbcCmd(); + } catch (e) { + } + expect(stub.calledWithMatch('ArkTS:ERROR failed to execute es2abc with async handler: ')).to.be.true; + triggerAsyncStub.restore(); + stub.restore(); + }); + + mocha.it('3-1: test the error message of collectBundleFileList(file.type is invalid value)', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': '' + } + }; + const stub = sinon.stub(this.rollup.share, 'throwArkTsCompilerError'); + new BundleMode(this.rollup, rollupBundleFileSet); + expect(stub.calledWith('ArkTS:INTERNAL ERROR: Failed to retrieve source code ' + + 'for test.js from rollup file set.')).to.be.true; + stub.restore(); + }); + + mocha.it('3-2: test the error message of collectBundleFileList', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const existsSyncStub = sinon.stub(fs, 'existsSync').callsFake((path) => { + const pattern = /test\.temp\.js$/; + if (pattern.test(path)) { + return false; + } + return true; + }); + const stub = sinon.stub(this.rollup.share, 'throwArkTsCompilerError'); + try { + new BundleMode(this.rollup, rollupBundleFileSet); + } catch (e) { + } + expect(stub.calledWith('ArkTS:INTERNAL ERROR: Failed to generate cached source file: test.js')).to.be.true; + existsSyncStub.restore(); + stub.restore(); + }); + + mocha.it('4-1: test the error message of filterBundleFileListWithHashJson', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + const jsonData = JSON.stringify(rollupBundleFileSet, null, 2); + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + for (const value of bundleMode.intermediateJsBundle.values()) { + fs.unlinkSync(value.cacheFilePath); + } + fs.writeFileSync(bundleMode.hashJsonFilePath, jsonData) + bundleMode.filterBundleFileListWithHashJson(); + expect(stub.calledWithMatch('ArkTS:INTERNAL ERROR: Failed to get bundle cached abc from ')).to.be.true; + stub.restore(); + }); + + mocha.it('5-1: test the error message of invokeTs2AbcWorkersToGenAbc(worker error)', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + const clusterStub = sinon.stub(cluster, 'fork'); + const fakeWorker = { + on: sinon.stub() + }; + clusterStub.returns(fakeWorker); + const splittedBundles = bundleMode.getSplittedBundles() + try { + fakeWorker.on.withArgs('message').callsFake((event, callback) => { + callback({ data: 'error' }); + }); + bundleMode.invokeTs2AbcWorkersToGenAbc(splittedBundles) + } catch (e) { + } + expect(stub.calledWith('ArkTS:ERROR Failed to execute ts2abc')).to.be.true; + clusterStub.restore(); + stub.restore(); + }); + + mocha.it('6-1: test the error message of writeHashJson', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + try { + bundleMode.writeHashJson(); + } catch (e) { + } + expect(stub.calledWithMatch('ArkTS:INTERNAL ERROR: During hash JSON file generation, ')).to.be.true; + stub.restore(); + }); + + mocha.it('7-1: test the error message of copyFileFromCachePathToOutputPath', function () { + this.rollup.build(); + const rollupBundleFileSet: Object = { + 'test.js': { + 'type': 'asset', + 'source': 'test' + } + }; + const bundleMode = new BundleMode(this.rollup, rollupBundleFileSet); + const stub = sinon.stub(bundleMode, 'throwArkTsCompilerError'); + try { + bundleMode.copyFileFromCachePathToOutputPath(); + } catch (e) { + } + expect(stub.calledWithMatch('not found during incremental build. ' + + 'Please try to rebuild the project')).to.be.true; + stub.restore(); + }); +}); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/common/gen_aot.test.ts b/compiler/test/ark_compiler_ut/common/gen_aot.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..b839c686e7c3c6bcb26e9c87855b49d3f5417cb4 --- /dev/null +++ b/compiler/test/ark_compiler_ut/common/gen_aot.test.ts @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use rollupObject file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { expect } from 'chai'; +import mocha from 'mocha'; +import path from "path"; +import fs from "fs"; +import sinon from 'sinon'; +import childProcess from 'child_process'; + +import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock'; +import { + generateAot, + generateBuiltinAbc +} from '../../../lib/gen_aot'; +import { ModuleMode } from '../../../lib/fast_build/ark_compiler/module/module_mode'; +import { TEMPORARY } from '../../../lib/pre_define'; + +mocha.describe('test gen_aot file api', function () { + mocha.before(function () { + this.rollup = new RollUpPluginMock(); + }); + + mocha.after(() => { + delete this.rollup; + }); + + mocha.it('1-1: test the error message of generateAot (full)', function () { + this.rollup.build(); + const moduleMode = new ModuleMode(this.rollup); + const loggerStub = sinon.stub(moduleMode.logger, 'debug'); + const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); + const faultHandler = ((error: string) => { moduleMode.throwArkTsCompilerError(error); }) + const builtinAbcPath = path.join(moduleMode.projectConfig.cachePath, TEMPORARY, 'aot', 'lib_ark_builtins.d.abc'); + try { + generateAot(moduleMode.arkConfig.arkRootPath, builtinAbcPath, moduleMode.moduleAbcPath, + moduleMode.projectConfig, moduleMode.logger, faultHandler); + } catch (e) { + } + expect(stub.calledWithMatch('ArkTS:ERROR GenerateAot failed. AppAbc not found in ')).to.be.true; + expect(stub.calledWithMatch('ArkTS:ERROR GenerateAot failed. unknown anBuildMode: ')).to.be.true; + loggerStub.restore(); + stub.restore(); + }); + + mocha.it('1-2: test the error message of generateAot (partial)', function () { + this.rollup.build(); + const moduleMode = new ModuleMode(this.rollup); + const loggerStub = sinon.stub(moduleMode.logger, 'debug'); + const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); + const faultHandler = ((error: string) => { moduleMode.throwArkTsCompilerError(error); }); + const builtinAbcPath = path.join(moduleMode.projectConfig.cachePath, TEMPORARY, 'aot', 'lib_ark_builtins.d.abc'); + moduleMode.projectConfig.anBuildMode = 'partial'; + moduleMode.projectConfig.apPath = ''; + try { + generateAot(moduleMode.arkConfig.arkRootPath, builtinAbcPath, moduleMode.moduleAbcPath, + moduleMode.projectConfig, moduleMode.logger, faultHandler); + } catch (e) { + } + expect(stub.calledWith('ArkTS:ERROR GenerateAot failed. Invalid profile file path.')).to.be.true; + expect(stub.calledWithMatch('ArkTS:ERROR GenerateAot failed. Partial mode lost profile in "')).to.be.true; + loggerStub.restore(); + stub.restore(); + }); + + mocha.it('2-1: test the error message of generateBuiltinAbc', function () { + this.rollup.build(); + const moduleMode = new ModuleMode(this.rollup); + const loggerStub = sinon.stub(moduleMode.logger, 'debug'); + const execSyncStub = sinon.stub(childProcess, 'execSync'); + const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); + const faultHandler = ((error: string) => { moduleMode.throwArkTsCompilerError(error); }) + try { + generateBuiltinAbc(moduleMode.arkConfig.arkRootPath, moduleMode.initCmdEnv(), + moduleMode.projectConfig.cachePath, moduleMode.logger, faultHandler, moduleMode.projectConfig.pandaMode); + } catch (e) { + } + expect(stub.calledWithMatch('ArkTS:ERROR Failed to generate builtin to abc.\n')).to.be.true; + loggerStub.restore(); + execSyncStub.restore(); + stub.restore(); + }); +}); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts b/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts index e2b8a0f33fdcfcaf12f4bc23f91b73d01b4bd014..2d4e84075b798b223a68043f31e9509889891eca 100644 --- a/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts +++ b/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts @@ -20,8 +20,10 @@ import path from 'path'; import { processKitImport, - kitTransformLog -} from '../../../lib/process_kit_import' + kitTransformLog, + KitInfo +} from '../../../lib/process_kit_import'; +import { findImportSpecifier } from '../utils/utils'; const KIT_IMPORT_CODE: string = ` @@ -62,9 +64,12 @@ const KIT_STAR_EXPORT_CODE_EXPECT: string = 'export * from "@ohos.multimedia.systemSoundManager";\n'+ '//# sourceMappingURL=kitTest.js.map' -const KIT_IMPORT_ERROR_EXPECT: string = +const KIT_IMPORT_ERROR_CODE: string = 'import { Ability } from "@kit.Kit";' +const KIT_IMPORT_DEFAULT_CODE: string = +'import { Ability } from "@kit.AbilityKit";' + const compilerOptions = ts.readConfigFile( path.resolve(__dirname, '../../../tsconfig.json'), ts.sys.readFile).config.compilerOptions; compilerOptions['moduleResolution'] = 'nodenext'; @@ -100,7 +105,7 @@ mocha.describe('process Kit Imports tests', function () { }); mocha.it('the error message of processKitImport', function () { - ts.transpileModule(KIT_IMPORT_ERROR_EXPECT, { + ts.transpileModule(KIT_IMPORT_ERROR_CODE, { compilerOptions: compilerOptions, fileName: "kitTest.ts", transformers: { before: [ processKitImport() ] } @@ -112,4 +117,24 @@ mocha.describe('process Kit Imports tests', function () { ); expect(hasError).to.be.true; }); + + mocha.it('the error message of newSpecificerInfo', function () { + const symbols = { + 'test': '' + } + const sourceCode = 'import { test } from "my-module";'; + const sourceFile = ts.createSourceFile( + "tempFile.ts", + sourceCode, + ts.ScriptTarget.Latest, + true + ); + const kitNode = findImportSpecifier(sourceFile); + const kitInfo = new KitInfo(kitNode, symbols); + kitInfo.newSpecificerInfo('', 'test', undefined) + const hasError = kitTransformLog.errors.some(error => + error.message.includes("'test' is not exported from Kit") + ); + expect(hasError).to.be.true; + }); }); diff --git a/compiler/test/ark_compiler_ut/mock/rollup_mock/path_config.ts b/compiler/test/ark_compiler_ut/mock/rollup_mock/path_config.ts index b244772c93e8501e3b4440356c8fce5f9cdd871a..e288ca69a0f032468ad7fe19cd608f4d83496d7f 100644 --- a/compiler/test/ark_compiler_ut/mock/rollup_mock/path_config.ts +++ b/compiler/test/ark_compiler_ut/mock/rollup_mock/path_config.ts @@ -28,6 +28,7 @@ export const MODULE_ID_ROLLUP_PLACEHOLDER = "\x00rollup_plugin_ignore_empty_modu // project build node_modules export const NODE_MODULES_PATH = "default/intermediates/loader_out/default/node_modules"; +export const AN_BUILD_OUTPUT_PATH = 'default/intermediates/loader_out/default/an/arm64-v8a'; export const ES2ABC_PATH: string = '/build/bin/es2abc'; export const TS2ABC_PATH: string = '/build/src/index.js'; diff --git a/compiler/test/ark_compiler_ut/mock/rollup_mock/project_config.ts b/compiler/test/ark_compiler_ut/mock/rollup_mock/project_config.ts index b7ee8eceb5f30ce4a906f83d9ad1799088e62110..18bc552d48ad20b1df39785a2513ebe95770a0cf 100644 --- a/compiler/test/ark_compiler_ut/mock/rollup_mock/project_config.ts +++ b/compiler/test/ark_compiler_ut/mock/rollup_mock/project_config.ts @@ -39,7 +39,7 @@ interface IArkProjectConfig { oldMapFilePath?: object, processTs: boolean, pandaMode: string, - anBuildOutPut?: object, + anBuildOutPut?: string, anBuildMode?: object, apPath?: object, nodeModulesPath?: object, diff --git a/compiler/test/ark_compiler_ut/mock/rollup_mock/rollup_plugin_mock.ts b/compiler/test/ark_compiler_ut/mock/rollup_mock/rollup_plugin_mock.ts index 958ebbe7d29d8622d07dffd5c91ef9d48edc5b64..cf30adbac21bd5bb435adfb78521cf6043d7ca67 100644 --- a/compiler/test/ark_compiler_ut/mock/rollup_mock/rollup_plugin_mock.ts +++ b/compiler/test/ark_compiler_ut/mock/rollup_mock/rollup_plugin_mock.ts @@ -28,7 +28,8 @@ import { import { DEFAULT_PROJECT, MODULE_ID_ROLLUP_PLACEHOLDER, - NODE_MODULES_PATH + NODE_MODULES_PATH, + AN_BUILD_OUTPUT_PATH } from "./path_config"; import { scanFiles } from "../../utils/utils"; import { IArkProjectConfig } from "./project_config"; @@ -121,7 +122,8 @@ class RollUpPluginMock { hotReload: undefined, patchAbcPath: undefined, changedFileList: undefined, - compileMode: ESMODULE + compileMode: ESMODULE, + anBuildOutPut: `${projectRootDir}/${entryName}/${mode}/${AN_BUILD_OUTPUT_PATH}` } } diff --git a/compiler/test/ark_compiler_ut/module/module_mode.test.ts b/compiler/test/ark_compiler_ut/module/module_mode.test.ts index 99aba6b4a7b325cabae4742a21cf44dfcc2daf20..5627453553cb7932ba2a3529cb84c840cd37b156 100644 --- a/compiler/test/ark_compiler_ut/module/module_mode.test.ts +++ b/compiler/test/ark_compiler_ut/module/module_mode.test.ts @@ -19,7 +19,8 @@ import mocha from 'mocha'; import path from 'path'; import sinon from 'sinon'; import fs from 'fs'; -import childProcess from 'child_process' +import childProcess from 'child_process'; +import cluster from 'cluster'; import { toUnixPath } from '../../../lib/utils'; import { newSourceMaps } from '../../../lib/fast_build/ark_compiler/transform'; @@ -924,21 +925,17 @@ mocha.describe('test module_mode file api', function () { expect(returnInfo === path.join(cachePath, sufStr)).to.be.true; }); - mocha.it('13-1: test the error message of generateMergedAbcOfEs2Abc throw error on failed code', function () { + mocha.it('13-1: test the error message of generateMergedAbcOfEs2Abc throw error on failed code', async function () { this.rollup.build(); const moduleMode = new ModuleModeMock(this.rollup); - const childStub = sinon.stub(childProcess, 'exec').callsFake((cmd, options, callback) => { - const child = new EventEmitter(); - process.nextTick(() => { - child.emit('close', FAIL); - }); - return child; - }); + const child = childProcess.exec('false', { windowsHide: true }); + const triggerAsyncStub = sinon.stub(moduleMode, 'triggerAsync').returns(child); const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); let parentEvent = undefined; moduleMode.generateMergedAbcOfEs2AbcMock(parentEvent); - expect(stub.calledWithMatch('ArkTS:ERROR Failed to execute es2abc')).to.be.true; - childStub.restore(); + await sleep(1000); + expect(stub.calledWithMatch('ArkTS:ERROR Failed to execute es2abc\n')).to.be.true; + triggerAsyncStub.restore(); stub.restore(); }); @@ -964,7 +961,7 @@ mocha.describe('test module_mode file api', function () { let readFileSyncStub = sinon.stub(fs, 'readFileSync'); let stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); moduleMode.moduleInfos = new Map([ - ['moduleKey', { cacheFilePath: 'test' }] // 添加测试条目 + ['moduleKey', { cacheFilePath: 'test' }] ]); existsSyncStub.callsFake((path) => { if (path === moduleMode.hashJsonFilePath) { @@ -995,4 +992,49 @@ mocha.describe('test module_mode file api', function () { execSyncStub.restore(); stub.restore(); }); + + mocha.it('16-1: test the error message of invokeTs2AbcWorkersToGenProto', function () { + this.rollup.build(); + const moduleMode = new ModuleMode(this.rollup); + const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); + const clusterStub = sinon.stub(cluster, 'fork'); + const fakeWorker = { + on: sinon.stub() + }; + clusterStub.returns(fakeWorker); + const splittedModules = [{ + 'test': '' + }] + try { + fakeWorker.on.withArgs('message').callsFake((event, callback) => { + callback({ data: 'error' }); + }); + moduleMode.invokeTs2AbcWorkersToGenProto(splittedModules) + } catch (e) { + } + expect(stub.calledWith('ArkTS:ERROR Failed to execute ts2abc.')).to.be.true; + clusterStub.restore(); + stub.restore(); + }); + + mocha.it('17-1: test the error message of invokeTs2AbcWorkersToGenAbc', function () { + this.rollup.build(); + const moduleMode = new ModuleMode(this.rollup); + const stub = sinon.stub(moduleMode, 'throwArkTsCompilerError'); + const clusterStub = sinon.stub(cluster, 'on'); + const fakeWorker = { + on: sinon.stub() + }; + clusterStub.returns(fakeWorker); + try { + clusterStub.withArgs('exit').callsFake((event, callback) => { + callback(fakeWorker, 1, null); + }); + moduleMode.processTs2abcWorkersToGenAbc() + } catch (e) { + } + expect(stub.calledWith('ArkTS:ERROR Failed to execute ts2abc')).to.be.true; + clusterStub.restore(); + stub.restore(); + }); }); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/module/module_preview_mode.test.ts b/compiler/test/ark_compiler_ut/module/module_preview_mode.test.ts index 2d4fea1d334a9192a7bd60d1fda613f7150980ce..16df1903616435eef3a66981979270d1c2d2ffd3 100644 --- a/compiler/test/ark_compiler_ut/module/module_preview_mode.test.ts +++ b/compiler/test/ark_compiler_ut/module/module_preview_mode.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use rollupObject file except in compliance with the License. * You may obtain a copy of the License at @@ -21,7 +21,7 @@ import sinon from 'sinon'; import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock'; import { ModulePreviewMode } from '../../../lib/fast_build/ark_compiler/module/module_preview_mode'; -mocha.describe('test module_mode file api', function () { +mocha.describe('test module_preview_mode file api', function () { mocha.before(function () { this.rollup = new RollUpPluginMock(); }); diff --git a/compiler/test/ark_compiler_ut/module/ohmUrl/ohmUrl.test.ts b/compiler/test/ark_compiler_ut/module/ohmUrl/ohmUrl.test.ts index 0c98367271abfa74c35453bda80d10e4224ff043..887dad5684bc27805a31f6799eeeb54c7bc0d2a2 100644 --- a/compiler/test/ark_compiler_ut/module/ohmUrl/ohmUrl.test.ts +++ b/compiler/test/ark_compiler_ut/module/ohmUrl/ohmUrl.test.ts @@ -150,4 +150,23 @@ mocha.describe('generate ohmUrl', function () { `and the corresponding file name matches (case sensitive)`, reset)).to.be.true; loggerStub.restore(); }); + + mocha.it('the error message of processPackageDir(packageDir is invalid value)', function () { + this.rollup.build(); + projectConfig.packageDir = undefined; + projectConfig.modulePathMap = {}; + const red: string = '\u001b[31m'; + const reset: string = '\u001b[39m'; + const filePath = `${projectConfig.projectRootPath}/entry/oh_modules/json5/dist/index.js`; + const moduleName = 'entry'; + const importerFile = 'importTest.ts'; + const logger = this.rollup.share.getLogger(GEN_ABC_PLUGIN_NAME) + const loggerStub = sinon.stub(logger, 'error'); + getOhmUrlByFilepath(filePath, projectConfig, logger, moduleName, importerFile); + expect(loggerStub.calledWith(red, + `ArkTS:ERROR Failed to get a resolved OhmUrl for "${filePath}" imported by "${importerFile}". ` + + `Please check whether the module which ${filePath} belongs to is correctly configured` + + `and the corresponding file name matches (case sensitive)`, reset)).to.be.true; + loggerStub.restore(); + }); }); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/utils/utils.ts b/compiler/test/ark_compiler_ut/utils/utils.ts index c61151643f552f67d71ba6e38a83d318e786043a..f6793e52ea25665bb6860cb64fa008f24ccfae34 100644 --- a/compiler/test/ark_compiler_ut/utils/utils.ts +++ b/compiler/test/ark_compiler_ut/utils/utils.ts @@ -16,6 +16,7 @@ import os from 'os'; import fs from "fs"; import path from "path"; +import * as ts from 'typescript'; import { PROJECT_ROOT } from "../mock/rollup_mock/path_config"; import { DEFAULT_PROJECT } from "../mock/rollup_mock/path_config"; @@ -45,3 +46,21 @@ export function scanFiles(filepath: string, fileList: Set) { export function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } + +export function findImportSpecifier(node) { + if (ts.isImportSpecifier(node)) { + return node; + } + let result = null; + let found = false; + ts.forEachChild(node, child => { + if (!found) { + const potentialResult = findImportSpecifier(child); + if (potentialResult !== null) { + result = potentialResult; + found = true; + } + } + }); + return result; +}