@@ -21,11 +21,11 @@ import Testing
2121@Suite ( " BuiltInUnicodeScalarSet " )
2222private struct BuiltInUnicodeScalarSetTests {
2323
24- @Test func membership( ) {
25- func setContainsScalar( _ set: BuiltInUnicodeScalarSet , _ scalar: Unicode . Scalar , _ expect: Bool , sourceLocation: SourceLocation = #_sourceLocation) {
26- #expect( set. contains ( scalar) == expect, sourceLocation: sourceLocation)
27- }
24+ func setContainsScalar( _ set: BuiltInUnicodeScalarSet , _ scalar: Unicode . Scalar , _ expect: Bool , sourceLocation: SourceLocation = #_sourceLocation) {
25+ #expect( set. contains ( scalar) == expect, sourceLocation: sourceLocation)
26+ }
2827
28+ @Test func membership( ) {
2929 setContainsScalar ( . lowercaseLetters, " a " , true )
3030 setContainsScalar ( . lowercaseLetters, " ô " , true )
3131 setContainsScalar ( . lowercaseLetters, " \u{01FB} " , true )
@@ -56,4 +56,109 @@ private struct BuiltInUnicodeScalarSetTests {
5656 setContainsScalar ( . graphemeExtends, " ~ " , false )
5757 }
5858
59+ @Test func bmpMembership( ) {
60+ setContainsScalar ( . uppercaseLetters, " \u{FFFF} " , false )
61+ setContainsScalar ( . lowercaseLetters, " \u{FFFF} " , false )
62+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . letter) , " \u{FFFF} " , false )
63+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . alphanumeric) , " \u{FFFF} " , false )
64+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . decimalDigit) , " \u{FFFF} " , false )
65+ }
66+
67+ @Test func nonBMPMembership( ) {
68+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . letter) , " \u{10000} " , true ) // LINEAR B SYLLABLE B008 A
69+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . alphanumeric) , " \u{10000} " , true ) // LINEAR B SYLLABLE B008 A
70+ setContainsScalar ( . uppercaseLetters, " \u{10000} " , false )
71+ setContainsScalar ( . lowercaseLetters, " \u{10000} " , false )
72+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . decimalDigit) , " \u{10000} " , false )
73+ }
74+
75+ @Test func illegalSetMembership( ) {
76+ let illegal = BuiltInUnicodeScalarSet ( type: . illegal)
77+ setContainsScalar ( illegal, " A " , false )
78+ setContainsScalar ( illegal, " 0 " , false )
79+ setContainsScalar ( illegal, " a " , false )
80+ setContainsScalar ( illegal, " \u{E0001} " , false ) // LANGUAGE TAG
81+ setContainsScalar ( illegal, " \u{E0020} " , false ) // TAG SPACE
82+ setContainsScalar ( illegal, " \u{E007F} " , false ) // CANCEL TAG
83+ setContainsScalar ( illegal, " \u{E0000} " , true )
84+ }
85+
86+ @Test func controlAndFormatterSetMembership( ) {
87+ let controlAndFormatter = BuiltInUnicodeScalarSet ( type: . controlAndFormatter)
88+ setContainsScalar ( controlAndFormatter, " \u{0001} " , true ) // START OF HEADING
89+ setContainsScalar ( controlAndFormatter, " \u{0007} " , true ) // BELL
90+ setContainsScalar ( controlAndFormatter, " \u{200B} " , true ) // ZERO WIDTH SPACE
91+ setContainsScalar ( controlAndFormatter, " a " , false )
92+ setContainsScalar ( controlAndFormatter, " 0 " , false )
93+ setContainsScalar ( controlAndFormatter, " \u{E0001} " , true ) // LANGUAGE TAG
94+ setContainsScalar ( controlAndFormatter, " \u{E0020} " , true ) // TAG SPACE
95+ setContainsScalar ( controlAndFormatter, " \u{E007F} " , true ) // CANCEL TAG
96+ setContainsScalar ( controlAndFormatter, " \u{E0000} " , false )
97+ }
98+
99+ @Test func whitespaceSetMembership( ) {
100+ let whitespace = BuiltInUnicodeScalarSet ( type: . whitespace)
101+ setContainsScalar ( whitespace, " " , true )
102+ setContainsScalar ( whitespace, " \u{0009} " , true ) // CHARACTER TABULATION
103+ setContainsScalar ( whitespace, " \u{00A0} " , true ) // NO-BREAK SPACE
104+ setContainsScalar ( whitespace, " \u{1680} " , true ) // OGHAM SPACE MARK
105+ setContainsScalar ( whitespace, " \u{2000} " , true ) // EN QUAD
106+ setContainsScalar ( whitespace, " \u{200B} " , true ) // ZERO WIDTH SPACE
107+ setContainsScalar ( whitespace, " \u{202F} " , true ) // NARROW NO-BREAK SPACE
108+ setContainsScalar ( whitespace, " \u{205F} " , true ) // MEDIUM MATHEMATICAL SPACE
109+ setContainsScalar ( whitespace, " \u{3000} " , true ) // IDEOGRAPHIC SPACE
110+ setContainsScalar ( whitespace, " \u{000A} " , false ) // LINE FEED
111+ setContainsScalar ( whitespace, " a " , false )
112+ }
113+
114+ @Test func newlineSetMembership( ) {
115+ let newline = BuiltInUnicodeScalarSet ( type: . newline)
116+ setContainsScalar ( newline, " \u{000A} " , true ) // LINE FEED
117+ setContainsScalar ( newline, " \u{000B} " , true ) // LINE TABULATION
118+ setContainsScalar ( newline, " \u{000C} " , true ) // FORM FEED
119+ setContainsScalar ( newline, " \u{000D} " , true ) // CARRIAGE RETURN
120+ setContainsScalar ( newline, " \u{0085} " , true ) // NEXT LINE
121+ setContainsScalar ( newline, " \u{2028} " , true ) // LINE SEPARATOR
122+ setContainsScalar ( newline, " \u{2029} " , true ) // PARAGRAPH SEPARATOR
123+ setContainsScalar ( newline, " " , false )
124+ setContainsScalar ( newline, " a " , false )
125+ }
126+
127+ @Test func whitespaceAndNewlineSetMembership( ) {
128+ let whitespaceAndNewline = BuiltInUnicodeScalarSet ( type: . whitespaceAndNewline)
129+ setContainsScalar ( whitespaceAndNewline, " " , true )
130+ setContainsScalar ( whitespaceAndNewline, " \u{000A} " , true ) // LINE FEED
131+ setContainsScalar ( whitespaceAndNewline, " \u{2028} " , true ) // LINE SEPARATOR
132+ setContainsScalar ( whitespaceAndNewline, " \u{3000} " , true ) // IDEOGRAPHIC SPACE
133+ setContainsScalar ( whitespaceAndNewline, " a " , false )
134+ }
135+
136+ @Test func unsupportedNonBMPPlaneMembership( ) {
137+ setContainsScalar ( . uppercaseLetters, " \u{D0000} " , false )
138+ setContainsScalar ( . lowercaseLetters, " \u{D0000} " , false )
139+ setContainsScalar ( BuiltInUnicodeScalarSet ( type: . decimalDigit) , " \u{D0000} " , false )
140+ }
141+
142+ @Test func illegalSetUnsupportedNonBMPNonSpecialPlaneMembership( ) {
143+ let illegal = BuiltInUnicodeScalarSet ( type: . illegal)
144+ setContainsScalar ( illegal, " \u{10000} " , false ) // LINEAR B SYLLABLE B008 A
145+ setContainsScalar ( illegal, " \u{1D7CF} " , false ) // MATHEMATICAL BOLD DIGIT ZERO
146+ setContainsScalar ( illegal, " \u{D0000} " , false )
147+ }
148+
149+ @Test func illegalSetUnsupportedPlane15 And16 Membership( ) {
150+ let illegal = BuiltInUnicodeScalarSet ( type: . illegal)
151+ setContainsScalar ( illegal, " \u{F0000} " , false )
152+ setContainsScalar ( illegal, " \u{FFFFE} " , false )
153+ setContainsScalar ( illegal, " \u{100000} " , false )
154+ setContainsScalar ( illegal, " \u{10FFFD} " , false )
155+ }
156+
157+ @Test func controlAndFormatterSetUnsupportedNonBMPNonPlane14 ( ) {
158+ let controlAndFormatter = BuiltInUnicodeScalarSet ( type: . controlAndFormatter)
159+ setContainsScalar ( controlAndFormatter, " \u{10000} " , false ) // LINEAR B SYLLABLE B008 A
160+ setContainsScalar ( controlAndFormatter, " \u{1D7CF} " , false ) // MATHEMATICAL BOLD DIGIT ZERO
161+ setContainsScalar ( controlAndFormatter, " \u{D0000} " , false )
162+ }
163+
59164}
0 commit comments