Skip to content

Commit ec9998f

Browse files
committed
Update test suite for lossless string conversion
1 parent ffe4eda commit ec9998f

34 files changed

+184
-161
lines changed

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,12 @@ public func checkStrideable<Instances : Collection, Strides : Collection>(
22152215
}
22162216
}
22172217

2218+
public func checkLosslessStringConvertible<Instance>(
2219+
_ instances: [Instance]
2220+
) where Instance : LosslessStringConvertible & Equatable {
2221+
expectEqualFunctionsForDomain(instances, { $0 }, { Instance(String($0))! })
2222+
}
2223+
22182224
public func nthIndex<C: Collection>(_ x: C, _ n: Int) -> C.Index {
22192225
return x.index(x.startIndex, offsetBy: numericCast(n))
22202226
}

stdlib/public/core/AnyHashable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ extension AnyHashable : Hashable {
151151

152152
extension AnyHashable : CustomStringConvertible {
153153
public var description: String {
154-
return String(base)
154+
return String(describing: base)
155155
}
156156
}
157157

stdlib/public/core/Character.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ public struct Character :
355355

356356
extension Character : CustomStringConvertible {
357357
public var description: String {
358-
return String(self)
358+
return String(describing: self)
359359
}
360360
}
361361

stdlib/public/core/FloatingPointParsing.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ internal func _isspace_clocale(_ u: UTF16.CodeUnit) -> Bool {
4242
% end
4343

4444
//===--- Parsing ----------------------------------------------------------===//
45-
extension ${Self} {
45+
extension ${Self} : LosslessStringConvertible {
4646
/// Construct from an ASCII representation.
4747
///
4848
/// Returns the result of calling the POSIX function

stdlib/public/core/OutputStream.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public protocol CustomStringConvertible {
171171
///
172172
/// The description property of a conforming type must be a value-preserving
173173
/// representation of the original value. As such, it should be possible to
174-
/// attempt to re-create an instance from its string representation.
174+
/// re-create an instance from its string representation.
175175
public protocol LosslessStringConvertible : CustomStringConvertible {
176176
/// Instantiates an instance of the conforming type from a string
177177
/// representation.

stdlib/public/core/String.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ extension String {
983983
}
984984

985985
/// Creates an instance from the description of a given
986-
/// LosslessStringConvertible instance.
986+
/// `LosslessStringConvertible` instance.
987987
public init<T : LosslessStringConvertible>(_ value: T) {
988988
self = value.description
989989
}

stdlib/public/core/UnicodeScalar.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,13 @@ public struct UnicodeScalar :
271271
}
272272

273273
extension UnicodeScalar : CustomStringConvertible, CustomDebugStringConvertible {
274-
/// An escaped textual representation of the Unicode scalar.
274+
/// A textual representation of the Unicode scalar.
275275
public var description: String {
276-
return String(value)
276+
return String._fromWellFormedCodeUnitSequence(
277+
UTF32.self,
278+
input: repeatElement(self.value, count: 1))
277279
}
280+
278281
/// An escaped textual representation of the Unicode scalar, suitable for
279282
/// debugging.
280283
public var debugDescription: String {
@@ -284,12 +287,11 @@ extension UnicodeScalar : CustomStringConvertible, CustomDebugStringConvertible
284287

285288
extension UnicodeScalar : LosslessStringConvertible {
286289
public init?(_ description: String) {
287-
if let v = UInt32(description) where (v < 0xD800 || v > 0xDFFF)
288-
&& v <= 0x10FFFF {
289-
self = UnicodeScalar(v)
290-
} else {
290+
let scalars = description.unicodeScalars
291+
guard let v = scalars.first, scalars.count == 1 else {
291292
return nil
292293
}
294+
self = v
293295
}
294296
}
295297

test/1_stdlib/Character.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SwiftPrivate
1414
//
1515
// These scalars should be "base characters" with regards to their position in
1616
// a grapheme cluster.
17-
let baseScalars = [
17+
let baseScalars: [UnicodeScalar] = [
1818
// U+0065 LATIN SMALL LETTER E
1919
"\u{0065}",
2020

@@ -54,7 +54,7 @@ let baseScalars = [
5454

5555
// Single Unicode scalars that are "continuing characters" with regards to
5656
// their position in a grapheme cluster.
57-
let continuingScalars = [
57+
let continuingScalars: [UnicodeScalar] = [
5858
// U+0300 COMBINING GRAVE ACCENT
5959
"\u{0300}",
6060

@@ -94,9 +94,9 @@ let testCharacters = [
9494

9595
func randomGraphemeCluster(_ minSize: Int, _ maxSize: Int) -> String {
9696
let n = pickRandom((minSize + 1)..<maxSize)
97-
var result = pickRandom(baseScalars)
97+
var result = String(pickRandom(baseScalars))
9898
for _ in 0..<n {
99-
result += pickRandom(continuingScalars)
99+
result += String(pickRandom(continuingScalars))
100100
}
101101
return result
102102
}
@@ -150,8 +150,8 @@ CharacterTests.test("sizeof") {
150150

151151
CharacterTests.test("Hashable") {
152152
for characters in [
153-
baseScalars,
154-
continuingScalars,
153+
baseScalars.map { String($0) },
154+
continuingScalars.map { String($0) },
155155
testCharacters
156156
] {
157157
for i in characters.indices {
@@ -197,8 +197,8 @@ func checkRepresentation(_ s: String) {
197197
CharacterTests.test("RoundTripping") {
198198
// Single Unicode Scalar Value tests
199199
for s in baseScalars {
200-
checkRepresentation(s)
201-
checkRoundTripThroughCharacter(s)
200+
checkRepresentation(String(s))
201+
checkRoundTripThroughCharacter(String(s))
202202
}
203203

204204
// Edge case tests
@@ -274,7 +274,7 @@ UnicodeScalarTests.test("UInt8(ascii: UnicodeScalar)/non-ASCII should trap")
274274
}
275275

276276
UnicodeScalarTests.test("UInt32(_: UnicodeScalar),UInt64(_: UnicodeScalar)") {
277-
for us in baseScalars.map({ $0.unicodeScalars.first! }) {
277+
for us in baseScalars {
278278
expectEqual(us.value, UInt32(us))
279279
expectEqual(UInt64(us.value), UInt64(us))
280280
}
@@ -304,5 +304,12 @@ UnicodeScalarTests.test("Comparable") {
304304
expectTrue("B" >= CharA)
305305
}
306306

307+
UnicodeScalarTests.test("LosslessStringConvertible") {
308+
// FIXME: these tests are insufficient.
309+
310+
checkLosslessStringConvertible((0xE000...0xF000).map { UnicodeScalar(Int($0))! })
311+
checkLosslessStringConvertible((0...127).map { UnicodeScalar(Int($0))! })
312+
}
313+
307314
runAllTests()
308315

test/1_stdlib/FloatingPoint.swift.gyb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,17 @@ FloatingPoint.test("${Self}.addingProduct") {
370370
let ulp = ${Self}.ulpOfOne
371371
expectEqual(ulp*ulp, one.addingProduct(ulp + one, ulp - one))
372372
}
373+
374+
FloatingPoint.test("${Self}/LosslessStringConvertible") {
375+
let instances = [
376+
1.0, -1.0,
377+
0.0, -0.0,
378+
${Self}.infinity, -${Self}.infinity
379+
]
380+
381+
checkLosslessStringConvertible(instances)
382+
expectTrue(Float(String(Float.nan))!.isNaN)
383+
}
373384
% if Self == 'Float80':
374385
#endif
375386
% end

test/1_stdlib/Inputs/PrintTestTypes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public struct MyString : ExpressibleByStringLiteral,
151151
}
152152

153153
public init<T>(stringInterpolationSegment expr: T) {
154-
self.init(str: "<segment " + String(expr) + ">")
154+
self.init(str: "<segment " + String(describing: expr) + ">")
155155
}
156156
}
157157

0 commit comments

Comments
 (0)