Skip to content

Commit 2e47be7

Browse files
uros-dbMaxGekk
authored andcommitted
[SPARK-49213][SQL][TESTS] Add collation support unit tests for comparison and equality
### What changes were proposed in this pull request? Add collation support unit tests for: - comparison - equality check This PR contains test-only changes, providing additional test coverage for cases such as: - case and accent variation - one-to-many case mapping - conditional case mapping - surrogate pairs - etc. ### Why are the changes needed? Improve collation support testing. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? New unit tests in `CollationSupportSuite`. ### Was this patch authored or co-authored using generative AI tooling? Yes. Closes #47725 from uros-db/unit-tests-1. Authored-by: Uros Bojanic <157381213+uros-db@users.noreply.github.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
1 parent 5166cb3 commit 2e47be7

File tree

1 file changed

+176
-119
lines changed

1 file changed

+176
-119
lines changed

common/unsafe/src/test/java/org/apache/spark/unsafe/types/CollationSupportSuite.java

Lines changed: 176 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -40,157 +40,214 @@ public class CollationSupportSuite {
4040
{"UTF8_BINARY", "UTF8_LCASE", "UNICODE", "UNICODE_CI"};
4141

4242
/**
43-
* Collation-aware UTF8String comparison.
43+
* Collation-aware UTF8String comparison and equality check.
4444
*/
4545

46-
private void assertStringCompare(String s1, String s2, String collationName, int expected)
46+
private void assertCompare(String s1, String s2, String collationName, int expected)
4747
throws SparkException {
4848
UTF8String l = UTF8String.fromString(s1);
4949
UTF8String r = UTF8String.fromString(s2);
50+
// Test the comparator, which is the most general way to compare strings with collations.
5051
int compare = CollationFactory.fetchCollation(collationName).comparator.compare(l, r);
5152
assertEquals(Integer.signum(expected), Integer.signum(compare));
53+
// Test the equals function, which may be faster than the comparator for equality checks.
54+
boolean equals = CollationFactory.fetchCollation(collationName).equalsFunction.apply(l ,r);
55+
assertEquals(expected == 0, equals);
5256
}
5357

5458
@Test
5559
public void testCompare() throws SparkException {
5660
for (String collationName: testSupportedCollations) {
57-
// Edge cases
58-
assertStringCompare("", "", collationName, 0);
59-
assertStringCompare("a", "", collationName, 1);
60-
assertStringCompare("", "a", collationName, -1);
61-
// Basic tests
62-
assertStringCompare("a", "a", collationName, 0);
63-
assertStringCompare("a", "b", collationName, -1);
64-
assertStringCompare("b", "a", collationName, 1);
65-
assertStringCompare("A", "A", collationName, 0);
66-
assertStringCompare("A", "B", collationName, -1);
67-
assertStringCompare("B", "A", collationName, 1);
68-
assertStringCompare("aa", "a", collationName, 1);
69-
assertStringCompare("b", "bb", collationName, -1);
70-
assertStringCompare("abc", "a", collationName, 1);
71-
assertStringCompare("abc", "b", collationName, -1);
72-
assertStringCompare("abc", "ab", collationName, 1);
73-
assertStringCompare("abc", "abc", collationName, 0);
74-
// ASCII strings
75-
assertStringCompare("aaaa", "aaa", collationName, 1);
76-
assertStringCompare("hello", "world", collationName, -1);
77-
assertStringCompare("Spark", "Spark", collationName, 0);
78-
// Non-ASCII strings
79-
assertStringCompare("ü", "ü", collationName, 0);
80-
assertStringCompare("ü", "", collationName, 1);
81-
assertStringCompare("", "ü", collationName, -1);
82-
assertStringCompare("äü", "äü", collationName, 0);
83-
assertStringCompare("äxx", "äx", collationName, 1);
84-
assertStringCompare("a", "ä", collationName, -1);
61+
// Empty strings.
62+
assertCompare("", "", collationName, 0);
63+
assertCompare("a", "", collationName, 1);
64+
assertCompare("", "a", collationName, -1);
65+
// Basic tests.
66+
assertCompare("a", "a", collationName, 0);
67+
assertCompare("a", "b", collationName, -1);
68+
assertCompare("b", "a", collationName, 1);
69+
assertCompare("A", "A", collationName, 0);
70+
assertCompare("A", "B", collationName, -1);
71+
assertCompare("B", "A", collationName, 1);
72+
assertCompare("aa", "a", collationName, 1);
73+
assertCompare("b", "bb", collationName, -1);
74+
assertCompare("abc", "a", collationName, 1);
75+
assertCompare("abc", "b", collationName, -1);
76+
assertCompare("abc", "ab", collationName, 1);
77+
assertCompare("abc", "abc", collationName, 0);
78+
assertCompare("aaaa", "aaa", collationName, 1);
79+
assertCompare("hello", "world", collationName, -1);
80+
assertCompare("Spark", "Spark", collationName, 0);
81+
assertCompare("ü", "ü", collationName, 0);
82+
assertCompare("ü", "", collationName, 1);
83+
assertCompare("", "ü", collationName, -1);
84+
assertCompare("äü", "äü", collationName, 0);
85+
assertCompare("äxx", "äx", collationName, 1);
86+
assertCompare("a", "ä", collationName, -1);
8587
}
86-
// Non-ASCII strings
87-
assertStringCompare("äü", "bü", "UTF8_BINARY", 1);
88-
assertStringCompare("bxx", "bü", "UTF8_BINARY", -1);
89-
assertStringCompare("äü", "bü", "UTF8_LCASE", 1);
90-
assertStringCompare("bxx", "bü", "UTF8_LCASE", -1);
91-
assertStringCompare("äü", "bü", "UNICODE", -1);
92-
assertStringCompare("bxx", "bü", "UNICODE", 1);
93-
assertStringCompare("äü", "bü", "UNICODE_CI", -1);
94-
assertStringCompare("bxx", "bü", "UNICODE_CI", 1);
95-
// Case variation
96-
assertStringCompare("AbCd", "aBcD", "UTF8_BINARY", -1);
97-
assertStringCompare("ABCD", "abcd", "UTF8_LCASE", 0);
98-
assertStringCompare("AbcD", "aBCd", "UNICODE", 1);
99-
assertStringCompare("abcd", "ABCD", "UNICODE_CI", 0);
100-
// Accent variation
101-
assertStringCompare("aBćD", "ABĆD", "UTF8_BINARY", 1);
102-
assertStringCompare("AbCδ", "ABCΔ", "UTF8_LCASE", 0);
103-
assertStringCompare("äBCd", "ÄBCD", "UNICODE", -1);
104-
assertStringCompare("Ab́cD", "AB́CD", "UNICODE_CI", 0);
105-
// Case-variable character length
106-
assertStringCompare("i\u0307", "İ", "UTF8_BINARY", -1);
107-
assertStringCompare("İ", "i\u0307", "UTF8_BINARY", 1);
108-
assertStringCompare("i\u0307", "İ", "UTF8_LCASE", 0);
109-
assertStringCompare("İ", "i\u0307", "UTF8_LCASE", 0);
110-
assertStringCompare("i\u0307", "İ", "UNICODE", -1);
111-
assertStringCompare("İ", "i\u0307", "UNICODE", 1);
112-
assertStringCompare("i\u0307", "İ", "UNICODE_CI", 0);
113-
assertStringCompare("İ", "i\u0307", "UNICODE_CI", 0);
114-
assertStringCompare("i\u0307İ", "i\u0307İ", "UTF8_LCASE", 0);
115-
assertStringCompare("i\u0307İ", "İi\u0307", "UTF8_LCASE", 0);
116-
assertStringCompare("İi\u0307", "i\u0307İ", "UTF8_LCASE", 0);
117-
assertStringCompare("İi\u0307", "İi\u0307", "UTF8_LCASE", 0);
118-
assertStringCompare("i\u0307İ", "i\u0307İ", "UNICODE_CI", 0);
119-
assertStringCompare("i\u0307İ", "İi\u0307", "UNICODE_CI", 0);
120-
assertStringCompare("İi\u0307", "i\u0307İ", "UNICODE_CI", 0);
121-
assertStringCompare("İi\u0307", "İi\u0307", "UNICODE_CI", 0);
122-
// Conditional case mapping
123-
assertStringCompare("ς", "σ", "UTF8_BINARY", -1);
124-
assertStringCompare("ς", "Σ", "UTF8_BINARY", 1);
125-
assertStringCompare("σ", "Σ", "UTF8_BINARY", 1);
126-
assertStringCompare("ς", "σ", "UTF8_LCASE", 0);
127-
assertStringCompare("ς", "Σ", "UTF8_LCASE", 0);
128-
assertStringCompare("σ", "Σ", "UTF8_LCASE", 0);
129-
assertStringCompare("ς", "σ", "UNICODE", 1);
130-
assertStringCompare("ς", "Σ", "UNICODE", 1);
131-
assertStringCompare("σ", "Σ", "UNICODE", -1);
132-
assertStringCompare("ς", "σ", "UNICODE_CI", 0);
133-
assertStringCompare("ς", "Σ", "UNICODE_CI", 0);
134-
assertStringCompare("σ", "Σ", "UNICODE_CI", 0);
88+
// Advanced tests.
89+
assertCompare("äü", "bü", "UTF8_BINARY", 1);
90+
assertCompare("bxx", "bü", "UTF8_BINARY", -1);
91+
assertCompare("äü", "bü", "UTF8_LCASE", 1);
92+
assertCompare("bxx", "bü", "UTF8_LCASE", -1);
93+
assertCompare("äü", "bü", "UNICODE", -1);
94+
assertCompare("bxx", "bü", "UNICODE", 1);
95+
assertCompare("äü", "bü", "UNICODE_CI", -1);
96+
assertCompare("bxx", "bü", "UNICODE_CI", 1);
97+
// Case variation.
98+
assertCompare("AbCd", "aBcD", "UTF8_BINARY", -1);
99+
assertCompare("ABCD", "abcd", "UTF8_LCASE", 0);
100+
assertCompare("AbcD", "aBCd", "UNICODE", 1);
101+
assertCompare("abcd", "ABCD", "UNICODE_CI", 0);
102+
// Accent variation.
103+
assertCompare("aBćD", "ABĆD", "UTF8_BINARY", 1);
104+
assertCompare("AbCδ", "ABCΔ", "UTF8_LCASE", 0);
105+
assertCompare("äBCd", "ÄBCD", "UNICODE", -1);
106+
assertCompare("Ab́cD", "AB́CD", "UNICODE_CI", 0);
107+
// One-to-many case mapping (e.g. Turkish dotted I).
108+
assertCompare("i\u0307", "İ", "UTF8_BINARY", -1);
109+
assertCompare("İ", "i\u0307", "UTF8_BINARY", 1);
110+
assertCompare("i\u0307", "İ", "UTF8_LCASE", 0);
111+
assertCompare("İ", "i\u0307", "UTF8_LCASE", 0);
112+
assertCompare("i\u0307", "İ", "UNICODE", -1);
113+
assertCompare("İ", "i\u0307", "UNICODE", 1);
114+
assertCompare("i\u0307", "İ", "UNICODE_CI", 0);
115+
assertCompare("İ", "i\u0307", "UNICODE_CI", 0);
116+
assertCompare("i\u0307İ", "i\u0307İ", "UTF8_LCASE", 0);
117+
assertCompare("i\u0307İ", "İi\u0307", "UTF8_LCASE", 0);
118+
assertCompare("İi\u0307", "i\u0307İ", "UTF8_LCASE", 0);
119+
assertCompare("İi\u0307", "İi\u0307", "UTF8_LCASE", 0);
120+
assertCompare("i\u0307İ", "i\u0307İ", "UNICODE_CI", 0);
121+
assertCompare("i\u0307İ", "İi\u0307", "UNICODE_CI", 0);
122+
assertCompare("İi\u0307", "i\u0307İ", "UNICODE_CI", 0);
123+
assertCompare("İi\u0307", "İi\u0307", "UNICODE_CI", 0);
124+
// Conditional case mapping (e.g. Greek sigmas).
125+
assertCompare("ς", "σ", "UTF8_BINARY", -1);
126+
assertCompare("ς", "Σ", "UTF8_BINARY", 1);
127+
assertCompare("σ", "Σ", "UTF8_BINARY", 1);
128+
assertCompare("ς", "σ", "UTF8_LCASE", 0);
129+
assertCompare("ς", "Σ", "UTF8_LCASE", 0);
130+
assertCompare("σ", "Σ", "UTF8_LCASE", 0);
131+
assertCompare("ς", "σ", "UNICODE", 1);
132+
assertCompare("ς", "Σ", "UNICODE", 1);
133+
assertCompare("σ", "Σ", "UNICODE", -1);
134+
assertCompare("ς", "σ", "UNICODE_CI", 0);
135+
assertCompare("ς", "Σ", "UNICODE_CI", 0);
136+
assertCompare("σ", "Σ", "UNICODE_CI", 0);
137+
// Surrogate pairs.
138+
assertCompare("a🙃b🙃c", "aaaaa", "UTF8_BINARY", 1);
139+
assertCompare("a🙃b🙃c", "aaaaa", "UTF8_LCASE", 1);
140+
assertCompare("a🙃b🙃c", "aaaaa", "UNICODE", -1); // != UTF8_BINARY
141+
assertCompare("a🙃b🙃c", "aaaaa", "UNICODE_CI", -1); // != UTF8_LCASE
142+
assertCompare("a🙃b🙃c", "a🙃b🙃c", "UTF8_BINARY", 0);
143+
assertCompare("a🙃b🙃c", "a🙃b🙃c", "UTF8_LCASE", 0);
144+
assertCompare("a🙃b🙃c", "a🙃b🙃c", "UNICODE", 0);
145+
assertCompare("a🙃b🙃c", "a🙃b🙃c", "UNICODE_CI", 0);
146+
assertCompare("a🙃b🙃c", "a🙃b🙃d", "UTF8_BINARY", -1);
147+
assertCompare("a🙃b🙃c", "a🙃b🙃d", "UTF8_LCASE", -1);
148+
assertCompare("a🙃b🙃c", "a🙃b🙃d", "UNICODE", -1);
149+
assertCompare("a🙃b🙃c", "a🙃b🙃d", "UNICODE_CI", -1);
135150
// Maximum code point.
136151
int maxCodePoint = Character.MAX_CODE_POINT;
137152
String maxCodePointStr = new String(Character.toChars(maxCodePoint));
138153
for (int i = 0; i < maxCodePoint && Character.isValidCodePoint(i); ++i) {
139-
assertStringCompare(new String(Character.toChars(i)), maxCodePointStr, "UTF8_BINARY", -1);
140-
assertStringCompare(new String(Character.toChars(i)), maxCodePointStr, "UTF8_LCASE", -1);
154+
assertCompare(new String(Character.toChars(i)), maxCodePointStr, "UTF8_BINARY", -1);
155+
assertCompare(new String(Character.toChars(i)), maxCodePointStr, "UTF8_LCASE", -1);
141156
}
142157
// Minimum code point.
143158
int minCodePoint = Character.MIN_CODE_POINT;
144159
String minCodePointStr = new String(Character.toChars(minCodePoint));
145160
for (int i = minCodePoint + 1; i <= maxCodePoint && Character.isValidCodePoint(i); ++i) {
146-
assertStringCompare(new String(Character.toChars(i)), minCodePointStr, "UTF8_BINARY", 1);
147-
assertStringCompare(new String(Character.toChars(i)), minCodePointStr, "UTF8_LCASE", 1);
161+
assertCompare(new String(Character.toChars(i)), minCodePointStr, "UTF8_BINARY", 1);
162+
assertCompare(new String(Character.toChars(i)), minCodePointStr, "UTF8_LCASE", 1);
148163
}
149164
}
150165

151-
private void assertLowerCaseCodePoints(UTF8String target, UTF8String expected,
152-
Boolean useCodePoints) {
166+
/**
167+
* Collation-aware UTF8String lowercase conversion.
168+
*/
169+
170+
private void assertLowerCaseCodePoints(String string, String expected, Boolean useCodePoints) {
171+
UTF8String str = UTF8String.fromString(string);
153172
if (useCodePoints) {
154-
assertEquals(expected, CollationAwareUTF8String.lowerCaseCodePoints(target));
173+
UTF8String result = CollationAwareUTF8String.lowerCaseCodePoints(str);
174+
assertEquals(UTF8String.fromString(expected), result);
155175
} else {
156-
assertEquals(expected, target.toLowerCase());
176+
UTF8String result = str.toLowerCase();
177+
assertEquals(UTF8String.fromString(expected), result);
157178
}
158179
}
159180

160181
@Test
161182
public void testLowerCaseCodePoints() {
162-
// Edge cases
163-
assertLowerCaseCodePoints(UTF8String.fromString(""), UTF8String.fromString(""), false);
164-
assertLowerCaseCodePoints(UTF8String.fromString(""), UTF8String.fromString(""), true);
165-
// Basic tests
166-
assertLowerCaseCodePoints(UTF8String.fromString("abcd"), UTF8String.fromString("abcd"), false);
167-
assertLowerCaseCodePoints(UTF8String.fromString("AbCd"), UTF8String.fromString("abcd"), false);
168-
assertLowerCaseCodePoints(UTF8String.fromString("abcd"), UTF8String.fromString("abcd"), true);
169-
assertLowerCaseCodePoints(UTF8String.fromString("aBcD"), UTF8String.fromString("abcd"), true);
170-
// Accent variation
171-
assertLowerCaseCodePoints(UTF8String.fromString("AbĆd"), UTF8String.fromString("abćd"), false);
172-
assertLowerCaseCodePoints(UTF8String.fromString("aBcΔ"), UTF8String.fromString("abcδ"), true);
173-
// Case-variable character length
174-
assertLowerCaseCodePoints(
175-
UTF8String.fromString("İoDiNe"), UTF8String.fromString("i̇odine"), false);
176-
assertLowerCaseCodePoints(
177-
UTF8String.fromString("Abi̇o12"), UTF8String.fromString("abi̇o12"), false);
178-
assertLowerCaseCodePoints(
179-
UTF8String.fromString("İodInE"), UTF8String.fromString("i̇odine"), true);
180-
assertLowerCaseCodePoints(
181-
UTF8String.fromString("aBi̇o12"), UTF8String.fromString("abi̇o12"), true);
182-
// Conditional case mapping
183-
assertLowerCaseCodePoints(
184-
UTF8String.fromString("ΘΑΛΑΣΣΙΝΟΣ"), UTF8String.fromString("θαλασσινος"), false);
185-
assertLowerCaseCodePoints(
186-
UTF8String.fromString("ΘΑΛΑΣΣΙΝΟΣ"), UTF8String.fromString("θαλασσινοσ"), true);
187-
// Surrogate pairs are treated as invalid UTF8 sequences
188-
assertLowerCaseCodePoints(UTF8String.fromBytes(new byte[]
189-
{(byte) 0xED, (byte) 0xA0, (byte) 0x80, (byte) 0xED, (byte) 0xB0, (byte) 0x80}),
190-
UTF8String.fromString("\uFFFD\uFFFD"), false);
191-
assertLowerCaseCodePoints(UTF8String.fromBytes(new byte[]
192-
{(byte) 0xED, (byte) 0xA0, (byte) 0x80, (byte) 0xED, (byte) 0xB0, (byte) 0x80}),
193-
UTF8String.fromString("\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"), true); // != Java toLowerCase
183+
// Empty strings.
184+
assertLowerCaseCodePoints("", "", false);
185+
assertLowerCaseCodePoints("", "", true);
186+
// Basic tests.
187+
assertLowerCaseCodePoints("xyz", "xyz", false);
188+
assertLowerCaseCodePoints("xyz", "xyz", true);
189+
assertLowerCaseCodePoints("abcd", "abcd", false);
190+
assertLowerCaseCodePoints("abcd", "abcd", true);
191+
// Advanced tests.
192+
assertLowerCaseCodePoints("你好", "你好", false);
193+
assertLowerCaseCodePoints("你好", "你好", true);
194+
assertLowerCaseCodePoints("Γειά", "γειά", false);
195+
assertLowerCaseCodePoints("Γειά", "γειά", true);
196+
assertLowerCaseCodePoints("Здраво", "здраво", false);
197+
assertLowerCaseCodePoints("Здраво", "здраво", true);
198+
// Case variation.
199+
assertLowerCaseCodePoints("xYz", "xyz", false);
200+
assertLowerCaseCodePoints("xYz", "xyz", true);
201+
assertLowerCaseCodePoints("AbCd", "abcd", false);
202+
assertLowerCaseCodePoints("aBcD", "abcd", true);
203+
// Accent variation.
204+
assertLowerCaseCodePoints("äbć", "äbć", false);
205+
assertLowerCaseCodePoints("äbć", "äbć", true);
206+
assertLowerCaseCodePoints("AbĆd", "abćd", false);
207+
assertLowerCaseCodePoints("aBcΔ", "abcδ", true);
208+
// One-to-many case mapping (e.g. Turkish dotted I).
209+
assertLowerCaseCodePoints("i\u0307", "i\u0307", false);
210+
assertLowerCaseCodePoints("i\u0307", "i\u0307", true);
211+
assertLowerCaseCodePoints("I\u0307", "i\u0307", false);
212+
assertLowerCaseCodePoints("I\u0307", "i\u0307", true);
213+
assertLowerCaseCodePoints("İ", "i\u0307", false);
214+
assertLowerCaseCodePoints("İ", "i\u0307", true);
215+
assertLowerCaseCodePoints("İİİ", "i\u0307i\u0307i\u0307", false);
216+
assertLowerCaseCodePoints("İİİ", "i\u0307i\u0307i\u0307", true);
217+
assertLowerCaseCodePoints("İiIi\u0307", "i\u0307iii\u0307", false);
218+
assertLowerCaseCodePoints("İiIi\u0307", "i\u0307iii\u0307", true);
219+
assertLowerCaseCodePoints("İoDiNe", "i\u0307odine", false);
220+
assertLowerCaseCodePoints("İodInE", "i\u0307odine", true);
221+
assertLowerCaseCodePoints("Abi\u0307o12", "abi\u0307o12", false);
222+
assertLowerCaseCodePoints("aBi\u0307o12", "abi\u0307o12", true);
223+
// Conditional case mapping (e.g. Greek sigmas).
224+
assertLowerCaseCodePoints("ς", "ς", false);
225+
assertLowerCaseCodePoints("ς", "σ", true);
226+
assertLowerCaseCodePoints("σ", "σ", false);
227+
assertLowerCaseCodePoints("σ", "σ", true);
228+
assertLowerCaseCodePoints("Σ", "σ", false);
229+
assertLowerCaseCodePoints("Σ", "σ", true);
230+
assertLowerCaseCodePoints("ςΑΛΑΤΑ", "ςαλατα", false);
231+
assertLowerCaseCodePoints("ςΑΛΑΤΑ", "σαλατα", true);
232+
assertLowerCaseCodePoints("σΑΛΑΤΑ", "σαλατα", false);
233+
assertLowerCaseCodePoints("σΑΛΑΤΑ", "σαλατα", true);
234+
assertLowerCaseCodePoints("ΣΑΛΑΤΑ", "σαλατα", false);
235+
assertLowerCaseCodePoints("ΣΑΛΑΤΑ", "σαλατα", true);
236+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟς", "θαλασσινος", false);
237+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟς", "θαλασσινοσ", true);
238+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟσ", "θαλασσινοσ", false);
239+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟσ", "θαλασσινοσ", true);
240+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟΣ", "θαλασσινος", false);
241+
assertLowerCaseCodePoints("ΘΑΛΑΣΣΙΝΟΣ", "θαλασσινοσ", true);
242+
// Surrogate pairs.
243+
assertLowerCaseCodePoints("a🙃b🙃c", "a🙃b🙃c", false);
244+
assertLowerCaseCodePoints("a🙃b🙃c", "a🙃b🙃c", true);
245+
assertLowerCaseCodePoints("😀😆😃😄😄😆", "😀😆😃😄😄😆", false);
246+
assertLowerCaseCodePoints("😀😆😃😄😄😆", "😀😆😃😄😄😆", true);
247+
assertLowerCaseCodePoints("𐐅", "𐐭", false);
248+
assertLowerCaseCodePoints("𐐅", "𐐭", true);
249+
assertLowerCaseCodePoints("𝔸", "𝔸", false);
250+
assertLowerCaseCodePoints("𝔸", "𝔸", true);
194251
}
195252

196253
/**

0 commit comments

Comments
 (0)