@@ -18,6 +18,7 @@ final class Test_URIParser: Test_Runtime {
18
18
19
19
let testedVariants : [ URICoderConfiguration ] = [
20
20
. formExplode, . formUnexplode, . simpleExplode, . simpleUnexplode, . formDataExplode, . formDataUnexplode,
21
+ . deepObjectExplode,
21
22
]
22
23
23
24
func testParsing( ) throws {
@@ -29,7 +30,8 @@ final class Test_URIParser: Test_Runtime {
29
30
simpleExplode: . custom( " " , value: [ " " : [ " " ] ] ) ,
30
31
simpleUnexplode: . custom( " " , value: [ " " : [ " " ] ] ) ,
31
32
formDataExplode: " empty= " ,
32
- formDataUnexplode: " empty= "
33
+ formDataUnexplode: " empty= " ,
34
+ deepObjectExplode: " object%5Bempty%5D= "
33
35
) ,
34
36
value: [ " empty " : [ " " ] ]
35
37
) ,
@@ -40,7 +42,8 @@ final class Test_URIParser: Test_Runtime {
40
42
simpleExplode: . custom( " " , value: [ " " : [ " " ] ] ) ,
41
43
simpleUnexplode: . custom( " " , value: [ " " : [ " " ] ] ) ,
42
44
formDataExplode: " " ,
43
- formDataUnexplode: " "
45
+ formDataUnexplode: " " ,
46
+ deepObjectExplode: " "
44
47
) ,
45
48
value: [ : ]
46
49
) ,
@@ -51,7 +54,8 @@ final class Test_URIParser: Test_Runtime {
51
54
simpleExplode: . custom( " fred " , value: [ " " : [ " fred " ] ] ) ,
52
55
simpleUnexplode: . custom( " fred " , value: [ " " : [ " fred " ] ] ) ,
53
56
formDataExplode: " who=fred " ,
54
- formDataUnexplode: " who=fred "
57
+ formDataUnexplode: " who=fred " ,
58
+ deepObjectExplode: " object%5Bwho%5D=fred "
55
59
) ,
56
60
value: [ " who " : [ " fred " ] ]
57
61
) ,
@@ -62,7 +66,8 @@ final class Test_URIParser: Test_Runtime {
62
66
simpleExplode: . custom( " Hello%20World " , value: [ " " : [ " Hello World " ] ] ) ,
63
67
simpleUnexplode: . custom( " Hello%20World " , value: [ " " : [ " Hello World " ] ] ) ,
64
68
formDataExplode: " hello=Hello+World " ,
65
- formDataUnexplode: " hello=Hello+World "
69
+ formDataUnexplode: " hello=Hello+World " ,
70
+ deepObjectExplode: " object%5Bhello%5D=Hello%20World "
66
71
) ,
67
72
value: [ " hello " : [ " Hello World " ] ]
68
73
) ,
@@ -73,7 +78,11 @@ final class Test_URIParser: Test_Runtime {
73
78
simpleExplode: . custom( " red,green,blue " , value: [ " " : [ " red " , " green " , " blue " ] ] ) ,
74
79
simpleUnexplode: . custom( " red,green,blue " , value: [ " " : [ " red " , " green " , " blue " ] ] ) ,
75
80
formDataExplode: " list=red&list=green&list=blue " ,
76
- formDataUnexplode: " list=red,green,blue "
81
+ formDataUnexplode: " list=red,green,blue " ,
82
+ deepObjectExplode: . custom(
83
+ " object%5Blist%5D=red&object%5Blist%5D=green&object%5Blist%5D=blue " ,
84
+ expectedError: . malformedKeyValuePair( " list " )
85
+ )
77
86
) ,
78
87
value: [ " list " : [ " red " , " green " , " blue " ] ]
79
88
) ,
@@ -93,22 +102,37 @@ final class Test_URIParser: Test_Runtime {
93
102
formDataUnexplode: . custom(
94
103
" keys=comma,%2C,dot,.,semi,%3B " ,
95
104
value: [ " keys " : [ " comma " , " , " , " dot " , " . " , " semi " , " ; " ] ]
96
- )
105
+ ) ,
106
+ deepObjectExplode: " keys%5Bcomma%5D=%2C&keys%5Bdot%5D=.&keys%5Bsemi%5D=%3B "
97
107
) ,
98
108
value: [ " semi " : [ " ; " ] , " dot " : [ " . " ] , " comma " : [ " , " ] ]
99
109
) ,
100
110
]
101
111
for testCase in cases {
102
112
func testVariant( _ variant: Case . Variant , _ input: Case . Variants . Input ) throws {
103
113
var parser = URIParser ( configuration: variant. config, data: input. string [ ... ] )
104
- let parsedNode = try parser. parseRoot ( )
105
- XCTAssertEqual (
106
- parsedNode,
107
- input. valueOverride ?? testCase. value,
108
- " Failed for config: \( variant. name) " ,
109
- file: testCase. file,
110
- line: testCase. line
111
- )
114
+ do {
115
+ let parsedNode = try parser. parseRoot ( )
116
+ XCTAssertEqual (
117
+ parsedNode,
118
+ input. valueOverride ?? testCase. value,
119
+ " Failed for config: \( variant. name) " ,
120
+ file: testCase. file,
121
+ line: testCase. line
122
+ )
123
+ } catch {
124
+ guard let expectedError = input. expectedError, let parsingError = error as? ParsingError else {
125
+ XCTAssert ( false , " Unexpected error thrown: \( error) " , file: testCase. file, line: testCase. line)
126
+ return
127
+ }
128
+ XCTAssertEqual (
129
+ expectedError,
130
+ parsingError,
131
+ " Failed for config: \( variant. name) " ,
132
+ file: testCase. file,
133
+ line: testCase. line
134
+ )
135
+ }
112
136
}
113
137
let variants = testCase. variants
114
138
try testVariant ( . formExplode, variants. formExplode)
@@ -117,6 +141,7 @@ final class Test_URIParser: Test_Runtime {
117
141
try testVariant ( . simpleUnexplode, variants. simpleUnexplode)
118
142
try testVariant ( . formDataExplode, variants. formDataExplode)
119
143
try testVariant ( . formDataUnexplode, variants. formDataUnexplode)
144
+ try testVariant ( . deepObjectExplode, variants. deepObjectExplode)
120
145
}
121
146
}
122
147
}
@@ -133,25 +158,32 @@ extension Test_URIParser {
133
158
static let simpleUnexplode : Self = . init( name: " simpleUnexplode " , config: . simpleUnexplode)
134
159
static let formDataExplode : Self = . init( name: " formDataExplode " , config: . formDataExplode)
135
160
static let formDataUnexplode : Self = . init( name: " formDataUnexplode " , config: . formDataUnexplode)
161
+ static let deepObjectExplode : Self = . init( name: " deepObjectExplode " , config: . deepObjectExplode)
136
162
}
137
163
struct Variants {
138
164
139
165
struct Input : ExpressibleByStringLiteral {
140
166
var string : String
141
167
var valueOverride : URIParsedNode ?
168
+ var expectedError : ParsingError ?
142
169
143
- init ( string: String , valueOverride: URIParsedNode ? = nil ) {
170
+ init ( string: String , valueOverride: URIParsedNode ? = nil , expectedError : ParsingError ? = nil ) {
144
171
self . string = string
145
172
self . valueOverride = valueOverride
173
+ self . expectedError = expectedError
146
174
}
147
175
148
176
static func custom( _ string: String , value: URIParsedNode ) -> Self {
149
- . init( string: string, valueOverride: value)
177
+ . init( string: string, valueOverride: value, expectedError: nil )
178
+ }
179
+ static func custom( _ string: String , expectedError: ParsingError ) -> Self {
180
+ . init( string: string, valueOverride: nil , expectedError: expectedError)
150
181
}
151
182
152
183
init ( stringLiteral value: String ) {
153
184
self . string = value
154
185
self . valueOverride = nil
186
+ self . expectedError = nil
155
187
}
156
188
}
157
189
@@ -161,6 +193,7 @@ extension Test_URIParser {
161
193
var simpleUnexplode : Input
162
194
var formDataExplode : Input
163
195
var formDataUnexplode : Input
196
+ var deepObjectExplode : Input
164
197
}
165
198
var variants : Variants
166
199
var value : URIParsedNode
0 commit comments