|
@@ -0,0 +1,271 @@
|
|
|
+//
|
|
|
+// CharacterAutoTest.swift
|
|
|
+// KdanAuto
|
|
|
+//
|
|
|
+// Created by 朱东勇 on 2022/11/22.
|
|
|
+//
|
|
|
+
|
|
|
+import Foundation
|
|
|
+import Cocoa
|
|
|
+
|
|
|
+class CharacterAutoTest : AutoTest {
|
|
|
+
|
|
|
+// override func type() -> String {
|
|
|
+// return "PDFConvert_China_Auto_Test"
|
|
|
+// }
|
|
|
+
|
|
|
+ override func name() -> String {
|
|
|
+ return "字符转换准确率测试"
|
|
|
+ }
|
|
|
+
|
|
|
+ override func keys() -> NSArray {
|
|
|
+ return ["字符对比", "快照对比"]
|
|
|
+ }
|
|
|
+
|
|
|
+ static var cSharedInstance = CharacterAutoTest()
|
|
|
+ override class func shared() -> AutoTest? {
|
|
|
+ return cSharedInstance
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Auto Test refrence Check File
|
|
|
+ override func autoTest() {
|
|
|
+ let checkString = self.selectedKeys().contains("字符对比")
|
|
|
+ let needCompare = self.selectedKeys().contains("快照对比")
|
|
|
+
|
|
|
+ if !needCompare && !checkString {
|
|
|
+ _status = .Finished
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ _status = .Process
|
|
|
+ reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】字符比对开始!\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.blue])
|
|
|
+ let files = DataModel.shared.originFilesFor(_fileType, type: _type)
|
|
|
+
|
|
|
+ let checkDirectory = self.checkFileDirectory()
|
|
|
+ let originDirectory = self.originFileDirectory()
|
|
|
+ let resultDirectory = self.resultFileDirectory()
|
|
|
+ for fileName in files {
|
|
|
+ let fName = NSString(string: fileName).deletingPathExtension
|
|
|
+ let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
|
|
|
+ let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+".rtf")
|
|
|
+ let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+".rtf")
|
|
|
+
|
|
|
+
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】开始转换文件 \"\(fName)\"\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.blue]))
|
|
|
+ // ...
|
|
|
+ // 执行转换过程
|
|
|
+
|
|
|
+ if FileManager.default.fileExists(atPath: resultPath) {
|
|
|
+ if checkString {
|
|
|
+ // Load check file
|
|
|
+ let checkData = NSData.init(contentsOfFile: checkPath) as! Data
|
|
|
+ var documentAttributes:NSDictionary!
|
|
|
+ let checkAttString = NSAttributedString.init(rtf: checkData, documentAttributes: &documentAttributes)
|
|
|
+ var checkString = NSString(string: checkAttString!.string) as NSString
|
|
|
+
|
|
|
+ let resultString = try? NSString.init(contentsOfFile: resultPath, encoding: NSUTF8StringEncoding)
|
|
|
+
|
|
|
+
|
|
|
+#if true
|
|
|
+ //识别字符串 \shptxt\shptxt ... }
|
|
|
+ let pageInfoStrings = resultString!.components(separatedBy: "\\shptxt\\shptxt") as NSArray
|
|
|
+ var finalString = ""
|
|
|
+ if pageInfoStrings.count > 0 {
|
|
|
+ let subStrings = pageInfoStrings.subarray(with: NSMakeRange(1, Int(pageInfoStrings.count - 1))) as! [String]
|
|
|
+ for pageInfoString in subStrings {
|
|
|
+ let endRange = NSString(string: pageInfoString).range(of: "}")
|
|
|
+ finalString = finalString.appending(NSString(string: pageInfoString).substring(to: endRange.location))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //识别所有 【空格 ~ \】 之间的值,并进行缝合
|
|
|
+ // Detect all strings between Spaces and \ and stitch
|
|
|
+ let strings = finalString.components(separatedBy: " ")
|
|
|
+ var resultStr = "" as NSString
|
|
|
+ for str in strings {
|
|
|
+ let markStr = str as NSString
|
|
|
+
|
|
|
+ if (markStr.contains("\\f")) {
|
|
|
+ let fRange = markStr.range(of: "\\f")
|
|
|
+ let cRange = markStr.range(of: "\\c")
|
|
|
+ let bRange = markStr.range(of: "\\b")
|
|
|
+ let iRange = markStr.range(of: "\\i")
|
|
|
+ let eRange = markStr.range(of: "\\e")
|
|
|
+ let pRange = markStr.range(of: "\\p")
|
|
|
+ let minPos = min(Int(fRange.location),
|
|
|
+ Int(cRange.location),
|
|
|
+ Int(bRange.location),
|
|
|
+ Int(iRange.location),
|
|
|
+ Int(eRange.location),
|
|
|
+ Int(pRange.location))
|
|
|
+ resultStr = resultStr.appending(markStr.substring(to: minPos)) as NSString
|
|
|
+ }else {
|
|
|
+ resultStr = resultStr.appending(markStr as String) as NSString
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resultStr = self.replaceUnicodeString(resultStr)
|
|
|
+#else
|
|
|
+ let resultData = NSData.init(contentsOfFile: resultPath) as! Data
|
|
|
+ var rDocumentAttributes:NSDictionary!
|
|
|
+ let resultAttString = NSAttributedString.init(rtf: resultData, documentAttributes: &rDocumentAttributes)
|
|
|
+ var resultStr = NSString(string: resultAttString!.string)
|
|
|
+#endif
|
|
|
+ resultStr = resultStr.replacingOccurrences(of: "\n", with: "") as NSString
|
|
|
+ checkString = checkString.replacingOccurrences(of: "\n", with: "") as NSString
|
|
|
+ resultStr = resultStr.replacingOccurrences(of: " ", with: "") as NSString
|
|
|
+ checkString = checkString.replacingOccurrences(of: " ", with: "") as NSString
|
|
|
+ resultStr = resultStr.replacingOccurrences(of: "\\pard", with: "") as NSString
|
|
|
+ resultStr = resultStr.replacingOccurrences(of: "\\par", with: "") as NSString
|
|
|
+
|
|
|
+ // do { // save cache file for test
|
|
|
+ // try? NSString(string: resultStr).write(toFile: NSString(string: DataModel.shared.resultPath()).appending("/\(self.name())-result-cache.txt"),
|
|
|
+ // atomically: true, encoding: NSUTF8StringEncoding)
|
|
|
+ //
|
|
|
+ // try? NSString(string: checkString).write(toFile: NSString(string: DataModel.shared.resultPath()).appending("/\(self.name())-check-cache.txt"),
|
|
|
+ // atomically: true, encoding: NSUTF8StringEncoding)
|
|
|
+ // }
|
|
|
+
|
|
|
+ let maxSize = checkString.length
|
|
|
+ var successCount = 0;
|
|
|
+ /**
|
|
|
+ (A0 = B0)
|
|
|
+ - A-1 & B-1
|
|
|
+ (A0 != B0) & (A0 in B) & (B0 in A)
|
|
|
+ - 取 A0,B0最小 Range 值
|
|
|
+ - 字符串裁剪对齐
|
|
|
+ (A0 != B0) & (A0 in B)
|
|
|
+ - 存储B0到识别错误缓存
|
|
|
+ (A0 != B0) & (B0 in A)
|
|
|
+ - 存储 A0到识别遗漏字符串
|
|
|
+ (A0 != B0)
|
|
|
+ - 分别存储 A0、B0到遗漏及错误字串
|
|
|
+ */
|
|
|
+ var skipString = NSString()
|
|
|
+ var failString = NSString()
|
|
|
+ while (checkString.length > 0 && resultStr.length > 0) {
|
|
|
+ let subc = checkString.substring(to: 1) as NSString
|
|
|
+ let subr = resultStr.substring(to: 1) as NSString
|
|
|
+
|
|
|
+ if subc.isEqual(to: subr) { // (A0 = B0)
|
|
|
+ // Check Success
|
|
|
+ appendErrorInfo(skipString, failString: failString)
|
|
|
+ skipString = NSString()
|
|
|
+ failString = NSString()
|
|
|
+
|
|
|
+
|
|
|
+ checkString = checkString.substring(from:1) as NSString
|
|
|
+ resultStr = resultStr.substring(from:1) as NSString
|
|
|
+ successCount = successCount + 1
|
|
|
+ }else if (checkString.contains(subr as String) && resultStr.contains(subc as String)) {
|
|
|
+ appendErrorInfo(skipString, failString: failString)
|
|
|
+ skipString = NSString()
|
|
|
+ failString = NSString()
|
|
|
+
|
|
|
+ let cRange = checkString.range(of: subr as String)
|
|
|
+ let rRange = resultStr.range(of: subc as String)
|
|
|
+
|
|
|
+ if (cRange.location < rRange.location) {
|
|
|
+ let cacheString = checkString.substring(to:cRange.location + cRange.length)
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "对照字符串【\(cacheString)】未识别到\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ checkString = checkString.substring(from:cRange.location) as NSString
|
|
|
+ }else {
|
|
|
+ let cacheString = resultStr.substring(to:rRange.location)
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "字符串【\(cacheString)】识别出错\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ resultStr = resultStr.substring(from:rRange.location + rRange.length) as NSString
|
|
|
+ }
|
|
|
+
|
|
|
+ }else if (checkString.contains(subr as String)) {
|
|
|
+ skipString = skipString.appending(subc as String) as NSString
|
|
|
+ checkString = checkString.substring(from:1) as NSString
|
|
|
+ }else if (resultStr.contains(subc as String)) {
|
|
|
+ failString = failString.appending(subr as String) as NSString
|
|
|
+ resultStr = resultStr.substring(from:1) as NSString
|
|
|
+ }else {
|
|
|
+ skipString = skipString.appending(subc as String) as NSString
|
|
|
+ failString = failString.appending(subr as String) as NSString
|
|
|
+
|
|
|
+ checkString = checkString.substring(from:1) as NSString
|
|
|
+ resultStr = resultStr.substring(from:1) as NSString
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ skipString = skipString.appending(checkString as String) as NSString
|
|
|
+ failString = failString.appending(resultStr as String) as NSString
|
|
|
+
|
|
|
+
|
|
|
+ appendErrorInfo(skipString, failString: failString)
|
|
|
+
|
|
|
+ reportString?.append(NSAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"比对完成,准确率\(Float(successCount)/Float(maxSize) * 100)%(\(successCount)/\(maxSize))\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.blue]))
|
|
|
+
|
|
|
+ // compare screenshoot between result file with check file
|
|
|
+ if needCompare {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照生成中\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.black]))
|
|
|
+ let rComparePath = NSString(string: resultDirectory).appendingPathComponent(fName+"_\(DataModel.shared.latestReportID()!).png")
|
|
|
+
|
|
|
+ if (ProcessThumbnal.process(resultPath, desPath: rComparePath, outputSize: CGSize.init(width: 1000, height: 1000)) &&
|
|
|
+ FileManager.default.fileExists(atPath: rComparePath)) {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照对比完成,图像准确率 X%\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }else {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照生成失败\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档失败!\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ NSLog("\(reportString)")
|
|
|
+
|
|
|
+
|
|
|
+ _status = .Finished
|
|
|
+ }
|
|
|
+
|
|
|
+ func appendErrorInfo(_ skipString:NSString, failString: NSString) {
|
|
|
+ if skipString.length > 0 && failString.length > 0 {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "对比字符串【\(skipString)】错识别为【\(failString)】\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }else if (skipString.length > 0) {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "对比字符串【\(skipString)】未识别到\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }else if failString.length > 0 {
|
|
|
+ reportString?.append(NSMutableAttributedString.init(string: "字符串【\(failString)】识别出错\n",
|
|
|
+ attributes:[.foregroundColor : NSColor.red]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func replaceUnicodeString(_ string:NSString) -> NSString {
|
|
|
+ let items = string.components(separatedBy: "\\u") as [NSString]
|
|
|
+
|
|
|
+ var resultString = NSString()
|
|
|
+ for item in items {
|
|
|
+ if (item.contains("?")) {
|
|
|
+ let unicodeValue = item.intValue
|
|
|
+ let skipRange = item.range(of: "?")
|
|
|
+ let nextString = item.substring(from: Int(skipRange.location + skipRange.length)) as NSString
|
|
|
+ let bytes : [UInt8] = [UInt8(unicodeValue/256),UInt8(unicodeValue%256)]
|
|
|
+ let data = NSData.init(bytes: bytes, length: 2)
|
|
|
+
|
|
|
+ let unicodeString = NSString.init(data: data as Data, encoding: NSUnicodeStringEncoding)! as NSString
|
|
|
+ resultString = resultString.appending(String("\(unicodeString)\(nextString)")) as NSString
|
|
|
+ }else {
|
|
|
+ resultString = resultString.appending(String(item)) as NSString
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultString
|
|
|
+ }
|
|
|
+
|
|
|
+}
|