@@ -391,6 +391,43 @@ extension MyCustomizedError : RecoverableError {
391
391
}
392
392
}
393
393
394
+ /// An error type that provides localization and recovery, but doesn't
395
+ /// customize NSError directly.
396
+ enum MySwiftCustomizedError : Error {
397
+ case failed
398
+ static var errorDescriptionCount = 0
399
+ }
400
+
401
+ extension MySwiftCustomizedError : LocalizedError {
402
+ var errorDescription : String ? {
403
+ MySwiftCustomizedError . errorDescriptionCount =
404
+ MySwiftCustomizedError . errorDescriptionCount + 1
405
+ return NSLocalizedString ( " something went horribly wrong " , comment: " " )
406
+ }
407
+
408
+ var failureReason : String ? {
409
+ return NSLocalizedString ( " because someone wrote 'throw' " , comment: " " )
410
+ }
411
+
412
+ var recoverySuggestion : String ? {
413
+ return NSLocalizedString ( " delete the 'throw' " , comment: " " )
414
+ }
415
+
416
+ var helpAnchor : String ? {
417
+ return NSLocalizedString ( " there is no help when writing tests " , comment: " " )
418
+ }
419
+ }
420
+
421
+ extension MySwiftCustomizedError : RecoverableError {
422
+ var recoveryOptions : [ String ] {
423
+ return [ " Delete 'throw' " , " Disable the test " ]
424
+ }
425
+
426
+ func attemptRecovery( optionIndex recoveryOptionIndex: Int ) -> Bool {
427
+ return recoveryOptionIndex == 0
428
+ }
429
+ }
430
+
394
431
/// Fake definition of the informal protocol
395
432
/// "NSErrorRecoveryAttempting" that we use to poke at the object
396
433
/// produced for a RecoverableError.
@@ -425,34 +462,48 @@ class RecoveryDelegate {
425
462
}
426
463
}
427
464
428
- ErrorBridgingTests . test ( " Customizing NSError via protocols " ) {
429
- let error = MyCustomizedError ( code: 12345 )
430
- let nsError = error as NSError
431
-
432
- // CustomNSError
433
- expectEqual ( " custom " , nsError. domain)
434
- expectEqual ( 12345 , nsError. code)
435
- expectOptionalEqual ( URL ( string: " https://swift.org " ) !,
436
- nsError. userInfo [ NSURLErrorKey] as? URL )
437
-
465
+ /// Helper for testing a customized error.
466
+ func testCustomizedError( error: Error , nsError: NSError ) {
438
467
// LocalizedError
439
- expectOptionalEqual ( " something went horribly wrong " ,
440
- nsError. userInfo [ NSLocalizedDescriptionKey] as? String )
441
- expectOptionalEqual ( " because someone wrote 'throw' " ,
442
- nsError. userInfo [ NSLocalizedFailureReasonErrorKey] as? String )
443
- expectOptionalEqual ( " delete the 'throw' " ,
444
- nsError. userInfo [ NSLocalizedRecoverySuggestionErrorKey] as? String )
445
- expectOptionalEqual ( " there is no help when writing tests " ,
446
- nsError. userInfo [ NSHelpAnchorErrorKey] as? String )
447
- expectEqual ( nsError. localizedDescription, " something went horribly wrong " )
448
- expectEqual ( error. localizedDescription, " something went horribly wrong " )
468
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
469
+ expectEmpty ( nsError. userInfo [ NSLocalizedDescriptionKey] )
470
+ expectEmpty ( nsError. userInfo [ NSLocalizedFailureReasonErrorKey] )
471
+ expectEmpty ( nsError. userInfo [ NSLocalizedRecoverySuggestionErrorKey] )
472
+ expectEmpty ( nsError. userInfo [ NSHelpAnchorErrorKey] )
473
+ } else {
474
+ expectOptionalEqual ( " something went horribly wrong " ,
475
+ nsError. userInfo [ NSLocalizedDescriptionKey] as? String )
476
+ expectOptionalEqual ( " because someone wrote 'throw' " ,
477
+ nsError. userInfo [ NSLocalizedFailureReasonErrorKey] as? String )
478
+ expectOptionalEqual ( " delete the 'throw' " ,
479
+ nsError. userInfo [ NSLocalizedRecoverySuggestionErrorKey] as? String )
480
+ expectOptionalEqual ( " there is no help when writing tests " ,
481
+ nsError. userInfo [ NSHelpAnchorErrorKey] as? String )
482
+ }
483
+ expectEqual ( " something went horribly wrong " , error. localizedDescription)
484
+ expectEqual ( " something went horribly wrong " , nsError. localizedDescription)
485
+ expectEqual ( " because someone wrote 'throw' " , nsError. localizedFailureReason)
486
+ expectEqual ( " delete the 'throw' " , nsError. localizedRecoverySuggestion)
487
+ expectEqual ( " there is no help when writing tests " , nsError. helpAnchor)
449
488
450
489
// RecoverableError
490
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
491
+ expectEmpty ( nsError. userInfo [ NSLocalizedRecoveryOptionsErrorKey] )
492
+ } else {
493
+ expectOptionalEqual ( [ " Delete 'throw' " , " Disable the test " ] ,
494
+ nsError. userInfo [ NSLocalizedRecoveryOptionsErrorKey] as? [ String ] )
495
+ }
451
496
expectOptionalEqual ( [ " Delete 'throw' " , " Disable the test " ] ,
452
- nsError. userInfo [ NSLocalizedRecoveryOptionsErrorKey ] as? [ String ] )
497
+ nsError. localizedRecoveryOptions )
453
498
454
499
// Directly recover.
455
- let attempter = nsError. userInfo [ NSRecoveryAttempterErrorKey] !
500
+ let attempter : AnyObject
501
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
502
+ expectEmpty ( nsError. userInfo [ NSRecoveryAttempterErrorKey] )
503
+ attempter = nsError. recoveryAttempter!
504
+ } else {
505
+ attempter = nsError. userInfo [ NSRecoveryAttempterErrorKey] !
506
+ }
456
507
expectOptionalEqual ( attempter. attemptRecovery ( fromError: nsError,
457
508
optionIndex: 0 ) ,
458
509
true )
@@ -482,4 +533,52 @@ ErrorBridgingTests.test("Customizing NSError via protocols") {
482
533
expectEqual ( true , rd2. called)
483
534
}
484
535
536
+ ErrorBridgingTests . test ( " Customizing NSError via protocols " ) {
537
+ let error = MyCustomizedError ( code: 12345 )
538
+ let nsError = error as NSError
539
+
540
+ // CustomNSError
541
+ expectEqual ( " custom " , nsError. domain)
542
+ expectEqual ( 12345 , nsError. code)
543
+ expectOptionalEqual ( URL ( string: " https://swift.org " ) !,
544
+ nsError. userInfo [ NSURLErrorKey] as? URL )
545
+
546
+ testCustomizedError ( error: error, nsError: nsError)
547
+ }
548
+
549
+ ErrorBridgingTests . test ( " Customizing localization/recovery via protocols " ) {
550
+ let error = MySwiftCustomizedError . failed
551
+ let nsError = error as NSError
552
+ testCustomizedError ( error: error, nsError: nsError)
553
+ }
554
+
555
+ ErrorBridgingTests . test ( " Customizing localization/recovery laziness " ) {
556
+ let countBefore = MySwiftCustomizedError . errorDescriptionCount
557
+ let error = MySwiftCustomizedError . failed
558
+ let nsError = error as NSError
559
+
560
+ // RecoverableError
561
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
562
+ expectEmpty ( nsError. userInfo [ NSLocalizedRecoveryOptionsErrorKey] )
563
+ } else {
564
+ expectOptionalEqual ( [ " Delete 'throw' " , " Disable the test " ] ,
565
+ nsError. userInfo [ NSLocalizedRecoveryOptionsErrorKey] as? [ String ] )
566
+ }
567
+ expectOptionalEqual ( [ " Delete 'throw' " , " Disable the test " ] ,
568
+ nsError. localizedRecoveryOptions)
569
+
570
+ // None of the operations above should affect the count
571
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
572
+ expectEqual ( countBefore, MySwiftCustomizedError . errorDescriptionCount)
573
+ }
574
+
575
+ // This one does affect the count.
576
+ expectEqual ( " something went horribly wrong " , error. localizedDescription)
577
+
578
+ // Check that we did get a call to errorDescription.
579
+ if #available( OSX 10 . 11 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
580
+ expectEqual ( countBefore+ 1 , MySwiftCustomizedError . errorDescriptionCount)
581
+ }
582
+ }
583
+
485
584
runAllTests ( )
0 commit comments