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()
|