diff --git a/LICENSE b/LICENSE
index ca9fb45..97d854a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018-2022 Tibor BΓΆdecs
+Copyright (c) 2022-2023 Binary Birds Ltd.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/makefile b/Makefile
similarity index 51%
rename from makefile
rename to Makefile
index 526d8f4..00749f2 100644
--- a/makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
-install:
+release:
swift package update && swift build -c release
- install .build/Release/testify-cli /usr/local/bin/testify
+
+install: release
+ install .build/Release/testify /usr/local/bin/testify
uninstall:
rm /usr/local/bin/testify
diff --git a/Package.swift b/Package.swift
index f3b03e3..b325b19 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,15 +1,37 @@
-// swift-tools-version:5.5
+// swift-tools-version:5.7
import PackageDescription
let package = Package(
- name: "Testify",
+ name: "testify",
+ platforms: [
+ .macOS(.v10_15),
+ ],
products: [
- .library(name: "Testify", targets: ["Testify"]),
- .executable(name: "testify-cli", targets: ["testify-cli"])
+ .executable(name: "testify", targets: ["testify"]),
+ .library(name: "TestifySDK", targets: ["TestifySDK"])
],
targets: [
- .executableTarget(name: "testify-cli", dependencies: ["Testify"], path: "./Sources/cli"),
- .target(name: "Testify", dependencies: [], path: "./Sources/lib"),
- .testTarget(name: "TestifyTests", dependencies: ["Testify"]),
+ .executableTarget(
+ name: "testify",
+ dependencies: [
+ .target(name: "TestifySDK")
+ ]
+ ),
+
+ // MARK: - targets
+
+ .target(
+ name: "TestifySDK",
+ dependencies: []
+ ),
+
+ // MARK: - test targets
+
+ .testTarget(
+ name: "TestifySDKTests",
+ dependencies: [
+ .target(name: "TestifySDK"),
+ ]
+ ),
]
)
diff --git a/README.md b/README.md
index 2e8755e..543108f 100755
--- a/README.md
+++ b/README.md
@@ -1,13 +1,11 @@
-# Testify (β
)
+# Testify
-Testify converts XCTest output into a proper structure (JSON), or it'll miserably fail. π
+Testify converts XCTest output into a proper structure (JSON, JUNIT, MD), or it'll miserably fail. π
-## Install Testify cli
+## Install command line utility
-You can use the cli to convert test results into JSON on the fly.
-
-You can use the cli to convert test results into JSON on the fly.
+You can use the command line utility to convert test results into JSON, JUNIT and MD on the fly.
```
git clone https://github.com/BinaryBirds/Testify.git && cd Testify
@@ -17,12 +15,18 @@ which testify
## Usage
-In your projetct folder run `swift test 2>&1 | testify` or
+In your project folder run:
+
+* for JSON format: `swift test | testify json`
+* for JUNIT format: `swift test | testify junit`
+* for MD format: `swift test | testify md`
-Just use the [Swift Package Manager](https://theswiftdev.com/2017/11/09/swift-package-manager-tutorial/) as usual:
+If no argument or wrong argument added then output format fallbacks to JSON!
+
+You can just use the [Swift Package Manager](https://theswiftdev.com/2017/11/09/swift-package-manager-tutorial/) as usual:
```swift
-.package(url: "https://github.com/binarybirds/testify", from: "1.0.0"),
+.package(url: "https://github.com/binarybirds/testify", from: "1.1.0"),
```
β οΈ Don't forget to add "Testify" to your target as a dependency!
@@ -32,4 +36,3 @@ Just use the [Swift Package Manager](https://theswiftdev.com/2017/11/09/swift-pa
import Testify
let suite = TestSuite.parse("test-output-string")
-```
diff --git a/Sources/lib/Extensions/TestSuite+Parse.swift b/Sources/TestifySDK/Codable/RawTestResultDecoder.swift
similarity index 56%
rename from Sources/lib/Extensions/TestSuite+Parse.swift
rename to Sources/TestifySDK/Codable/RawTestResultDecoder.swift
index 0104909..1e7c3f1 100644
--- a/Sources/lib/Extensions/TestSuite+Parse.swift
+++ b/Sources/TestifySDK/Codable/RawTestResultDecoder.swift
@@ -1,25 +1,65 @@
//
-// TestSuite+Parse.swift
+// RawTestResultParser.swift
// Testify
//
-// Created by Tibor BΓΆdecs on 2019. 01. 20..
+// Created by Tibor Bodecs on 2023. 02. 12..
//
import Foundation
-public extension TestSuite {
+private extension String {
+
+ func match(_ pattern: String) -> String? {
+ let regex = try! NSRegularExpression(pattern: pattern)
+ let matches = regex.matches(
+ in: self,
+ range: .init(location: 0, length: count)
+ )
+ guard
+ let match = matches.first,
+ let range = Range(match.range, in: self)
+ else {
+ return nil
+ }
+ return String(self[range])
+ }
+
+ var matchedTestName: String? {
+ guard let match = match("(\\'.+\\')") else {
+ return nil
+ }
+ return String(match.dropFirst().dropLast())
+ }
- static func parse(_ output: String) -> TestSuite {
-
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
-
+ var matchedDate: String? {
+ match("(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{3})")
+ }
+
+ var matchedSeconds: String? {
+ match("(\\d+\\.\\d+)")
+ }
+
+ var matchedUnexpected: String? {
+ String(match("\\((\\d+)")!.dropFirst())
+ }
+}
+
+public struct RawTestResultDecoder {
+
+ private let dateFormatter: DateFormatter
+
+ public init() {
+ self.dateFormatter = .init()
+ self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
+ }
+
+ public func decode(_ input: String) throws -> TestSuite {
var suites: [TestSuite] = []
var currentCaseName: String?
var testCaseOutput: String!
var gatherTestCaseOutput = false
- let lines = output.split(separator: "\n").map({ String($0) })
+ let lines = input.split(separator: "\n").map({ String($0) })
for (index, line) in lines.enumerated() {
// start or end test suite
if line.contains("Test Suite") {
@@ -27,11 +67,15 @@ public extension TestSuite {
let name = line.matchedTestName!
let date = dateFormatter.date(from: line.matchedDate!)!
- suites.append(TestSuite(name: name,
- startDate: date,
- endDate: date,
- unexpected: 0,
- outcome: .failure))
+ suites.append(
+ TestSuite(
+ name: name,
+ startDate: date,
+ endDate: date,
+ unexpected: 0,
+ outcome: .failure
+ )
+ )
continue;
}
else {
@@ -44,7 +88,7 @@ public extension TestSuite {
if index+1 < lines.count {
let nextLine = lines[index+1]
if nextLine.contains("Executed") {
- suite.unexpected = Int(nextLine.matchedUnexpected!)!
+ suite.unexpected = UInt(nextLine.matchedUnexpected!)!
}
}
@@ -71,12 +115,12 @@ public extension TestSuite {
gatherTestCaseOutput = false
var suite = suites.last!
suites = Array(suites.dropLast())
- let outcome: TestOutcome = line.contains("passed") ? .success : .failure
+ let outcome: Outcome = line.contains("passed") ? .success : .failure
let caseName = currentCaseName!.dropFirst(2).dropLast()
let firstSplit = caseName.split(separator: ".")
let secondSplit = firstSplit[1].split(separator: " ")
- var failureInfo: TestFailureInfo? = nil
+ var failureInfo: FailureInfo? = nil
if outcome == .failure {
let outputSplit = testCaseOutput.split(separator: ":")
let file = String(outputSplit[0])
@@ -84,15 +128,17 @@ public extension TestSuite {
let reason = String(outputSplit.dropFirst(4)
.joined(separator: ":")
.trimmingCharacters(in: CharacterSet(charactersIn: "-").union(.whitespaces)))
- failureInfo = TestFailureInfo(file: file, line: line, reason: reason)
+ failureInfo = FailureInfo(file: file, line: line, reason: reason)
}
- let testCase = TestCase(moduleName: String(firstSplit[0]),
- className: String(secondSplit[0]),
- testName: String(secondSplit[1]),
- duration: TimeInterval(line.matchedSeconds!)!,
- outcome: outcome,
- failureInfo: failureInfo)
+ let testCase = TestCase(
+ moduleName: String(firstSplit[0]),
+ className: String(secondSplit[0]),
+ testName: String(secondSplit[1]),
+ duration: TimeInterval(line.matchedSeconds!)!,
+ outcome: outcome,
+ failureInfo: failureInfo
+ )
suite.cases.append(testCase)
suites.append(suite)
currentCaseName = nil
diff --git a/Sources/TestifySDK/Codable/TestResultCodable.swift b/Sources/TestifySDK/Codable/TestResultCodable.swift
new file mode 100644
index 0000000..c7ddfd0
--- /dev/null
+++ b/Sources/TestifySDK/Codable/TestResultCodable.swift
@@ -0,0 +1,24 @@
+//
+// TestResultCodable.swift
+// Testify
+//
+// Created by Tibor Bodecs on 2023. 02. 12..
+//
+
+import Foundation
+
+public enum TestResultEncoderError: Error {
+ case unknown
+}
+
+public enum TestResultDecoderError: Error {
+ case unknown
+}
+
+public protocol TestResultEncoder {
+ func encode(_: TestSuite) throws -> String
+}
+
+public protocol TestResultDecoder {
+ func decode(_: String) throws -> TestSuite
+}
diff --git a/Sources/TestifySDK/Codable/TestResultJSONEncoder.swift b/Sources/TestifySDK/Codable/TestResultJSONEncoder.swift
new file mode 100644
index 0000000..f15f88a
--- /dev/null
+++ b/Sources/TestifySDK/Codable/TestResultJSONEncoder.swift
@@ -0,0 +1,20 @@
+//
+// File.swift
+//
+//
+// Created by Tibor Bodecs on 2023. 02. 12..
+//
+
+import Foundation
+
+struct TestResultJSONEncoder: TestResultEncoder {
+
+ func encode(_ suite: TestSuite) throws -> String {
+ let encoder = JSONEncoder()
+ let data = try encoder.encode(suite)
+ guard let value = String(data: data, encoding: .utf8) else {
+ throw TestResultEncoderError.unknown
+ }
+ return value
+ }
+}
diff --git a/Sources/TestifySDK/Codable/TestResultJunitEncoder.swift b/Sources/TestifySDK/Codable/TestResultJunitEncoder.swift
new file mode 100644
index 0000000..4362c73
--- /dev/null
+++ b/Sources/TestifySDK/Codable/TestResultJunitEncoder.swift
@@ -0,0 +1,68 @@
+//
+// File.swift
+//
+//
+// Created by Lengyel GΓ‘bor on 2023. 02. 15..
+//
+
+import Foundation
+
+public struct TestResultJunitEncoder: TestResultEncoder {
+
+ public init() {
+
+ }
+
+ public func encode(_ input: TestSuite) throws -> String {
+ var restOfResult = ""
+ var allTests = 0
+ var allTimes = 0.0
+ var allFails = 0
+
+ let suites: [TestSuite] = input.children.reduce([]) { $0 + $1.children }
+ for suite in suites {
+ let start = suite.startDate
+ let name = suite.name
+ let tests = suite.cases.count
+ let time = suite.cases.reduce(0) { $0 + $1.duration }
+ let failureCount = suite.cases.reduce(0) { $0 + ($1.outcome == .failure ? 1 : 0) }
+ allTests += tests
+ allTimes += time
+ allFails += failureCount
+ restOfResult += "\n"
+
+ for testCase in suite.cases {
+ let name = testCase.testName
+ let className = testCase.className
+ let success = testCase.outcome == .success
+ let time = testCase.duration
+ let failLine = testCase.failureInfo?.line
+ let failReason = testCase.failureInfo?.reason
+
+ restOfResult += "\n"
+ } else {
+ if (testCase.failureInfo != nil) {
+ restOfResult += ">\n"
+ restOfResult += "\n"
+ restOfResult += "\(failReason ?? "")\n"
+ restOfResult += "\n"
+ restOfResult += "\n"
+ } else {
+ restOfResult += "/>\n"
+ }
+ }
+ }
+ restOfResult += "\n"
+ }
+ restOfResult += "\n"
+
+ let formatter = DateFormatter()
+ formatter.dateFormat = "yyyyMMdd_HHmmss"
+ var startResult = "\n\n"
+ startResult += "\n"
+
+ return startResult + restOfResult
+ }
+}
diff --git a/Sources/TestifySDK/Codable/TestResultMarkdownEncoder.swift b/Sources/TestifySDK/Codable/TestResultMarkdownEncoder.swift
new file mode 100644
index 0000000..877e246
--- /dev/null
+++ b/Sources/TestifySDK/Codable/TestResultMarkdownEncoder.swift
@@ -0,0 +1,57 @@
+//
+// File.swift
+//
+//
+// Created by Tibor Bodecs on 2023. 02. 12..
+//
+
+import Foundation
+
+public struct TestResultMarkdownEncoder: TestResultEncoder {
+
+ public init() {
+
+ }
+
+ public func encode(_ input: TestSuite) throws -> String {
+ var result = ""
+
+ let suites: [TestSuite] = input.children.reduce([]) { $0 + $1.children }
+ for suite in suites {
+ result += "\n"
+ let name = suite.name
+ let count = suite.cases.count
+ let time = suite.cases.reduce(0) { $0 + $1.duration }
+ let successCount = suite.cases.reduce(0) { $0 + ($1.outcome == .success ? 1 : 0) }
+ let failureCount = suite.cases.reduce(0) { $0 + ($1.outcome == .failure ? 1 : 0) }
+
+ result += "\(name): \(count) tests were completed in \(time) with \(successCount) passed, \(failureCount) failed and \(0) skipped.\n\n"
+ result += "| Test case | Passed | Failed | Skipped | Time |\n"
+ result += "| :--- | ---: | ---: | ---: | ---: |\n"
+
+ for testCase in suite.cases {
+ let name = testCase.testName
+ let passed = testCase.outcome == .success ? "β
" : ""
+ let failed = testCase.outcome == .failure ? "β" : ""
+ let skipped = "π"
+ let time = "\(testCase.duration)s βοΈ"
+ result += "| \(name) | \(passed) | \(failed) | \(skipped) | \(time) |\n"
+ }
+
+ }
+
+ return result
+ }
+}
+
+/*
+| git status lorem ipsum dolor sit amet | git status | git status | 0 | 12.32s |
+| git diff | git diff | git diff | 0 | 123.323s |
+| git diff | git diff | git diff | 0 | 123.323s |
+| git diff | git diff | git diff | 0 | 123.323s |
+| [git diff](Sources/test/test.swift#L4) | git diff β
| git diff β | 0 π | 123.323s βοΈ |
+| git diff | git diff β
| git diff β | 0 π | 123.323s βοΈ |
+| git diff | git diff β
| git diff β | 0 π | 123.323s βοΈ |
+| git diff | git diff β
| git diff β | 0 π | 123.323s βοΈ |
+| git diff | git diff β
| git diff β | 0 π | 123.323s βοΈ |
+*/
diff --git a/Sources/TestifySDK/Models/FailureInfo.swift b/Sources/TestifySDK/Models/FailureInfo.swift
new file mode 100644
index 0000000..d0eab1d
--- /dev/null
+++ b/Sources/TestifySDK/Models/FailureInfo.swift
@@ -0,0 +1,24 @@
+//
+// FailureInfo.swift
+// Testify
+//
+// Created by Tibor BΓΆdecs on 2019. 01. 19..
+//
+
+import Foundation
+
+public struct FailureInfo: Codable {
+ public let file: String
+ public let line: Int
+ public let reason: String
+
+ public init(
+ file: String,
+ line: Int,
+ reason: String
+ ) {
+ self.file = file
+ self.line = line
+ self.reason = reason
+ }
+}
diff --git a/Sources/lib/Models/TestOutcome.swift b/Sources/TestifySDK/Models/Outcome.swift
similarity index 65%
rename from Sources/lib/Models/TestOutcome.swift
rename to Sources/TestifySDK/Models/Outcome.swift
index 0277d15..e4a56f8 100644
--- a/Sources/lib/Models/TestOutcome.swift
+++ b/Sources/TestifySDK/Models/Outcome.swift
@@ -1,5 +1,5 @@
//
-// TestOutcome.swift
+// Outcome.swift
// Testify
//
// Created by Tibor BΓΆdecs on 2019. 01. 18..
@@ -7,7 +7,7 @@
import Foundation
-public enum TestOutcome: String, Codable {
+public enum Outcome: String, Codable {
case success
case failure
}
diff --git a/Sources/TestifySDK/Models/OutputFormat.swift b/Sources/TestifySDK/Models/OutputFormat.swift
new file mode 100644
index 0000000..6f40536
--- /dev/null
+++ b/Sources/TestifySDK/Models/OutputFormat.swift
@@ -0,0 +1,14 @@
+//
+// File.swift
+//
+//
+// Created by Lengyel GΓ‘bor on 2023. 02. 17..
+//
+
+import Foundation
+
+public enum OutputFormat : String {
+ case json
+ case junit
+ case md
+}
diff --git a/Sources/TestifySDK/Models/TestCase.swift b/Sources/TestifySDK/Models/TestCase.swift
new file mode 100644
index 0000000..234877a
--- /dev/null
+++ b/Sources/TestifySDK/Models/TestCase.swift
@@ -0,0 +1,34 @@
+//
+// TestCase.swift
+// Testify
+//
+// Created by Tibor BΓΆdecs on 2019. 01. 17..
+//
+
+import Foundation
+
+public struct TestCase: Codable {
+ public let moduleName: String
+ public let className: String
+ public let testName: String
+ public let duration: TimeInterval
+ public let outcome: Outcome
+ public let failureInfo: FailureInfo?
+
+ public init(
+ moduleName: String,
+ className: String,
+ testName: String,
+ duration: TimeInterval,
+ outcome: Outcome,
+ failureInfo: FailureInfo? = nil
+ ) {
+ self.moduleName = moduleName
+ self.className = className
+ self.testName = testName
+ self.duration = duration
+ self.outcome = outcome
+ self.failureInfo = failureInfo
+ }
+
+}
diff --git a/Sources/TestifySDK/Models/TestSuite.swift b/Sources/TestifySDK/Models/TestSuite.swift
new file mode 100644
index 0000000..d69408c
--- /dev/null
+++ b/Sources/TestifySDK/Models/TestSuite.swift
@@ -0,0 +1,46 @@
+//
+// TestSuite.swift
+// Testify
+//
+// Created by Tibor BΓΆdecs on 2019. 01. 17..
+//
+
+import Foundation
+
+public extension TestSuite {
+
+ static func parse(_ input: String) -> TestSuite? {
+ let decoder = RawTestResultDecoder()
+ let suite = try! decoder.decode(input)
+ return suite
+ }
+
+}
+
+public struct TestSuite: Codable {
+ public let name: String
+ public let startDate: Date
+ public var endDate: Date
+ public var unexpected: UInt
+ public var outcome: Outcome
+ public var cases: [TestCase]
+ public var children: [TestSuite]
+
+ public init(
+ name: String,
+ startDate: Date,
+ endDate: Date,
+ unexpected: UInt,
+ outcome: Outcome,
+ cases: [TestCase] = [],
+ children: [TestSuite] = []
+ ) {
+ self.name = name
+ self.startDate = startDate
+ self.endDate = endDate
+ self.unexpected = unexpected
+ self.outcome = outcome
+ self.cases = cases
+ self.children = children
+ }
+}
diff --git a/Sources/cli/main.swift b/Sources/cli/main.swift
deleted file mode 100644
index c163156..0000000
--- a/Sources/cli/main.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// String+Regex.swift
-// Testify
-//
-// Created by Tibor BΓΆdecs on 2019. 01. 17..
-//
-
-import Foundation
-import Testify
-
-var data: Data
-var input: String = ""
-repeat {
- data = FileHandle.standardInput.availableData
- input += String(data: data, encoding: .utf8)!
-} while (data.count > 0)
-
-
-
-//let input = String(bytes: FileHandle.standardInput.availableData, encoding: .utf8)!
-let suite = TestSuite.parse(input)
-let encoder = JSONEncoder()
-encoder.outputFormatting = .prettyPrinted
-let jsonData = try! encoder.encode(suite)
-print(String(data: jsonData, encoding: .utf8)!)
diff --git a/Sources/lib/Extensions/String+Regex.swift b/Sources/lib/Extensions/String+Regex.swift
deleted file mode 100644
index afd5c47..0000000
--- a/Sources/lib/Extensions/String+Regex.swift
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// String+Regex.swift
-// Testify
-//
-// Created by Tibor BΓΆdecs on 2019. 01. 17..
-//
-
-import Foundation
-
-extension String {
-
- func match(regex pattern: String) -> String? {
- let regex = try! NSRegularExpression(pattern: pattern)
- let matches = regex.matches(in: self, range: NSRange(location: 0, length: self.count))
- guard
- let match = matches.first,
- let range = Range(match.range, in: self)
- else {
- return nil
- }
- return String(self[range])
- }
-
- var matchedTestName: String? {
- guard let match = self.match(regex: "(\\'.+\\')") else {
- return nil
- }
- return String(match.dropFirst().dropLast())
- }
-
- var matchedDate: String? {
- return self.match(regex: "(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{3})")
- }
-
- var matchedSeconds: String? {
- return self.match(regex: "(\\d+\\.\\d+)")
- }
-
- var matchedUnexpected: String? {
- return String(self.match(regex: "\\((\\d+)")!.dropFirst())
- }
-}
diff --git a/Sources/lib/Models/TestCase.swift b/Sources/lib/Models/TestCase.swift
deleted file mode 100644
index 888dee2..0000000
--- a/Sources/lib/Models/TestCase.swift
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// TestCase.swift
-// Testify
-//
-// Created by Tibor BΓΆdecs on 2019. 01. 17..
-//
-
-import Foundation
-
-public struct TestCase: Codable {
-
- public var moduleName: String
- public var className: String
- public var testName: String
- public var duration: TimeInterval
- public var outcome: TestOutcome
- public var failureInfo: TestFailureInfo?
-
- public init(moduleName: String,
- className: String,
- testName: String,
- duration: TimeInterval,
- outcome: TestOutcome,
- failureInfo: TestFailureInfo? = nil) {
- self.moduleName = moduleName
- self.className = className
- self.testName = testName
- self.duration = duration
- self.outcome = outcome
- self.failureInfo = failureInfo
- }
-}
diff --git a/Sources/lib/Models/TestFailureInfo.swift b/Sources/lib/Models/TestFailureInfo.swift
deleted file mode 100644
index 59b5bfe..0000000
--- a/Sources/lib/Models/TestFailureInfo.swift
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// TestFailureInfo.swift
-// Testify
-//
-// Created by Tibor BΓΆdecs on 2019. 01. 19..
-//
-
-import Foundation
-
-public struct TestFailureInfo: Codable {
-
- public var file: String
- public var line: Int
- public var reason: String
-
- public init(file: String, line: Int, reason: String) {
- self.file = file
- self.line = line
- self.reason = reason
- }
-}
diff --git a/Sources/lib/Models/TestSuite.swift b/Sources/lib/Models/TestSuite.swift
deleted file mode 100644
index 944d8fc..0000000
--- a/Sources/lib/Models/TestSuite.swift
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// TestSuite.swift
-// Testify
-//
-// Created by Tibor BΓΆdecs on 2019. 01. 17..
-//
-
-import Foundation
-
-public struct TestSuite: Codable {
-
- public var name: String
- public var startDate: Date
- public var endDate: Date
- public var unexpected: Int
- public var outcome: TestOutcome
- public var cases: [TestCase]
- public var children: [TestSuite]
-
- public init(name: String,
- startDate: Date,
- endDate: Date,
- unexpected: Int,
- outcome: TestOutcome,
- cases: [TestCase] = [],
- children: [TestSuite] = []) {
- self.name = name
- self.startDate = startDate
- self.endDate = endDate
- self.unexpected = unexpected
- self.outcome = outcome
- self.cases = cases
- self.children = children
- }
-}
diff --git a/Sources/testify/main.swift b/Sources/testify/main.swift
new file mode 100644
index 0000000..fb85b26
--- /dev/null
+++ b/Sources/testify/main.swift
@@ -0,0 +1,54 @@
+//
+// main.swift
+// Testify
+//
+// Created by Tibor BΓΆdecs on 2019. 01. 17..
+//
+
+import Foundation
+import TestifySDK
+
+let args = CommandLine.arguments
+var format: String = OutputFormat.json.rawValue
+let msg = "Testify output format is"
+if (args.count >= 2) {
+ if let enumCase = OutputFormat(rawValue: args[1]) {
+ format = enumCase.rawValue
+ print(msg, "'\(format)'")
+ } else {
+ print("Unknown Testify output format, the format is 'json' for now. Available formats: 'json', 'junit', 'md'")
+ }
+} else {
+ print(msg, "'json'")
+}
+
+var data: Data
+var input: String = ""
+repeat {
+ data = FileHandle.standardInput.availableData
+ input += String(data: data, encoding: .utf8)!
+} while (data.count > 0)
+
+let decoder = RawTestResultDecoder()
+let suite = try decoder.decode(input)
+
+switch format {
+case OutputFormat.json.rawValue:
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .prettyPrinted
+ let jsonData = try! encoder.encode(suite)
+ print("\n", String(data: jsonData, encoding: .utf8)!, "\n")
+
+case OutputFormat.junit.rawValue:
+ let encoder = TestResultJunitEncoder()
+ let junitData = try! encoder.encode(suite)
+ print(junitData)
+
+case OutputFormat.md.rawValue:
+ let encoder = TestResultMarkdownEncoder()
+ let mdData = try! encoder.encode(suite)
+ print(mdData)
+
+default:
+ print("Unknown output format")
+}
diff --git a/Tests/Assets/Alamofire.json b/Tests/Assets/json/Alamofire.json
similarity index 100%
rename from Tests/Assets/Alamofire.json
rename to Tests/Assets/json/Alamofire.json
diff --git a/Tests/Assets/Kitura-coverage.json b/Tests/Assets/json/Kitura-coverage.json
similarity index 100%
rename from Tests/Assets/Kitura-coverage.json
rename to Tests/Assets/json/Kitura-coverage.json
diff --git a/Tests/Assets/Kitura.json b/Tests/Assets/json/Kitura.json
similarity index 100%
rename from Tests/Assets/Kitura.json
rename to Tests/Assets/json/Kitura.json
diff --git a/Tests/Assets/PromiseFailure.json b/Tests/Assets/json/PromiseFailure.json
similarity index 100%
rename from Tests/Assets/PromiseFailure.json
rename to Tests/Assets/json/PromiseFailure.json
diff --git a/Tests/Assets/PromiseUnexpectedFailure.json b/Tests/Assets/json/PromiseUnexpectedFailure.json
similarity index 100%
rename from Tests/Assets/PromiseUnexpectedFailure.json
rename to Tests/Assets/json/PromiseUnexpectedFailure.json
diff --git a/Tests/Assets/Shell-coverage.json b/Tests/Assets/json/Shell-coverage.json
similarity index 100%
rename from Tests/Assets/Shell-coverage.json
rename to Tests/Assets/json/Shell-coverage.json
diff --git a/Tests/Assets/Shell.json b/Tests/Assets/json/Shell.json
similarity index 100%
rename from Tests/Assets/Shell.json
rename to Tests/Assets/json/Shell.json
diff --git a/Tests/Assets/ShellFailure.json b/Tests/Assets/json/ShellFailure.json
similarity index 100%
rename from Tests/Assets/ShellFailure.json
rename to Tests/Assets/json/ShellFailure.json
diff --git a/Tests/Assets/ShellOutFailure.json b/Tests/Assets/json/ShellOutFailure.json
similarity index 100%
rename from Tests/Assets/ShellOutFailure.json
rename to Tests/Assets/json/ShellOutFailure.json
diff --git a/Tests/Assets/md/Alamofire.md b/Tests/Assets/md/Alamofire.md
new file mode 100644
index 0000000..1073ea3
--- /dev/null
+++ b/Tests/Assets/md/Alamofire.md
@@ -0,0 +1,778 @@
+AutomaticValidationTestCase: 5 tests were completed in 1.502 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatValidationForRequestWithAcceptableComplexContentTypeResponseSucceeds | β
| | π | 0.786s βοΈ |
+| testThatValidationForRequestWithAcceptableStatusCodeAndContentTypeResponseSucceeds | β
| | π | 0.178s βοΈ |
+| testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceeds | β
| | π | 0.179s βοΈ |
+| testThatValidationForRequestWithUnacceptableContentTypeResponseFails | β
| | π | 0.18s βοΈ |
+| testThatValidationForRequestWithUnacceptableStatusCodeResponseFails | β
| | π | 0.179s βοΈ |
+
+BasicAuthenticationTestCase: 3 tests were completed in 2.3680000000000003 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testHiddenHTTPBasicAuthentication | β
| | π | 0.348s βοΈ |
+| testHTTPBasicAuthenticationWithInvalidCredentials | β
| | π | 1.066s βοΈ |
+| testHTTPBasicAuthenticationWithValidCredentials | β
| | π | 0.954s βοΈ |
+
+CacheTestCase: 5 tests were completed in 13.501999999999999 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testDefaultCachePolicy | β
| | π | 3.235s βοΈ |
+| testIgnoreLocalCacheDataPolicy | β
| | π | 3.221s βοΈ |
+| testURLCacheContainsCachedResponsesForAllRequests | β
| | π | 2.298s βοΈ |
+| testUseLocalCacheDataAndDontLoadFromNetworkPolicy | β
| | π | 2.364s βοΈ |
+| testUseLocalCacheDataIfExistsOtherwiseLoadFromNetworkPolicy | β
| | π | 2.384s βοΈ |
+
+ContentTypeValidationTestCase: 6 tests were completed in 1.605 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatValidationForRequestWithAcceptableContentTypeResponseSucceeds | β
| | π | 0.184s βοΈ |
+| testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceeds | β
| | π | 0.182s βοΈ |
+| testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceedsWhenResponseIsNil | β
| | π | 0.679s βοΈ |
+| testThatValidationForRequestWithNoAcceptableContentTypeResponseFails | β
| | π | 0.183s βοΈ |
+| testThatValidationForRequestWithNoAcceptableContentTypeResponseSucceedsWhenNoDataIsReturned | β
| | π | 0.185s βοΈ |
+| testThatValidationForRequestWithUnacceptableContentTypeResponseFails | β
| | π | 0.192s βοΈ |
+
+CustomResponseSerializerTestCases: 1 tests were completed in 0.187 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatCustomResponseSerializersCanBeWrittenWithoutCompilerIssues | β
| | π | 0.187s βοΈ |
+
+CustomValidationTestCase: 4 tests were completed in 0.73 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatCustomValidationCanThrowCustomError | β
| | π | 0.193s βοΈ |
+| testThatCustomValidationClosureHasAccessToServerResponseData | β
| | π | 0.179s βοΈ |
+| testThatValidationExtensionCanThrowCustomError | β
| | π | 0.177s βοΈ |
+| testThatValidationExtensionHasAccessToServerResponseData | β
| | π | 0.181s βοΈ |
+
+DataResponseSerializationTestCase: 22 tests were completed in 0.059000000000000025 with 22 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatDataResponseSerializerFailsWhenDataIsNil | β
| | π | 0.003s βοΈ |
+| testThatDataResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerSucceedsWhenDataIsNotNil | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsEmpty | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsInvalidJSON | β
| | π | 0.004s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsNil | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerSucceedsWhenDataIsValidJSON | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenDataIsEmpty | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenDataIsNil | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWithUTF32DataAndUTF8ProvidedEncoding | β
| | π | 0.009s βοΈ |
+| testThatStringResponseSerializerFailsWithUTF32DataAndUTF8ResponseEncoding | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataAndNoProvidedEncoding | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataAndUTF8ProvidedEncoding | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataUsingResponseTextEncodingName | β
| | π | 0.003s βοΈ |
+
+DecodableResponseSerializerTests: 7 tests were completed in 0.019 with 7 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatDecodableResponseSerializerFailsWhenDataIsEmpty | β
| | π | 0.003s βοΈ |
+| testThatDecodableResponseSerializerFailsWhenDataIsInvalidRepresentation | β
| | π | 0.004s βοΈ |
+| testThatDecodableResponseSerializerFailsWhenDataIsNil | β
| | π | 0.002s βοΈ |
+| testThatDecodableResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatDecodableResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.002s βοΈ |
+| testThatDecodableResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.003s βοΈ |
+| testThatDecodableResponseSerializerSucceedsWhenDataIsValidJSON | β
| | π | 0.003s βοΈ |
+
+DownloadInitializationTestCase: 2 tests were completed in 0.335 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testDownloadClassMethodWithMethodURLAndDestination | β
| | π | 0.169s βοΈ |
+| testDownloadClassMethodWithMethodURLHeadersAndDestination | β
| | π | 0.166s βοΈ |
+
+DownloadResponseFlatMapErrorTestCase: 3 tests were completed in 3.105 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatFlatMapErrorCatchesTransformationError | β
| | π | 2.919s βοΈ |
+| testThatFlatMapErrorPreservesSuccessValue | β
| | π | 0.176s βοΈ |
+| testThatFlatMapErrorTransformsError | β
| | π | 0.01s βοΈ |
+
+DownloadResponseFlatMapTestCase: 3 tests were completed in 0.371 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatFlatMapCatchesTransformationError | β
| | π | 0.189s βοΈ |
+| testThatFlatMapPreservesFailureError | β
| | π | 0.009s βοΈ |
+| testThatFlatMapTransformsSuccessValue | β
| | π | 0.173s βοΈ |
+
+DownloadResponseMapErrorTestCase: 2 tests were completed in 0.18 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatMapErrorPreservesSuccessValue | β
| | π | 0.172s βοΈ |
+| testThatMapErrorTransformsFailureValue | β
| | π | 0.008s βοΈ |
+
+DownloadResponseMapTestCase: 2 tests were completed in 0.183 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatMapPreservesFailureError | β
| | π | 0.009s βοΈ |
+| testThatMapTransformsSuccessValue | β
| | π | 0.174s βοΈ |
+
+DownloadResponseSerializationTestCase: 26 tests were completed in 0.07300000000000002 with 26 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatDataResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.003s βοΈ |
+| testThatDataResponseSerializerFailsWhenFileDataIsEmpty | β
| | π | 0.003s βοΈ |
+| testThatDataResponseSerializerFailsWhenFileURLIsInvalid | β
| | π | 0.003s βοΈ |
+| testThatDataResponseSerializerFailsWhenFileURLIsNil | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerFailsWhenFileURLIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatDataResponseSerializerSucceedsWhenFileDataIsNotNil | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsInvalidJSON | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerFailsWhenFileDataIsEmpty | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerFailsWhenFileURLIsInvalid | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerFailsWhenFileURLIsNil | β
| | π | 0.002s βοΈ |
+| testThatJSONResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.003s βοΈ |
+| testThatJSONResponseSerializerSucceedsWhenDataIsValidJSON | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerFailsWhenDataIsNilWithNonEmptyResponseStatusCode | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenErrorIsNotNil | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenFileDataIsEmpty | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenFileURLIsInvalid | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWhenFileURLIsNil | β
| | π | 0.002s βοΈ |
+| testThatStringResponseSerializerFailsWithUTF32DataAndUTF8ProvidedEncoding | β
| | π | 0.005s βοΈ |
+| testThatStringResponseSerializerFailsWithUTF32DataAndUTF8ResponseEncoding | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerSucceedsWhenDataIsNilWithEmptyResponseStatusCode | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataAndNoProvidedEncoding | β
| | π | 0.003s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataAndUTF8ProvidedEncoding | β
| | π | 0.005s βοΈ |
+| testThatStringResponseSerializerSucceedsWithUTF8DataUsingResponseTextEncodingName | β
| | π | 0.004s βοΈ |
+
+DownloadResponseTestCase: 9 tests were completed in 2.138 with 9 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCancelledDownloadRequest | β
| | π | 0.005s βοΈ |
+| testDownloadRequest | β
| | π | 0.329s βοΈ |
+| testDownloadRequestWithHeaders | β
| | π | 0.169s βοΈ |
+| testDownloadRequestWithParameters | β
| | π | 0.175s βοΈ |
+| testDownloadRequestWithProgress | β
| | π | 0.696s βοΈ |
+| testThatDownloadingFileAndMovingToDestinationThatIsOccupiedThrowsError | β
| | π | 0.202s βοΈ |
+| testThatDownloadingFileAndMovingToDirectoryThatDoesNotExistThrowsError | β
| | π | 0.184s βοΈ |
+| testThatDownloadOptionsCanCreateIntermediateDirectoriesPriorToMovingFile | β
| | π | 0.192s βοΈ |
+| testThatDownloadOptionsCanRemovePreviousFilePriorToMovingFile | β
| | π | 0.186s βοΈ |
+
+DownloadResumeDataTestCase: 3 tests were completed in 5.079000000000001 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatCancelledDownloadCanBeResumedWithResumeData | β
| | π | 4.014s βοΈ |
+| testThatCancelledDownloadResponseDataMatchesResumeData | β
| | π | 0.546s βοΈ |
+| testThatCancelledDownloadResumeDataIsAvailableWithJSONResponseSerializer | β
| | π | 0.519s βοΈ |
+
+HTTPDigestAuthenticationTestCase: 2 tests were completed in 1.915 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testHTTPDigestAuthenticationWithInvalidCredentials | β
| | π | 1.057s βοΈ |
+| testHTTPDigestAuthenticationWithValidCredentials | β
| | π | 0.858s βοΈ |
+
+HTTPHeadersTests: 6 tests were completed in 0.013000000000000001 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testHeadersAreStoreUniquelyByCaseInsensitiveName | β
| | π | 0.003s βοΈ |
+| testHeadersCanBeProperlySortedByName | β
| | π | 0.002s βοΈ |
+| testHeadersCanInsensitivelyGetAndSetThroughSubscript | β
| | π | 0.002s βοΈ |
+| testHeadersHaveUnsortedDescription | β
| | π | 0.002s βοΈ |
+| testHeadersPreserveLastFormAndValueOfAName | β
| | π | 0.002s βοΈ |
+| testHeadersPreserveOrderOfInsertion | β
| | π | 0.002s βοΈ |
+
+JSONParameterEncoderTests: 5 tests were completed in 0.013 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatDataIsProperlyEncodedAndProperContentTypeIsSet | β
| | π | 0.003s βοΈ |
+| testThatDataIsProperlyEncodedButContentTypeIsNotSetIfRequestAlreadyHasAContentType | β
| | π | 0.002s βοΈ |
+| testThatJSONEncoderCanBeCustomized | β
| | π | 0.002s βοΈ |
+| testThatJSONEncoderDefaultWorks | β
| | π | 0.004s βοΈ |
+| testThatJSONEncoderPrettyPrintedPrintsPretty | β
| | π | 0.002s βοΈ |
+
+JSONParameterEncodingTestCase: 4 tests were completed in 0.01 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testJSONParameterEncodeArray | β
| | π | 0.003s βοΈ |
+| testJSONParameterEncodeComplexParameters | β
| | π | 0.003s βοΈ |
+| testJSONParameterEncodeNilParameters | β
| | π | 0.002s βοΈ |
+| testJSONParameterEncodeParametersRetainsCustomContentType | β
| | π | 0.002s βοΈ |
+
+MultipartFormDataEncodingTestCase: 7 tests were completed in 0.049 with 7 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testEncodingDataBodyPart | β
| | π | 0.003s βοΈ |
+| testEncodingFileBodyPart | β
| | π | 0.021s βοΈ |
+| testEncodingMultipleBodyPartsWithVaryingTypes | β
| | π | 0.006s βοΈ |
+| testEncodingMultipleDataBodyParts | β
| | π | 0.003s βοΈ |
+| testEncodingMultipleFileBodyParts | β
| | π | 0.007s βοΈ |
+| testEncodingMultipleStreamBodyParts | β
| | π | 0.005s βοΈ |
+| testEncodingStreamBodyPart | β
| | π | 0.004s βοΈ |
+
+MultipartFormDataFailureTestCase: 6 tests were completed in 0.021 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatAppendingFileBodyPartThatIsDirectoryReturnsError | β
| | π | 0.003s βοΈ |
+| testThatAppendingFileBodyPartThatIsNotFileURLReturnsError | β
| | π | 0.003s βοΈ |
+| testThatAppendingFileBodyPartThatIsNotReachableReturnsError | β
| | π | 0.004s βοΈ |
+| testThatAppendingFileBodyPartWithInvalidLastPathComponentReturnsError | β
| | π | 0.003s βοΈ |
+| testThatWritingEncodedDataToBadURLFails | β
| | π | 0.003s βοΈ |
+| testThatWritingEncodedDataToExistingFileURLFails | β
| | π | 0.005s βοΈ |
+
+MultipartFormDataPropertiesTestCase: 2 tests were completed in 0.006 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatContentLengthMatchesTotalBodyPartSize | β
| | π | 0.003s βοΈ |
+| testThatContentTypeContainsBoundary | β
| | π | 0.003s βοΈ |
+
+MultipartFormDataWriteEncodedDataToDiskTestCase: 7 tests were completed in 0.041999999999999996 with 7 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testWritingEncodedDataBodyPartToDisk | β
| | π | 0.004s βοΈ |
+| testWritingEncodedFileBodyPartToDisk | β
| | π | 0.006s βοΈ |
+| testWritingEncodedStreamBodyPartToDisk | β
| | π | 0.005s βοΈ |
+| testWritingMultipleEncodedBodyPartsWithVaryingTypesToDisk | β
| | π | 0.008s βοΈ |
+| testWritingMultipleEncodedDataBodyPartsToDisk | β
| | π | 0.003s βοΈ |
+| testWritingMultipleEncodedFileBodyPartsToDisk | β
| | π | 0.011s βοΈ |
+| testWritingMultipleEncodedStreamBodyPartsToDisk | β
| | π | 0.005s βοΈ |
+
+MultipleValidationTestCase: 3 tests were completed in 0.5429999999999999 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatValidationForRequestWithAcceptableStatusCodeAndContentTypeResponseSucceeds | β
| | π | 0.178s βοΈ |
+| testThatValidationForRequestWithUnacceptableStatusCodeAndContentTypeResponseFailsWithContentTypeError | β
| | π | 0.181s βοΈ |
+| testThatValidationForRequestWithUnacceptableStatusCodeAndContentTypeResponseFailsWithStatusCodeError | β
| | π | 0.184s βοΈ |
+
+NetworkReachabilityManagerTestCase: 17 tests were completed in 0.05200000000000002 with 17 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatAddressManagerCanBeDeinitialized | β
| | π | 0.003s βοΈ |
+| testThatAddressManagerIsNotifiedWhenStartListeningIsCalled | β
| | π | 0.004s βοΈ |
+| testThatAddressManagerStartsWithReachableStatus | β
| | π | 0.003s βοΈ |
+| testThatHostManagerCanBeDeinitialized | β
| | π | 0.002s βοΈ |
+| testThatHostManagerIsNotifiedWhenStartListeningIsCalled | β
| | π | 0.004s βοΈ |
+| testThatHostManagerIsReachableOnWiFi | β
| | π | 0.004s βοΈ |
+| testThatHostManagerStartsWithReachableStatus | β
| | π | 0.004s βοΈ |
+| testThatManagerCanBeInitializedFromAddress | β
| | π | 0.003s βοΈ |
+| testThatManagerCanBeInitializedFromHost | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsNotReachableOnWWANStatusWhenIsWWANAndConnectionIsRequired | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsNotReachableStatusWhenConnectionIsRequired | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsNotReachableStatusWhenInterventionIsRequired | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsNotReachableStatusWhenReachableFlagIsAbsent | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsReachableOnWiFiStatusWhenConnectionIsNotRequired | β
| | π | 0.003s βοΈ |
+| testThatManagerReturnsReachableOnWiFiStatusWhenConnectionIsOnDemand | β
| | π | 0.002s βοΈ |
+| testThatManagerReturnsReachableOnWiFiStatusWhenConnectionIsOnTraffic | β
| | π | 0.002s βοΈ |
+| testThatManagerReturnsReachableOnWWANStatusWhenIsWWAN | β
| | π | 0.003s βοΈ |
+
+RequestDebugDescriptionTestCase: 9 tests were completed in 4.523999999999999 with 9 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testGETRequestDebugDescription | β
| | π | 0.646s βοΈ |
+| testGETRequestWithDuplicateHeadersDebugDescription | β
| | π | 0.658s βοΈ |
+| testGETRequestWithJSONHeaderDebugDescription | β
| | π | 0.652s βοΈ |
+| testMultipartFormDataRequestWithDuplicateHeadersDebugDescription | β
| | π | 0.599s βοΈ |
+| testPOSTRequestDebugDescription | β
| | π | 0.605s βοΈ |
+| testPOSTRequestWithCookieDebugDescription | β
| | π | 0.682s βοΈ |
+| testPOSTRequestWithCookiesDisabledDebugDescription | β
| | π | 0.004s βοΈ |
+| testPOSTRequestWithJSONParametersDebugDescription | β
| | π | 0.666s βοΈ |
+| testThatRequestWithInvalidURLDebugDescription | β
| | π | 0.012s βοΈ |
+
+RequestDescriptionTestCase: 1 tests were completed in 0.733 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testRequestDescription | β
| | π | 0.733s βοΈ |
+
+RequestResponseTestCase: 8 tests were completed in 3.2600000000000002 with 8 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testPOSTRequestWithBase64EncodedImages | β
| | π | 1.134s βοΈ |
+| testPOSTRequestWithUnicodeParameters | β
| | π | 0.188s βοΈ |
+| testRequestResponse | β
| | π | 0.191s βοΈ |
+| testRequestResponseWithProgress | β
| | π | 0.578s βοΈ |
+| testThatRequestsCanPassEncodableParametersAsAURLQuery | β
| | π | 0.184s βοΈ |
+| testThatRequestsCanPassEncodableParametersAsJSONBodyData | β
| | π | 0.184s βοΈ |
+| testThatRequestsCanPassEncodableParametersAsURLEncodedBodyData | β
| | π | 0.188s βοΈ |
+| testThatResponseSerializationWorksWithSerializationQueue | β
| | π | 0.613s βοΈ |
+
+ResponseDataTestCase: 2 tests were completed in 0.191 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatResponseDataReturnsFailureResultWithOptionalDataAndError | β
| | π | 0.011s βοΈ |
+| testThatResponseDataReturnsSuccessResultWithValidData | β
| | π | 0.18s βοΈ |
+
+ResponseFlatMapErrorTestCase: 3 tests were completed in 0.201 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatFlatMapErrorCatchesTransformationError | β
| | π | 0.009s βοΈ |
+| testThatFlatMapErrorPreservesSuccessValue | β
| | π | 0.182s βοΈ |
+| testThatFlatMapErrorTransformsError | β
| | π | 0.01s βοΈ |
+
+ResponseFlatMapTestCase: 3 tests were completed in 0.38 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatFlatMapCatchesTransformationError | β
| | π | 0.182s βοΈ |
+| testThatFlatMapPreservesFailureError | β
| | π | 0.011s βοΈ |
+| testThatFlatMapTransformsSuccessValue | β
| | π | 0.187s βοΈ |
+
+ResponseJSONDecodableTestCase: 2 tests were completed in 0.192 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatResponseJSONReturnsSuccessResultWithValidJSON | β
| | π | 0.182s βοΈ |
+| testThatResponseStringReturnsFailureResultWithOptionalDataAndError | β
| | π | 0.01s βοΈ |
+
+ResponseJSONTestCase: 4 tests were completed in 0.564 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatResponseJSONReturnsSuccessResultForGETRequest | β
| | π | 0.186s βοΈ |
+| testThatResponseJSONReturnsSuccessResultForPOSTRequest | β
| | π | 0.18s βοΈ |
+| testThatResponseJSONReturnsSuccessResultWithValidJSON | β
| | π | 0.187s βοΈ |
+| testThatResponseStringReturnsFailureResultWithOptionalDataAndError | β
| | π | 0.011s βοΈ |
+
+ResponseMapErrorTestCase: 2 tests were completed in 0.193 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatMapErrorPreservesSuccessValue | β
| | π | 0.183s βοΈ |
+| testThatMapErrorTransformsFailureValue | β
| | π | 0.01s βοΈ |
+
+ResponseMapTestCase: 2 tests were completed in 0.218 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatMapPreservesFailureError | β
| | π | 0.012s βοΈ |
+| testThatMapTransformsSuccessValue | β
| | π | 0.206s βοΈ |
+
+ResponseStringTestCase: 2 tests were completed in 0.193 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatResponseStringReturnsFailureResultWithOptionalDataAndError | β
| | π | 0.013s βοΈ |
+| testThatResponseStringReturnsSuccessResultWithValidString | β
| | π | 0.18s βοΈ |
+
+ResponseTestCase: 2 tests were completed in 0.199 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatResponseReturnsFailureResultWithOptionalDataAndError | β
| | π | 0.01s βοΈ |
+| testThatResponseReturnsSuccessResultWithValidData | β
| | π | 0.189s βοΈ |
+
+ResultTestCase: 34 tests were completed in 0.08800000000000005 with 34 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testFlatMapErrorCapturesThrownError | β
| | π | 0.002s βοΈ |
+| testFlatMapErrorTransformsErrorValue | β
| | π | 0.002s βοΈ |
+| testFunctionalMethodsCanBeChained | β
| | π | 0.002s βοΈ |
+| testIfFailureDoesNotExecuteWhenSuccess | β
| | π | 0.003s βοΈ |
+| testIfFailureExecutesWhenFailure | β
| | π | 0.003s βοΈ |
+| testIfSuccessDoesNotExecutesWhenFailure | β
| | π | 0.003s βοΈ |
+| testIfSuccessExecutesWhenSuccess | β
| | π | 0.003s βοΈ |
+| testMapErrorPreservesSuccessError | β
| | π | 0.003s βοΈ |
+| testMapErrorTransformsErrorValue | β
| | π | 0.003s βοΈ |
+| testThatDebugDescriptionStringMatchesExpectedValueForFailureCase | β
| | π | 0.003s βοΈ |
+| testThatDebugDescriptionStringMatchesExpectedValueForSuccessCase | β
| | π | 0.002s βοΈ |
+| testThatDescriptionStringMatchesExpectedValueForFailureCase | β
| | π | 0.003s βοΈ |
+| testThatDescriptionStringMatchesExpectedValueForSuccessCase | β
| | π | 0.002s βοΈ |
+| testThatErrorPropertyReturnsErrorForFailureCase | β
| | π | 0.003s βοΈ |
+| testThatErrorPropertyReturnsNilForSuccessCase | β
| | π | 0.003s βοΈ |
+| testThatFlatMapCatchesTransformationError | β
| | π | 0.002s βοΈ |
+| testThatFlatMapPreservesFailureError | β
| | π | 0.002s βοΈ |
+| testThatFlatMapTransformsSuccessValue | β
| | π | 0.002s βοΈ |
+| testThatInitializerFromThrowingClosureCatchesErrorAsAFailure | β
| | π | 0.003s βοΈ |
+| testThatInitializerFromThrowingClosureStoresResultAsASuccess | β
| | π | 0.003s βοΈ |
+| testThatIsFailurePropertyReturnsFalseForSuccessCase | β
| | π | 0.002s βοΈ |
+| testThatIsFailurePropertyReturnsTrueForFailureCase | β
| | π | 0.003s βοΈ |
+| testThatIsSuccessPropertyReturnsFalseForFailureCase | β
| | π | 0.003s βοΈ |
+| testThatIsSuccessPropertyReturnsTrueForSuccessCase | β
| | π | 0.002s βοΈ |
+| testThatMapPreservesFailureError | β
| | π | 0.002s βοΈ |
+| testThatMapTransformsSuccessValue | β
| | π | 0.002s βοΈ |
+| testThatUnwrapReturnsSuccessValue | β
| | π | 0.003s βοΈ |
+| testThatUnwrapThrowsFailureError | β
| | π | 0.003s βοΈ |
+| testThatValuePropertyReturnsNilForFailureCase | β
| | π | 0.002s βοΈ |
+| testThatValuePropertyReturnsValueForSuccessCase | β
| | π | 0.003s βοΈ |
+| testWithErrorDoesNotExecuteWhenSuccess | β
| | π | 0.003s βοΈ |
+| testWithErrorExecutesWhenFailure | β
| | π | 0.003s βοΈ |
+| testWithValueDoesNotExecutesWhenFailure | β
| | π | 0.002s βοΈ |
+| testWithValueExecutesWhenSuccess | β
| | π | 0.003s βοΈ |
+
+ServerTrustPolicyCertificatesInBundleTestCase: 1 tests were completed in 0.019 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testOnlyValidCertificatesAreDetected | β
| | π | 0.019s βοΈ |
+
+ServerTrustPolicyCompositeTestCase: 3 tests were completed in 0.041 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatExpiredLeafCertificateFailsDefaultAndRevocationComposite | β
| | π | 0.017s βοΈ |
+| testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.009s βοΈ |
+| testThatValidCertificateChainPassesDefaultAndRevocationCompositeChecks | β
| | π | 0.015s βοΈ |
+
+ServerTrustPolicyDisableEvaluationTestCase: 2 tests were completed in 0.005 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatCertificateChainMissingIntermediateCertificatePassesEvaluation | β
| | π | 0.002s βοΈ |
+| testThatExpiredLeafCertificatePassesEvaluation | β
| | π | 0.003s βοΈ |
+
+ServerTrustPolicyExplorationBasicX509PolicyValidationTestCase: 4 tests were completed in 0.03 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatAnchoredRootCertificatePassesBasicX509ValidationWithoutRootInTrust | β
| | π | 0.009s βοΈ |
+| testThatAnchoredRootCertificatePassesBasicX509ValidationWithRootInTrust | β
| | π | 0.005s βοΈ |
+| testThatCertificateMissingDNSNamePassesBasicX509Validation | β
| | π | 0.006s βοΈ |
+| testThatExpiredCertificateFailsBasicX509Validation | β
| | π | 0.01s βοΈ |
+
+ServerTrustPolicyExplorationSSLPolicyValidationTestCase: 9 tests were completed in 0.066 with 9 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatAnchoredRootCertificatePassesSSLValidationWithoutRootInTrust | β
| | π | 0.007s βοΈ |
+| testThatAnchoredRootCertificatePassesSSLValidationWithRootInTrust | β
| | π | 0.007s βοΈ |
+| testThatCertificateMissingDNSNameFailsSSLValidation | β
| | π | 0.007s βοΈ |
+| testThatDNSNameCertificatePassesSSLValidation | β
| | π | 0.006s βοΈ |
+| testThatExpiredCertificateFailsSSLValidation | β
| | π | 0.008s βοΈ |
+| testThatMultipleDNSNamesCertificatePassesSSLValidationForAllEntries | β
| | π | 0.007s βοΈ |
+| testThatPassingNilForHostParameterAllowsCertificateMissingDNSNameToPassSSLValidation | β
| | π | 0.005s βοΈ |
+| testThatURICertificateFailsSSLValidation | β
| | π | 0.007s βοΈ |
+| testThatWildcardCertificatePassesSSLValidation | β
| | π | 0.012s βοΈ |
+
+ServerTrustPolicyPerformDefaultEvaluationTestCase: 11 tests were completed in 0.094 with 11 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatExpiredCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.01s βοΈ |
+| testThatExpiredCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.01s βοΈ |
+| testThatMissingDNSNameLeafCertificateFailsEvaluationWithHostValidation | β
| | π | 0.009s βοΈ |
+| testThatMissingDNSNameLeafCertificatePassesEvaluationWithoutHostValidation | β
| | π | 0.007s βοΈ |
+| testThatMissingIntermediateCertificateInChainFailsEvaluationWithHostValidation | β
| | π | 0.006s βοΈ |
+| testThatMissingIntermediateCertificateInChainFailsEvaluationWithoutHostValidation | β
| | π | 0.004s βοΈ |
+| testThatNonAnchoredRootCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.009s βοΈ |
+| testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.009s βοΈ |
+| testThatValidCertificateChainPassesEvaluationWithHostValidation | β
| | π | 0.011s βοΈ |
+| testThatValidCertificateChainPassesEvaluationWithoutHostValidation | β
| | π | 0.007s βοΈ |
+| testThatWildcardedLeafCertificateChainPassesEvaluationWithHostValidation | β
| | π | 0.012s βοΈ |
+
+ServerTrustPolicyPerformRevokedEvaluationTestCase: 11 tests were completed in 0.11699999999999999 with 11 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatExpiredCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.008s βοΈ |
+| testThatExpiredCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.01s βοΈ |
+| testThatMissingDNSNameLeafCertificateFailsEvaluationWithHostValidation | β
| | π | 0.014s βοΈ |
+| testThatMissingDNSNameLeafCertificatePassesEvaluationWithoutHostValidation | β
| | π | 0.011s βοΈ |
+| testThatMissingIntermediateCertificateInChainFailsEvaluationWithHostValidation | β
| | π | 0.006s βοΈ |
+| testThatMissingIntermediateCertificateInChainFailsEvaluationWithoutHostValidation | β
| | π | 0.006s βοΈ |
+| testThatNonAnchoredRootCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.008s βοΈ |
+| testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.009s βοΈ |
+| testThatValidCertificateChainPassesEvaluationWithHostValidation | β
| | π | 0.018s βοΈ |
+| testThatValidCertificateChainPassesEvaluationWithoutHostValidation | β
| | π | 0.012s βοΈ |
+| testThatWildcardedLeafCertificateChainPassesEvaluationWithHostValidation | β
| | π | 0.015s βοΈ |
+
+ServerTrustPolicyPinCertificatesTestCase: 23 tests were completed in 0.23100000000000007 with 23 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatPinnedIntermediateCertificatePassesEvaluationWithoutHostValidation | β
| | π | 0.009s βοΈ |
+| testThatPinnedIntermediateCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation | β
| | π | 0.014s βοΈ |
+| testThatPinnedIntermediateCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.01s βοΈ |
+| testThatPinnedLeafCertificatePassesEvaluationWithoutHostValidation | β
| | π | 0.011s βοΈ |
+| testThatPinnedLeafCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation | β
| | π | 0.007s βοΈ |
+| testThatPinnedLeafCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.01s βοΈ |
+| testThatPinnedRootCertificatePassesEvaluationWithoutHostValidation | β
| | π | 0.01s βοΈ |
+| testThatPinnedRootCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation | β
| | π | 0.012s βοΈ |
+| testThatPinnedRootCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.01s βοΈ |
+| testThatPinningExpiredLeafCertificateFailsEvaluationWithHostValidation | β
| | π | 0.01s βοΈ |
+| testThatPinningExpiredLeafCertificateFailsEvaluationWithoutHostValidation | β
| | π | 0.011s βοΈ |
+| testThatPinningExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.009s βοΈ |
+| testThatPinningIntermediateCertificateNotInCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.011s βοΈ |
+| testThatPinningIntermediateCertificateNotInCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.01s βοΈ |
+| testThatPinningIntermediateCertificateNotInCertificateChainWithoutCertificateChainValidationFailsEvaluation | β
| | π | 0.008s βοΈ |
+| testThatPinningIntermediateCertificateWithExpiredLeafCertificateFailsEvaluationWithHostValidation | β
| | π | 0.007s βοΈ |
+| testThatPinningIntermediateCertificateWithExpiredLeafCertificateFailsEvaluationWithoutHostValidation | β
| | π | 0.012s βοΈ |
+| testThatPinningIntermediateCertificateWithExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.009s βοΈ |
+| testThatPinningLeafCertificateNotInCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.008s βοΈ |
+| testThatPinningLeafCertificateNotInCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.009s βοΈ |
+| testThatPinningLeafCertificateNotInCertificateChainWithoutCertificateChainValidationFailsEvaluation | β
| | π | 0.013s βοΈ |
+| testThatPinningMultipleCertificatesWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.012s βοΈ |
+| testThatPinningRootCertificateWithExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation | β
| | π | 0.009s βοΈ |
+
+ServerTrustPolicyPinPublicKeysTestCase: 16 tests were completed in 0.14100000000000001 with 16 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatPinningBackupKeyPassesEvaluationWithHostValidation | β
| | π | 0.011s βοΈ |
+| testThatPinningBackupKeyPassesEvaluationWithoutHostValidation | β
| | π | 0.007s βοΈ |
+| testThatPinningIntermediateKeyPassesEvaluationWithHostValidation | β
| | π | 0.01s βοΈ |
+| testThatPinningIntermediateKeyPassesEvaluationWithoutHostValidation | β
| | π | 0.006s βοΈ |
+| testThatPinningIntermediateKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate | β
| | π | 0.008s βοΈ |
+| testThatPinningKeyNotInCertificateChainFailsEvaluationWithHostValidation | β
| | π | 0.013s βοΈ |
+| testThatPinningKeyNotInCertificateChainFailsEvaluationWithoutHostValidation | β
| | π | 0.008s βοΈ |
+| testThatPinningLeafKeyPassesEvaluationWithHostValidation | β
| | π | 0.012s βοΈ |
+| testThatPinningLeafKeyPassesEvaluationWithoutHostValidation | β
| | π | 0.008s βοΈ |
+| testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate | β
| | π | 0.009s βοΈ |
+| testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithIncorrectIntermediateCertificate | β
| | π | 0.004s βοΈ |
+| testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithMissingIntermediateCertificate | β
| | π | 0.007s βοΈ |
+| testThatPinningRootKeyPassesEvaluationWithHostValidation | β
| | π | 0.014s βοΈ |
+| testThatPinningRootKeyPassesEvaluationWithoutHostValidation | β
| | π | 0.007s βοΈ |
+| testThatPinningRootKeyWithoutCertificateChainValidationFailsEvaluationWithMissingIntermediateCertificate | β
| | π | 0.006s βοΈ |
+| testThatPinningRootKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate | β
| | π | 0.011s βοΈ |
+
+SessionDelegateTestCase: 4 tests were completed in 3.583 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatAppropriateNotificationsAreCalledWithRequestForDataRequest | β
| | π | 0.735s βοΈ |
+| testThatDidCompleteNotificationIsCalledWithRequestForDownloadRequests | β
| | π | 0.631s βοΈ |
+| testThatRequestWillPerformHTTPRedirectionByDefault | β
| | π | 0.85s βοΈ |
+| testThatRequestWillPerformRedirectionMultipleTimesByDefault | β
| | π | 1.367s βοΈ |
+
+SessionManagerConfigurationHeadersTestCase: 2 tests were completed in 1.287 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatDefaultConfigurationHeadersAreSentWithRequest | β
| | π | 0.609s βοΈ |
+| testThatEphemeralConfigurationHeadersAreSentWithRequest | β
| | π | 0.678s βοΈ |
+
+SessionTestCase: 29 tests were completed in 6.391999999999998 with 29 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testDefaultAcceptEncodingSupportsAppropriateEncodingsOnAppropriateSystems | β
| | π | 0.722s βοΈ |
+| testDefaultUserAgentHeader | β
| | π | 0.003s βοΈ |
+| testInitializerWithDefaultArguments | β
| | π | 0.004s βοΈ |
+| testInitializerWithSpecifiedArguments | β
| | π | 0.003s βοΈ |
+| testReleasingManagerWithPendingCanceledRequestDeinitializesSuccessfully | β
| | π | 0.003s βοΈ |
+| testReleasingManagerWithPendingRequestDeinitializesSuccessfully | β
| | π | 0.005s βοΈ |
+| testSetStartRequestsImmediatelyToFalseAndCancelledCallsResponseHandlers | β
| | π | 0.005s βοΈ |
+| testSetStartRequestsImmediatelyToFalseAndCancelThenResumeRequestDoesntCreateTaskAndStaysCancelled | β
| | π | 0.006s βοΈ |
+| testSetStartRequestsImmediatelyToFalseAndResumeRequest | β
| | π | 0.636s βοΈ |
+| testSetStartRequestsImmediatelyToFalseAndResumeThenCancelRequestHasCorrectOutput | β
| | π | 0.006s βοΈ |
+| testThatDataRequestWithInvalidURLStringThrowsResponseHandlerError | β
| | π | 0.007s βοΈ |
+| testThatDownloadRequestWithInvalidURLStringThrowsResponseHandlerError | β
| | π | 0.005s βοΈ |
+| testThatRequestAdapterErrorThrowsResponseHandlerError | β
| | π | 0.004s βοΈ |
+| testThatRequestAdapterErrorThrowsResponseHandlerErrorWhenRequestIsRetried | β
| | π | 0.896s βοΈ |
+| testThatSessionInitializerSucceedsWithDefaultArguments | β
| | π | 0.004s βοΈ |
+| testThatSessionInitializerSucceedsWithSpecifiedArguments | β
| | π | 0.003s βοΈ |
+| testThatSessionManagerCallsAdapterWhenRequestIsRetried | β
| | π | 0.997s βοΈ |
+| testThatSessionManagerCallsRequestAdapterWhenCreatingDataRequest | β
| | π | 0.004s βοΈ |
+| testThatSessionManagerCallsRequestAdapterWhenCreatingDownloadRequest | β
| | π | 0.005s βοΈ |
+| testThatSessionManagerCallsRequestAdapterWhenCreatingUploadRequestWithData | β
| | π | 0.007s βοΈ |
+| testThatSessionManagerCallsRequestAdapterWhenCreatingUploadRequestWithFile | β
| | π | 0.006s βοΈ |
+| testThatSessionManagerCallsRequestAdapterWhenCreatingUploadRequestWithInputStream | β
| | π | 0.006s βοΈ |
+| testThatSessionManagerCallsRequestRetrierWhenDownloadInitiallyEncountersAdaptError | β
| | π | 0.629s βοΈ |
+| testThatSessionManagerCallsRequestRetrierWhenRequestEncountersError | β
| | π | 1.097s βοΈ |
+| testThatSessionManagerCallsRequestRetrierWhenRequestInitiallyEncountersAdaptError | β
| | π | 0.686s βοΈ |
+| testThatSessionManagerCallsRequestRetrierWhenUploadInitiallyEncountersAdaptError | β
| | π | 0.629s βοΈ |
+| testThatUploadDataRequestWithInvalidURLStringThrowsResponseHandlerError | β
| | π | 0.004s βοΈ |
+| testThatUploadFileRequestWithInvalidURLStringThrowsResponseHandlerError | β
| | π | 0.005s βοΈ |
+| testThatUploadStreamRequestWithInvalidURLStringThrowsResponseHandlerError | β
| | π | 0.005s βοΈ |
+
+SortedKeysJSONParameterEncoderTests: 1 tests were completed in 0.004 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testTestJSONEncoderSortedKeysHasSortedKeys | β
| | π | 0.004s βοΈ |
+
+StatusCodeValidationTestCase: 3 tests were completed in 0.5389999999999999 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatValidationForRequestWithAcceptableStatusCodeResponseSucceeds | β
| | π | 0.18s βοΈ |
+| testThatValidationForRequestWithNoAcceptableStatusCodesFails | β
| | π | 0.18s βοΈ |
+| testThatValidationForRequestWithUnacceptableStatusCodeResponseFails | β
| | π | 0.179s βοΈ |
+
+TLSEvaluationExpiredLeafCertificateTestCase: 14 tests were completed in 6.6690000000000005 with 14 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatExpiredCertificateRequestFailsWhenPinningAllCertificatesWithCertificateChainValidation | β
| | π | 0.58s βοΈ |
+| testThatExpiredCertificateRequestFailsWhenPinningLeafCertificateWithCertificateChainValidation | β
| | π | 0.323s βοΈ |
+| testThatExpiredCertificateRequestFailsWhenPinningLeafPublicKeyWithCertificateChainValidation | β
| | π | 0.318s βοΈ |
+| testThatExpiredCertificateRequestFailsWithDefaultServerTrustPolicy | β
| | π | 0.322s βοΈ |
+| testThatExpiredCertificateRequestFailsWithNoServerTrustPolicy | β
| | π | 0.329s βοΈ |
+| testThatExpiredCertificateRequestFailsWithRevokedServerTrustPolicy | β
| | π | 0.319s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenDisablingEvaluation | β
| | π | 0.631s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCACertificateWithoutCertificateChainOrHostValidation | β
| | π | 0.627s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCAPublicKeyWithoutCertificateChainOrHostValidation | β
| | π | 0.626s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningLeafCertificateWithoutCertificateChainOrHostValidation | β
| | π | 0.686s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningLeafPublicKeyWithoutCertificateChainOrHostValidation | β
| | π | 0.626s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningRootCACertificateWithoutCertificateChainValidation | β
| | π | 0.335s βοΈ |
+| testThatExpiredCertificateRequestSucceedsWhenPinningRootCAPublicKeyWithoutCertificateChainValidation | β
| | π | 0.325s βοΈ |
+| testThatRevokedCertificateRequestFailsWithRevokedServerTrustPolicy | β
| | π | 0.622s βοΈ |
+
+URLEncodedFormEncoderTests: 38 tests were completed in 0.12600000000000006 with 38 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testEncoderCanEncodeDictionary | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeDouble | β
| | π | 0.004s βοΈ |
+| testEncoderCanEncodeFloat | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeInt16 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeInt32 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeInt64 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeInt8 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeUInt | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeUInt16 | β
| | π | 0.004s βοΈ |
+| testEncoderCanEncodeUInt32 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeUInt64 | β
| | π | 0.003s βοΈ |
+| testEncoderCanEncodeUInt8 | β
| | π | 0.003s βοΈ |
+| testEncoderThrowsErrorWhenAttemptingToEncodeNilInKeyedContainer | β
| | π | 0.003s βοΈ |
+| testEncoderThrowsErrorWhenAttemptingToEncodeNilInUnkeyedContainer | β
| | π | 0.003s βοΈ |
+| testStringWithThousandsOfChineseCharactersIsPercentEscaped | β
| | π | 0.011s βοΈ |
+| testThatAmpersandsInKeysAndValuesArePercentEscaped | β
| | π | 0.004s βοΈ |
+| testThatARootArrayCannotBeEncoded | β
| | π | 0.004s βοΈ |
+| testThatARootValueCannotBeEncoded | β
| | π | 0.003s βοΈ |
+| testThatArraysCanBeEncodedWithoutBrackets | β
| | π | 0.003s βοΈ |
+| testThatBoolsCanBeLiteralEncoded | β
| | π | 0.003s βοΈ |
+| testThatEncodableClassWithNoInheritanceCanBeEncoded | β
| | π | 0.003s βοΈ |
+| testThatEncodableStructCanBeEncoded | β
| | π | 0.004s βοΈ |
+| testThatEncodableSubclassCanBeEncoded | β
| | π | 0.003s βοΈ |
+| testThatEscapedCharactersCanBeCustomized | β
| | π | 0.002s βοΈ |
+| testThatIllegalASCIICharactersArePercentEscaped | β
| | π | 0.004s βοΈ |
+| testThatManuallyEncodableStructCanBeEncoded | β
| | π | 0.005s βοΈ |
+| testThatManuallyEncodableSubclassCanBeEncoded | β
| | π | 0.004s βοΈ |
+| testThatNestedDictionariesHaveBracketedKeys | β
| | π | 0.004s βοΈ |
+| testThatNonLatinCharactersArePercentEscaped | β
| | π | 0.003s βοΈ |
+| testThatOptionalValuesCannotBeEncoded | β
| | π | 0.003s βοΈ |
+| testThatPercentsInKeysAndValuesArePercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatPlusesInKeysAndValuesArePercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatQuestionMarksInKeysAndValuesAreNotPercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatReseredCharactersArePercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatSlashesInKeysAndValuesAreNotPercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatSpacesCanBeEncodedAsPluses | β
| | π | 0.003s βοΈ |
+| testThatSpacesInKeysAndValuesArePercentEscaped | β
| | π | 0.004s βοΈ |
+| testThatUnreservedCharactersAreNotPercentEscaped | β
| | π | 0.002s βοΈ |
+
+URLEncodedFormParameterEncoderTests: 4 tests were completed in 0.011000000000000001 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatEncoderCanBeCustomized | β
| | π | 0.003s βοΈ |
+| testThatQueryIsBodyEncodedAndProperContentTypeIsSetForPOSTRequest | β
| | π | 0.003s βοΈ |
+| testThatQueryIsBodyEncodedButContentTypeIsNotSetWhenRequestAlreadyHasContentType | β
| | π | 0.003s βοΈ |
+| testThatQueryIsInURLWhenDestinationIsURLAndMethodIsPOST | β
| | π | 0.002s βοΈ |
+
+URLParameterEncodingTestCase: 36 tests were completed in 0.11400000000000007 with 36 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatIllegalASCIICharactersArePercentEscaped | β
| | π | 0.004s βοΈ |
+| testThatReservedCharactersArePercentEscapedMinusQuestionMarkAndForwardSlash | β
| | π | 0.003s βοΈ |
+| testThatReservedCharactersQuestionMarkAndForwardSlashAreNotPercentEscaped | β
| | π | 0.003s βοΈ |
+| testThatUnreservedLowercaseCharactersAreNotPercentEscaped | β
| | π | 0.004s βοΈ |
+| testThatUnreservedNumericCharactersAreNotPercentEscaped | β
| | π | 0.003s βοΈ |
+| testThatUnreservedUppercaseCharactersAreNotPercentEscaped | β
| | π | 0.002s βοΈ |
+| testThatURLEncodedInURLParameterEncodingEncodesPOSTParametersInURL | β
| | π | 0.003s βοΈ |
+| testThatURLParameterEncodingEncodesGETParametersInURL | β
| | π | 0.003s βοΈ |
+| testThatURLParameterEncodingEncodesPOSTParametersInHTTPBody | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeEmptyDictionaryParameter | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeNilParameters | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeOneStringKeyStringValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeOneStringKeyStringValueParameterAppendedToQuery | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringForRequestWithPrecomposedQuery | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyArrayValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyArrayValueParameterWithoutBrackets | β
| | π | 0.004s βοΈ |
+| testURLParameterEncodeStringKeyBoolValueParameter | β
| | π | 0.004s βοΈ |
+| testURLParameterEncodeStringKeyDictionaryValueParameter | β
| | π | 0.004s βοΈ |
+| testURLParameterEncodeStringKeyDoubleValueParameter | β
| | π | 0.004s βοΈ |
+| testURLParameterEncodeStringKeyIntegerValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyNestedDictionaryArrayValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyNestedDictionaryArrayValueParameterWithoutBrackets | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeStringKeyNestedDictionaryValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyNonLatinStringValueParameter | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeStringKeyNSNumberBoolValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringKeyNSNumberIntegerValueParameter | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeStringKeyPercentEncodedStringValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithAmpersandKeyStringWithAmpersandValueParameter | β
| | π | 0.002s βοΈ |
+| testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameterForRequestWithPrecomposedQuery | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithQuestionMarkKeyStringWithQuestionMarkValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithSlashKeyStringWithQuestionMarkValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithSpaceKeyStringWithSpaceValueParameter | β
| | π | 0.003s βοΈ |
+| testURLParameterEncodeStringWithThousandsOfChineseCharacters | β
| | π | 0.008s βοΈ |
+| testURLParameterEncodeTwoStringKeyStringValueParameters | β
| | π | 0.004s βοΈ |
+| testURLParameterLiteralBoolEncodingWorksAndDoesNotAffectNumbers | β
| | π | 0.004s βοΈ |
+
+URLProtocolTestCase: 1 tests were completed in 0.636 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatURLProtocolReceivesRequestHeadersAndSessionConfigurationHeaders | β
| | π | 0.636s βοΈ |
+
+UploadDataInitializationTestCase: 2 tests were completed in 0.361 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testUploadClassMethodWithMethodURLAndData | β
| | π | 0.181s βοΈ |
+| testUploadClassMethodWithMethodURLHeadersAndData | β
| | π | 0.18s βοΈ |
+
+UploadDataTestCase: 2 tests were completed in 0.405 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testUploadDataRequest | β
| | π | 0.183s βοΈ |
+| testUploadDataRequestWithProgress | β
| | π | 0.222s βοΈ |
+
+UploadFileInitializationTestCase: 2 tests were completed in 0.479 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testUploadClassMethodWithMethodURLAndFile | β
| | π | 0.237s βοΈ |
+| testUploadClassMethodWithMethodURLHeadersAndFile | β
| | π | 0.242s βοΈ |
+
+UploadMultipartFormDataTestCase: 8 tests were completed in 2.012 with 8 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThatUploadingMultipartFormDataAboveMemoryThresholdSetsContentTypeHeader | β
| | π | 0.196s βοΈ |
+| testThatUploadingMultipartFormDataAboveMemoryThresholdStreamsFromDisk | β
| | π | 0.183s βοΈ |
+| testThatUploadingMultipartFormDataBelowMemoryThresholdSetsContentTypeHeader | β
| | π | 0.183s βοΈ |
+| testThatUploadingMultipartFormDataBelowMemoryThresholdStreamsFromMemory | β
| | π | 0.224s βοΈ |
+| testThatUploadingMultipartFormDataSetsContentTypeHeader | β
| | π | 0.286s βοΈ |
+| testThatUploadingMultipartFormDataSucceedsWithDefaultParameters | β
| | π | 0.28s βοΈ |
+| testThatUploadingMultipartFormDataWhileStreamingFromDiskMonitorsProgress | β
| | π | 0.32s βοΈ |
+| testThatUploadingMultipartFormDataWhileStreamingFromMemoryMonitorsProgress | β
| | π | 0.34s βοΈ |
+
+UploadStreamInitializationTestCase: 2 tests were completed in 0.653 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testUploadClassMethodWithMethodURLAndStream | β
| | π | 0.346s βοΈ |
+| testUploadClassMethodWithMethodURLHeadersAndStream | β
| | π | 0.307s βοΈ |
diff --git a/Tests/Assets/md/Kitura.md b/Tests/Assets/md/Kitura.md
new file mode 100644
index 0000000..2b0a2f9
--- /dev/null
+++ b/Tests/Assets/md/Kitura.md
@@ -0,0 +1,360 @@
+MiscellaneousTests: 2 tests were completed in 0.095 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testHeaders | β
| | π | 0.095s βοΈ |
+| testHeadersHelpers | β
| | π | 0.0s βοΈ |
+
+TestBridgingHTTPStatusCode: 1 tests were completed in 0.126 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testSimpleResponse | β
| | π | 0.126s βοΈ |
+
+TestBridgingRequestError: 1 tests were completed in 0.053 with 1 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testRequestError | β
| | π | 0.053s βοΈ |
+
+TestCodableRouter: 25 tests were completed in 36.36 with 25 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testBasicDelete | β
| | π | 0.158s βοΈ |
+| testBasicDeleteSingle | β
| | π | 0.155s βοΈ |
+| testBasicGetArray | β
| | π | 0.153s βοΈ |
+| testBasicGetIdentifiersArray | β
| | π | 0.208s βοΈ |
+| testBasicGetSingle | β
| | π | 0.16s βοΈ |
+| testBasicGetSingleton | β
| | π | 0.158s βοΈ |
+| testBasicPatch | β
| | π | 6.195s βοΈ |
+| testBasicPost | β
| | π | 0.364s βοΈ |
+| testBasicPostIdentifier | β
| | π | 0.163s βοΈ |
+| testBasicPut | β
| | π | 6.194s βοΈ |
+| testCodableDeleteQueryParameters | β
| | π | 0.291s βοΈ |
+| testCodableGetArrayQueryParameters | β
| | π | 0.285s βοΈ |
+| testCodableGetSingleQueryParameters | β
| | π | 0.292s βοΈ |
+| testCodablePostSuccessStatuses | β
| | π | 0.158s βοΈ |
+| testCodableRoutesWithBodyParsingFail | β
| | π | 4.194s βοΈ |
+| testErrorOverridesBody | β
| | π | 8.488s βοΈ |
+| testIdentifierNotExpected | β
| | π | 0.05s βοΈ |
+| testIdentifierNotSupplied | β
| | π | 0.053s βοΈ |
+| testInvalidIdentifierSupplied | β
| | π | 0.052s βοΈ |
+| testJoinPath | β
| | π | 0.001s βοΈ |
+| testNoDataCustomStatus | β
| | π | 2.124s βοΈ |
+| testNoDataDefaultStatus | β
| | π | 2.122s βοΈ |
+| testPartialIdentifierSupplied | β
| | π | 0.054s βοΈ |
+| testRouteParameters | β
| | π | 0.05s βοΈ |
+| testRouteWithTrailingSlash | β
| | π | 4.238s βοΈ |
+
+TestContentType: 3 tests were completed in 0.0 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testFilename | β
| | π | 0.0s βοΈ |
+| testInitialize | β
| | π | 0.0s βοΈ |
+| testIsContentType | β
| | π | 0.0s βοΈ |
+
+TestCookies: 5 tests were completed in 0.36 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCookieFromServer | β
| | π | 0.111s βοΈ |
+| testCookieToServerWithSemiColonSeparator | β
| | π | 0.053s βοΈ |
+| testCookieToServerWithSemiColonSpaceSeparator | β
| | π | 0.054s βοΈ |
+| testCookieToServerWithSemiColonWhitespacesSeparator | β
| | π | 0.049s βοΈ |
+| testNoCookies | β
| | π | 0.093s βοΈ |
+
+TestCustomCoders: 3 tests were completed in 0.46599999999999997 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCustomCoder | β
| | π | 0.108s βοΈ |
+| testCustomQueryEncoder | β
| | π | 0.253s βοΈ |
+| testRawCustomCoder | β
| | π | 0.105s βοΈ |
+
+TestDecodingErrorExtension: 4 tests were completed in 0.0 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testMalformedJson | β
| | π | 0.0s βοΈ |
+| testMissingRequiredKey | β
| | π | 0.0s βοΈ |
+| testMissingValue | β
| | π | 0.0s βοΈ |
+| testWrongType | β
| | π | 0.0s βοΈ |
+
+TestErrors: 3 tests were completed in 0.153 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testInvalidEndpoint | β
| | π | 0.05s βοΈ |
+| testInvalidHeader | β
| | π | 0.049s βοΈ |
+| testInvalidMethod | β
| | π | 0.054s βοΈ |
+
+TestMediaType: 10 tests were completed in 0.0 with 10 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAllTextMediaTypeBuilder | β
| | π | 0.0s βοΈ |
+| testAllTextSlashMediaTypeBuilder | β
| | π | 0.0s βοΈ |
+| testHTMLMediaTypeBuilder | β
| | π | 0.0s βοΈ |
+| testIncorrectTopLevelType | β
| | π | 0.0s βοΈ |
+| testInvalidMediaType | β
| | π | 0.0s βοΈ |
+| testMediaCaseInsensitive | β
| | π | 0.0s βοΈ |
+| testPartsAllTextMediaTypeBuilder | β
| | π | 0.0s βοΈ |
+| testPartsHTMLMediaTypeBuilder | β
| | π | 0.0s βοΈ |
+| testPartsMediaCaseInsensitive | β
| | π | 0.0s βοΈ |
+| testValidMediaType | β
| | π | 0.0s βοΈ |
+
+TestMultiplicity: 4 tests were completed in 0.594 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCombined | β
| | π | 0.148s βοΈ |
+| testPlus | β
| | π | 0.151s βοΈ |
+| testQuestion | β
| | π | 0.146s βοΈ |
+| testStar | β
| | π | 0.149s βοΈ |
+
+TestRangeHeaderDataExtensions: 3 tests were completed in 0.012 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testPartialDataRead | β
| | π | 0.008s βοΈ |
+| testPartialDataReadEntireFile | β
| | π | 0.002s βοΈ |
+| testPartialDataReadWithErrorFileNotFound | β
| | π | 0.002s βοΈ |
+
+TestRangeHeaderParser: 17 tests were completed in 0.001 with 17 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testIsBytesRangeHeader | β
| | π | 0.0s βοΈ |
+| testParseString | β
| | π | 0.001s βοΈ |
+| testReturnNilOnInvalidNonDigitsRanges | β
| | π | 0.0s βοΈ |
+| testReturnNilOnInvalidRanges | β
| | π | 0.0s βοΈ |
+| testReturnNilOnMalformedHeader | β
| | π | 0.0s βοΈ |
+| testShouldCapEndAtSize | β
| | π | 0.0s βοΈ |
+| testShouldCombineOverlappingRanges | β
| | π | 0.0s βοΈ |
+| testShouldCombineOverlappingRangesAndRetainOriginalOrder | β
| | π | 0.0s βοΈ |
+| testShouldParseNonBytesRange | β
| | π | 0.0s βοΈ |
+| testShouldParseNormalString | β
| | π | 0.0s βοΈ |
+| testShouldParseStringAskingForLastByte | β
| | π | 0.0s βοΈ |
+| testShouldParseStringWithBytesEqualZeroZero | β
| | π | 0.0s βοΈ |
+| testShouldParseStringWithMultipleRanges | β
| | π | 0.0s βοΈ |
+| testShouldParseStringWithOnlyEnd | β
| | π | 0.0s βοΈ |
+| testShouldParseStringWithOnlyStart | β
| | π | 0.0s βοΈ |
+| testShouldParseStringWithSomeInvalidRanges | β
| | π | 0.0s βοΈ |
+| testShouldParseWithStartBytesEqualtToZero | β
| | π | 0.0s βοΈ |
+
+TestRequests: 8 tests were completed in 0.612 with 8 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCustomMiddlewareURLParameter | β
| | π | 0.051s βοΈ |
+| testCustomMiddlewareURLParameterWithQueryParam | β
| | π | 0.052s βοΈ |
+| testMultipleParametersMultipleHandlers | β
| | π | 0.098s βοΈ |
+| testOneParameterMultipleHandlers | β
| | π | 0.053s βοΈ |
+| testParameterExit | β
| | π | 0.097s βοΈ |
+| testParameters | β
| | π | 0.097s βοΈ |
+| testQueryParameters | β
| | π | 0.111s βοΈ |
+| testRouteParameters | β
| | π | 0.053s βοΈ |
+
+TestResponse: 35 tests were completed in 7.216 with 35 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAcceptEncodingTypes | β
| | π | 0.1s βοΈ |
+| testAcceptTypes | β
| | π | 0.105s βοΈ |
+| testChangeStatusCodeOnInvokedSend | β
| | π | 0.1s βοΈ |
+| testEmptyHandler | β
| | π | 0.05s βοΈ |
+| testErrorHandler | β
| | π | 0.05s βοΈ |
+| testFormat | β
| | π | 0.15s βοΈ |
+| testHeaderModifiers | β
| | π | 0.058s βοΈ |
+| testJsonp | β
| | π | 0.25s βοΈ |
+| testLargeGet | β
| | π | 0.089s βοΈ |
+| testLargePost | β
| | π | 2.146s βοΈ |
+| testLifecycle | β
| | π | 0.05s βοΈ |
+| testLink | β
| | π | 0.104s βοΈ |
+| testMultipartFormParsing | β
| | π | 0.207s βοΈ |
+| testOptionalStringNilResponse | β
| | π | 0.053s βοΈ |
+| testOptionalStringResponse | β
| | π | 0.055s βοΈ |
+| testParameters | β
| | π | 0.048s βοΈ |
+| testParametersPercent20InPath | β
| | π | 0.05s βοΈ |
+| testParametersPercent20InQuery | β
| | π | 0.05s βοΈ |
+| testParametersPercentageEncoding | β
| | π | 0.046s βοΈ |
+| testParametersPlusInPath | β
| | π | 0.052s βοΈ |
+| testParametersPlusInQuery | β
| | π | 0.05s βοΈ |
+| testPostJSONRequest | β
| | π | 0.054s βοΈ |
+| testPostRequest | β
| | π | 0.054s βοΈ |
+| testPostRequestTheHardWay | β
| | π | 0.05s βοΈ |
+| testPostRequestUrlEncoded | β
| | π | 0.157s βοΈ |
+| testPostRequestWithDoubleBodyParser | β
| | π | 0.048s βοΈ |
+| testRawDataPost | β
| | π | 2.061s βοΈ |
+| testRedirect | β
| | π | 0.094s βοΈ |
+| testResponseNoEndOrNext | β
| | π | 0.053s βοΈ |
+| testRouteFunc | β
| | π | 0.107s βοΈ |
+| testSend | β
| | π | 0.37s βοΈ |
+| testSendAfterEnd | β
| | π | 0.051s βοΈ |
+| testSimpleResponse | β
| | π | 0.049s βοΈ |
+| testSubdomains | β
| | π | 0.155s βοΈ |
+| testUserInfo | β
| | π | 0.05s βοΈ |
+
+TestRouteRegex: 7 tests were completed in 2.7859999999999996 with 7 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testBuildRegexFromPattern | β
| | π | 0.001s βοΈ |
+| testCustomMatchesWithModifiers | β
| | π | 1.102s βοΈ |
+| testRouteWithPercentEncoding | β
| | π | 0.051s βοΈ |
+| testSimpleCustomMatches | β
| | π | 0.199s βοΈ |
+| testSimpleMatches | β
| | π | 0.254s βοΈ |
+| testSimpleModifiers | β
| | π | 0.786s βοΈ |
+| testSimplePaths | β
| | π | 0.393s βοΈ |
+
+TestRouterHTTPVerbsGenerated: 4 tests were completed in 0.004 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testFirstTypeVerbsAdded | β
| | π | 0.001s βοΈ |
+| testFourthTypeVerbsAdded | β
| | π | 0.001s βοΈ |
+| testSecondTypeVerbsAdded | β
| | π | 0.001s βοΈ |
+| testThirdTypeVerbsAdded | β
| | π | 0.001s βοΈ |
+
+TestServer: 4 tests were completed in 20.392 with 2 passed, 2 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testServerFail | β
| | π | 0.04s βοΈ |
+| testServerRestart | β
| | π | 0.175s βοΈ |
+| testServerRun | | β | π | 10.169s βοΈ |
+| testServerStartStop | | β | π | 10.008s βοΈ |
+
+TestStack: 2 tests were completed in 0.0 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testEmpty | β
| | π | 0.0s βοΈ |
+| testPushPop | β
| | π | 0.0s βοΈ |
+
+TestStaticFileServer: 30 tests were completed in 2.3390000000000004 with 30 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAbsolutePathFunction | β
| | π | 0.0s βοΈ |
+| testAbsoluteRootPath | β
| | π | 0.0s βοΈ |
+| testDataIsNotCorrupted | β
| | π | 0.195s βοΈ |
+| testFileServer | β
| | π | 0.496s βοΈ |
+| testGetDefaultResponse | β
| | π | 0.05s βοΈ |
+| testGetKituraResource | β
| | π | 0.052s βοΈ |
+| testGetMissingKituraResource | β
| | π | 0.056s βοΈ |
+| testGetTraversedFile | β
| | π | 0.047s βοΈ |
+| testGetTraversedFileKituraResource | β
| | π | 0.047s βοΈ |
+| testGetWithSpecialCharacters | β
| | π | 0.052s βοΈ |
+| testGetWithSpecialCharactersEncoded | β
| | π | 0.051s βοΈ |
+| testGetWithWhiteSpaces | β
| | π | 0.051s βοΈ |
+| testParameterizedSubRouterSubFolderStaticFileServer | β
| | π | 0.089s βοΈ |
+| testParameterizedSubRouterSubFolderStaticFileServerRedirect | β
| | π | 0.118s βοΈ |
+| testRangeRequestIsIgnoredOnNonGetMethod | β
| | π | 0.052s βοΈ |
+| testRangeRequestIsIgnoredOnOptionOff | β
| | π | 0.053s βοΈ |
+| testRangeRequests | β
| | π | 0.052s βοΈ |
+| testRangeRequestsWithLargeLastBytePos | β
| | π | 0.05s βοΈ |
+| testRangeRequestsWithMultipleRanges | β
| | π | 0.056s βοΈ |
+| testRangeRequestWithIfRangeHeaderAsLastModified | β
| | π | 0.099s βοΈ |
+| testRangeRequestWithIfRangeHeaderAsOldLastModified | β
| | π | 0.05s βοΈ |
+| testRangeRequestWithIfRangeHeaderWithETag | β
| | π | 0.117s βοΈ |
+| testRangeRequestWithIfRangeHeaderWithOldETag | β
| | π | 0.055s βοΈ |
+| testRangeRequestWithNotSatisfiableRange | β
| | π | 0.057s βοΈ |
+| testRangeRequestWithSintacticallyInvalidRange | β
| | π | 0.067s βοΈ |
+| testSubRouterStaticFileServer | β
| | π | 0.052s βοΈ |
+| testSubRouterStaticFileServerRedirect | β
| | π | 0.085s βοΈ |
+| testSubRouterSubFolderStaticFileServer | β
| | π | 0.052s βοΈ |
+| testSubRouterSubFolderStaticFileServerRedirect | β
| | π | 0.089s βοΈ |
+| testWelcomePageCanBeDisabled | β
| | π | 0.049s βοΈ |
+
+TestSubrouter: 5 tests were completed in 0.502 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testExternSub | β
| | π | 0.1s βοΈ |
+| testMergeParams | β
| | π | 0.155s βοΈ |
+| testMultipleMiddleware | β
| | π | 0.051s βοΈ |
+| testSimpleSub | β
| | π | 0.097s βοΈ |
+| testSubSubs | β
| | π | 0.099s βοΈ |
+
+TestSwaggerGeneration: 9 tests were completed in 0.99 with 9 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testArrayReturnTypes | β
| | π | 0.101s βοΈ |
+| testBasePath | β
| | π | 0.095s βοΈ |
+| testInfo | β
| | π | 0.095s βοΈ |
+| testInputTypesModelled | β
| | π | 0.172s βοΈ |
+| testNestedTypesModelled | β
| | π | 0.1s βοΈ |
+| testSwaggerContent | β
| | π | 0.1s βοΈ |
+| testSwaggerDefinitions | β
| | π | 0.102s βοΈ |
+| testSwaggerQueryParams | β
| | π | 0.104s βοΈ |
+| testSwaggerVersion | β
| | π | 0.121s βοΈ |
+
+TestTemplateEngine: 23 tests were completed in 0.37999999999999995 with 23 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAddWithFileExtensions | β
| | π | 0.001s βοΈ |
+| testAddWithFileExtensionsWithoutTheDefaultOne | β
| | π | 0.001s βοΈ |
+| testCodableAddWithFileExtensions | β
| | π | 0.001s βοΈ |
+| testCodableAddWithFileExtensionsWithoutTheDefaultOne | β
| | π | 0.001s βοΈ |
+| testCodableRender | β
| | π | 0.001s βοΈ |
+| testCodableRenderWithExtensionAndWithoutDefaultTemplateEngine | β
| | π | 0.001s βοΈ |
+| testCodableRenderWithExtensionAndWithoutDefaultTemplateEngineAfterSettingViewsPath | β
| | π | 0.001s βοΈ |
+| testCodableRenderWithOptionsWithServer | β
| | π | 0.052s βοΈ |
+| testCodableRenderWithServer | β
| | π | 0.051s βοΈ |
+| testCodableRenderWithServerAndSubRouter | β
| | π | 0.053s βοΈ |
+| testCodableRenderWithTuple | β
| | π | 0.051s βοΈ |
+| testEmptyTemplateName | β
| | π | 0.001s βοΈ |
+| testEmptyTemplateNameCodable | β
| | π | 0.001s βοΈ |
+| testMissingExtension | β
| | π | 0.001s βοΈ |
+| testMissingExtensionCodable | β
| | π | 0.001s βοΈ |
+| testNoDefaultEngine | β
| | π | 0.001s βοΈ |
+| testNoDefaultEngineCodable | β
| | π | 0.001s βοΈ |
+| testRender | β
| | π | 0.001s βοΈ |
+| testRenderWithExtensionAndWithoutDefaultTemplateEngine | β
| | π | 0.001s βοΈ |
+| testRenderWithExtensionAndWithoutDefaultTemplateEngineAfterSettingViewsPath | β
| | π | 0.001s βοΈ |
+| testRenderWithOptionsWithServer | β
| | π | 0.052s βοΈ |
+| testRenderWithServer | β
| | π | 0.054s βοΈ |
+| testRenderWithServerAndSubRouter | β
| | π | 0.051s βοΈ |
+
+TestTypeSafeMiddleware: 33 tests were completed in 28.692999999999994 with 33 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCustomCoder | β
| | π | 4.24s βοΈ |
+| testCustomCoderGet | β
| | π | 0.294s βοΈ |
+| testMiddlewareLogging | β
| | π | 0.059s βοΈ |
+| testMultipleMiddlewareDelete | β
| | π | 0.163s βοΈ |
+| testMultipleMiddlewareDeleteIdentifier | β
| | π | 0.164s βοΈ |
+| testMultipleMiddlewareDeleteOptionalParameters | β
| | π | 0.115s βοΈ |
+| testMultipleMiddlewareDeleteParameters | β
| | π | 0.159s βοΈ |
+| testMultipleMiddlewareGetArray | β
| | π | 0.153s βοΈ |
+| testMultipleMiddlewareGetArrayOptionalParameters | β
| | π | 0.163s βοΈ |
+| testMultipleMiddlewareGetArrayParameters | β
| | π | 0.158s βοΈ |
+| testMultipleMiddlewareGetIdentifier | β
| | π | 0.156s βοΈ |
+| testMultipleMiddlewareGetIdentifierCodableArray | β
| | π | 0.153s βοΈ |
+| testMultipleMiddlewareGetSingleton | β
| | π | 0.155s βοΈ |
+| testMultipleMiddlewareGetSingletonParameters | β
| | π | 0.161s βοΈ |
+| testMultipleMiddlewarePatch | β
| | π | 6.187s βοΈ |
+| testMultipleMiddlewarePost | β
| | π | 0.159s βοΈ |
+| testMultipleMiddlewarePostIdentifier | β
| | π | 0.156s βοΈ |
+| testMultipleMiddlewarePut | β
| | π | 6.181s βοΈ |
+| testSingleMiddlewareDelete | β
| | π | 0.113s βοΈ |
+| testSingleMiddlewareDeleteIdentifier | β
| | π | 0.102s βοΈ |
+| testSingleMiddlewareDeleteOptionalParameters | β
| | π | 0.113s βοΈ |
+| testSingleMiddlewareDeleteParameters | β
| | π | 0.112s βοΈ |
+| testSingleMiddlewareGetArray | β
| | π | 0.104s βοΈ |
+| testSingleMiddlewareGetArrayOptionalParameters | β
| | π | 0.154s βοΈ |
+| testSingleMiddlewareGetArrayParameters | β
| | π | 0.112s βοΈ |
+| testSingleMiddlewareGetIdentifier | β
| | π | 0.104s βοΈ |
+| testSingleMiddlewareGetIdentifierCodableArray | β
| | π | 0.106s βοΈ |
+| testSingleMiddlewareGetSingleton | β
| | π | 0.104s βοΈ |
+| testSingleMiddlewareGetSingletonParameters | β
| | π | 0.115s βοΈ |
+| testSingleMiddlewarePatch | β
| | π | 4.127s βοΈ |
+| testSingleMiddlewarePost | β
| | π | 0.11s βοΈ |
+| testSingleMiddlewarePostIdentifier | β
| | π | 0.108s βοΈ |
+| testSingleMiddlewarePut | β
| | π | 4.133s βοΈ |
diff --git a/Tests/Assets/md/PromiseFailure.md b/Tests/Assets/md/PromiseFailure.md
new file mode 100644
index 0000000..5064a05
--- /dev/null
+++ b/Tests/Assets/md/PromiseFailure.md
@@ -0,0 +1,120 @@
+ExecutionContextTests: 6 tests were completed in 18.541 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testConcurrency | β
| | π | 15.354s βοΈ |
+| testInvalidatableQueueSupportsNonMainQueues | β
| | π | 0.002s βοΈ |
+| testInvalidatedInvalidatableQueue | β
| | π | 0.102s βοΈ |
+| testNonInvalidatedInvalidatableQueue | β
| | π | 0.007s βοΈ |
+| testTapContinuesToFireInvalidatableQueue | β
| | π | 0.001s βοΈ |
+| testThreads | β
| | π | 3.075s βοΈ |
+
+PromiseAllTests: 5 tests were completed in 0.271 with 5 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAll | β
| | π | 0.108s βοΈ |
+| testAllWithEmptyArray | β
| | π | 0.001s βοΈ |
+| testAllWithPreFulfilledValues | β
| | π | 0.001s βοΈ |
+| testAllWithRejectionHappeningFirst | β
| | π | 0.058s βοΈ |
+| testAllWithRejectionHappeningLast | β
| | π | 0.103s βοΈ |
+
+PromiseAlwaysTests: 4 tests were completed in 1.024 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAlways | β
| | π | 0.507s βοΈ |
+| testAlwaysInstantFulfill | β
| | π | 0.001s βοΈ |
+| testAlwaysInstantReject | β
| | π | 0.001s βοΈ |
+| testAlwaysRejects | β
| | π | 0.515s βοΈ |
+
+PromiseDelayTests: 4 tests were completed in 0.9360000000000002 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testDelay | β
| | π | 0.202s βοΈ |
+| testTimeoutFunctionFails | β
| | π | 0.519s βοΈ |
+| testTimeoutFunctionSucceeds | β
| | π | 0.012s βοΈ |
+| testTimeoutPromise | β
| | π | 0.203s βοΈ |
+
+PromiseEnsureTests: 3 tests were completed in 0.003 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testEnsureOnlyCalledOnSucceess | β
| | π | 0.001s βοΈ |
+| testEnsureRejects | β
| | π | 0.001s βοΈ |
+| testEnsureSucceeds | β
| | π | 0.001s βοΈ |
+
+PromiseKickoffTests: 3 tests were completed in 0.104 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testFailingKickoff | β
| | π | 0.001s βοΈ |
+| testKickoff | β
| | π | 0.001s βοΈ |
+| testPromiseKickoff | β
| | π | 0.102s βοΈ |
+
+PromiseRaceTests: 4 tests were completed in 0.111 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testInstantReject | β
| | π | 0.001s βοΈ |
+| testInstantResolve | β
| | π | 0.001s βοΈ |
+| testRace | β
| | π | 0.056s βοΈ |
+| testRaceFailure | β
| | π | 0.053s βοΈ |
+
+PromiseRecoverTests: 6 tests were completed in 0.423 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testIgnoreRecover | β
| | π | 0.107s βοΈ |
+| testIgnoreRecoverInstant | β
| | π | 0.001s βοΈ |
+| testRecover | β
| | π | 0.105s βοΈ |
+| testRecoverInstant | β
| | π | 0.001s βοΈ |
+| testRecoverWithThrowingFunction | β
| | π | 0.106s βοΈ |
+| testRecoverWithThrowingFunctionError | β
| | π | 0.103s βοΈ |
+
+PromiseRetryTests: 3 tests were completed in 0.005 with 3 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testRetry | β
| | π | 0.002s βοΈ |
+| testRetryWithInstantSuccess | β
| | π | 0.001s βοΈ |
+| testRetryWithNeverSuccess | β
| | π | 0.002s βοΈ |
+
+PromiseTests: 17 tests were completed in 0.503 with 16 passed, 1 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAsync | β
| | π | 0.056s βοΈ |
+| testAsyncRejection | β
| | π | 0.052s βοΈ |
+| testAsyncThrowing | β
| | π | 0.002s βοΈ |
+| testDoubleReject | β
| | π | 0.001s βοΈ |
+| testDoubleResolve | β
| | π | 0.001s βοΈ |
+| testFlatMap | β
| | π | 0.108s βοΈ |
+| testFulfilled | β
| | π | 0.053s βοΈ |
+| testMap | β
| | π | 0.001s βοΈ |
+| testPending | β
| | π | 0.001s βοΈ |
+| testRejected | β
| | π | 0.001s βοΈ |
+| testRejectedAfterFulfilled | β
| | π | 0.051s βοΈ |
+| testRejectThenResolve | β
| | π | 0.001s βοΈ |
+| testResolveThenReject | β
| | π | 0.001s βοΈ |
+| testThen | β
| | π | 0.001s βοΈ |
+| testThenWhenPending | β
| | π | 0.054s βοΈ |
+| testTrailingClosuresCompile | β
| | π | 0.107s βοΈ |
+| testZalgoContained | | β | π | 0.012s βοΈ |
+
+PromiseThrowsTests: 4 tests were completed in 0.004 with 4 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testThrowsInFlatmapping | β
| | π | 0.001s βοΈ |
+| testThrowsInFlatmappingWithError | β
| | π | 0.001s βοΈ |
+| testThrowsInMapping | β
| | π | 0.001s βοΈ |
+| testThrowsInMappingWithError | β
| | π | 0.001s βοΈ |
+
+PromiseZipTests: 2 tests were completed in 0.007 with 2 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testMultipleParameters | β
| | π | 0.001s βοΈ |
+| testZipping2 | β
| | π | 0.006s βοΈ |
diff --git a/Tests/Assets/md/PromiseUnexpectedFailure.md b/Tests/Assets/md/PromiseUnexpectedFailure.md
new file mode 100644
index 0000000..28b4586
--- /dev/null
+++ b/Tests/Assets/md/PromiseUnexpectedFailure.md
@@ -0,0 +1,5 @@
+PromiseTests: 1 tests were completed in 0.021 with 0 passed, 1 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testUnexpected | | β | π | 0.021s βοΈ |
diff --git a/Tests/Assets/md/Shell.md b/Tests/Assets/md/Shell.md
new file mode 100644
index 0000000..798f730
--- /dev/null
+++ b/Tests/Assets/md/Shell.md
@@ -0,0 +1,10 @@
+ShellTests: 6 tests were completed in 2.497 with 6 passed, 0 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAsyncRun | β
| | π | 2.172s βοΈ |
+| testEnvironment | β
| | π | 0.065s βοΈ |
+| testError | β
| | π | 0.065s βοΈ |
+| testErrorHandler | β
| | π | 0.066s βοΈ |
+| testOutput | β
| | π | 0.065s βοΈ |
+| testOutputHandler | β
| | π | 0.064s βοΈ |
diff --git a/Tests/Assets/md/ShellFailure.md b/Tests/Assets/md/ShellFailure.md
new file mode 100644
index 0000000..52177ff
--- /dev/null
+++ b/Tests/Assets/md/ShellFailure.md
@@ -0,0 +1,11 @@
+ShellTests: 7 tests were completed in 2.532 with 4 passed, 3 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testAsyncRun | β
| | π | 2.143s βοΈ |
+| testEnvironment | | β | π | 0.067s βοΈ |
+| testError | β
| | π | 0.064s βοΈ |
+| testErrorHandler | β
| | π | 0.064s βοΈ |
+| testOutput | | β | π | 0.064s βοΈ |
+| testOutputHandler | β
| | π | 0.064s βοΈ |
+| testThrow | | β | π | 0.066s βοΈ |
diff --git a/Tests/Assets/md/ShellOutFailure.md b/Tests/Assets/md/ShellOutFailure.md
new file mode 100644
index 0000000..4bb33eb
--- /dev/null
+++ b/Tests/Assets/md/ShellOutFailure.md
@@ -0,0 +1,18 @@
+ShellOutTests: 14 tests were completed in 6.191999999999998 with 11 passed, 3 failed and 0 skipped.
+
+| Test case | Passed | Failed | Skipped | Time |
+| :--- | ---: | ---: | ---: | ---: |
+| testCapturingErrorWithHandle | β
| | π | 0.269s βοΈ |
+| testCapturingOutputWithHandle | β
| | π | 0.185s βοΈ |
+| testErrorDescription | β
| | π | 0.001s βοΈ |
+| testGitCommands | β
| | π | 1.833s βοΈ |
+| testSeriesOfCommands | | β | π | 0.169s βοΈ |
+| testSeriesOfCommandsAtPath | β
| | π | 0.345s βοΈ |
+| testSingleCommandAtPath | | β | π | 0.336s βοΈ |
+| testSingleCommandAtPathContainingSpace | β
| | π | 0.525s βοΈ |
+| testSingleCommandAtPathContainingTilde | β
| | π | 0.165s βοΈ |
+| testSwiftPackageManagerCommands | β
| | π | 1.665s βοΈ |
+| testThrowingError | β
| | π | 0.188s βοΈ |
+| testWithArguments | | β | π | 0.18s βοΈ |
+| testWithInlineArguments | β
| | π | 0.159s βοΈ |
+| testWithoutArguments | β
| | π | 0.172s βοΈ |
diff --git a/Tests/Assets/Alamofire.tests b/Tests/Assets/tests/Alamofire.tests
similarity index 100%
rename from Tests/Assets/Alamofire.tests
rename to Tests/Assets/tests/Alamofire.tests
diff --git a/Tests/Assets/Kitura.tests b/Tests/Assets/tests/Kitura.tests
similarity index 100%
rename from Tests/Assets/Kitura.tests
rename to Tests/Assets/tests/Kitura.tests
diff --git a/Tests/Assets/Promise.tests b/Tests/Assets/tests/Promise.tests
similarity index 100%
rename from Tests/Assets/Promise.tests
rename to Tests/Assets/tests/Promise.tests
diff --git a/Tests/Assets/PromiseFailure.tests b/Tests/Assets/tests/PromiseFailure.tests
similarity index 100%
rename from Tests/Assets/PromiseFailure.tests
rename to Tests/Assets/tests/PromiseFailure.tests
diff --git a/Tests/Assets/PromiseUnexpectedFailure.tests b/Tests/Assets/tests/PromiseUnexpectedFailure.tests
similarity index 100%
rename from Tests/Assets/PromiseUnexpectedFailure.tests
rename to Tests/Assets/tests/PromiseUnexpectedFailure.tests
diff --git a/Tests/Assets/Shell.tests b/Tests/Assets/tests/Shell.tests
similarity index 100%
rename from Tests/Assets/Shell.tests
rename to Tests/Assets/tests/Shell.tests
diff --git a/Tests/Assets/ShellFailure.tests b/Tests/Assets/tests/ShellFailure.tests
similarity index 100%
rename from Tests/Assets/ShellFailure.tests
rename to Tests/Assets/tests/ShellFailure.tests
diff --git a/Tests/Assets/ShellOutFailure.tests b/Tests/Assets/tests/ShellOutFailure.tests
similarity index 100%
rename from Tests/Assets/ShellOutFailure.tests
rename to Tests/Assets/tests/ShellOutFailure.tests
diff --git a/Tests/Assets/xml/Alamofire.xml b/Tests/Assets/xml/Alamofire.xml
new file mode 100644
index 0000000..7fed57e
--- /dev/null
+++ b/Tests/Assets/xml/Alamofire.xml
@@ -0,0 +1,593 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Assets/xml/Kitura.xml b/Tests/Assets/xml/Kitura.xml
new file mode 100644
index 0000000..6c7d7e0
--- /dev/null
+++ b/Tests/Assets/xml/Kitura.xml
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+failed - Error code: -9992(0x-2708), Address already in use/Users/tib/Downloads/Kitura-master/Tests/KituraTests/TestServer.swift:144: error: -[KituraTests.TestServer testServerRun] : Asynchronous wait failed: Exceeded timeout of 10 seconds, with unfulfilled expectations: "FastCGIServer started()"./Users/tib/Downloads/Kitura-master/Tests/KituraTests/TestServer.swift:146: error: -[KituraTests.TestServer testServerRun] : XCTAssertNil failed: "Error Domain=com.apple.XCTestErrorDomain Code=0 "(null)""
+
+
+
+
+failed - Error code: -9992(0x-2708), Address already in use/Users/tib/Downloads/Kitura-master/Tests/KituraTests/TestServer.swift:131: error: -[KituraTests.TestServer testServerStartStop] : Asynchronous wait failed: Exceeded timeout of 10 seconds, with unfulfilled expectations: "FastCGIServer started()", "FastCGIServer stopped()"./Users/tib/Downloads/Kitura-master/Tests/KituraTests/TestServer.swift:132: error: -[KituraTests.TestServer testServerStartStop] : XCTAssertNil failed: "Error Domain=com.apple.XCTestErrorDomain Code=0 "(null)""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Assets/xml/PromiseFailure.xml b/Tests/Assets/xml/PromiseFailure.xml
new file mode 100644
index 0000000..7f9c6f5
--- /dev/null
+++ b/Tests/Assets/xml/PromiseFailure.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+XCTAssertTrue failed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Assets/xml/PromiseUnexpectedFailure.xml b/Tests/Assets/xml/PromiseUnexpectedFailure.xml
new file mode 100644
index 0000000..951d94b
--- /dev/null
+++ b/Tests/Assets/xml/PromiseUnexpectedFailure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+failed: caught error: The operation couldnβt be completed. (PromiseTests.WrenchError error 1.)
+
+
+
+
diff --git a/Tests/Assets/xml/Shell.xml b/Tests/Assets/xml/Shell.xml
new file mode 100644
index 0000000..c2d5551
--- /dev/null
+++ b/Tests/Assets/xml/Shell.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Assets/xml/ShellFailure.xml b/Tests/Assets/xml/ShellFailure.xml
new file mode 100644
index 0000000..8dd7406
--- /dev/null
+++ b/Tests/Assets/xml/ShellFailure.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+XCTAssertEqual failed: ("Custom bad env variable") is not equal to ("Custom env variable") - Invalid output `Custom bad env variable`, expected `Custom env variable`.
+
+
+
+
+
+
+XCTAssertEqual failed: ("Hello world!") is not equal to ("Hello outside world!") - Invalid output `Hello world!`, expected `Hello outside world!`.
+
+
+
+
+
+failed: caught error: The operation couldnβt be completed. (Shell.ShellError error 0.)
+
+
+
+
diff --git a/Tests/Assets/xml/ShellOutFailure.xml b/Tests/Assets/xml/ShellOutFailure.xml
new file mode 100644
index 0000000..3e3c615
--- /dev/null
+++ b/Tests/Assets/xml/ShellOutFailure.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+XCTAssertEqual failed: ("Helloworld") is not equal to ("Hellowdorld")
+
+
+
+
+
+XCTAssertEqual failed: ("Hello") is not equal to ("Heallo")
+
+
+
+
+
+
+
+
+XCTAssertEqual failed: ("Hello world") is not equal to ("Hello worldd")
+
+
+
+
+
+
diff --git a/Tests/TestifySDKTests/TestifyJunitTests.swift b/Tests/TestifySDKTests/TestifyJunitTests.swift
new file mode 100644
index 0000000..198add6
--- /dev/null
+++ b/Tests/TestifySDKTests/TestifyJunitTests.swift
@@ -0,0 +1,87 @@
+import XCTest
+@testable import TestifySDK
+
+final class TestifyJunitTests: XCTestCase {
+
+ func testTests() throws {
+ let testFiles = [
+ "PromiseUnexpectedFailure",
+ "PromiseFailure",
+ "ShellOutFailure",
+ "Shell",
+ "ShellFailure",
+ "Alamofire",
+ "Kitura",
+ ]
+
+ let packageRootPath = URL(fileURLWithPath: #file)
+ .pathComponents
+ .prefix(while: { $0 != "Tests" })
+ .joined(separator: "/")
+ .dropFirst()
+
+ let assetsUrl = URL(fileURLWithPath: String(packageRootPath)).appendingPathComponent("Tests")
+ .appendingPathComponent("Assets")
+ let decoder = RawTestResultDecoder()
+
+ for file in testFiles {
+ let testUrl = assetsUrl.appendingPathComponent("/tests/" + file)
+ .appendingPathExtension("tests")
+ let xmlUrl = assetsUrl.appendingPathComponent("/xml/" + file)
+ .appendingPathExtension("xml")
+
+ let testData = try Data(contentsOf: testUrl)
+ guard let testOutput = String(data: testData, encoding: .utf8) else {
+ return XCTFail("Could not decode test data.")
+ }
+
+ let suite = try decoder.decode(testOutput)
+ let xmlData = try Data(contentsOf: xmlUrl)
+ let xmlParser = XMLParser(data: xmlData)
+ let parser = SuiteXmlParser()
+ xmlParser.delegate = parser
+ xmlParser.parse()
+
+ XCTAssertTrue(self.checkNumbers(suite, parser), "Invalid numbers count for \(file).")
+ }
+ }
+
+ //@TODO: is there a better way to check this ?
+ func checkNumbers(_ suite: TestSuite, _ parser: SuiteXmlParser) -> Bool {
+ let suites: [TestSuite] = suite.children.reduce([]) { $0 + $1.children }
+ var allTests = 0
+ var allFails = 0
+ for suite in suites {
+ let tests = suite.cases.count
+ let failureCount = suite.cases.reduce(0) { $0 + ($1.outcome == .failure ? 1 : 0) }
+ allTests += tests
+ allFails += failureCount
+ }
+ return suites.count == parser.suites &&
+ allTests == parser.tests &&
+ allFails == parser.fails
+ }
+
+ class SuiteXmlParser : NSObject, XMLParserDelegate {
+ var suites = 0
+ var tests = 0
+ var fails = 0
+
+ func parser(
+ _ parser: XMLParser,
+ didStartElement elementName: String,
+ namespaceURI: String?,
+ qualifiedName qName: String?,
+ attributes attributeDict: [String : String] = [:]
+ ) {
+ if (elementName=="testsuite") {
+ suites += 1
+ } else if (elementName=="testcase") {
+ tests += 1
+ } else if (elementName=="failure") {
+ fails += 1
+ }
+ }
+ }
+
+}
diff --git a/Tests/TestifySDKTests/TestifyMarkdownTests.swift b/Tests/TestifySDKTests/TestifyMarkdownTests.swift
new file mode 100644
index 0000000..54ce1e0
--- /dev/null
+++ b/Tests/TestifySDKTests/TestifyMarkdownTests.swift
@@ -0,0 +1,84 @@
+import XCTest
+@testable import TestifySDK
+
+final class TestifyMarkdownTests: XCTestCase {
+
+ func testTests() throws {
+
+ let testFiles = [
+ "PromiseUnexpectedFailure",
+ "PromiseFailure",
+ "ShellOutFailure",
+ "Shell",
+ "ShellFailure",
+ "Alamofire",
+ "Kitura",
+ ]
+
+ let packageRootPath = URL(fileURLWithPath: #file)
+ .pathComponents
+ .prefix(while: { $0 != "Tests" })
+ .joined(separator: "/")
+ .dropFirst()
+
+ let assetsUrl = URL(fileURLWithPath: String(packageRootPath)).appendingPathComponent("Tests")
+ .appendingPathComponent("Assets")
+ let decoder = RawTestResultDecoder()
+
+ for file in testFiles {
+ let testUrl = assetsUrl.appendingPathComponent("/tests/" + file)
+ .appendingPathExtension("tests")
+ let mdUrl = assetsUrl.appendingPathComponent("/md/" + file)
+ .appendingPathExtension("md")
+
+ let testData = try Data(contentsOf: testUrl)
+ guard let testOutput = String(data: testData, encoding: .utf8) else {
+ return XCTFail("Could not decode test data.")
+ }
+ let suite = try decoder.decode(testOutput)
+
+ let resultData = try Data(contentsOf: mdUrl)
+ guard let testMdOutput = String(data: resultData, encoding: .utf8) else {
+ return XCTFail("Could not decode test data.")
+ }
+
+ let filtered = testMdOutput.split(separator: "\n").map({ String($0) }).filter {
+ $0.contains("tests were completed") &&
+ $0.contains("passed") &&
+ $0.contains("failed")
+ }
+
+ XCTAssertTrue(self.checkNumbers(suite, filtered), "Invalid numbers count for \(file).")
+ }
+ }
+
+ //@TODO: is there a better way to check this ?
+ func checkNumbers(_ suite: TestSuite, _ filtered: [String]) -> Bool {
+ var mdAllTests = 0
+ var mdAllFails = 0
+ for item in filtered {
+
+ let tests = Int(item.components(separatedBy: " tests were completed in ").filter { $0.contains(": ") }[0]
+ .components(separatedBy: ": ")[1])
+ let fails = Int(item.components(separatedBy: " passed, ").filter { $0.contains("failed and") }[0]
+ .components(separatedBy: " failed ")[0])
+ mdAllTests += tests ?? 0
+ mdAllFails += fails ?? 0
+ }
+
+ let suites: [TestSuite] = suite.children.reduce([]) { $0 + $1.children }
+ var allTests = 0
+ var allFails = 0
+ for suite in suites {
+ let tests = suite.cases.count
+ let failureCount = suite.cases.reduce(0) { $0 + ($1.outcome == .failure ? 1 : 0) }
+ allTests += tests
+ allFails += failureCount
+ }
+
+ return suites.count == filtered.count &&
+ allTests == mdAllTests &&
+ allFails == mdAllFails
+ }
+
+}
diff --git a/Tests/TestifyTests/TestifyTests.swift b/Tests/TestifySDKTests/TestifySDKTests.swift
similarity index 87%
rename from Tests/TestifyTests/TestifyTests.swift
rename to Tests/TestifySDKTests/TestifySDKTests.swift
index f30bbd0..eb30254 100644
--- a/Tests/TestifyTests/TestifyTests.swift
+++ b/Tests/TestifySDKTests/TestifySDKTests.swift
@@ -1,5 +1,5 @@
import XCTest
-@testable import Testify
+@testable import TestifySDK
final class TestifyTests: XCTestCase {
@@ -23,11 +23,12 @@ final class TestifyTests: XCTestCase {
let assetsUrl = URL(fileURLWithPath: String(packageRootPath)).appendingPathComponent("Tests")
.appendingPathComponent("Assets")
-
+ let decoder = RawTestResultDecoder()
+
for file in testFiles {
- let testUrl = assetsUrl.appendingPathComponent(file)
+ let testUrl = assetsUrl.appendingPathComponent("/tests/" + file)
.appendingPathExtension("tests")
- let jsonUrl = assetsUrl.appendingPathComponent(file)
+ let jsonUrl = assetsUrl.appendingPathComponent("/json/" + file)
.appendingPathExtension("json")
let testData = try Data(contentsOf: testUrl)
@@ -35,7 +36,7 @@ final class TestifyTests: XCTestCase {
return XCTFail("Could not decode test data.")
}
let resultData = try Data(contentsOf: jsonUrl)
- let suite = TestSuite.parse(testOutput)
+ let suite = try decoder.decode(testOutput)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
@@ -52,4 +53,5 @@ final class TestifyTests: XCTestCase {
testSuite1.cases.count == testSuite2.cases.count &&
testSuite1.children.count == testSuite2.children.count
}
+
}
diff --git a/cov.sh b/cov.sh
new file mode 100755
index 0000000..2b982cc
--- /dev/null
+++ b/cov.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+BIN_PATH="$(swift build --show-bin-path)"
+XCTEST_PATH="$(find ${BIN_PATH} -name '*.xctest')"
+
+COV_BIN=$XCTEST_PATH
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ f="$(basename $XCTEST_PATH .xctest)"
+ COV_BIN="${COV_BIN}/Contents/MacOS/$f"
+fi
+
+#llvm-cov report \
+# -instr-profile=.build/debug/codecov/default.profdata \
+# -ignore-filename-regex=".build|Tests" \
+# -use-color \
+# "${COV_BIN}"
+
+# brew install lcov
+# yum -y install lcov
+llvm-cov export \
+ --format=lcov \
+ -instr-profile ".build/debug/codecov/default.profdata" \
+ -ignore-filename-regex=".build|Tests" \
+ "${COV_BIN}" > lcov.data
+
+# genhtml lcov.data --output-directory out