@@ -98,19 +98,53 @@ final class BSONCorpusTests: BSONTestCase {
98
98
99
99
// swiftlint:disable:next cyclomatic_complexity
100
100
func testBSONCorpus( ) throws {
101
+ let SKIPPED_CORPUS_TESTS = [
102
+ " Decimal128 " :
103
+ [
104
+ // TODO: SWIFT-962
105
+ " Exact rounding " ,
106
+ " [dqbsr531] negatives (Rounded) " ,
107
+ " [dqbsr431] check rounding modes heeded (Rounded) " ,
108
+ " OK2 " ,
109
+ // TODO: SWIFT-965
110
+ " [decq438] clamped zeros... (Clamped) " ,
111
+ " [decq418] clamped zeros... (Clamped) "
112
+ ] ,
113
+ " Array " :
114
+ [
115
+ // TODO: SWIFT-963
116
+ " Multi Element Array with duplicate indexes " ,
117
+ " Single Element Array with index set incorrectly to empty string " ,
118
+ " Single Element Array with index set incorrectly to ab "
119
+ ] ,
120
+ " Top-level document validity " : [
121
+ " Bad DBRef (ref is number, not string) " ,
122
+ " Bad DBRef (db is number, not string) "
123
+ ]
124
+ ]
125
+
126
+ let shouldSkip = { testFileDesc, testDesc in
127
+ SKIPPED_CORPUS_TESTS [ testFileDesc] ? . contains { $0 == testDesc } == true
128
+ }
129
+
130
+ let decoder = ExtendedJSONDecoder ( )
131
+
101
132
for (_, testFile) in try retrieveSpecTestFiles ( specName: " bson-corpus " , asType: BSONCorpusTestFile . self) {
102
133
if let validityTests = testFile. valid {
103
134
for test in validityTests {
135
+ guard !shouldSkip( testFile. description, test. description) else {
136
+ continue
137
+ }
104
138
guard let cBData = Data ( hexString: test. canonicalBSON) else {
105
139
XCTFail ( " Unable to interpret canonical_bson as Data " )
106
140
return
107
141
}
108
- // guard let cEJData = test.canonicalExtJSON.data(using: .utf8) else {
109
- // XCTFail("Unable to interpret canonical_extjson as Data")
110
- // return
111
- // }
142
+ guard let cEJData = test. canonicalExtJSON. data ( using: . utf8) else {
143
+ XCTFail ( " Unable to interpret canonical_extjson as Data " )
144
+ return
145
+ }
112
146
113
- // let lossy = test.lossy ?? false
147
+ let lossy = test. lossy ?? false
114
148
115
149
// for cB input:
116
150
// native_to_bson( bson_to_native(cB) ) = cB
@@ -129,97 +163,93 @@ final class BSONCorpusTests: BSONTestCase {
129
163
let docFromNative = BSONDocument ( fromArray: nativeFromDoc)
130
164
expect ( docFromNative. toByteString ( ) ) . to ( equal ( cBData. toByteString ( ) ) )
131
165
132
- if testFile. description == " Decimal128 " {
133
- // TODO: This should be tested by EXTJSON
134
- struct Decimal128CanonicalExtJSON : Codable {
135
- struct Value : Codable {
136
- enum CodingKeys : String , CodingKey {
137
- case numberDecimal = " $numberDecimal "
138
- }
139
-
140
- var numberDecimal : String
141
- }
166
+ // native_to_canonical_extended_json( bson_to_native(cB) ) = cEJ
167
+ let canonicalEncoder = ExtendedJSONEncoder ( )
168
+ canonicalEncoder. mode = . canonical
169
+ expect ( try canonicalEncoder. encode ( docFromCB) )
170
+ . to ( cleanEqual ( test. canonicalExtJSON) , description: test. description)
142
171
143
- var d : Value
144
- }
145
- let extjson = test. canonicalExtJSON. data ( using: . ascii) !
146
- let jsonResult = try JSONDecoder ( ) . decode ( Decimal128CanonicalExtJSON . self, from: extjson)
147
- let decimal128CorpusString = jsonResult. d. numberDecimal
172
+ // native_to_relaxed_extended_json( bson_to_native(cB) ) = rEJ (if rEJ exists)
173
+ let relaxedEncoder = ExtendedJSONEncoder ( ) // default mode is .relaxed
174
+ if let rEJ = test. relaxedExtJSON {
175
+ expect ( try relaxedEncoder. encode ( docFromCB) )
176
+ . to ( cleanEqual ( rEJ) , description: test. description)
177
+ }
148
178
149
- let decimal128FromString = try BSONDecimal128 ( decimal128CorpusString)
150
- let decimal128FromBinary = docFromCB. d!. decimal128Value!
179
+ // for cEJ input:
180
+ // native_to_canonical_extended_json( json_to_native(cEJ) ) = cEJ
181
+ expect ( try canonicalEncoder. encode ( try decoder. decode ( BSONDocument . self, from: cEJData) ) )
182
+ . to ( cleanEqual ( test. canonicalExtJSON) , description: test. description)
151
183
152
- expect ( decimal128FromString. description) . to ( equal ( decimal128CorpusString) )
153
- expect ( decimal128FromBinary. description) . to ( equal ( decimal128CorpusString) )
184
+ // native_to_bson( json_to_native(cEJ) ) = cB (unless lossy)
185
+ if !lossy {
186
+ expect ( try decoder. decode ( BSONDocument . self, from: cEJData) )
187
+ . to ( sortedEqual ( docFromCB) , description: test. description)
154
188
}
155
189
156
- // native_to_canonical_extended_json( bson_to_native(cB) ) = cEJ
157
- // expect(docFromCB.canonicalExtendedJSON).to(cleanEqual(test.canonicalExtJSON))
190
+ // for dB input (if it exists): (change to language native part)
191
+ if let dB = test. degenerateBSON {
192
+ guard let dBData = Data ( hexString: dB) else {
193
+ XCTFail ( " Unable to interpret degenerate_bson as Data " )
194
+ return
195
+ }
158
196
159
- // native_to_relaxed_extended_json( bson_to_native(cB) ) = rEJ (if rEJ exists)
160
- // if let rEJ = test.relaxedExtJSON {
161
- // expect(try Document(fromBSON: cBData).extendedJSON).to(cleanEqual(rEJ))
162
- // }
197
+ let docFromDB = try BSONDocument ( fromBSON: dBData)
163
198
164
- // for cEJ input:
165
- // native_to_canonical_extended_json( json_to_native(cEJ) ) = cEJ
166
- // expect(try Document(fromJSON: cEJData).canonicalExtendedJSON)
167
- // .to(cleanEqual(test.canonicalExtJSON))
168
-
169
- // // native_to_bson( json_to_native(cEJ) ) = cB (unless lossy)
170
- // if !lossy {
171
- // expect(try Document(fromJSON: cEJData).rawBSON).to(equal(cBData))
172
- // }
173
-
174
- // for dB input (if it exists):
175
- // if let dB = test.degenerateBSON {
176
- // guard let dBData = Data(hexString: dB) else {
177
- // XCTFail("Unable to interpret degenerate_bson as Data")
178
- // return
179
- // }
180
-
181
- // // bson_to_canonical_extended_json(dB) = cEJ
182
- // expect(try Document(fromBSON: dBData).canonicalExtendedJSON)
183
- // .to(cleanEqual(test.canonicalExtJSON))
184
-
185
- // // bson_to_relaxed_extended_json(dB) = rEJ (if rEJ exists)
186
- // if let rEJ = test.relaxedExtJSON {
187
- // expect(try Document(fromBSON: dBData).extendedJSON).to(cleanEqual(rEJ))
188
- // }
189
- // }
199
+ // SKIPPING: native_to_bson( bson_to_native(dB) ) = cB
200
+ // We only validate the BSON bytes, we do not clean them up, so can't do this assertion
201
+ // Degenerate BSON round trip tests will be added in SWIFT-964
190
202
191
- // for dEJ input (if it exists):
192
- // if let dEJ = test.degenerateExtJSON {
193
- // // native_to_canonical_extended_json( json_to_native(dEJ) ) = cEJ
194
- // expect(try Document(fromJSON: dEJ).canonicalExtendedJSON)
195
- // .to(cleanEqual(test.canonicalExtJSON))
203
+ // native_to_canonical_extended_json( bson_to_native(dB) ) = cEJ
204
+ // (Not in spec yet, might be added in DRIVERS-1355)
205
+ expect ( try canonicalEncoder. encode ( docFromDB) )
206
+ . to ( cleanEqual ( test. canonicalExtJSON) )
196
207
197
- // // native_to_bson( json_to_native(dEJ) ) = cB (unless lossy)
198
- // if !lossy {
199
- // expect(try Document(fromJSON: dEJ).rawBSON).to(equal(cBData))
200
- // }
201
- // }
208
+ // native_to_relaxed_extended_json( bson_to_native(dB) ) = rEJ (if rEJ exists)
209
+ // (Not in spec yet, might be added in DRIVERS-1355)
210
+ if let rEJ = test. relaxedExtJSON {
211
+ expect ( try relaxedEncoder. encode ( docFromDB) )
212
+ . to ( cleanEqual ( rEJ) , description: test. description)
213
+ }
214
+ }
215
+
216
+ // for dEJ input (if it exists):
217
+ if let dEJ = test. degenerateExtJSON, let dEJData = dEJ. data ( using: . utf8) {
218
+ // native_to_canonical_extended_json( json_to_native(dEJ) ) = cEJ
219
+ expect ( try canonicalEncoder. encode ( try decoder. decode ( BSONDocument . self, from: dEJData) ) )
220
+ . to ( cleanEqual ( test. canonicalExtJSON) , description: test. description)
221
+ // native_to_bson( json_to_native(dEJ) ) = cB (unless lossy)
222
+ if !lossy {
223
+ try expect ( try decoder. decode ( BSONDocument . self, from: dEJData) )
224
+ . to ( sortedEqual ( BSONDocument ( fromBSON: cBData) ) , description: test. description)
225
+ }
226
+ }
202
227
203
228
// for rEJ input (if it exists):
204
- // if let rEJ = test.relaxedExtJSON {
205
- // // native_to_relaxed_extended_json( json_to_native(rEJ) ) = rEJ
206
- // expect(try Document(fromJSON: rEJ).extendedJSON).to(cleanEqual(rEJ))
207
- // }
229
+ if let rEJ = test. relaxedExtJSON, let rEJData = rEJ. data ( using: . utf8) {
230
+ // native_to_relaxed_extended_json( json_to_native(rEJ) ) = rEJ
231
+ expect ( try relaxedEncoder. encode ( try decoder. decode ( BSONDocument . self, from: rEJData) ) )
232
+ . to ( cleanEqual ( rEJ) , description: test. description)
233
+ }
208
234
}
209
235
}
210
236
211
237
if let parseErrorTests = testFile. parseErrors {
212
- continue // TODO: EXT JSON support required
213
238
for test in parseErrorTests {
239
+ guard !shouldSkip( testFile. description, test. description) else {
240
+ continue
241
+ }
214
242
let description = " \( testFile. description) - \( test. description) "
215
-
216
243
switch BSONType ( rawValue: UInt8 ( testFile. bsonType. dropFirst ( 2 ) , radix: 16 ) !) ! {
217
244
case . invalid: // "top level document" uses 0x00 for the bson type
218
- _ = ( )
219
- // expect(try BSONDocument(fromJSON: test.string)).to(throwError(), description: description)
245
+ guard let testData = test. string. data ( using: . utf8) else {
246
+ XCTFail ( " Unable to interpret canonical_bson as Data " )
247
+ return
248
+ }
249
+ expect ( try decoder. decode ( BSONDocument . self, from: testData) )
250
+ . to ( throwError ( errorType: DecodingError . self) , description: description)
220
251
case . decimal128:
221
- _ = ( )
222
- // expect(BSONDecimal128(test.string)).to(beNil(), description: description)
252
+ continue // TODO: SWIFT-968
223
253
default :
224
254
throw TestError (
225
255
message: " \( description) : parse error tests not implemented "
@@ -231,6 +261,9 @@ final class BSONCorpusTests: BSONTestCase {
231
261
232
262
if let decodeErrors = testFile. decodeErrors {
233
263
for test in decodeErrors {
264
+ guard !shouldSkip( testFile. description, test. description) else {
265
+ continue
266
+ }
234
267
let description = " \( testFile. description) - \( test. description) "
235
268
guard let data = Data ( hexString: test. bson) else {
236
269
XCTFail ( " \( description) : Unable to interpret bson as Data " )
0 commit comments