Skip to content

Commit eb755d2

Browse files
authored
fix: improve codable's (#352)
1 parent 8b90507 commit eb755d2

File tree

4 files changed

+179
-14
lines changed

4 files changed

+179
-14
lines changed

Sources/ParseSwift/Coding/AnyDecodable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Foundation
1313
let json = """
1414
{
1515
"boolean": true,
16-
"integer": 1,
16+
"integer": 42,
1717
"double": 3.14159265358979323846,
1818
"string": "string",
1919
"array": [1, 2, 3],

Sources/ParseSwift/Coding/AnyEncodable.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ import Foundation
1212

1313
let dictionary: [String: AnyEncodable] = [
1414
"boolean": true,
15-
"integer": 1,
15+
"integer": 42,
1616
"double": 3.14159265358979323846,
1717
"string": "string",
1818
"array": [1, 2, 3],
1919
"nested": [
2020
"a": "alpha",
2121
"b": "bravo",
2222
"c": "charlie"
23-
]
23+
],
24+
"null": nil
2425
]
2526

2627
let encoder = JSONEncoder()
@@ -99,6 +100,8 @@ extension _AnyEncodable {
99100
try container.encode(array.map { AnyEncodable($0) })
100101
case let dictionary as [String: Any?]:
101102
try container.encode(dictionary.mapValues { AnyEncodable($0) })
103+
case let encodable as Encodable:
104+
try encodable.encode(to: encoder)
102105
default:
103106
let context = EncodingError.Context(codingPath: container.codingPath,
104107
debugDescription: "AnyEncodable value cannot be encoded")

Tests/ParseSwiftTests/AnyCodableTests/AnyCodableTests.swift

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ import XCTest
22
@testable import ParseSwift
33

44
class AnyCodableTests: XCTestCase {
5+
6+
struct SomeCodable: Codable {
7+
var string: String
8+
var int: Int
9+
var bool: Bool
10+
var hasUnderscore: String
11+
12+
// swiftlint:disable:next nesting
13+
enum CodingKeys: String, CodingKey {
14+
case string
15+
case int
16+
case bool
17+
case hasUnderscore = "has_underscore"
18+
}
19+
}
20+
521
func testJSONDecoding() {
622
guard let json = """
723
{
@@ -42,17 +58,25 @@ class AnyCodableTests: XCTestCase {
4258
//Test has objective-c
4359
#if !os(Linux) && !os(Android) && !os(Windows)
4460
func testJSONEncoding() {
61+
62+
let someCodable = AnyCodable(SomeCodable(string: "String",
63+
int: 100,
64+
bool: true,
65+
hasUnderscore: "another string"))
66+
4567
let dictionary: [String: AnyCodable] = [
4668
"boolean": true,
47-
"integer": 1,
69+
"integer": 42,
4870
"double": 3.14159265358979323846,
4971
"string": "string",
5072
"array": [1, 2, 3],
5173
"nested": [
5274
"a": "alpha",
5375
"b": "bravo",
5476
"c": "charlie"
55-
]
77+
],
78+
"someCodable": someCodable,
79+
"null": nil
5680
]
5781
do {
5882
let encoder = JSONEncoder()
@@ -64,16 +88,23 @@ class AnyCodableTests: XCTestCase {
6488
}
6589
guard let expected = """
6690
{
67-
"boolean": true,
68-
"integer": 1,
91+
"boolean": 1,
92+
"integer": 42,
6993
"double": 3.14159265358979323846,
7094
"string": "string",
7195
"array": [1, 2, 3],
7296
"nested": {
7397
"a": "alpha",
7498
"b": "bravo",
7599
"c": "charlie"
76-
}
100+
},
101+
"someCodable": {
102+
"string":"String",
103+
"int":100,
104+
"bool": true,
105+
"has_underscore":"another string"
106+
},
107+
"null": null
77108
}
78109
""".data(using: .utf8) else {
79110
XCTFail("Should unrap data to utf8")

Tests/ParseSwiftTests/AnyCodableTests/AnyEncodableTests.swift

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,47 @@
11
import XCTest
22
@testable import ParseSwift
33

4-
//Test has objective-c
4+
// Test has objective-c
55
#if !os(Linux) && !os(Android) && !os(Windows)
66
class AnyEncodableTests: XCTestCase {
7+
8+
struct SomeEncodable: Encodable {
9+
var string: String
10+
var int: Int
11+
var bool: Bool
12+
var hasUnderscore: String
13+
14+
// swiftlint:disable:next nesting
15+
enum CodingKeys: String, CodingKey {
16+
case string
17+
case int
18+
case bool
19+
case hasUnderscore = "has_underscore"
20+
}
21+
}
22+
723
func testJSONEncoding() {
24+
25+
let someEncodable = AnyEncodable(SomeEncodable(string: "String",
26+
int: 100,
27+
bool: true,
28+
hasUnderscore: "another string"))
29+
830
let dictionary: [String: AnyEncodable] = [
931
"boolean": true,
10-
"integer": 1,
32+
"integer": 42,
1133
"double": 3.14159265358979323846,
1234
"string": "string",
1335
"array": [1, 2, 3],
1436
"nested": [
1537
"a": "alpha",
1638
"b": "bravo",
1739
"c": "charlie"
18-
]
40+
],
41+
"someCodable": someEncodable,
42+
"null": nil
1943
]
44+
2045
do {
2146
let encoder = JSONEncoder()
2247
let json = try encoder.encode(dictionary)
@@ -27,16 +52,23 @@ class AnyEncodableTests: XCTestCase {
2752
}
2853
guard let expected = """
2954
{
30-
"boolean": true,
31-
"integer": 1,
55+
"boolean": 1,
56+
"integer": 42,
3257
"double": 3.14159265358979323846,
3358
"string": "string",
3459
"array": [1, 2, 3],
3560
"nested": {
3661
"a": "alpha",
3762
"b": "bravo",
3863
"c": "charlie"
39-
}
64+
},
65+
"someCodable": {
66+
"string": "String",
67+
"int": 100,
68+
"bool": true,
69+
"has_underscore": "another string"
70+
},
71+
"null": null
4072
}
4173
""".data(using: .utf8) else {
4274
XCTFail("Should unrap data to utf8")
@@ -52,5 +84,104 @@ class AnyEncodableTests: XCTestCase {
5284
XCTFail(error.localizedDescription)
5385
}
5486
}
87+
88+
func testEncodeNSNumber() throws {
89+
let dictionary: [String: NSNumber] = [
90+
"boolean": true,
91+
"char": -127,
92+
"int": -32767,
93+
"short": -32767,
94+
"long": -2147483647,
95+
"longlong": -9223372036854775807,
96+
"uchar": 255,
97+
"uint": 65535,
98+
"ushort": 65535,
99+
"ulong": 4294967295,
100+
"ulonglong": 18446744073709615,
101+
"double": 3.141592653589793
102+
]
103+
104+
let encoder = JSONEncoder()
105+
106+
let json = try encoder.encode(AnyEncodable(dictionary))
107+
guard let encodedJSONObject = try JSONSerialization.jsonObject(with: json, options: []) as? NSDictionary else {
108+
XCTFail("Should have unwrapped")
109+
return
110+
}
111+
112+
let expected = """
113+
{
114+
"boolean": 1,
115+
"char": -127,
116+
"int": -32767,
117+
"short": -32767,
118+
"long": -2147483647,
119+
"longlong": -9223372036854775807,
120+
"uchar": 255,
121+
"uint": 65535,
122+
"ushort": 65535,
123+
"ulong": 4294967295,
124+
"ulonglong": 18446744073709615,
125+
"double": 3.141592653589793,
126+
}
127+
""".data(using: .utf8)!
128+
// swiftlint:disable:next line_length
129+
guard let expectedJSONObject = try JSONSerialization.jsonObject(with: expected, options: []) as? NSDictionary else {
130+
XCTFail("Should have unwrapped")
131+
return
132+
}
133+
134+
XCTAssertEqual(encodedJSONObject, expectedJSONObject)
135+
XCTAssert(encodedJSONObject["boolean"] is Bool)
136+
137+
XCTAssert(encodedJSONObject["char"] is Int8)
138+
XCTAssert(encodedJSONObject["int"] is Int16)
139+
XCTAssert(encodedJSONObject["short"] is Int32)
140+
XCTAssert(encodedJSONObject["long"] is Int32)
141+
XCTAssert(encodedJSONObject["longlong"] is Int64)
142+
143+
XCTAssert(encodedJSONObject["uchar"] is UInt8)
144+
XCTAssert(encodedJSONObject["uint"] is UInt16)
145+
XCTAssert(encodedJSONObject["ushort"] is UInt32)
146+
XCTAssert(encodedJSONObject["ulong"] is UInt32)
147+
XCTAssert(encodedJSONObject["ulonglong"] is UInt64)
148+
149+
XCTAssert(encodedJSONObject["double"] is Double)
150+
}
151+
152+
func testStringInterpolationEncoding() throws {
153+
let dictionary: [String: AnyEncodable] = [
154+
"boolean": "\(true)",
155+
"integer": "\(42)",
156+
"double": "\(3.141592653589793)",
157+
"string": "\("string")",
158+
"array": "\([1, 2, 3])"
159+
]
160+
161+
let encoder = JSONEncoder()
162+
163+
let json = try encoder.encode(dictionary)
164+
guard let encodedJSONObject = try JSONSerialization.jsonObject(with: json, options: []) as? NSDictionary else {
165+
XCTFail("Should have unwrapped")
166+
return
167+
}
168+
169+
let expected = """
170+
{
171+
"boolean": "true",
172+
"integer": "42",
173+
"double": "3.141592653589793",
174+
"string": "string",
175+
"array": "[1, 2, 3]",
176+
}
177+
""".data(using: .utf8)!
178+
// swiftlint:disable:next line_length
179+
guard let expectedJSONObject = try JSONSerialization.jsonObject(with: expected, options: []) as? NSDictionary else {
180+
XCTFail("Should have unwrapped")
181+
return
182+
}
183+
184+
XCTAssertEqual(encodedJSONObject, expectedJSONObject)
185+
}
55186
}
56187
#endif

0 commit comments

Comments
 (0)