Merge pull request #288 from tfrank64/default_dateFormatter
Implement remaining NSDateFormatter attributes, with more tests
diff --git a/CoreFoundation/String.subproj/CFRegularExpression.c b/CoreFoundation/String.subproj/CFRegularExpression.c
index 95ac971..785aa79 100644
--- a/CoreFoundation/String.subproj/CFRegularExpression.c
+++ b/CoreFoundation/String.subproj/CFRegularExpression.c
@@ -226,7 +226,8 @@
UErrorCode errorCode = U_ZERO_ERROR;
CFRange enclosingRange;
UniChar *stringBuffer = NULL;
-
+ int32_t textLength = length;
+
if (range.location + range.length > length || range.location >= INT_MAX) return NULL;
if (range.location + range.length > INT_MAX) range.length = INT_MAX - range.location;
@@ -267,11 +268,12 @@
*bufferToFree = stringBuffer;
}
}
+ textLength = enclosingRange.length;
}
if (stringBuffer) {
regex = checkOutRegularExpression(internal, checkout, checkedOutRegex);
- uregex_setText(regex, (const UChar *)stringBuffer, (int32_t)regionLimit, &errorCode);
+ uregex_setText(regex, (const UChar *)stringBuffer, textLength, &errorCode);
}
if (regex) {
@@ -412,4 +414,4 @@
_CFRegularExpressionOptions _CFRegularExpressionGetOptions(_CFRegularExpressionRef regex) {
return regex->options;
-}
\ No newline at end of file
+}
diff --git a/Foundation/NSArray.swift b/Foundation/NSArray.swift
index 438f07c..84fb229 100644
--- a/Foundation/NSArray.swift
+++ b/Foundation/NSArray.swift
@@ -543,15 +543,15 @@
}
}
- guard searchForInsertionIndex && lastEqual else {
+ if !searchForInsertionIndex {
return result
}
- guard result == NSNotFound else {
- return result + 1
+ if result == NSNotFound {
+ return indexOfLeastGreaterThanObj
}
- return indexOfLeastGreaterThanObj
+ return lastEqual ? result + 1 : result
}
diff --git a/Foundation/NSDecimalNumber.swift b/Foundation/NSDecimalNumber.swift
index aa4b9dc..0f87c79 100644
--- a/Foundation/NSDecimalNumber.swift
+++ b/Foundation/NSDecimalNumber.swift
@@ -55,7 +55,7 @@
NSRequiresConcreteImplementation()
}
- public func descriptionWithLocale(locale: AnyObject?) -> String { NSUnimplemented() }
+ public override func descriptionWithLocale(locale: AnyObject?) -> String { NSUnimplemented() }
// TODO: "declarations from extensions cannot be overridden yet"
// Although it's not clear we actually need to redeclare this here when the extension adds it to the superclass of this class
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index 9283087..e788490 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -434,6 +434,10 @@
return val
}
+ public var stringValue: String {
+ return descriptionWithLocale(nil)
+ }
+
/// Create an instance initialized to `value`.
public required convenience init(integerLiteral value: Int) {
self.init(integer: value)
@@ -452,6 +456,12 @@
public func compare(otherNumber: NSNumber) -> NSComparisonResult {
return ._fromCF(CFNumberCompare(_cfObject, otherNumber._cfObject, nil))
}
+
+ public func descriptionWithLocale(locale: AnyObject?) -> String {
+ guard let aLocale = locale else { return description }
+ let formatter = CFNumberFormatterCreate(nil, (aLocale as! NSLocale)._cfObject, kCFNumberFormatterDecimalStyle)
+ return CFNumberFormatterCreateStringWithNumber(nil, formatter, self._cfObject)._swiftObject
+ }
override public var _cfTypeID: CFTypeID {
return CFNumberGetTypeID()
diff --git a/Foundation/NSTextCheckingResult.swift b/Foundation/NSTextCheckingResult.swift
index 14c7856..f122bff 100644
--- a/Foundation/NSTextCheckingResult.swift
+++ b/Foundation/NSTextCheckingResult.swift
@@ -7,6 +7,7 @@
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
+import CoreFoundation
/* NSTextCheckingType in this project is limited to regular expressions. */
public struct NSTextCheckingType : OptionSet {
@@ -57,9 +58,10 @@
init(ranges: NSRangePointer, count: Int, regularExpression: NSRegularExpression) {
_regularExpression = regularExpression
super.init()
+ let notFound = NSRange(location: NSNotFound,length: 0)
for i in 0..<count {
- _ranges.append(ranges[i])
- }
+ ranges[i].location == kCFNotFound ? _ranges.append(notFound) : _ranges.append(ranges[i])
+ }
}
internal required init?(coder aDecoder: NSCoder) {
diff --git a/Foundation/NSTimeZone.swift b/Foundation/NSTimeZone.swift
index 3e4d89a..152ff9b 100644
--- a/Foundation/NSTimeZone.swift
+++ b/Foundation/NSTimeZone.swift
@@ -84,7 +84,13 @@
// do NOT follow the POSIX convention (of minutes-west).
public convenience init(forSecondsFromGMT seconds: Int) { NSUnimplemented() }
- public convenience init?(abbreviation: String) { NSUnimplemented() }
+ public convenience init?(abbreviation: String) {
+ let abbr = abbreviation._cfObject
+ guard let name = unsafeBitCast(CFDictionaryGetValue(CFTimeZoneCopyAbbreviationDictionary(), unsafeBitCast(abbr, to: UnsafePointer<Void>.self)), to: NSString!.self) else {
+ return nil
+ }
+ self.init(name: name._swiftObject , data: nil)
+ }
public func encodeWithCoder(aCoder: NSCoder) {
if aCoder.allowsKeyedCoding {
diff --git a/Foundation/NSUUID.swift b/Foundation/NSUUID.swift
index e07d123..819d536 100644
--- a/Foundation/NSUUID.swift
+++ b/Foundation/NSUUID.swift
@@ -45,7 +45,7 @@
public var UUIDString: String {
let strPtr = UnsafeMutablePointer<Int8>(allocatingCapacity: 37)
- _cf_uuid_unparse_lower(buffer, strPtr)
+ _cf_uuid_unparse_upper(buffer, strPtr)
return String(cString: strPtr)
}
diff --git a/TestFoundation/TestNSArray.swift b/TestFoundation/TestNSArray.swift
index 82042bf..c83b0cf 100644
--- a/TestFoundation/TestNSArray.swift
+++ b/TestFoundation/TestNSArray.swift
@@ -156,6 +156,14 @@
let rangeLength = 13
let endOfArray = objectIndexInArray(array, value: 10, startingFrom: rangeStart, length: rangeLength, options: [.InsertionIndex, .LastEqual])
XCTAssertTrue(endOfArray == (rangeStart + rangeLength), "...or the index at the end of the array if the object is larger than all other elements.")
+
+ let arrayOfTwo = NSArray(array: [NSNumber(int: 0), NSNumber(int: 2)])
+ let indexInMiddle = objectIndexInArray(arrayOfTwo, value: 1, startingFrom: 0, length: 2, options: [.InsertionIndex, .FirstEqual])
+ XCTAssertEqual(indexInMiddle, 1, "If no match found item should be inserted before least greater object")
+ let indexInMiddle2 = objectIndexInArray(arrayOfTwo, value: 1, startingFrom: 0, length: 2, options: [.InsertionIndex, .LastEqual])
+ XCTAssertEqual(indexInMiddle2, 1, "If no match found item should be inserted before least greater object")
+ let indexInMiddle3 = objectIndexInArray(arrayOfTwo, value: 1, startingFrom: 0, length: 2, options: [.InsertionIndex])
+ XCTAssertEqual(indexInMiddle3, 1, "If no match found item should be inserted before least greater object")
}
diff --git a/TestFoundation/TestNSRegularExpression.swift b/TestFoundation/TestNSRegularExpression.swift
index 6be8519..5d86881 100644
--- a/TestFoundation/TestNSRegularExpression.swift
+++ b/TestFoundation/TestNSRegularExpression.swift
@@ -24,7 +24,8 @@
static var allTests : [(String, TestNSRegularExpression -> () throws -> Void)] {
return [
("test_simpleRegularExpressions", test_simpleRegularExpressions),
- ("test_regularExpressionReplacement", test_regularExpressionReplacement)
+ ("test_regularExpressionReplacement", test_regularExpressionReplacement),
+ ("test_complexRegularExpressions", test_complexRegularExpressions)
]
}
@@ -218,7 +219,7 @@
if let first = firstResult where matches.count > 0 {
XCTAssertTrue(NSEqualRanges(first.range, firstMatchOverallRange), "Complex regex \(patternString) in \(searchString) match range \(NSStringFromRange(first.range)) should be \(NSStringFromRange(firstMatchOverallRange))", file: file, line: line)
if captureCount > 0 {
- XCTAssertTrue(NSEqualRanges(first.rangeAtIndex(1), firstMatchFirstCaptureRange), "Complex regex \(patternString) in \(searchString) match range \(first.rangeAtIndex(1)) should be \(NSStringFromRange(firstMatchOverallRange))", file: file, line: line)
+ XCTAssertTrue(NSEqualRanges(first.rangeAtIndex(1), firstMatchFirstCaptureRange), "Complex regex \(patternString) in \(searchString) match range \(first.rangeAtIndex(1)) should be \(NSStringFromRange(firstMatchFirstCaptureRange))", file: file, line: line)
} else {
XCTAssertTrue(NSEqualRanges(firstMatchFirstCaptureRange, NSMakeRange(NSNotFound, 0)), "Complex regex \(patternString) in \(searchString) no captures should be \(NSStringFromRange(firstMatchFirstCaptureRange))", file: file, line: line)
}
@@ -236,13 +237,13 @@
complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the the way.", [], NSMakeRange(0, 25), 1, NSMakeRange(13, 7), NSMakeRange(13, 3), NSMakeRange(13, 3));
complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "This this is the the way.", [], NSMakeRange(0, 25), 2, NSMakeRange(0, 9), NSMakeRange(0, 4), NSMakeRange(0, 4));
- complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the theway.", [], NSMakeRange(0, 24), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ //complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the theway.", [], NSMakeRange(0, 24), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the theway.", [], NSMakeRange(0, 20), 1, NSMakeRange(13, 7), NSMakeRange(13, 3), NSMakeRange(13, 3));
- complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the theway.", .WithTransparentBounds, NSMakeRange(0, 20), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ //complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "This this is the theway.", .WithTransparentBounds, NSMakeRange(0, 20), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "xThis this is the theway.", [], NSMakeRange(0, 25), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
- complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "xThis this is the theway.", [], NSMakeRange(1, 20), 1, NSMakeRange(14, 7), NSMakeRange(14, 3), NSMakeRange(14, 3));
+ //complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", [], "xThis this is the theway.", [], NSMakeRange(1, 20), 1, NSMakeRange(14, 7), NSMakeRange(14, 3), NSMakeRange(14, 3));
complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "xThis this is the theway.", [], NSMakeRange(1, 20), 2, NSMakeRange(1, 9), NSMakeRange(1, 4), NSMakeRange(1, 4));
- complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "xThis this is the theway.", .WithTransparentBounds, NSMakeRange(1, 20), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ //complexRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "xThis this is the theway.", .WithTransparentBounds, NSMakeRange(1, 20), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
complexRegularExpressionTest(NSRegularExpression.escapedPatternForString("\\b(th[a-z]+) \\1\\b"), [], "This this is the the way.", [], NSMakeRange(0, 25), 0, NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
complexRegularExpressionTest(NSRegularExpression.escapedPatternForString("\\b(th[a-z]+) \\1\\b"), [], "x\\b(th[a-z]+) \\1\\by", [], NSMakeRange(0, 19), 1, NSMakeRange(1, 17), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
@@ -270,10 +271,14 @@
complexRegularExpressionTest("\\b(th[a-z]+).\n#the first expression repeats\n\\1\\b", .AllowCommentsAndWhitespace, "This this is the the way.", [], NSMakeRange(0, 25), 1, NSMakeRange(13, 7), NSMakeRange(13, 3), NSMakeRange(13, 3));
complexRegularExpressionTest("(a(b|c|d)(x|y|z)*|123)", [], "abx", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(0, 3), NSMakeRange(2, 1));
- complexRegularExpressionTest("(a(b|c|d)(x|y|z)*|123)", [], "123", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(0, 3), NSMakeRange(NSNotFound, 0));
- complexRegularExpressionTest("a(b|c|d)(x|y|z)*|123", [], "123", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ //complexRegularExpressionTest("(a(b|c|d)(x|y|z)*|123)", [], "123", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(0, 3), NSMakeRange(NSNotFound, 0));
+ //complexRegularExpressionTest("a(b|c|d)(x|y|z)*|123", [], "123", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
complexRegularExpressionTest("a(b|c|d)(x|y|z)*", [], "abx", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 3), NSMakeRange(1, 1), NSMakeRange(2, 1));
complexRegularExpressionTest("(a(b|c|d)(x|y|z)*|123)", [], "abxy", [], NSMakeRange(0, 4), 1, NSMakeRange(0, 4), NSMakeRange(0, 4), NSMakeRange(3, 1));
complexRegularExpressionTest("a(b|c|d)(x|y|z)*", [], "abxy", [], NSMakeRange(0, 4), 1, NSMakeRange(0, 4), NSMakeRange(1, 1), NSMakeRange(3, 1));
+ complexRegularExpressionTest("(a|b)x|123|(c|d)y", [], "123dy", [], NSMakeRange(0, 5), 2, NSMakeRange(0, 3), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ complexRegularExpressionTest("(a|b)x|123|(c|d)y", [], "903847123", [], NSMakeRange(0, 9), 1, NSMakeRange(6, 3), NSMakeRange(NSNotFound, 0), NSMakeRange(NSNotFound, 0));
+ complexRegularExpressionTest("(a|b)x|123|(c|d)y", [], "axcy", [], NSMakeRange(0, 4), 2, NSMakeRange(0, 2), NSMakeRange(0, 1), NSMakeRange(NSNotFound, 0));
+ complexRegularExpressionTest("(a|b)x|123|(c|d)y", [], "cya", [], NSMakeRange(0, 3), 1, NSMakeRange(0, 2), NSMakeRange(NSNotFound, 0), NSMakeRange(0, 1));
}
}
diff --git a/TestFoundation/TestNSTimeZone.swift b/TestFoundation/TestNSTimeZone.swift
index c94ad5a..2bb8b83 100644
--- a/TestFoundation/TestNSTimeZone.swift
+++ b/TestFoundation/TestNSTimeZone.swift
@@ -26,6 +26,7 @@
// Disabled see https://bugs.swift.org/browse/SR-300
// ("test_abbreviation", test_abbreviation),
("test_initializingTimeZoneWithOffset", test_initializingTimeZoneWithOffset),
+ ("test_initializingTimeZoneWithAbbreviation", test_initializingTimeZoneWithAbbreviation),
// Also disabled due to https://bugs.swift.org/browse/SR-300
// ("test_systemTimeZoneUsesSystemTime", test_systemTimeZoneUsesSystemTime),
]
@@ -45,6 +46,16 @@
XCTAssertEqual(seconds, -14400, "GMT-0400 should be -14400 seconds but got \(seconds) instead")
}
+ func test_initializingTimeZoneWithAbbreviation() {
+ // Test invalid timezone abbreviation
+ var tz = NSTimeZone(abbreviation: "XXX")
+ XCTAssertNil(tz)
+ // Test valid timezone abbreviation of "AST" for "America/Halifax"
+ tz = NSTimeZone(abbreviation: "AST")
+ let expectedName = "America/Halifax"
+ XCTAssertEqual(tz?.name, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(tz?.name)\"")
+ }
+
func test_systemTimeZoneUsesSystemTime() {
tzset();
var t = time(nil)
diff --git a/TestFoundation/TestNSUUID.swift b/TestFoundation/TestNSUUID.swift
index 3fe75ce..1b0bf0f 100644
--- a/TestFoundation/TestNSUUID.swift
+++ b/TestFoundation/TestNSUUID.swift
@@ -52,9 +52,11 @@
XCTAssertEqual(uuid, NSUUID(UUIDBytes: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]), "The convenience initializer `init(UUIDBytes bytes:)` must return the Nil UUID when UUIDBytes is nil.")
}
+ // `UUIDString` should return an uppercase string
+ // See: https://bugs.swift.org/browse/SR-865
func test_UUIDString() {
let uuid = NSUUID(UUIDBytes: [0xe6,0x21,0xe1,0xf8,0xc3,0x6c,0x49,0x5a,0x93,0xfc,0x0c,0x24,0x7a,0x3e,0x6e,0x5f])
- XCTAssertEqual(uuid.UUIDString, "e621e1f8-c36c-495a-93fc-0c247a3e6e5f", "The UUIDString representation must be lowercase as defined by RFC 4122.")
+ XCTAssertEqual(uuid.UUIDString, "E621E1F8-C36C-495A-93FC-0C247A3E6E5F", "The UUIDString representation must be uppercase.")
}
func test_description() {