@@ -499,6 +499,104 @@ class TestJSONEncoder : XCTestCase {
499
499
}
500
500
}
501
501
502
+ func test_numericLimits( ) {
503
+ struct DataStruct : Codable {
504
+ let int8Value : Int8 ?
505
+ let uint8Value : UInt8 ?
506
+ let int16Value : Int16 ?
507
+ let uint16Value : UInt16 ?
508
+ let int32Value : Int32 ?
509
+ let uint32Value : UInt32 ?
510
+ let int64Value : Int64 ?
511
+ let intValue : Int ?
512
+ let uintValue : UInt ?
513
+ let uint64Value : UInt64 ?
514
+ let floatValue : Float ?
515
+ let doubleValue : Double ?
516
+ }
517
+
518
+ func decode( _ type: String , _ value: String ) throws {
519
+ var key = type. lowercased ( )
520
+ key. append ( " Value " )
521
+ _ = try JSONDecoder ( ) . decode ( DataStruct . self, from: " { \" \( key) \" : \( value) } " . data ( using: . utf8) !)
522
+ }
523
+
524
+ func testGoodValue( _ type: String , _ value: String ) {
525
+ do {
526
+ try decode ( type, value)
527
+ } catch {
528
+ XCTFail ( " Unexpected error: \( error) for parsing \( value) to \( type) " )
529
+ }
530
+ }
531
+
532
+ func testErrorThrown( _ type: String , _ value: String , errorMessage: String ) {
533
+ do {
534
+ try decode ( type, value)
535
+ XCTFail ( " Decode of \( value) to \( type) should not succeed " )
536
+ } catch DecodingError . dataCorrupted( let context) {
537
+ XCTAssertEqual ( context. debugDescription, errorMessage)
538
+ } catch {
539
+ XCTAssertEqual ( String ( describing: error) , errorMessage)
540
+ }
541
+ }
542
+
543
+
544
+ var goodValues = [
545
+ ( " Int8 " , " 0 " ) , ( " Int8 " , " 1 " ) , ( " Int8 " , " -1 " ) , ( " Int8 " , " -128 " ) , ( " Int8 " , " 127 " ) ,
546
+ ( " UInt8 " , " 0 " ) , ( " UInt8 " , " 1 " ) , ( " UInt8 " , " 255 " ) , ( " UInt8 " , " -0 " ) ,
547
+
548
+ ( " Int16 " , " 0 " ) , ( " Int16 " , " 1 " ) , ( " Int16 " , " -1 " ) , ( " Int16 " , " -32768 " ) , ( " Int16 " , " 32767 " ) ,
549
+ ( " UInt16 " , " 0 " ) , ( " UInt16 " , " 1 " ) , ( " UInt16 " , " 65535 " ) , ( " UInt16 " , " 34.0 " ) ,
550
+
551
+ ( " Int32 " , " 0 " ) , ( " Int32 " , " 1 " ) , ( " Int32 " , " -1 " ) , ( " Int32 " , " -2147483648 " ) , ( " Int32 " , " 2147483647 " ) ,
552
+ ( " UInt32 " , " 0 " ) , ( " UInt32 " , " 1 " ) , ( " UInt32 " , " 4294967295 " ) ,
553
+
554
+ ( " Int64 " , " 0 " ) , ( " Int64 " , " 1 " ) , ( " Int64 " , " -1 " ) , ( " Int64 " , " -9223372036854775808 " ) , ( " Int64 " , " 9223372036854775807 " ) ,
555
+ ( " UInt64 " , " 0 " ) , ( " UInt64 " , " 1 " ) , ( " UInt64 " , " 18446744073709551615 " ) ,
556
+ ]
557
+
558
+ if Int . max == Int64 . max {
559
+ goodValues += [
560
+ ( " Int " , " 0 " ) , ( " Int " , " 1 " ) , ( " Int " , " -1 " ) , ( " Int " , " -9223372036854775808 " ) , ( " Int " , " 9223372036854775807 " ) ,
561
+ ( " UInt " , " 0 " ) , ( " UInt " , " 1 " ) , ( " UInt " , " 18446744073709551615 " ) ,
562
+ ]
563
+ } else {
564
+ goodValues += [
565
+ ( " Int " , " 0 " ) , ( " Int " , " 1 " ) , ( " Int " , " -1 " ) , ( " Int " , " -2147483648 " ) , ( " Int " , " 2147483647 " ) ,
566
+ ( " UInt " , " 0 " ) , ( " UInt " , " 1 " ) , ( " UInt " , " 4294967295 " ) ,
567
+ ]
568
+ }
569
+
570
+ let badValues = [
571
+ ( " Int8 " , " -129 " ) , ( " Int8 " , " 128 " ) , ( " Int8 " , " 1.2 " ) ,
572
+ ( " UInt8 " , " -1 " ) , ( " UInt8 " , " 256 " ) ,
573
+
574
+ ( " Int16 " , " -32769 " ) , ( " Int16 " , " 32768 " ) ,
575
+ ( " UInt16 " , " -1 " ) , ( " UInt16 " , " 65536 " ) ,
576
+
577
+ ( " Int32 " , " -2147483649 " ) , ( " Int32 " , " 2147483648 " ) ,
578
+ ( " UInt32 " , " -1 " ) , ( " UInt32 " , " 4294967296 " ) ,
579
+
580
+ ( " Int64 " , " 9223372036854775808 " ) , ( " Int64 " , " 9223372036854775808 " ) , ( " Int64 " , " -100000000000000000000 " ) ,
581
+ ( " UInt64 " , " -1 " ) , ( " UInt64 " , " 18446744073709600000 " ) , ( " Int64 " , " 10000000000000000000000000000000000000 " ) ,
582
+ ]
583
+
584
+ for value in goodValues {
585
+ testGoodValue ( value. 0 , value. 1 )
586
+ }
587
+
588
+ for (type, value) in badValues {
589
+ testErrorThrown ( type, value, errorMessage: " Parsed JSON number < \( value) > does not fit in \( type) . " )
590
+ }
591
+
592
+ // Leading zeros are invalid
593
+ testErrorThrown ( " Int8 " , " 0000000000000000000000000000001 " , errorMessage: " The operation could not be completed " )
594
+ testErrorThrown ( " Double " , " -.1 " , errorMessage: " The operation could not be completed " )
595
+ testErrorThrown ( " Int32 " , " +1 " , errorMessage: " The operation could not be completed " )
596
+ testErrorThrown ( " Int " , " .012 " , errorMessage: " The operation could not be completed " )
597
+ }
598
+
599
+
502
600
// MARK: - Helper Functions
503
601
private var _jsonEmptyDictionary : Data {
504
602
return " {} " . data ( using: . utf8) !
@@ -1089,6 +1187,7 @@ extension TestJSONEncoder {
1089
1187
( " test_codingOfDouble " , test_codingOfDouble) ,
1090
1188
( " test_codingOfString " , test_codingOfString) ,
1091
1189
( " test_codingOfURL " , test_codingOfURL) ,
1190
+ ( " test_numericLimits " , test_numericLimits) ,
1092
1191
]
1093
1192
}
1094
1193
}
0 commit comments