Skip to content

[WIP] Implement NSRangeFromString #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Foundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
5BF7AEBF1BCD51F9008F214A /* NSURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4A1BCC5DCB00ED97BB /* NSURL.swift */; };
5BF7AEC01BCD51F9008F214A /* NSUUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4B1BCC5DCB00ED97BB /* NSUUID.swift */; };
5BF7AEC11BCD51F9008F214A /* NSValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4C1BCC5DCB00ED97BB /* NSValue.swift */; };
DCC7AF291C10DE57000417E3 /* TestNSRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC7AF271C10DE57000417E3 /* TestNSRange.swift */; };
EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */ = {isa = PBXBuildFile; fileRef = EA66F6351BEED03E00136161 /* TargetConditionals.h */; settings = {ATTRIBUTES = (Public, ); }; };
EA66F6441BF1619600136161 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA66F6381BF1619600136161 /* main.swift */; };
EA66F6481BF1619600136161 /* NSURLTestData.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA66F63B1BF1619600136161 /* NSURLTestData.plist */; };
Expand Down Expand Up @@ -503,6 +504,7 @@
5BDC3FCF1BCF17E600ED97BB /* NSCFSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCFSet.swift; sourceTree = "<group>"; };
5BDC405C1BD6D83B00ED97BB /* TestFoundation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestFoundation.app; sourceTree = BUILT_PRODUCTS_DIR; };
5BF7AEC21BCD568D008F214A /* ForSwiftFoundationOnly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForSwiftFoundationOnly.h; sourceTree = "<group>"; };
DCC7AF271C10DE57000417E3 /* TestNSRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSRange.swift; sourceTree = "<group>"; };
EA313DFC1BE7F2E90060A403 /* CFURLComponents_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFURLComponents_Internal.h; sourceTree = "<group>"; };
EA313DFD1BE7F2E90060A403 /* CFURLComponents_URIParser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLComponents_URIParser.c; sourceTree = "<group>"; };
EA313DFE1BE7F2E90060A403 /* CFURLComponents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLComponents.c; sourceTree = "<group>"; };
Expand Down Expand Up @@ -986,6 +988,7 @@
EA66F65A1BF1976100136161 /* Tests */ = {
isa = PBXGroup;
children = (
DCC7AF271C10DE57000417E3 /* TestNSRange.swift */,
EA66F63C1BF1619600136161 /* TestNSArray.swift */,
EA66F63D1BF1619600136161 /* TestNSDictionary.swift */,
EA66F63E1BF1619600136161 /* TestNSIndexSet.swift */,
Expand Down Expand Up @@ -1678,6 +1681,7 @@
files = (
525AECED1BF2C9C500D15BB0 /* TestNSFileManager.swift in Sources */,
EA66F6501BF1619600136161 /* TestNSNumber.swift in Sources */,
DCC7AF291C10DE57000417E3 /* TestNSRange.swift in Sources */,
EA66F6521BF1619600136161 /* TestNSPropertyList.swift in Sources */,
EA66F64E1BF1619600136161 /* TestNSIndexSet.swift in Sources */,
EA66F6541BF1619600136161 /* TestNSSet.swift in Sources */,
Expand Down
28 changes: 26 additions & 2 deletions Foundation/NSRange.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,29 @@ public func NSStringFromRange(range: NSRange) -> String {
}

public func NSRangeFromString(aString: String) -> NSRange {
NSUnimplemented()
}
// just by playing around in the REPL, it looks like
// NSRangeFromString just walks through the string finding
// all integers in order, defaulting to 0 if they're not found.
return NSRangeParser.parseRange(aString)
}

struct NSRangeParser {
// removes all characters that are not decimal digits and commas.
static let decimalDigitsAndCommas: NSCharacterSet = {
let characterSet = NSMutableCharacterSet(bitmapRepresentation: NSCharacterSet.decimalDigitCharacterSet().bitmapRepresentation)
characterSet.addCharactersInString(",")
return characterSet.invertedSet
}()
static func parseRange(string: String) -> NSRange {
var final = NSRange(location: 0, length: 0)
let removeNonDigits = (string as NSString)
.componentsSeparatedByCharactersInSet(NSRangeParser.decimalDigitsAndCommas)
.joinWithSeparator("")
let ints = removeNonDigits.componentsSeparatedByString(",").flatMap { Int($0) }
guard let location = ints.first else { return final }
final.location = location
guard let length = ints.dropFirst().first else { return final }
final.length = length
return final
}
}
32 changes: 30 additions & 2 deletions Foundation/NSString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -630,11 +630,39 @@ extension NSString {
}

public func componentsSeparatedByString(separator: String) -> [String] {
NSUnimplemented()
let sepLength = separator.characters.count
var previousSplit = 0
var components = [String]()
for i in (0..<self.length) {
let range = NSRange(location: i, length: sepLength)
if self.substringWithRange(range) == separator {
let componentRange = NSRange(location: previousSplit, length: i - previousSplit)
let substr = self.substringWithRange(componentRange)
components.append(substr)
previousSplit = i + 1
}
if (self.length - i) <= sepLength {
components.append(self.substringFromIndex(i))
break
}
}
return components
}

public func componentsSeparatedByCharactersInSet(separator: NSCharacterSet) -> [String] {
NSUnimplemented()
let worker = self as String
var components = [String]()
var current = ""
for scalar in worker.unicodeScalars {
if separator.characterIsMember(unichar(unicodeScalarLiteral: scalar)) {
components.append(current)
current = ""
} else {
current.append(scalar)
}
}
components.append(current)
return components
}

public func stringByTrimmingCharactersInSet(set: NSCharacterSet) -> String {
Expand Down
51 changes: 51 additions & 0 deletions TestFoundation/TestNSRange.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// TestNSRange.swift
// Foundation
//
// Created by Harlan Haskins on 12/3/15.
// Copyright © 2015 Apple. All rights reserved.
//

#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
import Foundation
import XCTest
#else
import SwiftFoundation
import SwiftXCTest
#endif

extension NSRange: Equatable {}

public func ==(lhs: NSRange, rhs: NSRange) -> Bool {
return lhs.location == rhs.location && lhs.length == rhs.length
}

class TestNSRange: XCTestCase {

var allTests: [(String, () -> ())] {
return [
("test_rangeWithValidInput", test_rangeWithValidInput),
("test_rangesWithInvalidInput", test_rangesWithInvalidInput),
("test_roundTrip", test_roundTrip)
]
}

func test_rangeWithValidInput() {
let practice = NSRangeFromString("{4,5}")
XCTAssertEqual(practice, NSRange(location: 4, length: 5))
}

func test_rangesWithInvalidInput() {
XCTAssertEqual(NSRangeFromString("4,5}"), NSRange(location: 4, length: 5))
XCTAssertEqual(NSRangeFromString("{4,5"), NSRange(location: 4, length: 5))
XCTAssertEqual(NSRangeFromString("{4,}"), NSRange(location: 4, length: 0))
XCTAssertEqual(NSRangeFromString(",4}"), NSRange(location: 4, length: 0))
XCTAssertEqual(NSRangeFromString("4,5"), NSRange(location: 4, length: 5))
}

func test_roundTrip() {
let initial = NSRange(location: 4, length: 5)
XCTAssertEqual(NSRangeFromString(NSStringFromRange(initial)), initial)
}

}
2 changes: 1 addition & 1 deletion TestFoundation/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ internal func testBundle() -> NSBundle {
}

// For the Swift version of the Foundation tests, we must manually list all test cases here.
XCTMain([TestNSString(), TestNSArray(), TestNSDictionary(), TestNSSet(), TestNSNumber(), TestNSPropertyList(), TestNSURL(), TestNSIndexSet(), TestNSCharacterSet(), TestNSFileManger()])
XCTMain([TestNSString(), TestNSArray(), TestNSDictionary(), TestNSSet(), TestNSNumber(), TestNSPropertyList(), TestNSURL(), TestNSIndexSet(), TestNSCharacterSet(), TestNSFileManger(), TestNSRange()])