From 6735f210ea25a417ffd2027cf19d611dc64ea551 Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Tue, 31 Jul 2018 10:49:09 +0100 Subject: [PATCH] SR-8407: NSNumber as? Bool should only work for 0 or 1 - NSNumber as? Bool should only work for NSNumber values 0 and 1 to match Darwin. --- Foundation/NSNumber.swift | 9 ++++- TestFoundation/TestNSNumber.swift | 48 +++++++++++++++++++++++ TestFoundation/TestNSNumberBridging.swift | 32 +++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift index 755b82888f..704caa36a4 100644 --- a/Foundation/NSNumber.swift +++ b/Foundation/NSNumber.swift @@ -541,8 +541,13 @@ extension Bool : _ObjectiveCBridgeable { } public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Bool?) -> Bool { - result = x.boolValue - return true + if x.intValue == 0 || x.intValue == 1 { + result = x.boolValue + return true + } else { + result = nil + return false + } } public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Bool { diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift index 4c74e15f9b..525a625e52 100644 --- a/TestFoundation/TestNSNumber.swift +++ b/TestFoundation/TestNSNumber.swift @@ -35,6 +35,7 @@ class TestNSNumber : XCTestCase { ("test_objCType", test_objCType ), ("test_stringValue", test_stringValue), ("test_Equals", test_Equals), + ("test_boolValue", test_boolValue), ] } @@ -1214,4 +1215,51 @@ class TestNSNumber : XCTestCase { XCTAssertEqual(NSNumber(value: Double.greatestFiniteMagnitude).compare(NSNumber(value: 0)), ComparisonResult.orderedDescending) XCTAssertTrue(NSNumber(value: Double(-0.0)) == NSNumber(value: Double(0.0))) } + + func test_boolValue() { + XCTAssertEqual(NSNumber(value: UInt8.max).boolValue, true) + XCTAssertEqual(NSNumber(value: UInt8.min).boolValue, false) + + XCTAssertEqual(NSNumber(value: UInt16.max).boolValue, true) + XCTAssertEqual(NSNumber(value: UInt16.min).boolValue, false) + + XCTAssertEqual(NSNumber(value: UInt32.max).boolValue, true) + XCTAssertEqual(NSNumber(value: UInt32.min).boolValue, false) + + XCTAssertEqual(NSNumber(value: UInt64.max).boolValue, true) + XCTAssertEqual(NSNumber(value: UInt64.min).boolValue, false) + + XCTAssertEqual(NSNumber(value: UInt.max).boolValue, true) + XCTAssertEqual(NSNumber(value: UInt.min).boolValue, false) + + XCTAssertEqual(NSNumber(value: Int8.max).boolValue, true) + XCTAssertEqual(NSNumber(value: Int8.max - 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int8.min).boolValue, true) + XCTAssertEqual(NSNumber(value: Int8.min + 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int8(-1)).boolValue, true) + + XCTAssertEqual(NSNumber(value: Int16.max).boolValue, true) + XCTAssertEqual(NSNumber(value: Int16.max - 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int16.min).boolValue, true) + XCTAssertEqual(NSNumber(value: Int16.min + 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int16(-1)).boolValue, true) + + XCTAssertEqual(NSNumber(value: Int32.max).boolValue, true) + XCTAssertEqual(NSNumber(value: Int32.max - 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int32.min).boolValue, true) + XCTAssertEqual(NSNumber(value: Int32.min + 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int32(-1)).boolValue, true) + + XCTAssertEqual(NSNumber(value: Int64.max).boolValue, true) + XCTAssertEqual(NSNumber(value: Int64.max - 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int64.min).boolValue, false) // Darwin compatibility + XCTAssertEqual(NSNumber(value: Int64.min + 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int64(-1)).boolValue, true) + + XCTAssertEqual(NSNumber(value: Int.max).boolValue, true) + XCTAssertEqual(NSNumber(value: Int.max - 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int.min).boolValue, false) // Darwin compatibility + XCTAssertEqual(NSNumber(value: Int.min + 1).boolValue, true) + XCTAssertEqual(NSNumber(value: Int(-1)).boolValue, true) + } } diff --git a/TestFoundation/TestNSNumberBridging.swift b/TestFoundation/TestNSNumberBridging.swift index 57978b1fbc..3a84175227 100644 --- a/TestFoundation/TestNSNumberBridging.swift +++ b/TestFoundation/TestNSNumberBridging.swift @@ -24,6 +24,7 @@ class TestNSNumberBridging : XCTestCase { ("testNSNumberBridgeFromDouble", testNSNumberBridgeFromDouble), ("test_numericBitPatterns_to_floatingPointTypes", test_numericBitPatterns_to_floatingPointTypes), ("testNSNumberBridgeAnyHashable", testNSNumberBridgeAnyHashable), + ("testNSNumberToBool", testNSNumberToBool), ] } @@ -623,6 +624,37 @@ class TestNSNumberBridging : XCTestCase { XCTAssertEqual(value, ns_value) } } + + func testNSNumberToBool() { + let b0 = NSNumber(value: 0) as? Bool + XCTAssertNotNil(b0) + XCTAssertEqual(b0, false) + + let b1 = NSNumber(value: false) as? Bool + XCTAssertNotNil(b1) + XCTAssertEqual(b1, false) + + let b2 = NSNumber(value: 1) as? Bool + XCTAssertNotNil(b2) + XCTAssertEqual(b2, true) + + let b3 = NSNumber(value: true) as? Bool + XCTAssertNotNil(b3) + XCTAssertEqual(b3, true) + + XCTAssertNil(NSNumber(value: -1) as? Bool) + XCTAssertNil(NSNumber(value: 2) as? Bool) + XCTAssertNil(NSNumber(value: Int8.min) as? Bool) + XCTAssertNil(NSNumber(value: Int8.max) as? Bool) + XCTAssertNil(NSNumber(value: Int16.min) as? Bool) + XCTAssertNil(NSNumber(value: Int16.max) as? Bool) + XCTAssertNil(NSNumber(value: Int32.min) as? Bool) + XCTAssertNil(NSNumber(value: Int32.max) as? Bool) + XCTAssertNil(NSNumber(value: Int64.min) as? Bool) + XCTAssertNil(NSNumber(value: Int64.max) as? Bool) + XCTAssertNil(NSNumber(value: Int.min) as? Bool) + XCTAssertNil(NSNumber(value: Int.max) as? Bool) + } } extension Float {