• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this 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
16
17const ts = require('typescript');
18const path = require('path');
19const fs = require('fs')
20
21
22const ignoreCaseFilePath= path.join(__dirname, "ignorecase.json")
23const compResults = {"detail":{}, 'failNum':0, "passedNum":0}
24let consoleDetail = false; ignoreList = []; failTestCaseList = []; genResultFile = false
25// Traverse the directory to find all test cases
26function getAllETSFiles(filePath) {
27  let allFilePaths = [];
28  if (fs.existsSync(filePath)) {
29      const files = fs.readdirSync(filePath);
30      for (let i = 0; i < files.length; i++) {
31          let file = files[i]; // File name (excluding file path)
32          let currentFilePath = filePath + '/' + file;
33          let stats = fs.lstatSync(currentFilePath);
34          if(ignoreList.includes(currentFilePath)){
35            continue
36          }
37          if (stats.isDirectory()) {
38              allFilePaths = allFilePaths.concat(getAllETSFiles(currentFilePath));
39          } else {
40              var index= currentFilePath.lastIndexOf(".");
41              var ext = currentFilePath.substring(index+1);
42              if (ext == "ets"){
43                allFilePaths.push(currentFilePath);
44                runComp(currentFilePath, file)
45              }
46          }
47      }
48  } else {
49      console.warn(`The specified directory ${filePath} Non-existent!`);
50  }
51  return allFilePaths;
52}
53
54function runComp(currentFilePath, file){
55    const result = runLinter(currentFilePath)
56    const jsonFile = currentFilePath.replace('ets','json')
57    const checkfile = fs.existsSync(jsonFile);
58    if(checkfile){
59      loadPares(jsonFile, result, currentFilePath, file)
60    }else{
61      if(!currentFilePath.includes("-dependencie.ets")){
62        console.log(`Test cases ${currentFilePath} expected results are not added`)
63      }
64    }
65}
66
67// Compare the results with expectations and count the success and failure situations
68function loadPares(jsonFile, result, currentFilePath, file){
69  const dirName = path.dirname(currentFilePath)
70  let rules = ""
71  if (dirName.includes("\\")){
72    rules = currentFilePath.split("\\")[currentFilePath.split("\\").length - 2]
73  }else{
74    rules = currentFilePath.split("/")[currentFilePath.split("/").length - 2]
75  }
76  const testCaseFileName = file
77  dataStr = fs.readFileSync(jsonFile, "utf-8")
78  const expect = JSON.parse(dataStr)
79  const compResult = compareResult(expect, result)
80  compResult["testCaseName"] = testCaseFileName
81  if (compResults["detail"].hasOwnProperty(rules)){
82    compResults["detail"][rules]["detail"].push(compResult)
83    compResults["detail"][rules]["testCaseNum"] += 1
84  }else{
85    compResults["detail"][rules] = {"detail":[compResult], "testCaseNum": 1, "failNum": 0, "passedNum": 0}
86  }
87  if(compResult.status){
88    compResults["passedNum"] += 1
89    compResults["detail"][rules]["passedNum"] += 1
90  }else{
91    failTestCaseList.push(currentFilePath)
92    if(consoleDetail){
93      console.log(`Test cases ${currentFilePath} Failed!`)
94      for(let compDetail of compResult.detail){
95        if(!compDetail.compResult){
96          console.log(`==>  Expect the error in Line ${compDetail.expectLineAndCharacter.line} The ${compDetail.expectLineAndCharacter.character} character. Expect exception rules:${compDetail.expectMessageText}  Actual error line ${compDetail.realLineAndCharacter.line}  The ${compDetail.realLineAndCharacter.character} character. Actual exception rules:${compDetail.realMessageText} Comparison Result:Fail!`)
97        }
98      }
99    }
100    compResults["failNum"] += 1
101    compResults['detail'][rules]["failNum"] += 1
102  }
103}
104
105
106// initial configuration
107options = ts.readConfigFile('tsconfig.json', ts.sys.readFile).config.compilerOptions;
108const allPath = ['*'];
109Object.assign(options, {
110  'emitNodeModulesFiles': true,
111  'importsNotUsedAsValues': ts.ImportsNotUsedAsValues.Preserve,
112  'module': ts.ModuleKind.CommonJS,
113  'moduleResolution': ts.ModuleResolutionKind.NodeJs,
114  'noEmit': true,
115  'target': ts.ScriptTarget.ES2017,
116  'baseUrl': "/",
117  'paths': {
118    '*': allPath
119  },
120  'lib': [
121    'lib.es2020.d.ts'
122  ],
123  'types': [],
124  'etsLoaderPath': 'null_sdkPath',
125});
126
127// Calling the runlinter interface
128function runLinter(rootName){
129    newprogram =  ts.createProgram({
130      rootNames: [path.join(process.cwd(), rootName)],
131      options: options,
132  })
133  const compilerHost = ts.createCompilerHost(newprogram.getCompilerOptions());
134  compilerHost.getCurrentDirectory = () => process.cwd();
135  compilerHost.getDefaultLibFileName = options => ts.getDefaultLibFilePath(options);
136  // compilerHost.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives;
137  let result= ts.runArkTSLinter(newprogram, compilerHost)
138  return result
139}
140
141// Compare the difference between the expected value and the actual return value of the runlinter to determine if the test has passed
142function compareResult(expect, reality){
143  let isPass = true
144  const itemPassList = new Array()
145   if(reality.length == 0){
146      if(expect.length == 0){
147        // pass
148        isPass = true
149      }else{
150        isPass = false
151        for(let expectInfo of expect){
152          const compInfo = {
153            'compResult':false,
154            'realLineAndCharacter':{"line": null,"character": null},
155            'realMessageText':null,
156            'expectLineAndCharacter':{"line": expectInfo.expectLineAndCharacter.line,"character": expectInfo.expectLineAndCharacter.character},
157            'expectMessageText':expectInfo.messageText,
158          }
159          itemPassList.push(compInfo)
160        }
161      }
162   }else{
163      if(expect.length == 0){
164        isPass = false
165        for(let realityInfo of reality){
166            const { line, character } = realityInfo.file.getLineAndCharacterOfPosition(realityInfo.start)
167            const compInfo = {
168              'compResult':false,
169              'realLineAndCharacter':{"line": line + 1,"character": character + 1},
170              'realMessageText':realityInfo.messageText,
171              'expectLineAndCharacter':{"line": null,"character": null},
172              'expectMessageText':null,
173            }
174            itemPassList.push(compInfo)
175        }
176      }else{
177        if( reality.length > expect.length){
178          isPass = false
179          for(let i=0; i<reality.length; i++){
180            const realErrorItem = reality[i]
181            const { line, character } = realErrorItem.file.getLineAndCharacterOfPosition(realErrorItem.start)
182            const realLine = {"line": line + 1,"character": character + 1}
183            const realMessageText = realErrorItem.messageText
184            let expectMessageText = null
185            let compResult = false
186            let expectLineAndCharacter = {"line": null,"character": null}
187            if( expect.length < i+1){
188              compResult = false
189            }else{
190              expectErrorItem = expect[i]
191              expectLineAndCharacter = {"line": expectErrorItem.expectLineAndCharacter.line,"character": expectErrorItem.expectLineAndCharacter.character}
192              expectMessageText = expectErrorItem.messageText
193              if ((expectErrorItem.expectLineAndCharacter.line === realLine.line && expectErrorItem.expectLineAndCharacter.character === realLine.character)
194              && realMessageText.includes(expectMessageText)){
195                compResult = true
196              }
197            }
198            const compInfo = {
199              'compResult':compResult,
200              'realLineAndCharacter':realLine,
201              'realMessageText':realMessageText,
202              'expectLineAndCharacter':expectLineAndCharacter,
203              'expectMessageText':expectMessageText,
204            }
205            itemPassList.push(compInfo)
206          }
207        }else if(reality.length < expect.length){
208          isPass = false
209          for(let i=0; i<expect.length; i++){
210            const expectErrorItem = expect[i]
211            const expectMessageText = expectErrorItem.messageText
212            let expectLineAndCharacter = {"line": expectErrorItem.expectLineAndCharacter.line,"character": expectErrorItem.expectLineAndCharacter.character}
213            let realLine = {"line": null,"character": null}
214            let realMessageText = null
215            let compResult = false
216            if( reality.length < i+1){
217              compResult = false
218            }else{
219              const realErrorItem = reality[i]
220              const { line, character } = realErrorItem.file.getLineAndCharacterOfPosition(realErrorItem.start)
221              realLine = {"line": line + 1,"character": character + 1}
222              realMessageText = realErrorItem.messageText
223              if ((expectErrorItem.expectLineAndCharacter.line === realLine.line && expectErrorItem.expectLineAndCharacter.character === realLine.character)
224              && realMessageText.includes(expectMessageText)){
225                compResult = true
226              }
227            }
228            const compInfo = {
229              'compResult':compResult,
230              'realLineAndCharacter':realLine,
231              'realMessageText':realMessageText,
232              'expectLineAndCharacter':expectLineAndCharacter,
233              'expectMessageText':expectMessageText,
234            }
235            itemPassList.push(compInfo)
236          }
237        }else{
238            for(let i =0;i<reality.length;i++){
239              const realErrorItem = reality[i]
240              const expectErrorItem = expect[i]
241              const expectMessageText = expectErrorItem.messageText
242              let expectLineAndCharacter = {"line": expectErrorItem.expectLineAndCharacter.line,"character": expectErrorItem.expectLineAndCharacter.character}
243              const { line, character } = realErrorItem.file.getLineAndCharacterOfPosition(realErrorItem.start)
244              const realLine = {"line": line + 1,"character": character + 1}
245              const realMessageText = realErrorItem.messageText
246              let compInfo = null; compResult = false
247              if ((expectErrorItem.expectLineAndCharacter.line === realLine.line && expectErrorItem.expectLineAndCharacter.character === realLine.character)
248                && realMessageText.includes(expectMessageText)){
249                compResult = true
250              }else{
251                isPass = false
252              }
253              compInfo = {
254                'compResult':compResult,
255                'realLineAndCharacter':realLine,
256                'realMessageText':realMessageText,
257                'expectLineAndCharacter':expectLineAndCharacter,
258                'expectMessageText':expectMessageText,
259              }
260              itemPassList.push(compInfo)
261            }
262      }
263    }
264  }
265  return {"status":isPass, "detail":itemPassList}
266}
267
268// output result file
269function writeResult(result){
270  const dir = path.join(__dirname, "test_results")
271  if (!fs.existsSync(dir)) {
272    fs.mkdirSync(dir)
273  }
274  fs.writeFileSync(path.join(dir, "test_result.json"), JSON.stringify(result, null, 4))
275}
276
277
278function run(){
279   let interval = 0, startTime = process.uptime()*1000, endTime = startTime;
280   const pathParam = getParam()
281   let filePath = 'testcase'
282   if(pathParam){
283    filePath = pathParam
284   }
285   let ignoreCaseConfigList = []
286   if(fs.existsSync(ignoreCaseFilePath)){
287    ignoreCaseConfigList = JSON.parse(fs.readFileSync(ignoreCaseFilePath)).ignoreCase
288   }
289
290   ignoreList = ignoreList.concat(ignoreCaseConfigList)
291   let filePathStats = fs.lstatSync(filePath)
292   if(!filePathStats.isDirectory()){
293      runComp(filePath, path.basename(filePath))
294   }else{
295      getAllETSFiles(filePath)
296   }
297   endTime = process.uptime()*1000
298   interval = (endTime - startTime);
299   const compReportDetail = {"compDetail": compResults, "compTime": interval, "failNum": compResults.failNum, "passedNum": compResults.passedNum}
300   const testCaseSum = compReportDetail.failNum + compReportDetail.passedNum
301   compReportDetail["testCaseSum"] = testCaseSum
302   console.log(`Total number of test cases:${testCaseSum} Number of use cases passed:${compResults.passedNum} The number of use cases that failed:${compResults.failNum} Total running time:${JSON.stringify(interval).split(".")[0]}ms`)
303   if(genResultFile){
304     writeResult(compReportDetail)
305   }
306   if (failTestCaseList.length > 0){
307      console.log("Failed test cases:")
308      for(let testCase of failTestCaseList){
309        console.log(testCase)
310      }
311    }
312   if(ignoreList.length>0){
313    console.log("Ignored test cases:")
314    for(let ignoreCase of ignoreList){
315      console.log(ignoreCase)
316    }
317   }
318   if(compReportDetail.failNum){
319    process.exit(1)
320   }
321}
322
323// get parameters
324function getParam(){
325  let pathArg = null
326  for(let key of process.argv){
327    if(key.includes("-P:")){
328      pathArg = key.replace("-P:", "")
329    }
330    if(key === "--detail" || key === "-D"){
331      consoleDetail = true
332    }
333    if(key === "-e"){
334      genResultFile = true
335    }
336    if(key.includes("--ignore-list:")){
337      let ignoreStr = key.replace("--ignore-list:", "")
338      ignoreList = ignoreStr.split(",")
339    }
340  }
341  return pathArg
342}
343
344// execute
345run()
346