|
| 1 | +// |
| 2 | +// TestSuite+Parse.swift |
| 3 | +// Testify |
| 4 | +// |
| 5 | +// Created by Tibor Bödecs on 2019. 01. 20.. |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | + |
| 10 | +public extension TestSuite { |
| 11 | + |
| 12 | + public static func parse(_ output: String) -> TestSuite { |
| 13 | + |
| 14 | + let dateFormatter = DateFormatter() |
| 15 | + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" |
| 16 | + |
| 17 | + var suites: [TestSuite] = [] |
| 18 | + var currentCaseName: String? |
| 19 | + var testCaseOutput: String! |
| 20 | + var gatherTestCaseOutput = false |
| 21 | + |
| 22 | + let lines = output.split(separator: "\n").map({ String($0) }) |
| 23 | + for (index, line) in lines.enumerated() { |
| 24 | + // start or end test suite |
| 25 | + if line.contains("Test Suite") { |
| 26 | + if line.contains("started") { |
| 27 | + let name = line.matchedTestName! |
| 28 | + let date = dateFormatter.date(from: line.matchedDate!)! |
| 29 | + |
| 30 | + suites.append(TestSuite(name: name, |
| 31 | + startDate: date, |
| 32 | + endDate: date, |
| 33 | + unexpected: 0, |
| 34 | + outcome: .failure)) |
| 35 | + continue; |
| 36 | + } |
| 37 | + else { |
| 38 | + var suite = suites.last! |
| 39 | + suites = Array(suites.dropLast()) |
| 40 | + |
| 41 | + suite.outcome = line.contains("passed") ? .success : .failure |
| 42 | + suite.endDate = dateFormatter.date(from: line.matchedDate!)! |
| 43 | + |
| 44 | + if index+1 < lines.count { |
| 45 | + let nextLine = lines[index+1] |
| 46 | + if nextLine.contains("Executed") { |
| 47 | + suite.unexpected = Int(nextLine.matchedUnexpected!)! |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + if suites.isEmpty { |
| 52 | + suites.append(suite) |
| 53 | + } |
| 54 | + else { |
| 55 | + var parentSuite = suites.last! |
| 56 | + suites = Array(suites.dropLast()) |
| 57 | + parentSuite.children.append(suite) |
| 58 | + suites.append(parentSuite) |
| 59 | + } |
| 60 | + continue; |
| 61 | + } |
| 62 | + } |
| 63 | + if line.contains("Test Case") { |
| 64 | + if line.contains("started") { |
| 65 | + testCaseOutput = "" |
| 66 | + gatherTestCaseOutput = true |
| 67 | + currentCaseName = line.matchedTestName |
| 68 | + continue; |
| 69 | + } |
| 70 | + else { |
| 71 | + gatherTestCaseOutput = false |
| 72 | + var suite = suites.last! |
| 73 | + suites = Array(suites.dropLast()) |
| 74 | + let outcome: TestOutcome = line.contains("passed") ? .success : .failure |
| 75 | + let caseName = currentCaseName!.dropFirst(2).dropLast() |
| 76 | + let firstSplit = caseName.split(separator: ".") |
| 77 | + let secondSplit = firstSplit[1].split(separator: " ") |
| 78 | + |
| 79 | + var failureInfo: TestFailureInfo? = nil |
| 80 | + if outcome == .failure { |
| 81 | + let outputSplit = testCaseOutput.split(separator: ":") |
| 82 | + let file = String(outputSplit[0]) |
| 83 | + let line = Int(outputSplit[1])! |
| 84 | + let reason = String(outputSplit.dropFirst(4) |
| 85 | + .joined(separator: ":") |
| 86 | + .trimmingCharacters(in: CharacterSet(charactersIn: "-").union(.whitespaces))) |
| 87 | + failureInfo = TestFailureInfo(file: file, line: line, reason: reason) |
| 88 | + } |
| 89 | + |
| 90 | + let testCase = TestCase(moduleName: String(firstSplit[0]), |
| 91 | + className: String(secondSplit[0]), |
| 92 | + testName: String(secondSplit[1]), |
| 93 | + duration: TimeInterval(line.matchedSeconds!)!, |
| 94 | + outcome: outcome, |
| 95 | + failureInfo: failureInfo) |
| 96 | + suite.cases.append(testCase) |
| 97 | + suites.append(suite) |
| 98 | + currentCaseName = nil |
| 99 | + continue; |
| 100 | + } |
| 101 | + } |
| 102 | + if gatherTestCaseOutput { |
| 103 | + testCaseOutput += line |
| 104 | + } |
| 105 | + } |
| 106 | + return suites.first! |
| 107 | + } |
| 108 | +} |
0 commit comments