-
Notifications
You must be signed in to change notification settings - Fork 473
/
Copy pathTest_JSONDecodingOptions.swift
166 lines (156 loc) · 6.97 KB
/
Test_JSONDecodingOptions.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Tests/SwiftProtobufTests/Test_JSONDecodingOptions.swift - Various JSON tests
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Test for the use of JSONDecodingOptions
///
// -----------------------------------------------------------------------------
import Foundation
import SwiftProtobuf
import XCTest
final class Test_JSONDecodingOptions: XCTestCase {
func testMessageDepthLimit() {
let jsonInputs: [String] = [
// Proper field names.
"{ \"a\": { \"a\": { \"i\": 1 } } }",
// Wrong names, causes the skipping of values to be trigger, which also should
// honor depth limits.
"{ \"x\": { \"x\": { \"z\": 1 } } }",
]
let tests: [(Int, Bool)] = [
// Limit, success/failure
(10, true),
(4, true),
(3, true),
(2, false),
(1, false),
]
for (i, jsonInput) in jsonInputs.enumerated() {
for (limit, expectSuccess) in tests {
do {
var options = JSONDecodingOptions()
options.messageDepthLimit = limit
options.ignoreUnknownFields = true
let _ = try SwiftProtoTesting_TestRecursiveMessage(jsonString: jsonInput, options: options)
if !expectSuccess {
XCTFail("Should not have succeed, pass: \(i), limit: \(limit)")
}
} catch JSONDecodingError.messageDepthLimit {
if expectSuccess {
XCTFail("Decode failed because of limit, but should *NOT* have, pass: \(i), limit: \(limit)")
} else {
// Nothing, this is what was expected.
}
} catch let e {
XCTFail("Decode failed (pass: \(i), limit: \(limit) with unexpected error: \(e)")
}
}
}
}
func testIgnoreUnknownFields() {
// (isValidJSON, jsonInput)
// isValidJSON - if the input is otherwise valid protobuf JSON, and
// hence should parse when ignoring unknown fields.
// jsonInput - The JSON string to parse.
let jsonInputs: [(Bool, String)] = [
// Try all the data types.
(true, "{\"unknown\":7}"),
(true, "{\"unknown\":null}"),
(true, "{\"unknown\":false}"),
(true, "{\"unknown\":true}"),
(true, "{\"unknown\": 7.0}"),
(true, "{\"unknown\": -3.04}"),
(true, "{\"unknown\": -7.0e-55}"),
(true, "{\"unknown\": 7.308e+8}"),
(true, "{\"unknown\": \"hi!\"}"),
(true, "{\"unknown\": []}"),
(true, "{\"unknown\": [[]]}"),
(true, "{\"unknown\": [[[]]]}"),
(true, "{\"unknown\": [[],[[]],[[[]],[]],[],7]}"),
(true, "{\"unknown\": [1,[2,[3,4],5],6]}"),
(true, "{\"unknown\": [3, 4, 5]}"),
(true, "{\"unknown\": [[3], [4], [5, [6, [7], 8, null, \"no\"]]]}"),
(true, "{\"unknown\": [3, {}, \"5\"]}"),
(true, "{\"unknown\": {}}"),
(true, "{\"unknown\": {\"foo\": 1}}"),
// multiple fields, fails on first.
(true, "{\"unknown\": 7, \"also_unknown\": 8}"),
(true, "{\"unknown\": 7, \"zz_unknown\": 8}"),
// Malformed fields, fails on the field, without trying to parse the value.
(false, "{\"unknown\": 1e999}"),
(false, "{\"unknown\": \"hi!\""),
(false, "{\"unknown\": \"hi!}"),
(false, "{\"unknown\": qqq }"),
(false, "{\"unknown\": [ }"),
(false, "{\"unknown\": { ]}"),
(false, "{\"unknown\": ]}"),
(false, "{\"unknown\": nulll }"),
(false, "{\"unknown\": nul }"),
(false, "{\"unknown\": Null }"),
(false, "{\"unknown\": NULL }"),
(false, "{\"unknown\": True }"),
(false, "{\"unknown\": False }"),
(false, "{\"unknown\": nan }"),
(false, "{\"unknown\": NaN }"),
(false, "{\"unknown\": Infinity }"),
(false, "{\"unknown\": infinity }"),
(false, "{\"unknown\": Inf }"),
(false, "{\"unknown\": inf }"),
(false, "{\"unknown\": {1, 2}}"),
(false, "{\"unknown\": 1.2.3.4.5}"),
(false, "{\"unknown\": -.04}"),
(false, "{\"unknown\": -19.}"),
(false, "{\"unknown\": -9.3e+}"),
(false, "{\"unknown\": 1 2 3}"),
(false, "{\"unknown\": { true false }}"),
(false, "{\"unknown\": [,[2,[3,4],5],6]}"),
(false, "{\"unknown\": [1,[2[3,4],5],6]}"),
(false, "{\"unknown\": [1,[2,[3,4],5],]}"),
(false, "{\"unknown\": [[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]}"),
(false, "{\"unknown\": [[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]}"),
(false, "{\"unknown\": [[[[[[[[[[[[[[[[[[[[[[,]]]]]]]]]]]]]]]]]]]]]]}"),
// Generally malformed JSON still errors on the field name
(false, "{\"unknown\": }"),
(false, "{\"unknown\": null true}"),
(false, "{\"unknown\": 1}}"),
(false, "{\"unknown\": { }"),
]
var options = JSONDecodingOptions()
options.ignoreUnknownFields = true
for (i, (isValidJSON, jsonInput)) in jsonInputs.enumerated() {
// Default options (error on unknown fields)
do {
let _ = try SwiftProtoTesting_TestEmptyMessage(jsonString: jsonInput)
XCTFail("Input \(i): Should not have gotten here! Input: \(jsonInput)")
} catch JSONDecodingError.unknownField(let field) {
XCTAssertEqual(field, "unknown", "Input \(i): got field \(field)")
} catch let e {
XCTFail("Input \(i): Error \(e) decoding into an empty message \(jsonInput)")
}
// Ignoring unknown fields
do {
let _ = try SwiftProtoTesting_TestEmptyMessage(
jsonString: jsonInput,
options: options
)
XCTAssertTrue(
isValidJSON,
"Input \(i): Should not have been able to parse: \(jsonInput)"
)
} catch JSONDecodingError.unknownField(let field) {
XCTFail("Input \(i): should not have gotten unknown field \(field), input \(jsonInput)")
} catch let e {
XCTAssertFalse(
isValidJSON,
"Input \(i): Error \(e): Should have been able to parse: \(jsonInput)"
)
}
}
}
}