File: UnicodeScalarPropertiesTests.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (257 lines) | stat: -rw-r--r-- 12,167 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
// RUN: %target-run-simple-swift %t
// REQUIRES: executable_test
// UNSUPPORTED: freestanding

import StdlibUnittest

var UnicodeScalarPropertiesTests = TestSuite("UnicodeScalarPropertiesTests")

func us(_ scalar: Unicode.Scalar) -> Unicode.Scalar { return scalar }

UnicodeScalarPropertiesTests.test("properties.booleanProperties") {
  func expectBooleanProperty(
    _ keyPath: KeyPath<Unicode.Scalar.Properties, Bool>,
    trueFor trueScalar: Unicode.Scalar,
    falseFor falseScalar: Unicode.Scalar,
    _ message: String = "",
    file: String = #file,
    line: UInt = #line
  ) {
    expectTrue(
      trueScalar.properties[keyPath: keyPath], message, file: file, line: line)
    expectFalse(
      falseScalar.properties[keyPath: keyPath], message, file: file, line: line)
  }

  // Some soundness checks for basic properties. Not intended to be comprehensive.
  expectBooleanProperty(\.isAlphabetic, trueFor: "A", falseFor: "5")
  expectBooleanProperty(\.isASCIIHexDigit, trueFor: "F", falseFor: "G")
  // U+200E LEFT-TO-RIGHT MARK
  expectBooleanProperty(\.isBidiControl, trueFor: "\u{200E}", falseFor: "A")
  expectBooleanProperty(\.isBidiMirrored, trueFor: "(", falseFor: "A")
  expectBooleanProperty(\.isDash, trueFor: "-", falseFor: "A")
  // U+00AD SOFT HYPHEN
  expectBooleanProperty(\.isDefaultIgnorableCodePoint, trueFor: "\u{00AD}", falseFor: "A")
  // U+0149 LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
  expectBooleanProperty(\.isDeprecated, trueFor: "\u{0149}", falseFor: "A")
  expectBooleanProperty(\.isDiacritic, trueFor: "^", falseFor: "A")
  // U+00B7 MIDDLE DOT
  expectBooleanProperty(\.isExtender, trueFor: "\u{00B7}", falseFor: "A")
  // U+0340 COMBINING GRAVE TONE MARK
  expectBooleanProperty(\.isFullCompositionExclusion, trueFor: "\u{0340}", falseFor: "A")
  // U+0300 COMBINING GRAVE ACCENT
  expectBooleanProperty(\.isGraphemeBase, trueFor: "A", falseFor: "\u{0300}")
  expectBooleanProperty(\.isGraphemeExtend, trueFor: "\u{0300}", falseFor: "A")
  // U+FF21 FULLWIDTH LATIN CAPITAL LETTER A
  expectBooleanProperty(\.isHexDigit, trueFor: "\u{FF21}", falseFor: "G")
  expectBooleanProperty(\.isIDContinue, trueFor: "0", falseFor: "!")
  expectBooleanProperty(\.isIDStart, trueFor: "A", falseFor: "!")
  // U+3400 CJK UNIFIED IDEOGRAPH-3400
  expectBooleanProperty(\.isIdeographic, trueFor: "\u{3400}", falseFor: "A")
  // U+2FF0 IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT
  expectBooleanProperty(\.isIDSBinaryOperator, trueFor: "\u{2FF0}", falseFor: "A")
  // U+2FF2 IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT
  expectBooleanProperty(\.isIDSTrinaryOperator, trueFor: "\u{2FF2}", falseFor: "A")
  // U+200C ZERO WIDTH NON-JOINER
  expectBooleanProperty(\.isJoinControl, trueFor: "\u{200C}", falseFor: "A")
  // U+0E40 THAI CHARACTER SARA E
  expectBooleanProperty(\.isLogicalOrderException, trueFor: "\u{0E40}", falseFor: "A")
  expectBooleanProperty(\.isLowercase, trueFor: "a", falseFor: "A")
  expectBooleanProperty(\.isMath, trueFor: "+", falseFor: "A")
  expectBooleanProperty(\.isNoncharacterCodePoint, trueFor: Unicode.Scalar(0xFDD0)!, falseFor: "A")
  expectBooleanProperty(\.isQuotationMark, trueFor: "'", falseFor: "A")
  // U+2E80 CJK RADICAL REPEAT
  expectBooleanProperty(\.isRadical, trueFor: "\u{2E80}", falseFor: "A")
  expectBooleanProperty(\.isSoftDotted, trueFor: "i", falseFor: "A")
  expectBooleanProperty(\.isTerminalPunctuation, trueFor: "!", falseFor: "A")
  expectBooleanProperty(\.isUnifiedIdeograph, trueFor: "\u{3400}", falseFor: "A")
  expectBooleanProperty(\.isUppercase, trueFor: "A", falseFor: "a")
  expectBooleanProperty(\.isWhitespace, trueFor: " ", falseFor: "A")
  expectBooleanProperty(\.isXIDContinue, trueFor: "0", falseFor: "!")
  expectBooleanProperty(\.isXIDStart, trueFor: "A", falseFor: "!")
  expectBooleanProperty(\.isSentenceTerminal, trueFor: "!", falseFor: "A")
  // U+FE00 VARIATION SELECTOR-1
  expectBooleanProperty(\.isVariationSelector, trueFor: "\u{FE00}", falseFor: "A")
  expectBooleanProperty(\.isPatternSyntax, trueFor: "!", falseFor: "A")
  expectBooleanProperty(\.isPatternWhitespace, trueFor: " ", falseFor: "A")
  expectBooleanProperty(\.isCased, trueFor: "A", falseFor: "!")
  expectBooleanProperty(\.isCaseIgnorable, trueFor: "'", falseFor: "A")
  expectBooleanProperty(\.changesWhenLowercased, trueFor: "A", falseFor: "a")
  expectBooleanProperty(\.changesWhenUppercased, trueFor: "a", falseFor: "A")
  expectBooleanProperty(\.changesWhenTitlecased, trueFor: "a", falseFor: "A")
  expectBooleanProperty(\.changesWhenCaseFolded, trueFor: "A", falseFor: "!")
  expectBooleanProperty(\.changesWhenCaseMapped, trueFor: "A", falseFor: "!")
  expectBooleanProperty(\.changesWhenNFKCCaseFolded, trueFor: "A", falseFor: "!")

#if canImport(Darwin)
  if #available(macOS 10.12.2, iOS 10.2, tvOS 10.1, watchOS 3.1.1, *) {
    // U+2708 AIRPLANE
    expectBooleanProperty(\.isEmoji, trueFor: "\u{2708}", falseFor: "A")
    // U+231A WATCH
    expectBooleanProperty(
      \.isEmojiPresentation, trueFor: "\u{231A}", falseFor: "A")
    // U+1F3FD EMOJI MODIFIER FITZPATRICK TYPE-4
    expectBooleanProperty(
      \.isEmojiModifier, trueFor: "\u{1F3FD}", falseFor: "A")
    // U+270B RAISED HAND
    expectBooleanProperty(
      \.isEmojiModifierBase, trueFor: "\u{270B}", falseFor: "A")
  }
#endif
}

UnicodeScalarPropertiesTests.test("properties.lowercaseMapping") {
  expectEqual("2", us("2").properties.lowercaseMapping)
  expectEqual("i", us("I").properties.lowercaseMapping)
  expectEqual("i\u{0307}", us("\u{0130}").properties.lowercaseMapping)
  // There are currently no lowercase mappings that produce multiple graphemes.
}

UnicodeScalarPropertiesTests.test("uppercaseMapping") {
  expectEqual("2", us("2").properties.uppercaseMapping)
  expectEqual("I", us("i").properties.uppercaseMapping)
  expectEqual("\u{02BC}N", us("\u{0149}").properties.uppercaseMapping)  // multiple scalars
  expectEqual("SS", us("ß").properties.uppercaseMapping)  // multiple graphemes
  expectEqual("FFL", us("\u{FB04}").properties.uppercaseMapping)  // multiple graphemes
}

UnicodeScalarPropertiesTests.test("titlecaseMapping") {
  expectEqual("2", us("2").properties.titlecaseMapping)
  expectEqual("I", us("i").properties.titlecaseMapping)
  expectEqual("\u{02BC}N", us("\u{0149}").properties.titlecaseMapping)  // multiple scalars
  expectEqual("Ff", us("\u{FB00}").properties.titlecaseMapping)  // multiple graphemes
  expectEqual("Ffl", us("\u{FB04}").properties.titlecaseMapping)  // multiple graphemes
}

UnicodeScalarPropertiesTests.test("properties.name") {
  // A scalar with no assigned name returns nil.
  expectNil(us("\u{0000}").properties.name)

  // Try some results that should fit in small strings.
  expectEqual("CARE OF", us("\u{2105}").properties.name)
  expectEqual("ACCOUNT OF", us("\u{2100}").properties.name)

  // Try some results that need heap-allocated strings.
  expectEqual("LATIN SMALL LETTER A", us("\u{0061}").properties.name)
  expectEqual(
    "COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS",
    us("\u{20ED}").properties.name)
  expectEqual(
    "PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET",  // [sic]
    us("\u{FE18}").properties.name)

  // Try some boundary cases around the length limit of a SmallUTF8String.
  expectEqual("COMBINING HORN", us("\u{031B}").properties.name)  // 14
  expectEqual("COMBINING TILDE", us("\u{0303}").properties.name)  // 15
  expectEqual("COMBINING MACRON", us("\u{0304}").properties.name)  // 16
}

UnicodeScalarPropertiesTests.test("properties.nameAlias") {
  // A scalar with no assigned alias returns nil.
  expectNil(us("\u{0000}").properties.nameAlias)
  expectNil(us("\u{0040}").properties.nameAlias)

  // Try some aliases of varying lengths, getting some small and large string
  // coverage.
  expectEqual("LAO LETTER RO", us("\u{0EA3}").properties.nameAlias)
  expectEqual("MICR DASH SYMBOL", us("\u{2449}").properties.nameAlias)
  expectEqual(
    "PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRACKET",
    us("\u{FE18}").properties.nameAlias)
}

UnicodeScalarPropertiesTests.test("properties.age") {
  func expectAgeEqual(
    _ expected: (Int, Int),
    _ scalar: Unicode.Scalar,
    _ message: String = "",
    file: String = #file,
    line: UInt = #line
  ) {
    expectNotNil(scalar.properties.age, message, file: file, line: line)
    expectEqual(
      expected, scalar.properties.age!, message, file: file, line: line)
  }

  expectNil(us("\u{0378}").properties.age)
  expectAgeEqual((1, 1), "\u{0040}")
  expectAgeEqual((3, 0), "\u{3500}")
  expectAgeEqual((3, 2), "\u{FE00}")
  expectAgeEqual((6, 1), "\u{11180}")
}

UnicodeScalarPropertiesTests.test("properties.generalCategory") {
  expectEqual(.uppercaseLetter, us("A").properties.generalCategory)
  expectEqual(.lowercaseLetter, us("a").properties.generalCategory)
  // U+01C8 LATIN CAPITAL LETTER L WITH SMALL LETTER J
  expectEqual(.titlecaseLetter, us("\u{01C8}").properties.generalCategory)
  // U+02B0 MODIFIER LETTER SMALL H
  expectEqual(.modifierLetter, us("\u{02B0}").properties.generalCategory)
  // U+00AA FEMININE ORDINAL INDICATOR
  expectEqual(.otherLetter, us("\u{00AA}").properties.generalCategory)

  // U+0300 COMBINING GRAVE ACCENT
  expectEqual(.nonspacingMark, us("\u{0300}").properties.generalCategory)
  // U+20DD COMBINING ENCLOSING CIRCLE
  expectEqual(.enclosingMark, us("\u{20DD}").properties.generalCategory)

  expectEqual(.decimalNumber, us("0").properties.generalCategory)
  // U+2160 ROMAN NUMERAL ONE
  expectEqual(.letterNumber, us("\u{2160}").properties.generalCategory)
  // U+00B2 SUPERSCRIPT TWO
  expectEqual(.otherNumber, us("\u{00B2}").properties.generalCategory)

  expectEqual(.connectorPunctuation, us("_").properties.generalCategory)
  expectEqual(.dashPunctuation, us("-").properties.generalCategory)
  expectEqual(.openPunctuation, us("(").properties.generalCategory)
  expectEqual(.closePunctuation, us(")").properties.generalCategory)
  // U+201C LEFT DOUBLE QUOTATION MARK
  expectEqual(.initialPunctuation, us("\u{201C}").properties.generalCategory)
  // U+201D RIGHT DOUBLE QUOTATION MARK
  expectEqual(.finalPunctuation, us("\u{201D}").properties.generalCategory)
  expectEqual(.otherPunctuation, us("!").properties.generalCategory)

  expectEqual(.mathSymbol, us("+").properties.generalCategory)
  expectEqual(.currencySymbol, us("$").properties.generalCategory)
  expectEqual(.modifierSymbol, us("^").properties.generalCategory)
  // U+00AE REGISTERED SIGN
  expectEqual(.otherSymbol, us("\u{00AE}").properties.generalCategory)

  expectEqual(.spaceSeparator, us(" ").properties.generalCategory)
  // U+2028 LINE SEPARATOR
  expectEqual(.lineSeparator, us("\u{2028}").properties.generalCategory)
  // U+2029 PARAGRAPH SEPARATOR
  expectEqual(.paragraphSeparator, us("\u{2029}").properties.generalCategory)

  expectEqual(.control, us("\u{0000}").properties.generalCategory)
  // U+200B ZERO WIDTH SPACE
  expectEqual(.format, us("\u{200B}").properties.generalCategory)
  expectEqual(.privateUse, us("\u{E000}").properties.generalCategory)
  expectEqual(.unassigned, us("\u{FFFE}").properties.generalCategory)
  // .surrogate cannot be tested because Swift does not permit creating
  // Unicode.Scalars for code points U+D800-DFFF.
}

UnicodeScalarPropertiesTests.test("properties.canonicalCombiningClass") {
  expectEqual(.notReordered, us("A").properties.canonicalCombiningClass)
  expectEqual(.above, us("\u{0301}").properties.canonicalCombiningClass)
  expectEqual(.below, us("\u{0316}").properties.canonicalCombiningClass)
}

UnicodeScalarPropertiesTests.test("properties.numericTypeAndValue") {
  expectNil(us("X").properties.numericType)
  expectNil(us("X").properties.numericValue)

  expectEqual(.decimal, us("3").properties.numericType)
  expectEqual(3, us("3").properties.numericValue)

  // U+00BC VULGAR FRACTION ONE QUARTER
  expectEqual(.numeric, us("\u{00BC}").properties.numericType)
  expectEqual(0.25, us("\u{00BC}").properties.numericValue)

  // U+2463 CIRCLED DIGIT FOUR
  expectEqual(.digit, us("\u{2463}").properties.numericType)
  expectEqual(4, us("\u{2463}").properties.numericValue)
}

runAllTests()