// // CharacterAutoTest.swift // KdanAuto // // Created by 朱东勇 on 2022/11/22. // import Foundation import Cocoa class StringAutoBackTest : StringAutoTest { override func needTest() -> Bool { return self.selectedKeys().count > 0 } override class func shared() -> AutoTest? { return StringAutoBackTest() } // // Auto Test refrence Check File // override func autoTest(_ complention:@escaping (_ object:AutoTest, _ report:NSAttributedString?) -> ()) { // self.compareFinishedFiles.removeAllObjects(); // self.convertFiles.removeAllObjects() // // clearCacheFiles() // // let needCheckString = self.selectedKeys().contains("字符") // // if !needCheckString { // _status = .Finished // complention(self, self.reportString) // 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) // self.testFiles = NSArray(array: files); // // let checkDirectory = self.checkFileDirectory() // let originDirectory = self.originFileDirectory() // let resultDirectory = self.resultFileDirectory() // // if (files.count > 0) { // try? FileManager.default.createDirectory(atPath: checkDirectory, withIntermediateDirectories: true); // try? FileManager.default.createDirectory(atPath: resultDirectory, withIntermediateDirectories: true); // } // // var tDegree = Double(0); // var tCount = Int(0) // var fileIndex = 0; // // var convertFileBlock = { (files:[String]) in } // convertFileBlock = { (files:[String]) in // if (fileIndex >= files.count) { // TestDegreeManager.shared().set(((tCount != 0) ? tDegree/Double(tCount) : 0.0), // fileType: self.fileType(), // type: self.type()) // // self._status = .Finished // DispatchQueue.main.async { // autoreleasepool { // complention(self, self.reportString); // } // } // return // } // // let fileName = files[fileIndex] // let fName = NSString(string: fileName).deletingPathExtension // let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf") // let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+self.extention()) // let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+self.extention()) // // // self.reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】开始转换文件 \"\(fName)\"\n", // attributes:[.foregroundColor : NSColor.black])) // // ... // // 执行转换过程 // let index = self.testFiles.index(of: fileName); // if (index != NSNotFound) { // self.convertProgress = Double(index) / Double(self.testFiles.count) // } // self.convertFiles.add(fileName); // self.testlog("开始转换:"+fileName, (self.compareProgress + self.convertProgress)/2.0) // self.process(originPath, resultPath: resultPath) { status in // if FileManager.default.fileExists(atPath: resultPath) && status == 1 { // if needCheckString && FileManager.default.fileExists(atPath: checkPath) { // DispatchQueue.global().async { // let checkString = self.readTextFile(checkPath as NSString) // let resultStr = self.readTextFile(resultPath as NSString) // // if (checkString != nil && resultStr != nil) { // let maxSize = checkString!.count // let report = NSMutableAttributedString(string: "") // let degree = self.compareString(checkString as! NSString, result: resultStr as! NSString) { appAttr in // report.append(appAttr) // } // // let degree = self.compareString(checkString as! NSString, result: resultStr as! NSString) { skipString, failString in // // self.appendErrorInfo(skipString, failString: failString) // // } // // var color = NSColor.black // if fabs(degree-100.0) >= 0.01 { // color = NSColor.red // } // tDegree += degree; // tCount += 1 // // TestDegreeManager.shared().set(degree, // fileType: self.fileType(), // type: self.type(), // fileName: fileName) // // let successCount = Int(maxSize * Int(degree)/100) // report.append(NSAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"比对完成,准确率\(degree)%(\(successCount)/\(maxSize))\n", // attributes:[.foregroundColor : color])) // if (report != nil) { // do { // let rtfData = try? report.data(from: .init(location: 0, length: report.length), // documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf]) // // let path = NSString(string: resultPath).appendingPathExtension("rtf") // try? FileManager.default.removeItem(atPath: path!); // try? rtfData?.write(to: NSURL.fileURL(withPath: path!)) // } catch { // } // self.reportString?.append(report) // } // } // // let index = self.testFiles.index(of: fileName); // if (index != NSNotFound) { // self.compareProgress = Double(index) / Double(self.testFiles.count) // } // self.compareFinishedFiles.add(fileName); // self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0) // // fileIndex += 1 // convertFileBlock(files); // } // }else { // self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】对照文件 \"\(fName)\"不存在!\n", // attributes:[.foregroundColor : NSColor.red])) // // let index = self.testFiles.index(of: fileName); // if (index != NSNotFound) { // self.compareProgress = Double(index) / Double(self.testFiles.count) // } // self.compareFinishedFiles.add(fileName); // self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0) // // fileIndex += 1 // convertFileBlock(files); // } // }else { // if (status == 0) { // self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档失败!\n", // attributes:[.foregroundColor : NSColor.red])) // }else if (status == -1 || status == -2) { // self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"文档无法打开!\n", // attributes:[.foregroundColor : NSColor.red])) // }else if (status == -3) { // self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档中 Crash!\n", // attributes:[.foregroundColor : NSColor.red])) // } // // let index = self.testFiles.index(of: fileName); // if (index != NSNotFound) { // self.compareProgress = Double(index) / Double(self.testFiles.count) // } // self.compareFinishedFiles.add(fileName); // self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0) // fileIndex += 1 // convertFileBlock(files); // } // } // } // convertFileBlock(files); // } // // /// Compare override func compareString(_ check:NSString, result:NSString, callback:@escaping (_ appAttr:NSAttributedString)->()) -> Double { // func compareString(_ check:NSString, result:NSString, failure:@escaping (_ skipString:NSString, _ failString:NSString)->()) -> Double { return autoreleasepool { var checkString = check var resultStr = result var maxSize = checkString.length var successCount = 0; resultStr = resultStr.replacingOccurrences(of: "\n", with: "") as NSString resultStr = resultStr.replacingOccurrences(of: " ", with: "") as NSString /** (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 let cRange = checkString.range(of: subr as String) let rRange = resultStr.range(of: subc as String) if subc.isEqual(to: subr) { // (A0 = B0) // Check Success callback(attributeStringWith(skipString, failString: failString)) // failure(skipString, failString) // self.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 callback(NSAttributedString(string: subc as String)) }else if (["\n", "\r", " "].contains(subc)) { callback(NSAttributedString(string: subc as String)) maxSize -= 1; checkString = checkString.substring(from:1) as NSString } else if (cRange.location != NSNotFound && rRange.location != NSNotFound) { if (min(cRange.location, rRange.location) >= 2) { let nextc = checkString.substring(with: NSRange(location: 1, length: 1)) as NSString let nextr = resultStr.substring(with: NSRange(location: 1, length: 1)) as NSString let ncRange = checkString.range(of: nextr as String) let nrRange = resultStr.range(of: nextc as String) if (min(nrRange.location, ncRange.location) < min(cRange.location, rRange.location)) { if (ncRange.location < nrRange.location) { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 skipString = skipString.appending(subc as String) as NSString checkString = checkString.substring(from:1) as NSString }else { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 failString = failString.appending(subr as String) as NSString resultStr = resultStr.substring(from:1) as NSString } }else if (cRange.location < rRange.location) { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 skipString = skipString.appending(subc as String) as NSString checkString = checkString.substring(from:1) as NSString }else { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 failString = failString.appending(subr as String) as NSString resultStr = resultStr.substring(from:1) as NSString } }else { // var scale = (skipString.length > 0) ? (Float(checkString.length) / Float(skipString.length)) : Float(1.0) // if (checkString.length > skipString.length && cRange.location <= Int(Float(rRange.location)*scale)) { // //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 // skipString = skipString.appending(subc as String) as NSString // checkString = checkString.substring(from:1) as NSString // }else if (checkString.length <= skipString.length && cRange.location > Int(Float(rRange.location)*scale)) { // failString = failString.appending(subr as String) as NSString // resultStr = resultStr.substring(from:1) as NSString // }else if (cRange.location < rRange.location) { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 skipString = skipString.appending(subc as String) as NSString checkString = checkString.substring(from:1) as NSString }else { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 failString = failString.appending(subr as String) as NSString resultStr = resultStr.substring(from:1) as NSString } } }else if (cRange.location != NSNotFound) { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 skipString = skipString.appending(subc as String) as NSString checkString = checkString.substring(from:1) as NSString }else if (rRange.location != NSNotFound) { //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一 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 // failure(skipString, failString) callback(attributeStringWith(skipString, failString: failString)) callback(NSAttributedString(string: "\n")) let degree = (maxSize>1) ? Double(Float(successCount)/Float(maxSize) * 100) : 0 return degree } } }