AutoTest.swift 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. //
  2. // AutoTest.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2022/11/25.
  6. //
  7. import Foundation
  8. import AppKit
  9. var cacheObjects = NSMutableDictionary()
  10. class AutoTest : NSObject, AutoTestProtocal {
  11. var reportString : NSMutableAttributedString? = nil
  12. public var _status : AutoTestStatus = .Normal
  13. var _fileType : String = "RTF"
  14. var _type : String = "Others"
  15. var _extention : String = "rtf"
  16. class func autoTestFor(_ fileType:NSString ,type:NSString) -> AutoTest? {
  17. let key = String(fileType) + "." + String(type)
  18. if cacheObjects.value(forKey: key) != nil {
  19. let object = cacheObjects.value(forKey: key)
  20. return object as? AutoTest
  21. }
  22. // if let cacheObject as AutoTest {
  23. // return cacheObject
  24. // }
  25. let fileTypes = testTypeInfo[fileType] as! NSArray
  26. let clsname = "KdanAuto"//Bundle.main.infoDictionary! ["CFBundleExecutable"]
  27. for item in fileTypes {
  28. let cItem = item as! NSDictionary
  29. let cType = cItem["Type"] as! NSString
  30. let cExtention = cItem["Extention"] as! NSString
  31. if (cType.isEqual(to: type)) {
  32. let className = String((clsname )+"."+(cItem["Class"] as! String)) as! String
  33. let cl = NSClassFromString(className) as! AutoTest.Type
  34. let object = cl.shared()
  35. object?._fileType = fileType as! String
  36. object?._type = String(cType)
  37. object?._extention = String(cExtention)
  38. cacheObjects.setValue(object, forKey: key)
  39. return object
  40. }
  41. }
  42. let object = AutoTest.shared()
  43. object?._fileType = fileType as String
  44. object?._type = String(cType)
  45. object?._extention = ""
  46. cacheObjects.setValue(object, forKey: key)
  47. return object
  48. }
  49. class func shared() -> AutoTest? {
  50. return AutoTest()
  51. }
  52. func fileType() -> String {
  53. return _fileType
  54. }
  55. func type() -> String {
  56. return _type
  57. }
  58. func name() -> String {
  59. return "对照测试"
  60. }
  61. func keys() -> NSArray {
  62. return ["快照"]
  63. }
  64. func selectedKeys() -> NSArray {
  65. let userDefaults = UserDefaults.standard
  66. let key = self.fileType() + "." + self.type() + ".selectedKeys"
  67. if userDefaults.value(forKey: key) != nil {
  68. return userDefaults.value(forKey: key) as! NSArray
  69. }
  70. self.setSelectedKeys(self.keys())
  71. return self.keys()
  72. }
  73. func setSelectedKeys(_ keys: NSArray) {
  74. let userDefaults = UserDefaults.standard
  75. let key = self.fileType() + "." + self.type() + ".selectedKeys"
  76. userDefaults.setValue(keys, forKey: key)
  77. userDefaults.synchronize()
  78. }
  79. func status() -> AutoTestStatus {
  80. return _status
  81. }
  82. func setStatus(_ status:AutoTestStatus) {
  83. _status = status
  84. }
  85. // Auto Test
  86. func autoTest() {
  87. clearCacheFiles()
  88. if hasOriginFile() {
  89. let needCompare = self.selectedKeys().contains("快照")
  90. if !needCompare {
  91. _status = .Finished
  92. return
  93. }
  94. _status = .Process
  95. reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】快照比对开始!\n",
  96. attributes:[.foregroundColor : NSColor.blue])
  97. let files = DataModel.shared.originFilesFor(_fileType, type: _type) as [String]
  98. let checkDirectory = self.checkFileDirectory()
  99. let originDirectory = self.originFileDirectory()
  100. let resultDirectory = self.resultFileDirectory()
  101. var tDegree = Double(0);
  102. var tCount = Int(0)
  103. for fileName in files {
  104. let fName = NSString(string: fileName).deletingPathExtension
  105. let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  106. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
  107. let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
  108. reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】开始转换文件 \"\(fName)\"\n",
  109. attributes:[.foregroundColor : NSColor.blue]))
  110. // ...
  111. // 执行转换过程
  112. var success = process(originPath, resultPath: resultPath)
  113. var isDirectory = ObjCBool(false)
  114. if FileManager.default.fileExists(atPath: resultPath, isDirectory:&isDirectory) && success {
  115. // compare screenshoot between result file with check file
  116. if needCompare {
  117. let items = NSMutableArray()
  118. if (isDirectory.boolValue) {
  119. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultPath)
  120. for item in NSArray(array: searchItems) {
  121. let ext = NSString(string: item as! String).pathExtension.lowercased()
  122. if NSArray(array: [_extention]).contains(ext) {
  123. let fileName = NSString(string: fName+"."+_extention+"/\(item as! String)").deletingPathExtension
  124. items.add(fileName)
  125. }
  126. }
  127. }else {
  128. items.add(fName)
  129. }
  130. var subDegree = Double(0);
  131. var subCount = Int(0)
  132. for item in items {
  133. let subFileName = item as! String
  134. let subResultPath = NSString(string: resultDirectory).appendingPathComponent(subFileName+"."+_extention)
  135. reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subFileName+".\(_extention)")\"快照生成中\n",
  136. attributes:[.foregroundColor : NSColor.black]))
  137. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
  138. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
  139. let processThumbSemaphore = DispatchSemaphore(value: 0)
  140. var processSuccess = false
  141. let thumbnailQueue = DispatchQueue.global()
  142. thumbnailQueue.async {
  143. processSuccess = ProcessThumbnal.process(subResultPath, desPath: rComparePath, outputSize: CGSize.init(width: 2048, height: 2048))
  144. if ( processSuccess &&
  145. FileManager.default.fileExists(atPath: rComparePath)) {
  146. var isDirectory = ObjCBool(false)
  147. if FileManager.default.fileExists(atPath: rComparePath, isDirectory: &isDirectory) && isDirectory.boolValue {
  148. // 单个文件生成批量快照目录情形
  149. let subImages = try! FileManager.default.contentsOfDirectory(atPath: rComparePath)
  150. for subImageName in subImages {
  151. let pathCompotent = "/"+subImageName
  152. let degree = ImageProcess.compareJPEG(String(rComparePath+pathCompotent), checkPath: String(cComparePath+pathCompotent), processCover: true)
  153. if isDirectory.boolValue {
  154. TestDegreeManager.shared().set(degree, fileType: self.fileType(), type: self.type(),
  155. fileName: fileName, refFilePath: subFileName+".jpg"+pathCompotent)
  156. }
  157. if degree == -1 {
  158. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比失败,生成快照失败或无比对文件\n",
  159. attributes:[.foregroundColor : NSColor.red]))
  160. }else {
  161. var color = NSColor.black
  162. if fabs(degree-100.0) >= 0.01 {
  163. color = NSColor.red
  164. }
  165. subDegree += degree
  166. subCount += 1
  167. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比完成,图像相似度 \(degree)%\n",
  168. attributes:[.foregroundColor : color]))
  169. }
  170. }
  171. }else {
  172. // 单个文件生成单个快照文件情形
  173. let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath, processCover: true)
  174. if isDirectory.boolValue {
  175. TestDegreeManager.shared().set(degree, fileType: self.fileType(), type: self.type(),
  176. fileName: fileName, refFilePath: subFileName+".jpg")
  177. }
  178. if degree == -1 {
  179. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比失败,生成快照失败或无比对文件\n",
  180. attributes:[.foregroundColor : NSColor.red]))
  181. }else {
  182. var color = NSColor.black
  183. if fabs(degree-100.0) >= 0.01 {
  184. color = NSColor.red
  185. }
  186. subDegree += degree
  187. subCount += 1
  188. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比完成,图像相似度 \(degree)%\n",
  189. attributes:[.foregroundColor : color]))
  190. }
  191. }
  192. }else {
  193. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照生成失败\n",
  194. attributes:[.foregroundColor : NSColor.red]))
  195. }
  196. processThumbSemaphore.signal()
  197. }
  198. processThumbSemaphore.wait()
  199. }
  200. if subCount != 0 {
  201. subDegree = subDegree/Double(subCount)
  202. }else {
  203. subDegree = 0.0
  204. }
  205. TestDegreeManager.shared().set(subDegree,
  206. fileType: self.fileType(),
  207. type: self.type(),
  208. fileName: fileName)
  209. tDegree += subDegree;
  210. tCount += 1
  211. }
  212. }else {
  213. reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档失败!\n",
  214. attributes:[.foregroundColor : NSColor.red]))
  215. }
  216. }
  217. TestDegreeManager.shared().set(((tCount != 0) ? tDegree/Double(tCount) : 0.0),
  218. fileType: _fileType,
  219. type: _type)
  220. _status = .Finished
  221. }else {
  222. _status = .Normal
  223. }
  224. }
  225. func process(_ originPath:String, resultPath:String) -> Bool {
  226. // ...
  227. // 执行转换过程
  228. let convertSemaphore = DispatchSemaphore(value: 0)
  229. var success = false
  230. let convertQueue = DispatchQueue.global()
  231. convertQueue.async {
  232. success = FileConverter.shared().converter(originPath, inDesPath: resultPath)
  233. convertSemaphore.signal()
  234. }
  235. convertSemaphore.wait()
  236. return success
  237. }
  238. func testReport() -> NSAttributedString? {
  239. return reportString
  240. }
  241. func degree() -> Double {
  242. return TestDegreeManager.shared().degreeFor(self.fileType(), type: self.type())
  243. }
  244. // func testReportOfFile(_ fileName:String) -> NSAttributedString? {
  245. //
  246. // }
  247. func degreeOfFile(_ fileName:String) -> Double {
  248. return TestDegreeManager.shared().degreeFor(self.fileType(), type: self.type(), fileName: fileName)
  249. }
  250. func degreeOfFile(_ fileName:String, refFilePath:String?) -> Double {
  251. if refFilePath != nil {
  252. return TestDegreeManager.shared().degreeFor(self.fileType(), type: self.type(), fileName: fileName, refFilePath: refFilePath)
  253. }else {
  254. return degreeOfFile(fileName)
  255. }
  256. }
  257. // Update Refrence image
  258. func canUpdateRefImage() -> Bool {
  259. let files = DataModel.shared.originFilesFor(_fileType, type: _type) as [String]
  260. let checkDirectory = self.checkFileDirectory()
  261. let originDirectory = self.originFileDirectory()
  262. let resultDirectory = self.resultFileDirectory()
  263. for fileName in files {
  264. let fName = NSString(string: fileName).deletingPathExtension
  265. let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  266. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
  267. let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
  268. var isDirectory = ObjCBool(false)
  269. if FileManager.default.fileExists(atPath: resultPath, isDirectory:&isDirectory) {
  270. // compare screenshoot between result file with check file
  271. let items = NSMutableArray()
  272. if (isDirectory.boolValue) {
  273. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultPath)
  274. for item in NSArray(array: searchItems) {
  275. let ext = NSString(string: item as! String).pathExtension.lowercased()
  276. if NSArray(array: [_extention]).contains(ext) {
  277. let fileName = NSString(string: fName+"."+_extention+"/\(item as! String)").deletingPathExtension
  278. items.add(fileName)
  279. }
  280. }
  281. }else {
  282. items.add(fName)
  283. }
  284. for item in items {
  285. let subFileName = item as! String
  286. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
  287. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
  288. if FileManager.default.fileExists(atPath: rComparePath) {
  289. if !FileManager.default.fileExists(atPath: cComparePath) {
  290. return true
  291. }
  292. let rfs = try! FileManager.default.attributesOfItem(atPath: rComparePath)[FileAttributeKey.size] as! NSNumber
  293. let cfs = try! FileManager.default.attributesOfItem(atPath: cComparePath)[FileAttributeKey.size] as! NSNumber
  294. if rfs.int64Value != cfs.int64Value {
  295. return true
  296. }
  297. }
  298. }
  299. }
  300. }
  301. return false
  302. }
  303. func updateRefImage() {
  304. let files = DataModel.shared.originFilesFor(_fileType, type: _type) as [String]
  305. for fileName in files {
  306. updateRefImage(fileName)
  307. }
  308. }
  309. func canUpdateRefImage(_ fileName:String) -> Bool {
  310. let checkDirectory = self.checkFileDirectory()
  311. let originDirectory = self.originFileDirectory()
  312. let resultDirectory = self.resultFileDirectory()
  313. let fName = NSString(string: fileName).deletingPathExtension
  314. let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  315. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
  316. let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
  317. var isDirectory = ObjCBool(false)
  318. if FileManager.default.fileExists(atPath: resultPath, isDirectory:&isDirectory) {
  319. // compare screenshoot between result file with check file
  320. let items = NSMutableArray()
  321. if (isDirectory.boolValue) {
  322. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultPath)
  323. for item in NSArray(array: searchItems) {
  324. let ext = NSString(string: item as! String).pathExtension.lowercased()
  325. if NSArray(array: [_extention]).contains(ext) {
  326. let fileName = NSString(string: fName+"."+_extention+"/\(item as! String)").deletingPathExtension
  327. items.add(fileName)
  328. }
  329. }
  330. }else {
  331. items.add(fName)
  332. }
  333. for item in items {
  334. let subFileName = item as! String
  335. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
  336. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
  337. if FileManager.default.fileExists(atPath: rComparePath) {
  338. if !FileManager.default.fileExists(atPath: cComparePath) {
  339. return true
  340. }
  341. let rfs = try! FileManager.default.attributesOfItem(atPath: rComparePath)[FileAttributeKey.size] as! NSNumber
  342. let cfs = try! FileManager.default.attributesOfItem(atPath: cComparePath)[FileAttributeKey.size] as! NSNumber
  343. if rfs.int64Value != cfs.int64Value {
  344. return true
  345. }
  346. }
  347. }
  348. }
  349. return false
  350. }
  351. func updateRefImage(_ fileName:String) {
  352. let checkDirectory = self.checkFileDirectory()
  353. let originDirectory = self.originFileDirectory()
  354. let resultDirectory = self.resultFileDirectory()
  355. let fName = NSString(string: fileName).deletingPathExtension
  356. let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  357. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
  358. let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
  359. var isDirectory = ObjCBool(false)
  360. if FileManager.default.fileExists(atPath: resultPath, isDirectory:&isDirectory) {
  361. // compare screenshoot between result file with check file
  362. let items = NSMutableArray()
  363. if (isDirectory.boolValue) {
  364. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultPath)
  365. for item in NSArray(array: searchItems) {
  366. let ext = NSString(string: item as! String).pathExtension.lowercased()
  367. if NSArray(array: [_extention]).contains(ext) {
  368. let fileName = NSString(string: fName+"."+_extention+"/\(item as! String)").deletingPathExtension
  369. items.add(fileName)
  370. }
  371. }
  372. }else {
  373. items.add(fName)
  374. }
  375. for item in items {
  376. let subFileName = item as! String
  377. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
  378. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
  379. if FileManager.default.fileExists(atPath: rComparePath) {
  380. if FileManager.default.fileExists(atPath: cComparePath) {
  381. try! FileManager.default.removeItem(atPath: cComparePath)
  382. }
  383. try! FileManager.default.createDirectory(atPath: NSString(string: cComparePath).deletingLastPathComponent,
  384. withIntermediateDirectories: true)
  385. try! FileManager.default.copyItem(atPath: rComparePath, toPath: cComparePath)
  386. }
  387. }
  388. }
  389. }
  390. func compareFiles() -> NSArray? {
  391. let items = NSMutableArray()
  392. let files = DataModel.shared.originFilesFor(_fileType, type: _type) as [String]
  393. for fileName in files {
  394. let sItems = compareFiles(fileName)
  395. if sItems != nil && sItems!.count != 0 {
  396. items.addObjects(from: sItems as! [Any])
  397. }
  398. }
  399. return items
  400. }
  401. func compareFiles(_ fileName: String) -> NSArray? {
  402. let files = NSMutableArray()
  403. let checkDirectory = self.checkFileDirectory()
  404. let originDirectory = self.originFileDirectory()
  405. let resultDirectory = self.resultFileDirectory()
  406. let fName = NSString(string: fileName).deletingPathExtension
  407. // let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  408. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
  409. // let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
  410. var isDirectory = ObjCBool(false)
  411. if FileManager.default.fileExists(atPath: resultPath, isDirectory:&isDirectory) {
  412. // compare screenshoot between result file with check file
  413. let items = NSMutableArray()
  414. if (isDirectory.boolValue) {
  415. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultPath)
  416. for item in NSArray(array: searchItems) {
  417. let ext = NSString(string: item as! String).pathExtension.lowercased()
  418. if NSArray(array: [_extention]).contains(ext) {
  419. let fileName = NSString(string: fName+"."+_extention+"/\(item as! String)").deletingPathExtension
  420. items.add(fileName)
  421. }
  422. }
  423. }else {
  424. items.add(fName)
  425. }
  426. let nitems = items.sortedArray { str1, str2 in
  427. let s1 = str1 as! String
  428. let s2 = str2 as! String
  429. return NSString(string: s1).compare(s2)
  430. }
  431. for item in nitems {
  432. let subFileName = item as! String
  433. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
  434. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
  435. let fileInfo = NSMutableDictionary.fileInfoWith(fileName,
  436. refFilePath: (isDirectory.boolValue ? (subFileName+".jpg") : nil),
  437. resultPath: rComparePath,
  438. comparePath: cComparePath,
  439. objc: self)
  440. files.add(fileInfo)
  441. }
  442. }
  443. return files
  444. }
  445. /// Path
  446. func originFileDirectory() -> String {
  447. return DataModel.shared.directoryPath().appendingFormat("/\(self.fileType())/\(self.type())/\(kOriginPathComponent)")
  448. }
  449. func resultFileDirectory() -> String {
  450. return DataModel.shared.directoryPath().appendingFormat("/\(self.fileType())/\(self.type())/\(kResultPathComponent)")
  451. }
  452. func checkFileDirectory() -> String {
  453. return DataModel.shared.directoryPath().appendingFormat("/\(self.fileType())/\(self.type())/\(kCheckPathComponent)")
  454. }
  455. // check File Exist
  456. func hasOriginFile() -> Bool {
  457. if nil != self.originFileDirectory() && FileManager.default.fileExists(atPath: self.originFileDirectory()) {
  458. let files = try? FileManager.default.subpathsOfDirectory(atPath: self.originFileDirectory())
  459. return (files ?? []).count > 0
  460. }
  461. return false
  462. }
  463. func hasResultFile() -> Bool {
  464. if nil != self.resultFileDirectory() && FileManager.default.fileExists(atPath: self.resultFileDirectory()) {
  465. let files = try? FileManager.default.subpathsOfDirectory(atPath: self.resultFileDirectory())
  466. return (files ?? []).count > 0
  467. }
  468. return false
  469. }
  470. ///
  471. func clearCacheFiles() {
  472. reportString = NSMutableAttributedString.init();
  473. let resultDirectory = self.resultFileDirectory()
  474. var isDirectory = ObjCBool(false)
  475. if FileManager.default.fileExists(atPath: resultDirectory, isDirectory: &isDirectory) && isDirectory.boolValue {
  476. let searchItems = try! FileManager.default.contentsOfDirectory(atPath: resultDirectory)
  477. for item in NSArray(array: searchItems) {
  478. let path = NSString(string: resultDirectory).appendingPathComponent(item as! String)
  479. if FileManager.default.fileExists(atPath: path) {
  480. try! FileManager.default.removeItem(atPath: path)
  481. }
  482. }
  483. }
  484. }
  485. }
  486. extension AutoTest {
  487. func stringToImage(_ string:String) ->NSImage? {
  488. let length = Int(string.lengthOfBytes(using: .utf8)/2)
  489. var bytes = malloc(length)!
  490. for i in 0..<length {
  491. let index = i
  492. let subString = String(NSString(string: string).substring(with: NSMakeRange(Int(index * 2), 2)))
  493. bytes.storeBytes(of: UInt8(hexForString(subString)), as: UInt8.self)
  494. }
  495. var data = Data.init(bytes: bytes, count: length)
  496. let image = NSImage.init(data: data)
  497. return image
  498. }
  499. func hexForString(_ string:String) -> UInt8 {
  500. let chars = string.utf8CString
  501. if (string.lengthOfBytes(using: .utf8) >= 2) {
  502. return UInt8(intvalueForChar(chars[0]) * 16 + intvalueForChar(chars[1]))
  503. }
  504. return UInt8(0)
  505. }
  506. func intvalueForChar(_ char:CChar) -> UInt8 {
  507. let iValue = char
  508. // 0 ~ 9s
  509. if iValue >= 48 && iValue <= 57 {
  510. return UInt8(iValue - 48)
  511. }else if iValue >= 65 && iValue <= 70 {
  512. return UInt8(iValue - 65 + 10)
  513. }else if iValue >= 97 && iValue <= 102 {
  514. return UInt8(iValue - 97 + 10)
  515. }
  516. return UInt8(0)
  517. }
  518. }