-
Notifications
You must be signed in to change notification settings - Fork 104
/
PlantTest.swift
128 lines (108 loc) · 3.89 KB
/
PlantTest.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) 2017-2020 Shawn Moore and XMLCoder contributors
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
//
// Created by Shawn Moore on 11/15/17.
//
import Foundation
import XCTest
@testable import XMLCoder
private struct PlantCatalog: Codable, Equatable {
var plants: [Plant]
enum CodingKeys: String, CodingKey {
case plants = "PLANT"
}
}
private struct CurrencyCodingError: Error {}
private struct Currency: Codable, Equatable {
let value: Double
private static let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "en_US")
return formatter
}()
init(_ value: Double) {
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
guard let value = Currency.formatter
.number(from: string)?.doubleValue else {
throw CurrencyCodingError()
}
self.init(value)
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(Currency.formatter
.string(from: value as NSNumber))
}
}
private struct Plant: Codable, Equatable {
var common: String
var botanical: String
var zone: String
var light: String
var price: Currency
var amountAvailable: Int
enum CodingKeys: String, CodingKey {
case common = "COMMON"
case botanical = "BOTANICAL"
case zone = "ZONE"
case light = "LIGHT"
case price = "PRICE"
case amountAvailable = "AVAILABILITY"
}
init(common: String,
botanical: String,
zone: String,
light: String,
price: Currency,
amountAvailable: Int) {
self.common = common
self.botanical = botanical
self.zone = zone
self.light = light
self.price = price
self.amountAvailable = amountAvailable
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let common = try values.decode(String.self, forKey: .common)
let botanical = try values.decode(String.self, forKey: .botanical)
let zone = try values.decode(String.self, forKey: .zone)
let light = try values.decode(String.self, forKey: .light)
let price = try values.decode(Currency.self, forKey: .price)
let availability = try values.decode(Int.self, forKey: .amountAvailable)
self.init(common: common,
botanical: botanical,
zone: zone,
light: light,
price: price,
amountAvailable: availability)
}
}
private let lastPlant = Plant(common: "Cardinal Flower",
botanical: "Lobelia cardinalis",
zone: "2",
light: "Shade",
price: Currency(3.02),
amountAvailable: 22299)
final class PlantTest: XCTestCase {
func testXML() throws {
let decoder = XMLDecoder()
let encoder = XMLEncoder()
let plantCatalog1 = try decoder.decode(PlantCatalog.self,
from: plantCatalogXML)
XCTAssertEqual(plantCatalog1.plants.count, 36)
XCTAssertEqual(plantCatalog1.plants[35], lastPlant)
let data = try encoder.encode(plantCatalog1, withRootKey: "CATALOG",
header: XMLHeader(version: 1.0,
encoding: "UTF-8"))
let plantCatalog2 = try decoder.decode(PlantCatalog.self, from: data)
XCTAssertEqual(plantCatalog1, plantCatalog2)
}
}