From 00bd4d695b20dba3ec7a09997c5817e55feb8893 Mon Sep 17 00:00:00 2001 From: John Sundell Date: Fri, 3 Jan 2020 14:41:15 +0100 Subject: [PATCH] Indentation + PodcastType: Make Equatable and Codable (#17) This will enable tools built on top of Plot (like Publish) to encode types containing these kinds of values. Also improve the Linux compatibility tooling to detect if a new test case was added only on Apple Platforms. --- Sources/Plot/API/Indentation.swift | 43 ++++++++++++++++++++++-- Sources/Plot/API/PodcastType.swift | 2 +- Tests/PlotTests/IndentationTests.swift | 27 +++++++++++++++ Tests/PlotTests/LinuxCompatibility.swift | 14 ++++++++ Tests/PlotTests/XCTestManifests.swift | 1 + 5 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 Tests/PlotTests/IndentationTests.swift diff --git a/Sources/Plot/API/Indentation.swift b/Sources/Plot/API/Indentation.swift index de58609..6f65e59 100644 --- a/Sources/Plot/API/Indentation.swift +++ b/Sources/Plot/API/Indentation.swift @@ -7,7 +7,7 @@ import Foundation /// A representation of a kind of indentation at a given level. -public struct Indentation { +public struct Indentation: Codable, Equatable { /// The kind of the indentation (see `Kind`). public var kind: Kind /// The level of the indentation (0 = root). @@ -22,7 +22,7 @@ public struct Indentation { public extension Indentation { /// Enum defining various kinds of indentation that a document /// can be rendered using. - enum Kind { + enum Kind: Equatable { /// Each level should be indented by a given number of tabs. case tabs(Int) /// Each level should be indented by a given number of spaces. @@ -56,3 +56,42 @@ extension Indentation.Kind: CustomStringConvertible { } } } + +extension Indentation.Kind: Codable { + private enum CodingKeys: CodingKey { + case kind + case count + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let kind = try container.decode(String.self, forKey: .kind) + let count = try container.decode(Int.self, forKey: .count) + + switch kind { + case "tabs": + self = .tabs(count) + case "spaces": + self = .spaces(count) + default: + throw DecodingError.dataCorruptedError( + forKey: CodingKeys.kind, + in: container, + debugDescription: "'\(kind)' is not an indentation kind" + ) + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + switch self { + case .tabs(let count): + try container.encode("tabs", forKey: .kind) + try container.encode(count, forKey: .count) + case .spaces(let count): + try container.encode("spaces", forKey: .kind) + try container.encode(count, forKey: .count) + } + } +} diff --git a/Sources/Plot/API/PodcastType.swift b/Sources/Plot/API/PodcastType.swift index ac5975b..7138ba3 100644 --- a/Sources/Plot/API/PodcastType.swift +++ b/Sources/Plot/API/PodcastType.swift @@ -7,7 +7,7 @@ import Foundation /// Enum describing various podcast types supported by Apple Podcasts. -public enum PodcastType: String { +public enum PodcastType: String, Codable { case episodic case serial } diff --git a/Tests/PlotTests/IndentationTests.swift b/Tests/PlotTests/IndentationTests.swift new file mode 100644 index 0000000..87d0267 --- /dev/null +++ b/Tests/PlotTests/IndentationTests.swift @@ -0,0 +1,27 @@ +import XCTest +import Plot + +final class IndentationTests: XCTestCase { + func testSpacesCoding() throws { + let indentation = Indentation(kind: .spaces(4)) + let data = try JSONEncoder().encode(indentation) + let decoded = try JSONDecoder().decode(Indentation.self, from: data) + XCTAssertEqual(indentation, decoded) + } + + func testTabsCoding() throws { + let indentation = Indentation(kind: .tabs(1)) + let data = try JSONEncoder().encode(indentation) + let decoded = try JSONDecoder().decode(Indentation.self, from: data) + XCTAssertEqual(indentation, decoded) + } +} + +extension IndentationTests { + static var allTests: Linux.TestList { + [ + ("testSpacesCoding", testSpacesCoding), + ("testTabsCoding", testTabsCoding) + ] + } +} diff --git a/Tests/PlotTests/LinuxCompatibility.swift b/Tests/PlotTests/LinuxCompatibility.swift index be2c799..357cecb 100644 --- a/Tests/PlotTests/LinuxCompatibility.swift +++ b/Tests/PlotTests/LinuxCompatibility.swift @@ -31,6 +31,8 @@ internal extension Linux { #if canImport(ObjectiveC) internal final class LinuxVerificationTests: XCTestCase { func testAllTestsRunOnLinux() { + var totalLinuxTestCount = 0 + for testCase in allTests() { let type = testCase.testCaseClass @@ -49,7 +51,19 @@ internal final class LinuxVerificationTests: XCTestCase { """) } } + + totalLinuxTestCount += linuxTestNames.count } + + XCTAssertEqual( + XCTestSuite.default.testCaseCount - 1, + totalLinuxTestCount, + """ + Linux and Apple Platforms test counts are not equal. + Perhaps you added a new test case class? + If so, you need to add it in XCTestManifests.swift. + """ + ) } } #endif diff --git a/Tests/PlotTests/XCTestManifests.swift b/Tests/PlotTests/XCTestManifests.swift index 8253bfa..6ba32a2 100644 --- a/Tests/PlotTests/XCTestManifests.swift +++ b/Tests/PlotTests/XCTestManifests.swift @@ -11,6 +11,7 @@ public func allTests() -> [Linux.TestCase] { Linux.makeTestCase(using: ControlFlowTests.allTests), Linux.makeTestCase(using: DocumentTests.allTests), Linux.makeTestCase(using: HTMLTests.allTests), + Linux.makeTestCase(using: IndentationTests.allTests), Linux.makeTestCase(using: NodeTests.allTests), Linux.makeTestCase(using: PodcastFeedTests.allTests), Linux.makeTestCase(using: RSSTests.allTests),