@@ -499,6 +499,113 @@ 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
+ let decimalValue : Decimal ?
517
+ }
518
+
519
+ func decode( _ type: String , _ value: String ) throws {
520
+ var key = type. lowercased ( )
521
+ key. append ( " Value " )
522
+ _ = try JSONDecoder ( ) . decode ( DataStruct . self, from: " { \" \( key) \" : \( value) } " . data ( using: . utf8) !)
523
+ }
524
+
525
+ func testGoodValue( _ type: String , _ value: String ) {
526
+ do {
527
+ try decode ( type, value)
528
+ } catch {
529
+ XCTFail ( " Unexpected error: \( error) for parsing \( value) to \( type) " )
530
+ }
531
+ }
532
+
533
+ func testErrorThrown( _ type: String , _ value: String , errorMessage: String ) {
534
+ do {
535
+ try decode ( type, value)
536
+ XCTFail ( " Decode of \( value) to \( type) should not succeed " )
537
+ } catch DecodingError . dataCorrupted( let context) {
538
+ XCTAssertEqual ( context. debugDescription, errorMessage)
539
+ } catch {
540
+ XCTAssertEqual ( String ( describing: error) , errorMessage)
541
+ }
542
+ }
543
+
544
+
545
+ var goodValues = [
546
+ ( " Int8 " , " 0 " ) , ( " Int8 " , " 1 " ) , ( " Int8 " , " -1 " ) , ( " Int8 " , " -128 " ) , ( " Int8 " , " 127 " ) ,
547
+ ( " UInt8 " , " 0 " ) , ( " UInt8 " , " 1 " ) , ( " UInt8 " , " 255 " ) , ( " UInt8 " , " -0 " ) ,
548
+
549
+ ( " Int16 " , " 0 " ) , ( " Int16 " , " 1 " ) , ( " Int16 " , " -1 " ) , ( " Int16 " , " -32768 " ) , ( " Int16 " , " 32767 " ) ,
550
+ ( " UInt16 " , " 0 " ) , ( " UInt16 " , " 1 " ) , ( " UInt16 " , " 65535 " ) , ( " UInt16 " , " 34.0 " ) ,
551
+
552
+ ( " Int32 " , " 0 " ) , ( " Int32 " , " 1 " ) , ( " Int32 " , " -1 " ) , ( " Int32 " , " -2147483648 " ) , ( " Int32 " , " 2147483647 " ) ,
553
+ ( " UInt32 " , " 0 " ) , ( " UInt32 " , " 1 " ) , ( " UInt32 " , " 4294967295 " ) ,
554
+
555
+ ( " Int64 " , " 0 " ) , ( " Int64 " , " 1 " ) , ( " Int64 " , " -1 " ) , ( " Int64 " , " -9223372036854775808 " ) , ( " Int64 " , " 9223372036854775807 " ) ,
556
+ ( " UInt64 " , " 0 " ) , ( " UInt64 " , " 1 " ) , ( " UInt64 " , " 18446744073709551615 " ) ,
557
+
558
+ ( " Double " , " 0 " ) , ( " Double " , " 1 " ) , ( " Double " , " -1 " ) , ( " Double " , " 2.2250738585072014e-308 " ) , ( " Double " , " 1.7976931348623157e+308 " ) ,
559
+ ( " Double " , " 5e-324 " ) , ( " Double " , " 3.141592653589793 " ) ,
560
+
561
+ ( " Decimal " , " 1.2 " ) , ( " Decimal " , " 3.14159265358979323846264338327950288419 " ) ,
562
+ ( " Decimal " , " 3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 " ) ,
563
+ ( " Decimal " , " -3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 " ) ,
564
+ ]
565
+
566
+ if Int . max == Int64 . max {
567
+ goodValues += [
568
+ ( " Int " , " 0 " ) , ( " Int " , " 1 " ) , ( " Int " , " -1 " ) , ( " Int " , " -9223372036854775808 " ) , ( " Int " , " 9223372036854775807 " ) ,
569
+ ( " UInt " , " 0 " ) , ( " UInt " , " 1 " ) , ( " UInt " , " 18446744073709551615 " ) ,
570
+ ]
571
+ } else {
572
+ goodValues += [
573
+ ( " Int " , " 0 " ) , ( " Int " , " 1 " ) , ( " Int " , " -1 " ) , ( " Int " , " -2147483648 " ) , ( " Int " , " 2147483647 " ) ,
574
+ ( " UInt " , " 0 " ) , ( " UInt " , " 1 " ) , ( " UInt " , " 4294967295 " ) ,
575
+ ]
576
+ }
577
+
578
+ let badValues = [
579
+ ( " Int8 " , " -129 " ) , ( " Int8 " , " 128 " ) , ( " Int8 " , " 1.2 " ) ,
580
+ ( " UInt8 " , " -1 " ) , ( " UInt8 " , " 256 " ) ,
581
+
582
+ ( " Int16 " , " -32769 " ) , ( " Int16 " , " 32768 " ) ,
583
+ ( " UInt16 " , " -1 " ) , ( " UInt16 " , " 65536 " ) ,
584
+
585
+ ( " Int32 " , " -2147483649 " ) , ( " Int32 " , " 2147483648 " ) ,
586
+ ( " UInt32 " , " -1 " ) , ( " UInt32 " , " 4294967296 " ) ,
587
+
588
+ ( " Int64 " , " 9223372036854775808 " ) , ( " Int64 " , " 9223372036854775808 " ) , ( " Int64 " , " -100000000000000000000 " ) ,
589
+ ( " UInt64 " , " -1 " ) , ( " UInt64 " , " 18446744073709600000 " ) , ( " Int64 " , " 10000000000000000000000000000000000000 " ) ,
590
+ ]
591
+
592
+ for value in goodValues {
593
+ testGoodValue ( value. 0 , value. 1 )
594
+ }
595
+
596
+ for (type, value) in badValues {
597
+ testErrorThrown ( type, value, errorMessage: " Parsed JSON number < \( value) > does not fit in \( type) . " )
598
+ }
599
+
600
+ // Invalid JSON number formats
601
+ testErrorThrown ( " Int8 " , " 0000000000000000000000000000001 " , errorMessage: " The given data was not valid JSON. " )
602
+ testErrorThrown ( " Double " , " -.1 " , errorMessage: " The given data was not valid JSON. " )
603
+ testErrorThrown ( " Int32 " , " +1 " , errorMessage: " The given data was not valid JSON. " )
604
+ testErrorThrown ( " Int " , " .012 " , errorMessage: " The given data was not valid JSON. " )
605
+ testErrorThrown ( " Double " , " 2.7976931348623158e+308 " , errorMessage: " The given data was not valid JSON. " )
606
+ }
607
+
608
+
502
609
// MARK: - Helper Functions
503
610
private var _jsonEmptyDictionary : Data {
504
611
return " {} " . data ( using: . utf8) !
@@ -1089,6 +1196,7 @@ extension TestJSONEncoder {
1089
1196
( " test_codingOfDouble " , test_codingOfDouble) ,
1090
1197
( " test_codingOfString " , test_codingOfString) ,
1091
1198
( " test_codingOfURL " , test_codingOfURL) ,
1199
+ ( " test_numericLimits " , test_numericLimits) ,
1092
1200
]
1093
1201
}
1094
1202
}
0 commit comments