Skip to content

Commit 41db69e

Browse files
authored
Merge pull request #1127 from bubski/codable
2 parents 79322e9 + 7a93797 commit 41db69e

File tree

3 files changed

+115
-19
lines changed

3 files changed

+115
-19
lines changed

Foundation/CharacterSet.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ internal final class _SwiftNSCharacterSet : NSCharacterSet, _SwiftNativeFoundati
9494
override func isSuperset(of other: CharacterSet) -> Bool {
9595
return _mapUnmanaged { $0.isSuperset(of: other) }
9696
}
97+
98+
override var _cfObject: CFType {
99+
// We cannot inherit super's unsafeBitCast(self, to: CFType.self) here, because layout of _SwiftNSCharacterSet
100+
// is not compatible with CFCharacterSet. We need to bitcast the underlying NSCharacterSet instead.
101+
return _mapUnmanaged { unsafeBitCast($0, to: CFType.self) }
102+
}
97103
}
98104

99105
/**
@@ -469,7 +475,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
469475

470476
/// Returns true if the two `CharacterSet`s are equal.
471477
public static func ==(lhs : CharacterSet, rhs: CharacterSet) -> Bool {
472-
return lhs._wrapped.isEqual(rhs._bridgeToObjectiveC()) // TODO: mlehew - as NSCharacterSet
478+
return lhs._mapUnmanaged { $0.isEqual(rhs) }
473479
}
474480
}
475481

@@ -503,3 +509,20 @@ extension CharacterSet : _ObjectTypeBridgeable {
503509
}
504510

505511
}
512+
513+
extension CharacterSet : Codable {
514+
private enum CodingKeys : Int, CodingKey {
515+
case bitmap
516+
}
517+
518+
public init(from decoder: Decoder) throws {
519+
let container = try decoder.container(keyedBy: CodingKeys.self)
520+
let bitmap = try container.decode(Data.self, forKey: .bitmap)
521+
self.init(bitmapRepresentation: bitmap)
522+
}
523+
524+
public func encode(to encoder: Encoder) throws {
525+
var container = encoder.container(keyedBy: CodingKeys.self)
526+
try container.encode(self.bitmapRepresentation, forKey: .bitmap)
527+
}
528+
}

TestFoundation/TestCodable.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,32 @@ class TestCodable : XCTestCase {
268268
expectRoundTripEqualityThroughJSON(for: rect)
269269
}
270270
}
271+
272+
// MARK: - CharacterSet
273+
lazy var characterSetValues: [CharacterSet] = [
274+
CharacterSet.controlCharacters,
275+
CharacterSet.whitespaces,
276+
CharacterSet.whitespacesAndNewlines,
277+
CharacterSet.decimalDigits,
278+
CharacterSet.letters,
279+
CharacterSet.lowercaseLetters,
280+
CharacterSet.uppercaseLetters,
281+
CharacterSet.nonBaseCharacters,
282+
CharacterSet.alphanumerics,
283+
CharacterSet.decomposables,
284+
CharacterSet.illegalCharacters,
285+
CharacterSet.punctuationCharacters,
286+
CharacterSet.capitalizedLetters,
287+
CharacterSet.symbols,
288+
CharacterSet.newlines,
289+
CharacterSet(charactersIn: "abcd")
290+
]
291+
292+
func test_CharacterSet_JSON() {
293+
for characterSet in characterSetValues {
294+
expectRoundTripEqualityThroughJSON(for: characterSet)
295+
}
296+
}
271297

272298
}
273299

@@ -286,6 +312,7 @@ extension TestCodable {
286312
("test_CGPoint_JSON", test_CGPoint_JSON),
287313
("test_CGSize_JSON", test_CGSize_JSON),
288314
("test_CGRect_JSON", test_CGRect_JSON),
315+
("test_CharacterSet_JSON", test_CharacterSet_JSON),
289316
]
290317
}
291318
}

TestFoundation/TestNSCharacterSet.swift

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// This source file is part of the Swift.org open source project
1+
// This source file is part of the Swift.org open source project
22
//
33
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
44
// Licensed under Apache License v2.0 with Runtime Library Exception
@@ -7,8 +7,6 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10-
11-
1210
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
1311
import Foundation
1412
import XCTest
@@ -17,7 +15,47 @@ import SwiftFoundation
1715
import SwiftXCTest
1816
#endif
1917

18+
private struct Box: Equatable {
19+
private let ns: NSCharacterSet
20+
private let swift: CharacterSet
21+
22+
private init(ns: NSCharacterSet, swift: CharacterSet) {
23+
self.ns = ns
24+
self.swift = swift
25+
}
26+
27+
init(charactersIn string: String) {
28+
self.ns = NSCharacterSet(charactersIn: string)
29+
self.swift = CharacterSet(charactersIn: string)
30+
}
31+
32+
static var alphanumerics: Box {
33+
return Box(ns: NSCharacterSet.alphanumerics._bridgeToObjectiveC(),
34+
swift: CharacterSet.alphanumerics)
35+
}
36+
37+
static var decimalDigits: Box {
38+
return Box(ns: NSCharacterSet.decimalDigits._bridgeToObjectiveC(),
39+
swift: CharacterSet.decimalDigits)
40+
}
2041

42+
// MARK: Equatable
43+
44+
static func ==(lhs: Box, rhs: Box) -> Bool {
45+
return lhs.ns == rhs.ns
46+
&& lhs.swift == rhs.swift
47+
&& lhs.ns._bridgeToSwift() == rhs.ns._bridgeToSwift()
48+
&& lhs.swift._bridgeToObjectiveC() == rhs.swift._bridgeToObjectiveC()
49+
&& lhs.ns.isEqual(rhs.ns)
50+
&& lhs.ns.isEqual(rhs.swift)
51+
&& lhs.ns.isEqual(rhs.ns._bridgeToSwift())
52+
&& lhs.ns.isEqual(rhs.swift._bridgeToObjectiveC())
53+
&& lhs.swift._bridgeToObjectiveC().isEqual(rhs.ns)
54+
&& lhs.swift._bridgeToObjectiveC().isEqual(rhs.swift)
55+
&& lhs.swift._bridgeToObjectiveC().isEqual(rhs.ns._bridgeToSwift())
56+
&& lhs.swift._bridgeToObjectiveC().isEqual(rhs.swift._bridgeToObjectiveC())
57+
}
58+
}
2159

2260
class TestNSCharacterSet : XCTestCase {
2361

@@ -283,28 +321,36 @@ class TestNSCharacterSet : XCTestCase {
283321
let expected = CharacterSet(charactersIn: "abc")
284322
XCTAssertEqual(expected, symmetricDifference)
285323
}
286-
324+
287325
func test_Equatable() {
288-
XCTAssertEqual(NSCharacterSet(charactersIn: ""), NSCharacterSet(charactersIn: ""))
289-
XCTAssertEqual(NSCharacterSet(charactersIn: "a"), NSCharacterSet(charactersIn: "a"))
290-
XCTAssertEqual(NSCharacterSet(charactersIn: "ab"), NSCharacterSet(charactersIn: "ab"))
291-
292-
XCTAssertNotEqual(NSCharacterSet(charactersIn: "abc"), NSCharacterSet(charactersIn: "123"))
293-
XCTAssertNotEqual(NSCharacterSet(charactersIn: "123"), NSCharacterSet(charactersIn: "abc"))
294-
295-
XCTAssertNotEqual(NSCharacterSet(charactersIn: ""), nil)
296-
326+
let equalPairs = [
327+
("", ""),
328+
("a", "a"),
329+
("abcde", "abcde"),
330+
("12345", "12345")
331+
]
332+
297333
/*
298334
Tests disabled due to CoreFoundation bug?
299335
These NSCharacterSet pairs are (wrongly?) evaluated to be equal. Same behaviour can be observed on macOS 10.12.
300336
Interestingly, on iOS 11 Simulator, they are evaluted to be _not_ equal,
301337
while on iOS 10.3.1 Simulator, they are evaluted to be equal.
302338
*/
303-
// XCTAssertNotEqual(NSCharacterSet(charactersIn: "ab"), NSCharacterSet(charactersIn: "abc"))
304-
// XCTAssertNotEqual(NSCharacterSet(charactersIn: "abc"), NSCharacterSet(charactersIn: "ab"))
305-
// XCTAssertNotEqual(NSCharacterSet(charactersIn: "abc"), NSCharacterSet(charactersIn: ""))
306-
// XCTAssertNotEqual(NSCharacterSet(charactersIn: ""), NSCharacterSet(charactersIn: "abc"))
339+
let notEqualPairs = [
340+
("abc", "123"),
341+
// ("ab", "abc"),
342+
// ("abc", "")
343+
]
344+
345+
for pair in equalPairs {
346+
XCTAssertEqual(Box(charactersIn: pair.0), Box(charactersIn: pair.1))
347+
}
348+
XCTAssertEqual(Box.alphanumerics, Box.alphanumerics)
349+
350+
for pair in notEqualPairs {
351+
XCTAssertNotEqual(Box(charactersIn: pair.0), Box(charactersIn: pair.1))
352+
}
353+
XCTAssertNotEqual(Box.alphanumerics, Box.decimalDigits)
307354
}
308355

309356
}
310-

0 commit comments

Comments
 (0)