Skip to content

Commit 03d534c

Browse files
eyeplumparkera
authored andcommitted
Implement basic initializers of NSAttributedString (#297)
* Implement basic initializers of NSAttributedString The implementation is based on CFAttributedString * Add a missing test to the test suit `test_initWithAttributedString` was not included in TestNSAttributedString.allTests previously * Change style to indicate the has-a relationship These changes are following The Design Principles documentation: https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Design.md * Make `_cfAttributedString` nonnull
1 parent 9f4651a commit 03d534c

File tree

4 files changed

+101
-5
lines changed

4 files changed

+101
-5
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0B6439E01CA192FC0019CB56 /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B6439DF1CA192FC0019CB56 /* TestNSAttributedString.swift */; };
1011
2EBE67A51C77BF0E006583D5 /* TestNSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */; };
1112
528776141BF2629700CB0090 /* FoundationErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522C253A1BF16E1600804FC6 /* FoundationErrors.swift */; };
1213
528776191BF27D9500CB0090 /* Test.plist in Resources */ = {isa = PBXBuildFile; fileRef = 528776181BF27D9500CB0090 /* Test.plist */; };
@@ -384,6 +385,7 @@
384385
/* End PBXCopyFilesBuildPhase section */
385386

386387
/* Begin PBXFileReference section */
388+
0B6439DF1CA192FC0019CB56 /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
387389
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDate.swift; sourceTree = "<group>"; };
388390
2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDateFormatter.swift; sourceTree = "<group>"; };
389391
400E22641C1A4E58007C5933 /* TestNSProcessInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSProcessInfo.swift; sourceTree = "<group>"; };
@@ -1162,6 +1164,7 @@
11621164
children = (
11631165
C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */,
11641166
EA66F63C1BF1619600136161 /* TestNSArray.swift */,
1167+
0B6439DF1CA192FC0019CB56 /* TestNSAttributedString.swift */,
11651168
6E203B8C1C1303BB003B2576 /* TestNSBundle.swift */,
11661169
A5A34B551C18C85D00FD972B /* TestNSByteCountFormatter.swift */,
11671170
52829AD61C160D64003BC4EF /* TestNSCalendar.swift */,
@@ -1989,6 +1992,7 @@
19891992
5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
19901993
5B13B3311C582D4C00651CE2 /* TestNSIndexPath.swift in Sources */,
19911994
5B13B3271C582D4C00651CE2 /* TestNSArray.swift in Sources */,
1995+
0B6439E01CA192FC0019CB56 /* TestNSAttributedString.swift in Sources */,
19921996
5B13B3461C582D4C00651CE2 /* TestNSTask.swift in Sources */,
19931997
555683BD1C1250E70041D4C6 /* TestNSUserDefaults.swift in Sources */,
19941998
7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */,

Foundation/NSAttributedString.swift

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10+
import CoreFoundation
1011

1112
public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
1213

14+
private var _cfAttributedString: CFAttributedString
15+
16+
internal init(cfObject: CFAttributedString) {
17+
_cfAttributedString = cfObject
18+
}
19+
1320
public required init?(coder aDecoder: NSCoder) {
1421
NSUnimplemented()
1522
}
@@ -38,10 +45,16 @@ public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecur
3845
NSUnimplemented()
3946
}
4047

41-
public var string: String { NSUnimplemented() }
48+
public var string: String {
49+
return CFAttributedStringGetString(_cfAttributedString)._swiftObject
50+
}
51+
4252
public func attributesAtIndex(_ location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] { NSUnimplemented() }
4353

44-
public var length: Int { NSUnimplemented() }
54+
public var length: Int {
55+
return CFAttributedStringGetLength(_cfAttributedString)
56+
}
57+
4558
public func attribute(_ attrName: String, atIndex location: Int, effectiveRange range: NSRangePointer) -> AnyObject? { NSUnimplemented() }
4659
public func attributedSubstringFromRange(_ range: NSRange) -> NSAttributedString { NSUnimplemented() }
4760

@@ -50,9 +63,20 @@ public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecur
5063

5164
public func isEqualToAttributedString(_ other: NSAttributedString) -> Bool { NSUnimplemented() }
5265

53-
public init(string str: String) { NSUnimplemented() }
54-
public init(string str: String, attributes attrs: [String : AnyObject]?) { NSUnimplemented() }
55-
public init(attributedString attrStr: NSAttributedString) { NSUnimplemented() }
66+
public init(string str: String) {
67+
_cfAttributedString = CFAttributedStringCreate(kCFAllocatorDefault, str._cfObject, nil)
68+
super.init()
69+
}
70+
71+
public init(string str: String, attributes attrs: [String : AnyObject]?) {
72+
_cfAttributedString = CFAttributedStringCreate(kCFAllocatorDefault, str._cfObject, attrs?._cfObject)
73+
super.init()
74+
}
75+
76+
public init(attributedString attrStr: NSAttributedString) {
77+
_cfAttributedString = CFAttributedStringCreateCopy(kCFAllocatorDefault, attrStr._cfAttributedString)
78+
super.init()
79+
}
5680

5781
public func enumerateAttributesInRange(_ enumerationRange: NSRange, options opts: NSAttributedStringEnumerationOptions, usingBlock block: ([String : AnyObject], NSRange, UnsafeMutablePointer<ObjCBool>) -> Void) { NSUnimplemented() }
5882
public func enumerateAttribute(_ attrName: String, inRange enumerationRange: NSRange, options opts: NSAttributedStringEnumerationOptions, usingBlock block: (AnyObject?, NSRange, UnsafeMutablePointer<ObjCBool>) -> Void) { NSUnimplemented() }
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
11+
12+
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
13+
import Foundation
14+
import XCTest
15+
#else
16+
import SwiftFoundation
17+
import SwiftXCTest
18+
#endif
19+
20+
21+
22+
class TestNSAttributedString: XCTestCase {
23+
24+
static var allTests: [(String, TestNSAttributedString -> () throws -> Void)] {
25+
return [
26+
("test_initWithSimpleString", test_initWithSimpleString),
27+
("test_initWithComplexString", test_initWithComplexString),
28+
("test_initWithSimpleStringAndAttributes", test_initWithSimpleStringAndAttributes),
29+
("test_initWithAttributedString", test_initWithAttributedString),
30+
]
31+
}
32+
33+
func test_initWithSimpleString() {
34+
let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
35+
let attrString = NSAttributedString(string: string)
36+
XCTAssertEqual(attrString.string, string)
37+
XCTAssertEqual(attrString.length, string.utf16Count)
38+
}
39+
40+
func test_initWithComplexString() {
41+
let string = "Lorem 😀 ipsum dolor sit amet, consectetur adipiscing elit. ⌘ Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit. ಠ_ರೃ"
42+
let attrString = NSAttributedString(string: string)
43+
XCTAssertEqual(attrString.string, string)
44+
XCTAssertEqual(attrString.length, string.utf16Count)
45+
}
46+
47+
func test_initWithSimpleStringAndAttributes() {
48+
let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
49+
let attributes: [String : AnyObject] = ["attribute.placeholder.key" : "attribute.placeholder.value" as NSString]
50+
51+
let attrString = NSAttributedString(string: string, attributes: attributes)
52+
XCTAssertEqual(attrString.string, string)
53+
XCTAssertEqual(attrString.length, string.utf16Count)
54+
55+
// TODO: None of the attributes retrival methods is implemented, as a result attributes can't be tested yet.
56+
}
57+
58+
func test_initWithAttributedString() {
59+
let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
60+
let attrString = NSAttributedString(string: string)
61+
let newAttrString = NSAttributedString(attributedString: attrString)
62+
63+
// FIXME: Should use `isEqualToAttributedString:` instead after it's implemented
64+
XCTAssertEqual(attrString.string, newAttrString.string)
65+
}
66+
67+
}

TestFoundation/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal func testBundle() -> NSBundle {
2323
XCTMain([
2424
testCase(TestNSAffineTransform.allTests),
2525
testCase(TestNSArray.allTests),
26+
testCase(TestNSAttributedString.allTests),
2627
testCase(TestNSBundle.allTests),
2728
testCase(TestNSByteCountFormatter.allTests),
2829
testCase(TestNSCalendar.allTests),

0 commit comments

Comments
 (0)