snuyanzin commented on code in PR #29023:
URL: https://github.com/apache/flink/pull/29023#discussion_r3878376293
##########
flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/data/BinaryStringDataTest.java:
##########
@@ -130,637 +115,766 @@ private BinaryStringData fromString(String str) {
}
}
- private void checkBasic(String str, int len) {
- BinaryStringData s1 = fromString(str);
+ /** Cases for the string-to-decimal conversion, shared by the string and
binary-row tests. */
+ private static final class DecimalCase {
+ private final String str;
+ private final int precision;
+ private final int scale;
+
+ private DecimalCase(String str, int precision, int scale) {
+ this.str = str;
+ this.precision = precision;
+ this.scale = scale;
+ }
+ }
+
+ private static final List<DecimalCase> DECIMAL_CASES =
+ List.of(
+ new DecimalCase("12.345", 5, 3),
+ new DecimalCase("-12.345", 5, 3),
+ new DecimalCase("+12345", 5, 0),
+ new DecimalCase("-12345", 5, 0),
+ new DecimalCase("12345.", 5, 0),
+ new DecimalCase("-12345.", 5, 0),
+ new DecimalCase(".12345", 5, 5),
+ new DecimalCase("-.12345", 5, 5),
+ new DecimalCase("+12.345E3", 5, 0),
+ new DecimalCase("-12.345e3", 5, 0),
+ new DecimalCase("12.345e-3", 6, 6),
+ new DecimalCase("-12.345E-3", 6, 6),
+ new DecimalCase("12345E3", 8, 0),
+ new DecimalCase("-12345e3", 8, 0),
+ new DecimalCase("12345e-3", 5, 3),
+ new DecimalCase("-12345E-3", 5, 3),
+ new DecimalCase("+.12345E3", 5, 2),
+ new DecimalCase("-.12345e3", 5, 2),
+ new DecimalCase(".12345e-3", 8, 8),
+ new DecimalCase("-.12345E-3", 8, 8),
+ new DecimalCase("1234512345.1234", 18, 8),
+ new DecimalCase("-1234512345.1234", 18, 8),
+ new DecimalCase("1234512345.1234", 12, 2),
+ new DecimalCase("-1234512345.1234", 12, 2),
+ new DecimalCase("1234512345.1299", 12, 2),
+ new DecimalCase("-1234512345.1299", 12, 2),
+ new DecimalCase("999999999999999999", 18, 0),
+ new DecimalCase("1234512345.1234512345", 20, 10),
+ new DecimalCase("-1234512345.1234512345", 20, 10),
+ new DecimalCase("1234512345.1234512345", 15, 5),
+ new DecimalCase("-1234512345.1234512345", 15, 5),
+ new DecimalCase("12345123451234512345E-10", 20, 10),
+ new DecimalCase("-12345123451234512345E-10", 20, 10),
+ new DecimalCase("12345123451234512345E-10", 15, 5),
+ new DecimalCase("-12345123451234512345E-10", 15, 5),
+ new DecimalCase("999999999999999999999", 21, 0),
+ new DecimalCase("-999999999999999999999", 21, 0),
+ new
DecimalCase("0.00000000000000000000123456789123456789", 38, 38),
+ new
DecimalCase("-0.00000000000000000000123456789123456789", 38, 38),
+ new
DecimalCase("0.00000000000000000000123456789123456789", 29, 29),
+ new
DecimalCase("-0.00000000000000000000123456789123456789", 29, 29),
+ new DecimalCase("123456789123E-27", 18, 18),
+ new DecimalCase("-123456789123E-27", 18, 18),
+ new DecimalCase("123456789999E-27", 18, 18),
+ new DecimalCase("-123456789999E-27", 18, 18),
+ new DecimalCase("123456789123456789E-36", 18, 18),
+ new DecimalCase("-123456789123456789E-36", 18, 18),
+ new DecimalCase("123456789999999999E-36", 18, 18),
+ new DecimalCase("-123456789999999999E-36", 18, 18));
+
+ private static Stream<Arguments> decimalCases() {
+ return Arrays.stream(Mode.values())
+ .flatMap(
+ mode ->
+ DECIMAL_CASES.stream()
+ .map(c -> arguments(mode, c.str,
c.precision, c.scale)));
+ }
+
+ private static void checkBasic(Mode mode, String str, int len) {
+ BinaryStringData s1 = fromString(mode, str);
BinaryStringData s2 = fromBytes(str.getBytes(StandardCharsets.UTF_8));
- assertThat(len).isEqualTo(s1.numChars());
- assertThat(len).isEqualTo(s2.numChars());
+ assertThat(s1.numChars()).isEqualTo(len);
+ assertThat(s2.numChars()).isEqualTo(len);
- assertThat(str).isEqualTo(s1.toString());
- assertThat(str).isEqualTo(s2.toString());
+ assertThat(s1).hasToString(str);
+ assertThat(s2).hasToString(str);
assertThat(s2).isEqualTo(s1);
assertThat(s2.hashCode()).isEqualTo(s1.hashCode());
- assertThat(s1.compareTo(s2)).isEqualTo(0);
+ assertThat(s1.compareTo(s2)).isZero();
assertThat(s1.contains(s2)).isTrue();
assertThat(s2.contains(s1)).isTrue();
assertThat(s1.startsWith(s1)).isTrue();
assertThat(s1.endsWith(s1)).isTrue();
}
- @TestTemplate
- void basicTest() {
- checkBasic("", 0);
- checkBasic(",", 1);
- checkBasic("hello", 5);
- checkBasic("hello world", 11);
- checkBasic("Flink中文社区", 9);
- checkBasic("中 文 社 区", 7);
-
- checkBasic("¡", 1); // 2 bytes char
- checkBasic("ку", 2); // 2 * 2 bytes chars
- checkBasic("︽﹋%", 3); // 3 * 3 bytes chars
- checkBasic("\uD83E\uDD19", 1); // 4 bytes char
- }
-
- @TestTemplate
- void emptyStringTest() {
- assertThat(fromString("")).isEqualTo(empty);
- assertThat(fromBytes(new byte[0])).isEqualTo(empty);
- assertThat(empty.numChars()).isEqualTo(0);
- assertThat(empty.getSizeInBytes()).isEqualTo(0);
- }
+ @Nested
+ @DisplayName("Basics")
+ class Basics {
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void basicTest(Mode mode) {
+ checkBasic(mode, "", 0);
+ checkBasic(mode, ",", 1);
+ checkBasic(mode, "hello", 5);
+ checkBasic(mode, "hello world", 11);
+ checkBasic(mode, "Flink中文社区", 9);
+ checkBasic(mode, "中 文 社 区", 7);
+
+ checkBasic(mode, "¡", 1); // 2 bytes char
+ checkBasic(mode, "ку", 2); // 2 * 2 bytes chars
+ checkBasic(mode, "︽﹋%", 3); // 3 * 3 bytes chars
+ checkBasic(mode, "🤙", 1); // 4 bytes char
+ }
- @TestTemplate
- void compareTo() {
- assertThat(fromString(" ").compareTo(blankString(3))).isEqualTo(0);
- assertThat(fromString("").compareTo(fromString("a"))).isLessThan(0);
-
assertThat(fromString("abc").compareTo(fromString("ABC"))).isGreaterThan(0);
-
assertThat(fromString("abc0").compareTo(fromString("abc"))).isGreaterThan(0);
-
assertThat(fromString("abcabcabc").compareTo(fromString("abcabcabc"))).isEqualTo(0);
-
assertThat(fromString("aBcabcabc").compareTo(fromString("Abcabcabc"))).isGreaterThan(0);
-
assertThat(fromString("Abcabcabc").compareTo(fromString("abcabcabC"))).isLessThan(0);
-
assertThat(fromString("abcabcabc").compareTo(fromString("abcabcabC"))).isGreaterThan(0);
-
-
assertThat(fromString("abc").compareTo(fromString("世界"))).isLessThan(0);
-
assertThat(fromString("你好").compareTo(fromString("世界"))).isGreaterThan(0);
-
assertThat(fromString("你好123").compareTo(fromString("你好122"))).isGreaterThan(0);
-
- MemorySegment segment1 =
MemorySegmentFactory.allocateUnpooledSegment(1024);
- MemorySegment segment2 =
MemorySegmentFactory.allocateUnpooledSegment(1024);
- SortUtil.putStringNormalizedKey(fromString("abcabcabc"), segment1, 0,
9);
- SortUtil.putStringNormalizedKey(fromString("abcabcabC"), segment2, 0,
9);
- assertThat(segment1.compare(segment2, 0, 0, 9)).isGreaterThan(0);
- SortUtil.putStringNormalizedKey(fromString("abcab"), segment1, 0, 9);
- assertThat(segment1.compare(segment2, 0, 0, 9)).isLessThan(0);
- }
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void emptyStringTest(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(fromString(mode, "")).isEqualTo(empty);
+ assertThat(fromBytes(new byte[0])).isEqualTo(empty);
+ assertThat(empty.numChars()).isZero();
+ assertThat(empty.getSizeInBytes()).isZero();
+ }
- @TestTemplate
- void testMultiSegments() {
-
- // prepare
- MemorySegment[] segments1 = new MemorySegment[2];
- segments1[0] = MemorySegmentFactory.wrap(new byte[10]);
- segments1[1] = MemorySegmentFactory.wrap(new byte[10]);
- segments1[0].put(5, "abcde".getBytes(UTF_8), 0, 5);
- segments1[1].put(0, "aaaaa".getBytes(UTF_8), 0, 5);
-
- MemorySegment[] segments2 = new MemorySegment[2];
- segments2[0] = MemorySegmentFactory.wrap(new byte[5]);
- segments2[1] = MemorySegmentFactory.wrap(new byte[5]);
- segments2[0].put(0, "abcde".getBytes(UTF_8), 0, 5);
- segments2[1].put(0, "b".getBytes(UTF_8), 0, 1);
-
- // test go ahead both
- BinaryStringData binaryString1 =
BinaryStringData.fromAddress(segments1, 5, 10);
- BinaryStringData binaryString2 =
BinaryStringData.fromAddress(segments2, 0, 6);
- assertThat(binaryString1.toString()).isEqualTo("abcdeaaaaa");
- assertThat(binaryString2.toString()).isEqualTo("abcdeb");
- assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
-
- // test needCompare == len
- binaryString1 = BinaryStringData.fromAddress(segments1, 5, 5);
- binaryString2 = BinaryStringData.fromAddress(segments2, 0, 5);
- assertThat(binaryString1.toString()).isEqualTo("abcde");
- assertThat(binaryString2.toString()).isEqualTo("abcde");
- assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(0);
-
- // test find the first segment of this string
- binaryString1 = BinaryStringData.fromAddress(segments1, 10, 5);
- binaryString2 = BinaryStringData.fromAddress(segments2, 0, 5);
- assertThat(binaryString1.toString()).isEqualTo("aaaaa");
- assertThat(binaryString2.toString()).isEqualTo("abcde");
- assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
- assertThat(binaryString2.compareTo(binaryString1)).isEqualTo(1);
-
- // test go ahead single
- segments2 = new MemorySegment[] {MemorySegmentFactory.wrap(new
byte[10])};
- segments2[0].put(4, "abcdeb".getBytes(UTF_8), 0, 6);
- binaryString1 = BinaryStringData.fromAddress(segments1, 5, 10);
- binaryString2 = BinaryStringData.fromAddress(segments2, 4, 6);
- assertThat(binaryString1.toString()).isEqualTo("abcdeaaaaa");
- assertThat(binaryString2.toString()).isEqualTo("abcdeb");
- assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
- assertThat(binaryString2.compareTo(binaryString1)).isEqualTo(1);
- }
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void testIsEmpty(Mode mode) {
+ assertThat(isEmpty(fromString(mode, ""))).isTrue();
+ assertThat(isEmpty(BinaryStringData.fromBytes(new byte[]
{}))).isTrue();
+ assertThat(isEmpty(fromString(mode, "hello"))).isFalse();
+
assertThat(isEmpty(BinaryStringData.fromBytes("hello".getBytes()))).isFalse();
+ assertThat(isEmpty(fromString(mode, "中文"))).isFalse();
+
assertThat(isEmpty(BinaryStringData.fromBytes("中文".getBytes()))).isFalse();
+ assertThat(isEmpty(new BinaryStringData())).isTrue();
+ }
- @TestTemplate
- void concatTest() {
- assertThat(concat()).isEqualTo(empty);
- assertThat(concat((BinaryStringData) null)).isNull();
- assertThat(concat(empty)).isEqualTo(empty);
- assertThat(concat(fromString("ab"))).isEqualTo(fromString("ab"));
- assertThat(concat(fromString("a"),
fromString("b"))).isEqualTo(fromString("ab"));
- assertThat(concat(fromString("a"), fromString("b"), fromString("c")))
- .isEqualTo(fromString("abc"));
- assertThat(concat(fromString("a"), null, fromString("c"))).isNull();
- assertThat(concat(fromString("a"), null, null)).isNull();
- assertThat(concat(null, null, null)).isNull();
- assertThat(concat(fromString("数据"),
fromString("砖头"))).isEqualTo(fromString("数据砖头"));
- }
+ @Test
+ void testLazy() {
+ String javaStr = "haha";
+ BinaryStringData str = BinaryStringData.fromString(javaStr);
+ str.ensureMaterialized();
- @TestTemplate
- void concatWsTest() {
- // Returns empty if the separator is null
- assertThat(concatWs(null, (BinaryStringData) null)).isNull();
- assertThat(concatWs(null, fromString("a"))).isNull();
-
- // If separator is null, concatWs should skip all null inputs and
never return null.
- BinaryStringData sep = fromString("哈哈");
- assertThat(concatWs(sep, empty)).isEqualTo(empty);
- assertThat(concatWs(sep,
fromString("ab"))).isEqualTo(fromString("ab"));
- assertThat(concatWs(sep, fromString("a"),
fromString("b"))).isEqualTo(fromString("a哈哈b"));
- assertThat(concatWs(sep, fromString("a"), fromString("b"),
fromString("c")))
- .isEqualTo(fromString("a哈哈b哈哈c"));
- assertThat(concatWs(sep, fromString("a"), null, fromString("c")))
- .isEqualTo(fromString("a哈哈c"));
- assertThat(concatWs(sep, fromString("a"), null,
null)).isEqualTo(fromString("a"));
- assertThat(concatWs(sep, null, null, null)).isEqualTo(empty);
- assertThat(concatWs(sep, fromString("数据"), fromString("砖头")))
- .isEqualTo(fromString("数据哈哈砖头"));
+ // check reference same.
+ assertThat(str.toString()).isSameAs(javaStr);
+ }
}
- @TestTemplate
- void contains() {
- assertThat(empty.contains(empty)).isTrue();
- assertThat(fromString("hello").contains(fromString("ello"))).isTrue();
-
assertThat(fromString("hello").contains(fromString("vello"))).isFalse();
-
assertThat(fromString("hello").contains(fromString("hellooo"))).isFalse();
- assertThat(fromString("大千世界").contains(fromString("千世界"))).isTrue();
- assertThat(fromString("大千世界").contains(fromString("世千"))).isFalse();
- assertThat(fromString("大千世界").contains(fromString("大千世界好"))).isFalse();
- }
+ @Nested
+ @DisplayName("Comparison")
+ class Comparison {
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void compareTo(Mode mode) {
+ assertThat(fromString(mode, "
").compareTo(blankString(3))).isZero();
+ assertThat(fromString(mode, "").compareTo(fromString(mode,
"a"))).isLessThan(0);
+ assertThat(fromString(mode, "abc").compareTo(fromString(mode,
"ABC"))).isGreaterThan(0);
+ assertThat(fromString(mode, "abc0").compareTo(fromString(mode,
"abc")))
+ .isGreaterThan(0);
+ assertThat(fromString(mode,
"abcabcabc").compareTo(fromString(mode, "abcabcabc")))
+ .isZero();
+ assertThat(fromString(mode,
"aBcabcabc").compareTo(fromString(mode, "Abcabcabc")))
+ .isGreaterThan(0);
+ assertThat(fromString(mode,
"Abcabcabc").compareTo(fromString(mode, "abcabcabC")))
+ .isLessThan(0);
+ assertThat(fromString(mode,
"abcabcabc").compareTo(fromString(mode, "abcabcabC")))
+ .isGreaterThan(0);
+
+ assertThat(fromString(mode, "abc").compareTo(fromString(mode,
"世界"))).isLessThan(0);
+ assertThat(fromString(mode, "你好").compareTo(fromString(mode,
"世界"))).isGreaterThan(0);
+ assertThat(fromString(mode, "你好123").compareTo(fromString(mode,
"你好122")))
+ .isGreaterThan(0);
+
+ MemorySegment segment1 =
MemorySegmentFactory.allocateUnpooledSegment(1024);
+ MemorySegment segment2 =
MemorySegmentFactory.allocateUnpooledSegment(1024);
+ SortUtil.putStringNormalizedKey(fromString(mode, "abcabcabc"),
segment1, 0, 9);
+ SortUtil.putStringNormalizedKey(fromString(mode, "abcabcabC"),
segment2, 0, 9);
+ assertThat(segment1.compare(segment2, 0, 0, 9)).isGreaterThan(0);
+ SortUtil.putStringNormalizedKey(fromString(mode, "abcab"),
segment1, 0, 9);
+ assertThat(segment1.compare(segment2, 0, 0, 9)).isLessThan(0);
+ }
- @TestTemplate
- void startsWith() {
- assertThat(empty.startsWith(empty)).isTrue();
-
assertThat(fromString("hello").startsWith(fromString("hell"))).isTrue();
-
assertThat(fromString("hello").startsWith(fromString("ell"))).isFalse();
-
assertThat(fromString("hello").startsWith(fromString("hellooo"))).isFalse();
- assertThat(fromString("数据砖头").startsWith(fromString("数据"))).isTrue();
- assertThat(fromString("大千世界").startsWith(fromString("千"))).isFalse();
-
assertThat(fromString("大千世界").startsWith(fromString("大千世界好"))).isFalse();
- }
+ @Test
+ void testMultiSegments() {
+
+ // prepare
+ MemorySegment[] segments1 = new MemorySegment[2];
+ segments1[0] = MemorySegmentFactory.wrap(new byte[10]);
+ segments1[1] = MemorySegmentFactory.wrap(new byte[10]);
+ segments1[0].put(5, "abcde".getBytes(UTF_8), 0, 5);
+ segments1[1].put(0, "aaaaa".getBytes(UTF_8), 0, 5);
+
+ MemorySegment[] segments2 = new MemorySegment[2];
+ segments2[0] = MemorySegmentFactory.wrap(new byte[5]);
+ segments2[1] = MemorySegmentFactory.wrap(new byte[5]);
+ segments2[0].put(0, "abcde".getBytes(UTF_8), 0, 5);
+ segments2[1].put(0, "b".getBytes(UTF_8), 0, 1);
+
+ // test go ahead both
+ BinaryStringData binaryString1 =
BinaryStringData.fromAddress(segments1, 5, 10);
+ BinaryStringData binaryString2 =
BinaryStringData.fromAddress(segments2, 0, 6);
+ assertThat(binaryString1).hasToString("abcdeaaaaa");
+ assertThat(binaryString2).hasToString("abcdeb");
+ assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
+
+ // test needCompare == len
+ binaryString1 = BinaryStringData.fromAddress(segments1, 5, 5);
+ binaryString2 = BinaryStringData.fromAddress(segments2, 0, 5);
+ assertThat(binaryString1).hasToString("abcde");
+ assertThat(binaryString2).hasToString("abcde");
+ assertThat(binaryString1.compareTo(binaryString2)).isZero();
+
+ // test find the first segment of this string
+ binaryString1 = BinaryStringData.fromAddress(segments1, 10, 5);
+ binaryString2 = BinaryStringData.fromAddress(segments2, 0, 5);
+ assertThat(binaryString1).hasToString("aaaaa");
+ assertThat(binaryString2).hasToString("abcde");
+ assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
+ assertThat(binaryString2.compareTo(binaryString1)).isEqualTo(1);
+
+ // test go ahead single
+ segments2 = new MemorySegment[] {MemorySegmentFactory.wrap(new
byte[10])};
+ segments2[0].put(4, "abcdeb".getBytes(UTF_8), 0, 6);
+ binaryString1 = BinaryStringData.fromAddress(segments1, 5, 10);
+ binaryString2 = BinaryStringData.fromAddress(segments2, 4, 6);
+ assertThat(binaryString1).hasToString("abcdeaaaaa");
+ assertThat(binaryString2).hasToString("abcdeb");
+ assertThat(binaryString1.compareTo(binaryString2)).isEqualTo(-1);
+ assertThat(binaryString2.compareTo(binaryString1)).isEqualTo(1);
+ }
- @TestTemplate
- void endsWith() {
- assertThat(empty.endsWith(empty)).isTrue();
- assertThat(fromString("hello").endsWith(fromString("ello"))).isTrue();
-
assertThat(fromString("hello").endsWith(fromString("ellov"))).isFalse();
-
assertThat(fromString("hello").endsWith(fromString("hhhello"))).isFalse();
- assertThat(fromString("大千世界").endsWith(fromString("世界"))).isTrue();
- assertThat(fromString("大千世界").endsWith(fromString("世"))).isFalse();
-
assertThat(fromString("数据砖头").endsWith(fromString("我的数据砖头"))).isFalse();
- }
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void testEmptyString(Mode mode) {
+ BinaryStringData str2 = fromString(mode, "hahahahah");
+ BinaryStringData str3;
+ {
+ MemorySegment[] segments = new MemorySegment[2];
+ segments[0] = MemorySegmentFactory.wrap(new byte[10]);
+ segments[1] = MemorySegmentFactory.wrap(new byte[10]);
+ str3 = BinaryStringData.fromAddress(segments, 15, 0);
+ }
- @TestTemplate
- void substring() {
- assertThat(fromString("hello").substring(0, 0)).isEqualTo(empty);
- assertThat(fromString("hello").substring(1,
3)).isEqualTo(fromString("el"));
- assertThat(fromString("数据砖头").substring(0,
1)).isEqualTo(fromString("数"));
- assertThat(fromString("数据砖头").substring(1,
3)).isEqualTo(fromString("据砖"));
- assertThat(fromString("数据砖头").substring(3,
5)).isEqualTo(fromString("头"));
- assertThat(fromString("ߵ梷").substring(0,
2)).isEqualTo(fromString("ߵ梷"));
- }
+
assertThat(BinaryStringData.EMPTY_UTF8.compareTo(str2)).isLessThan(0);
+
assertThat(str2.compareTo(BinaryStringData.EMPTY_UTF8)).isGreaterThan(0);
- @TestTemplate
- void trims() {
- assertThat(fromString("1").trim()).isEqualTo(fromString("1"));
-
- assertThat(fromString(" hello
").trim()).isEqualTo(fromString("hello"));
- assertThat(trimLeft(fromString(" hello
"))).isEqualTo(fromString("hello "));
- assertThat(trimRight(fromString(" hello "))).isEqualTo(fromString("
hello"));
-
- assertThat(trim(fromString(" hello "), false, false, fromString(" ")))
- .isEqualTo(fromString(" hello "));
- assertThat(trim(fromString(" hello "), true, true, fromString(" ")))
- .isEqualTo(fromString("hello"));
- assertThat(trim(fromString(" hello "), true, false, fromString(" ")))
- .isEqualTo(fromString("hello "));
- assertThat(trim(fromString(" hello "), false, true, fromString(" ")))
- .isEqualTo(fromString(" hello"));
- assertThat(trim(fromString("xxxhellox"), true, true, fromString("x")))
- .isEqualTo(fromString("hello"));
-
- assertThat(trim(fromString("xxxhellox"),
fromString("xoh"))).isEqualTo(fromString("ell"));
-
- assertThat(trimLeft(fromString("xxxhellox"), fromString("xoh")))
- .isEqualTo(fromString("ellox"));
-
- assertThat(trimRight(fromString("xxxhellox"), fromString("xoh")))
- .isEqualTo(fromString("xxxhell"));
-
- assertThat(empty.trim()).isEqualTo(empty);
- assertThat(fromString(" ").trim()).isEqualTo(empty);
- assertThat(trimLeft(fromString(" "))).isEqualTo(empty);
- assertThat(trimRight(fromString(" "))).isEqualTo(empty);
-
- assertThat(fromString(" 数据砖头 ").trim()).isEqualTo(fromString("数据砖头"));
- assertThat(trimLeft(fromString(" 数据砖头 "))).isEqualTo(fromString("数据砖头
"));
- assertThat(trimRight(fromString(" 数据砖头 "))).isEqualTo(fromString("
数据砖头"));
-
- assertThat(fromString("数据砖头").trim()).isEqualTo(fromString("数据砖头"));
- assertThat(trimLeft(fromString("数据砖头"))).isEqualTo(fromString("数据砖头"));
-
assertThat(trimRight(fromString("数据砖头"))).isEqualTo(fromString("数据砖头"));
-
- assertThat(trim(fromString("年年岁岁, 岁岁年年"), fromString("年岁
"))).isEqualTo(fromString(","));
- assertThat(trimLeft(fromString("年年岁岁, 岁岁年年"), fromString("年岁 ")))
- .isEqualTo(fromString(", 岁岁年年"));
- assertThat(trimRight(fromString("年年岁岁, 岁岁年年"), fromString("年岁 ")))
- .isEqualTo(fromString("年年岁岁,"));
-
- char[] charsLessThan0x20 = new char[10];
- Arrays.fill(charsLessThan0x20, (char) (' ' - 1));
- String stringStartingWithSpace =
- new String(charsLessThan0x20) + "hello" + new
String(charsLessThan0x20);
- assertThat(fromString(stringStartingWithSpace).trim())
- .isEqualTo(fromString(stringStartingWithSpace));
- assertThat(trimLeft(fromString(stringStartingWithSpace)))
- .isEqualTo(fromString(stringStartingWithSpace));
- assertThat(trimRight(fromString(stringStartingWithSpace)))
- .isEqualTo(fromString(stringStartingWithSpace));
- }
+ assertThat(BinaryStringData.EMPTY_UTF8.compareTo(str3)).isZero();
+ assertThat(str3.compareTo(BinaryStringData.EMPTY_UTF8)).isZero();
- @TestTemplate
- void testSqlSubstring() {
- assertThat(substringSQL(fromString("hello"),
2)).isEqualTo(fromString("ello"));
- assertThat(substringSQL(fromString("hello"), 2,
3)).isEqualTo(fromString("ell"));
- assertThat(substringSQL(empty, 2, 3)).isEqualTo(empty);
- assertThat(substringSQL(fromString("hello"), 0, -1)).isNull();
- assertThat(substringSQL(fromString("hello"), 10)).isEqualTo(empty);
- assertThat(substringSQL(fromString("hello"), 0,
3)).isEqualTo(fromString("hel"));
- assertThat(substringSQL(fromString("hello"), -2,
3)).isEqualTo(fromString("lo"));
- assertThat(substringSQL(fromString("hello"), -100,
3)).isEqualTo(empty);
- }
+ assertThat(str2).isNotEqualTo(BinaryStringData.EMPTY_UTF8);
+ assertThat(BinaryStringData.EMPTY_UTF8).isNotEqualTo(str2);
- @TestTemplate
- void reverseTest() {
-
assertThat(reverse(fromString("hello"))).isEqualTo(fromString("olleh"));
- assertThat(reverse(fromString("中国"))).isEqualTo(fromString("国中"));
- assertThat(reverse(fromString("hello, 中国"))).isEqualTo(fromString("国中
,olleh"));
- assertThat(reverse(empty)).isEqualTo(empty);
+ assertThat(str3).isEqualTo(BinaryStringData.EMPTY_UTF8);
+ assertThat(BinaryStringData.EMPTY_UTF8).isEqualTo(str3);
+ }
}
- @TestTemplate
- void indexOf() {
- assertThat(empty.indexOf(empty, 0)).isEqualTo(0);
- assertThat(empty.indexOf(fromString("l"), 0)).isEqualTo(-1);
- assertThat(fromString("hello").indexOf(empty, 0)).isEqualTo(0);
- assertThat(fromString("hello").indexOf(fromString("l"),
0)).isEqualTo(2);
- assertThat(fromString("hello").indexOf(fromString("l"),
3)).isEqualTo(3);
- assertThat(fromString("hello").indexOf(fromString("a"),
0)).isEqualTo(-1);
- assertThat(fromString("hello").indexOf(fromString("ll"),
0)).isEqualTo(2);
- assertThat(fromString("hello").indexOf(fromString("ll"),
4)).isEqualTo(-1);
- assertThat(fromString("数据砖头").indexOf(fromString("据砖"),
0)).isEqualTo(1);
- assertThat(fromString("数据砖头").indexOf(fromString("数"),
3)).isEqualTo(-1);
- assertThat(fromString("数据砖头").indexOf(fromString("数"),
0)).isEqualTo(0);
- assertThat(fromString("数据砖头").indexOf(fromString("头"),
0)).isEqualTo(3);
- }
+ @Nested
+ @DisplayName("Search")
+ class Search {
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void contains(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(empty.contains(empty)).isTrue();
+ assertThat(fromString(mode, "hello").contains(fromString(mode,
"ello"))).isTrue();
+ assertThat(fromString(mode, "hello").contains(fromString(mode,
"vello"))).isFalse();
+ assertThat(fromString(mode, "hello").contains(fromString(mode,
"hellooo"))).isFalse();
+ assertThat(fromString(mode, "大千世界").contains(fromString(mode,
"千世界"))).isTrue();
+ assertThat(fromString(mode, "大千世界").contains(fromString(mode,
"世千"))).isFalse();
+ assertThat(fromString(mode, "大千世界").contains(fromString(mode,
"大千世界好"))).isFalse();
+ }
- @TestTemplate
- void testToNumeric() {
- // Test to integer.
- assertThat(toByte(fromString("123"))).isEqualTo(Byte.parseByte("123"));
-
assertThat(toByte(fromString("+123"))).isEqualTo(Byte.parseByte("123"));
-
assertThat(toByte(fromString("-123"))).isEqualTo(Byte.parseByte("-123"));
-
-
assertThat(toShort(fromString("123"))).isEqualTo(Short.parseShort("123"));
-
assertThat(toShort(fromString("+123"))).isEqualTo(Short.parseShort("123"));
-
assertThat(toShort(fromString("-123"))).isEqualTo(Short.parseShort("-123"));
-
-
assertThat(toInt(fromString("123"))).isEqualTo(Integer.parseInt("123"));
-
assertThat(toInt(fromString("+123"))).isEqualTo(Integer.parseInt("123"));
-
assertThat(toInt(fromString("-123"))).isEqualTo(Integer.parseInt("-123"));
-
-
assertThat(toLong(fromString("1234567890"))).isEqualTo(Long.parseLong("1234567890"));
-
assertThat(toLong(fromString("+1234567890"))).isEqualTo(Long.parseLong("+1234567890"));
-
assertThat(toLong(fromString("-1234567890"))).isEqualTo(Long.parseLong("-1234567890"));
-
- // Test decimal string to integer.
-
assertThat(toInt(fromString("123.456789"))).isEqualTo(Integer.parseInt("123"));
-
assertThat(toLong(fromString("123.456789"))).isEqualTo(Long.parseLong("123"));
-
- // Test negative cases.
- assertThatThrownBy(() -> toInt(fromString("1a3.456789")))
- .isInstanceOf(NumberFormatException.class);
- assertThatThrownBy(() -> toInt(fromString("123.a56789")))
- .isInstanceOf(NumberFormatException.class);
-
- // Approximate numerics accept case-insensitive and abbreviated
special values.
- for (String infinity : new String[] {"Infinity", "infinity", "INF",
"inf", "+inf"}) {
-
assertThat(toFloat(fromString(infinity))).isEqualTo(Float.POSITIVE_INFINITY);
-
assertThat(toDouble(fromString(infinity))).isEqualTo(Double.POSITIVE_INFINITY);
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void startsWith(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(empty.startsWith(empty)).isTrue();
+ assertThat(fromString(mode, "hello").startsWith(fromString(mode,
"hell"))).isTrue();
+ assertThat(fromString(mode, "hello").startsWith(fromString(mode,
"ell"))).isFalse();
+ assertThat(fromString(mode, "hello").startsWith(fromString(mode,
"hellooo"))).isFalse();
+ assertThat(fromString(mode, "数据砖头").startsWith(fromString(mode,
"数据"))).isTrue();
+ assertThat(fromString(mode, "大千世界").startsWith(fromString(mode,
"千"))).isFalse();
+ assertThat(fromString(mode, "大千世界").startsWith(fromString(mode,
"大千世界好"))).isFalse();
}
- for (String negInfinity : new String[] {"-Infinity", "-infinity",
"-INF", " -inf "}) {
-
assertThat(toFloat(fromString(negInfinity))).isEqualTo(Float.NEGATIVE_INFINITY);
-
assertThat(toDouble(fromString(negInfinity))).isEqualTo(Double.NEGATIVE_INFINITY);
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void endsWith(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(empty.endsWith(empty)).isTrue();
+ assertThat(fromString(mode, "hello").endsWith(fromString(mode,
"ello"))).isTrue();
+ assertThat(fromString(mode, "hello").endsWith(fromString(mode,
"ellov"))).isFalse();
+ assertThat(fromString(mode, "hello").endsWith(fromString(mode,
"hhhello"))).isFalse();
+ assertThat(fromString(mode, "大千世界").endsWith(fromString(mode,
"世界"))).isTrue();
+ assertThat(fromString(mode, "大千世界").endsWith(fromString(mode,
"世"))).isFalse();
+ assertThat(fromString(mode, "数据砖头").endsWith(fromString(mode,
"我的数据砖头"))).isFalse();
}
- for (String nan : new String[] {"NaN", "nan", "NAN"}) {
- assertThat(toFloat(fromString(nan))).isNaN();
- assertThat(toDouble(fromString(nan))).isNaN();
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void indexOf(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(empty.indexOf(empty, 0)).isZero();
+ assertThat(empty.indexOf(fromString(mode, "l"), 0)).isEqualTo(-1);
+ assertThat(fromString(mode, "hello").indexOf(empty, 0)).isZero();
+ assertThat(fromString(mode, "hello").indexOf(fromString(mode,
"l"), 0)).isEqualTo(2);
+ assertThat(fromString(mode, "hello").indexOf(fromString(mode,
"l"), 3)).isEqualTo(3);
+ assertThat(fromString(mode, "hello").indexOf(fromString(mode,
"a"), 0)).isEqualTo(-1);
+ assertThat(fromString(mode, "hello").indexOf(fromString(mode,
"ll"), 0)).isEqualTo(2);
+ assertThat(fromString(mode, "hello").indexOf(fromString(mode,
"ll"), 4)).isEqualTo(-1);
+ assertThat(fromString(mode, "数据砖头").indexOf(fromString(mode,
"据砖"), 0)).isEqualTo(1);
+ assertThat(fromString(mode, "数据砖头").indexOf(fromString(mode, "数"),
3)).isEqualTo(-1);
+ assertThat(fromString(mode, "数据砖头").indexOf(fromString(mode, "数"),
0)).isZero();
+ assertThat(fromString(mode, "数据砖头").indexOf(fromString(mode, "头"),
0)).isEqualTo(3);
}
- // Ordinary numbers are unaffected and signed NaN stays invalid.
- assertThat(toDouble(fromString("1.5"))).isEqualTo(1.5);
- assertThatThrownBy(() -> toFloat(fromString("-nan")))
- .isInstanceOf(NumberFormatException.class);
- // Only the trimmed token matches: surrounding whitespace is allowed,
interior is not.
- assertThat(toDouble(fromString(" -infinity
"))).isEqualTo(Double.NEGATIVE_INFINITY);
- assertThatThrownBy(() -> toFloat(fromString("- Infinity")))
- .isInstanceOf(NumberFormatException.class);
-
- // Test composite in BinaryRowData.
- BinaryRowData row = new BinaryRowData(20);
- BinaryRowWriter writer = new BinaryRowWriter(row);
- writer.writeString(0, BinaryStringData.fromString("1"));
- writer.writeString(1, BinaryStringData.fromString("123"));
- writer.writeString(2, BinaryStringData.fromString("12345"));
- writer.writeString(3, BinaryStringData.fromString("123456789"));
- writer.complete();
-
- assertThat(toByte(((BinaryStringData)
row.getString(0)))).isEqualTo(Byte.parseByte("1"));
- assertThat(toShort(((BinaryStringData) row.getString(1))))
- .isEqualTo(Short.parseShort("123"));
- assertThat(toInt(((BinaryStringData) row.getString(2))))
- .isEqualTo(Integer.parseInt("12345"));
- assertThat(toLong(((BinaryStringData) row.getString(3))))
- .isEqualTo(Long.parseLong("123456789"));
}
- @TestTemplate
- void testToUpperLowerCase() {
-
assertThat(fromString("我是中国人").toLowerCase()).isEqualTo(fromString("我是中国人"));
-
assertThat(fromString("我是中国人").toUpperCase()).isEqualTo(fromString("我是中国人"));
-
-
assertThat(fromString("aBcDeFg").toLowerCase()).isEqualTo(fromString("abcdefg"));
-
assertThat(fromString("aBcDeFg").toUpperCase()).isEqualTo(fromString("ABCDEFG"));
-
-
assertThat(fromString("!@#$%^*").toLowerCase()).isEqualTo(fromString("!@#$%^*"));
-
assertThat(fromString("!@#$%^*").toLowerCase()).isEqualTo(fromString("!@#$%^*"));
- // Test composite in BinaryRowData.
- BinaryRowData row = new BinaryRowData(20);
- BinaryRowWriter writer = new BinaryRowWriter(row);
- writer.writeString(0, BinaryStringData.fromString("a"));
- writer.writeString(1, BinaryStringData.fromString("我是中国人"));
- writer.writeString(3, BinaryStringData.fromString("aBcDeFg"));
- writer.writeString(5, BinaryStringData.fromString("!@#$%^*"));
- writer.complete();
-
- assertThat(((BinaryStringData)
row.getString(0)).toUpperCase()).isEqualTo(fromString("A"));
- assertThat(((BinaryStringData) row.getString(1)).toUpperCase())
- .isEqualTo(fromString("我是中国人"));
- assertThat(((BinaryStringData) row.getString(1)).toLowerCase())
- .isEqualTo(fromString("我是中国人"));
- assertThat(((BinaryStringData) row.getString(3)).toUpperCase())
- .isEqualTo(fromString("ABCDEFG"));
- assertThat(((BinaryStringData) row.getString(3)).toLowerCase())
- .isEqualTo(fromString("abcdefg"));
- assertThat(((BinaryStringData) row.getString(5)).toUpperCase())
- .isEqualTo(fromString("!@#$%^*"));
- assertThat(((BinaryStringData) row.getString(5)).toLowerCase())
- .isEqualTo(fromString("!@#$%^*"));
- }
+ @Nested
+ @DisplayName("Manipulation")
+ class Manipulation {
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void concatTest(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(concat()).isEqualTo(empty);
+ assertThat(concat((BinaryStringData) null)).isNull();
+ assertThat(concat(empty)).isEqualTo(empty);
+ assertThat(concat(fromString(mode,
"ab"))).isEqualTo(fromString(mode, "ab"));
+ assertThat(concat(fromString(mode, "a"), fromString(mode, "b")))
+ .isEqualTo(fromString(mode, "ab"));
+ assertThat(concat(fromString(mode, "a"), fromString(mode, "b"),
fromString(mode, "c")))
+ .isEqualTo(fromString(mode, "abc"));
+ assertThat(concat(fromString(mode, "a"), null, fromString(mode,
"c"))).isNull();
+ assertThat(concat(fromString(mode, "a"), null, null)).isNull();
+ assertThat(concat(null, null, null)).isNull();
+ assertThat(concat(fromString(mode, "数据"), fromString(mode, "砖头")))
+ .isEqualTo(fromString(mode, "数据砖头"));
+ }
- @TestTemplate
- void testToDecimal() {
- class DecimalTestData {
- private String str;
- private int precision, scale;
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void concatWsTest(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ // Returns empty if the separator is null
+ assertThat(concatWs(null, (BinaryStringData) null)).isNull();
+ assertThat(concatWs(null, fromString(mode, "a"))).isNull();
+
+ // If separator is null, concatWs should skip all null inputs and
never return null.
+ BinaryStringData sep = fromString(mode, "哈哈");
+ assertThat(concatWs(sep, empty)).isEqualTo(empty);
+ assertThat(concatWs(sep, fromString(mode,
"ab"))).isEqualTo(fromString(mode, "ab"));
+ assertThat(concatWs(sep, fromString(mode, "a"), fromString(mode,
"b")))
+ .isEqualTo(fromString(mode, "a哈哈b"));
+ assertThat(
+ concatWs(
+ sep,
+ fromString(mode, "a"),
+ fromString(mode, "b"),
+ fromString(mode, "c")))
+ .isEqualTo(fromString(mode, "a哈哈b哈哈c"));
+ assertThat(concatWs(sep, fromString(mode, "a"), null,
fromString(mode, "c")))
+ .isEqualTo(fromString(mode, "a哈哈c"));
+ assertThat(concatWs(sep, fromString(mode, "a"), null, null))
+ .isEqualTo(fromString(mode, "a"));
+ assertThat(concatWs(sep, null, null, null)).isEqualTo(empty);
+ assertThat(concatWs(sep, fromString(mode, "数据"), fromString(mode,
"砖头")))
+ .isEqualTo(fromString(mode, "数据哈哈砖头"));
+ }
- private DecimalTestData(String str, int precision, int scale) {
- this.str = str;
- this.precision = precision;
- this.scale = scale;
- }
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void substring(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(fromString(mode, "hello").substring(0,
0)).isEqualTo(empty);
+ assertThat(fromString(mode, "hello").substring(1,
3)).isEqualTo(fromString(mode, "el"));
+ assertThat(fromString(mode, "数据砖头").substring(0,
1)).isEqualTo(fromString(mode, "数"));
+ assertThat(fromString(mode, "数据砖头").substring(1,
3)).isEqualTo(fromString(mode, "据砖"));
+ assertThat(fromString(mode, "数据砖头").substring(3,
5)).isEqualTo(fromString(mode, "头"));
+ assertThat(fromString(mode, "ߵ梷").substring(0,
2)).isEqualTo(fromString(mode, "ߵ梷"));
}
- DecimalTestData[] data = {
- new DecimalTestData("12.345", 5, 3),
- new DecimalTestData("-12.345", 5, 3),
- new DecimalTestData("+12345", 5, 0),
- new DecimalTestData("-12345", 5, 0),
- new DecimalTestData("12345.", 5, 0),
- new DecimalTestData("-12345.", 5, 0),
- new DecimalTestData(".12345", 5, 5),
- new DecimalTestData("-.12345", 5, 5),
- new DecimalTestData("+12.345E3", 5, 0),
- new DecimalTestData("-12.345e3", 5, 0),
- new DecimalTestData("12.345e-3", 6, 6),
- new DecimalTestData("-12.345E-3", 6, 6),
- new DecimalTestData("12345E3", 8, 0),
- new DecimalTestData("-12345e3", 8, 0),
- new DecimalTestData("12345e-3", 5, 3),
- new DecimalTestData("-12345E-3", 5, 3),
- new DecimalTestData("+.12345E3", 5, 2),
- new DecimalTestData("-.12345e3", 5, 2),
- new DecimalTestData(".12345e-3", 8, 8),
- new DecimalTestData("-.12345E-3", 8, 8),
- new DecimalTestData("1234512345.1234", 18, 8),
- new DecimalTestData("-1234512345.1234", 18, 8),
- new DecimalTestData("1234512345.1234", 12, 2),
- new DecimalTestData("-1234512345.1234", 12, 2),
- new DecimalTestData("1234512345.1299", 12, 2),
- new DecimalTestData("-1234512345.1299", 12, 2),
- new DecimalTestData("999999999999999999", 18, 0),
- new DecimalTestData("1234512345.1234512345", 20, 10),
- new DecimalTestData("-1234512345.1234512345", 20, 10),
- new DecimalTestData("1234512345.1234512345", 15, 5),
- new DecimalTestData("-1234512345.1234512345", 15, 5),
- new DecimalTestData("12345123451234512345E-10", 20, 10),
- new DecimalTestData("-12345123451234512345E-10", 20, 10),
- new DecimalTestData("12345123451234512345E-10", 15, 5),
- new DecimalTestData("-12345123451234512345E-10", 15, 5),
- new DecimalTestData("999999999999999999999", 21, 0),
- new DecimalTestData("-999999999999999999999", 21, 0),
- new DecimalTestData("0.00000000000000000000123456789123456789",
38, 38),
- new DecimalTestData("-0.00000000000000000000123456789123456789",
38, 38),
- new DecimalTestData("0.00000000000000000000123456789123456789",
29, 29),
- new DecimalTestData("-0.00000000000000000000123456789123456789",
29, 29),
- new DecimalTestData("123456789123E-27", 18, 18),
- new DecimalTestData("-123456789123E-27", 18, 18),
- new DecimalTestData("123456789999E-27", 18, 18),
- new DecimalTestData("-123456789999E-27", 18, 18),
- new DecimalTestData("123456789123456789E-36", 18, 18),
- new DecimalTestData("-123456789123456789E-36", 18, 18),
- new DecimalTestData("123456789999999999E-36", 18, 18),
- new DecimalTestData("-123456789999999999E-36", 18, 18)
- };
-
- for (DecimalTestData d : data) {
- assertThat(toDecimal(fromString(d.str), d.precision, d.scale))
- .isEqualTo(
- DecimalData.fromBigDecimal(
- new BigDecimal(d.str), d.precision,
d.scale));
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void trims(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(fromString(mode,
"1").trim()).isEqualTo(fromString(mode, "1"));
+
+ assertThat(fromString(mode, " hello
").trim()).isEqualTo(fromString(mode, "hello"));
+ assertThat(trimLeft(fromString(mode, " hello ")))
+ .isEqualTo(fromString(mode, "hello "));
+ assertThat(trimRight(fromString(mode, " hello ")))
+ .isEqualTo(fromString(mode, " hello"));
+
+ assertThat(trim(fromString(mode, " hello "), false, false,
fromString(mode, " ")))
+ .isEqualTo(fromString(mode, " hello "));
+ assertThat(trim(fromString(mode, " hello "), true, true,
fromString(mode, " ")))
+ .isEqualTo(fromString(mode, "hello"));
+ assertThat(trim(fromString(mode, " hello "), true, false,
fromString(mode, " ")))
+ .isEqualTo(fromString(mode, "hello "));
+ assertThat(trim(fromString(mode, " hello "), false, true,
fromString(mode, " ")))
+ .isEqualTo(fromString(mode, " hello"));
+ assertThat(trim(fromString(mode, "xxxhellox"), true, true,
fromString(mode, "x")))
+ .isEqualTo(fromString(mode, "hello"));
+
+ assertThat(trim(fromString(mode, "xxxhellox"), fromString(mode,
"xoh")))
+ .isEqualTo(fromString(mode, "ell"));
+
+ assertThat(trimLeft(fromString(mode, "xxxhellox"),
fromString(mode, "xoh")))
+ .isEqualTo(fromString(mode, "ellox"));
+
+ assertThat(trimRight(fromString(mode, "xxxhellox"),
fromString(mode, "xoh")))
+ .isEqualTo(fromString(mode, "xxxhell"));
+
+ assertThat(empty.trim()).isEqualTo(empty);
+ assertThat(fromString(mode, " ").trim()).isEqualTo(empty);
+ assertThat(trimLeft(fromString(mode, " "))).isEqualTo(empty);
+ assertThat(trimRight(fromString(mode, " "))).isEqualTo(empty);
+
+ assertThat(fromString(mode, " 数据砖头
").trim()).isEqualTo(fromString(mode, "数据砖头"));
+ assertThat(trimLeft(fromString(mode, " 数据砖头
"))).isEqualTo(fromString(mode, "数据砖头 "));
+ assertThat(trimRight(fromString(mode, " 数据砖头 ")))
+ .isEqualTo(fromString(mode, " 数据砖头"));
+
+ assertThat(fromString(mode,
"数据砖头").trim()).isEqualTo(fromString(mode, "数据砖头"));
+ assertThat(trimLeft(fromString(mode,
"数据砖头"))).isEqualTo(fromString(mode, "数据砖头"));
+ assertThat(trimRight(fromString(mode,
"数据砖头"))).isEqualTo(fromString(mode, "数据砖头"));
+
+ assertThat(trim(fromString(mode, "年年岁岁, 岁岁年年"), fromString(mode,
"年岁 ")))
+ .isEqualTo(fromString(mode, ","));
+ assertThat(trimLeft(fromString(mode, "年年岁岁, 岁岁年年"),
fromString(mode, "年岁 ")))
+ .isEqualTo(fromString(mode, ", 岁岁年年"));
+ assertThat(trimRight(fromString(mode, "年年岁岁, 岁岁年年"),
fromString(mode, "年岁 ")))
+ .isEqualTo(fromString(mode, "年年岁岁,"));
+
+ char[] charsLessThan0x20 = new char[10];
+ Arrays.fill(charsLessThan0x20, (char) (' ' - 1));
+ String stringStartingWithSpace =
+ new String(charsLessThan0x20) + "hello" + new
String(charsLessThan0x20);
+ assertThat(fromString(mode, stringStartingWithSpace).trim())
+ .isEqualTo(fromString(mode, stringStartingWithSpace));
+ assertThat(trimLeft(fromString(mode, stringStartingWithSpace)))
+ .isEqualTo(fromString(mode, stringStartingWithSpace));
+ assertThat(trimRight(fromString(mode, stringStartingWithSpace)))
+ .isEqualTo(fromString(mode, stringStartingWithSpace));
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void testSqlSubstring(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(substringSQL(fromString(mode, "hello"), 2))
+ .isEqualTo(fromString(mode, "ello"));
+ assertThat(substringSQL(fromString(mode, "hello"), 2, 3))
+ .isEqualTo(fromString(mode, "ell"));
+ assertThat(substringSQL(empty, 2, 3)).isEqualTo(empty);
+ assertThat(substringSQL(fromString(mode, "hello"), 0,
-1)).isNull();
+ assertThat(substringSQL(fromString(mode, "hello"),
10)).isEqualTo(empty);
+ assertThat(substringSQL(fromString(mode, "hello"), 0, 3))
+ .isEqualTo(fromString(mode, "hel"));
+ assertThat(substringSQL(fromString(mode, "hello"), -2, 3))
+ .isEqualTo(fromString(mode, "lo"));
+ assertThat(substringSQL(fromString(mode, "hello"), -100,
3)).isEqualTo(empty);
}
- BinaryRowData row = new BinaryRowData(data.length);
- BinaryRowWriter writer = new BinaryRowWriter(row);
- for (int i = 0; i < data.length; i++) {
- writer.writeString(i, BinaryStringData.fromString(data[i].str));
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void reverseTest(Mode mode) {
+ BinaryStringData empty = fromString(mode, "");
+ assertThat(reverse(fromString(mode,
"hello"))).isEqualTo(fromString(mode, "olleh"));
+ assertThat(reverse(fromString(mode,
"中国"))).isEqualTo(fromString(mode, "国中"));
+ assertThat(reverse(fromString(mode, "hello, 中国")))
+ .isEqualTo(fromString(mode, "国中 ,olleh"));
+ assertThat(reverse(empty)).isEqualTo(empty);
}
- writer.complete();
- for (int i = 0; i < data.length; i++) {
- DecimalTestData d = data[i];
- assertThat(toDecimal((BinaryStringData) row.getString(i),
d.precision, d.scale))
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void testSplit(Mode mode) {
+ assertThat(
+ splitByWholeSeparatorPreserveAllTokens(
+ fromString(mode, ""), fromString(mode,
"")))
+ .isEqualTo(EMPTY_STRING_ARRAY);
+ assertThat(splitByWholeSeparatorPreserveAllTokens(fromString(mode,
"ab de fg"), null))
+ .isEqualTo(
+ new BinaryStringData[] {
+ fromString(mode, "ab"),
+ fromString(mode, "de"),
+ fromString(mode, "fg")
+ });
+ assertThat(splitByWholeSeparatorPreserveAllTokens(fromString(mode,
"ab de fg"), null))
+ .isEqualTo(
+ new BinaryStringData[] {
+ fromString(mode, "ab"),
+ fromString(mode, ""),
+ fromString(mode, ""),
+ fromString(mode, "de"),
+ fromString(mode, "fg")
+ });
+ assertThat(
+ splitByWholeSeparatorPreserveAllTokens(
+ fromString(mode, "ab:cd:ef"),
fromString(mode, ":")))
.isEqualTo(
- DecimalData.fromBigDecimal(
- new BigDecimal(d.str), d.precision,
d.scale));
+ new BinaryStringData[] {
+ fromString(mode, "ab"),
+ fromString(mode, "cd"),
+ fromString(mode, "ef")
+ });
+ assertThat(
+ splitByWholeSeparatorPreserveAllTokens(
+ fromString(mode, "ab-!-cd-!-ef"),
fromString(mode, "-!-")))
+ .isEqualTo(
+ new BinaryStringData[] {
+ fromString(mode, "ab"),
+ fromString(mode, "cd"),
+ fromString(mode, "ef")
+ });
}
}
- @TestTemplate
- void testEmptyString() {
- BinaryStringData str2 = fromString("hahahahah");
- BinaryStringData str3;
- {
- MemorySegment[] segments = new MemorySegment[2];
- segments[0] = MemorySegmentFactory.wrap(new byte[10]);
- segments[1] = MemorySegmentFactory.wrap(new byte[10]);
- str3 = BinaryStringData.fromAddress(segments, 15, 0);
+ @Nested
+ @DisplayName("Conversion")
+ class Conversion {
+
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ void toIntegralTypes(Mode mode) {
+ // Test to integer.
+ assertThat(toByte(fromString(mode,
"123"))).isEqualTo(Byte.parseByte("123"));
+ assertThat(toByte(fromString(mode,
"+123"))).isEqualTo(Byte.parseByte("123"));
+ assertThat(toByte(fromString(mode,
"-123"))).isEqualTo(Byte.parseByte("-123"));
+
+ assertThat(toShort(fromString(mode,
"123"))).isEqualTo(Short.parseShort("123"));
+ assertThat(toShort(fromString(mode,
"+123"))).isEqualTo(Short.parseShort("123"));
+ assertThat(toShort(fromString(mode,
"-123"))).isEqualTo(Short.parseShort("-123"));
+
+ assertThat(toInt(fromString(mode,
"123"))).isEqualTo(Integer.parseInt("123"));
+ assertThat(toInt(fromString(mode,
"+123"))).isEqualTo(Integer.parseInt("123"));
+ assertThat(toInt(fromString(mode,
"-123"))).isEqualTo(Integer.parseInt("-123"));
+
+ assertThat(toLong(fromString(mode, "1234567890")))
+ .isEqualTo(Long.parseLong("1234567890"));
+ assertThat(toLong(fromString(mode, "+1234567890")))
+ .isEqualTo(Long.parseLong("+1234567890"));
+ assertThat(toLong(fromString(mode, "-1234567890")))
+ .isEqualTo(Long.parseLong("-1234567890"));
+
+ // Test decimal string to integer.
+ assertThat(toInt(fromString(mode,
"123.456789"))).isEqualTo(Integer.parseInt("123"));
+ assertThat(toLong(fromString(mode,
"123.456789"))).isEqualTo(Long.parseLong("123"));
+
+ // Test negative cases.
+ assertThatThrownBy(() -> toInt(fromString(mode, "1a3.456789")))
+ .isInstanceOf(NumberFormatException.class);
+ assertThatThrownBy(() -> toInt(fromString(mode, "123.a56789")))
+ .isInstanceOf(NumberFormatException.class);
}
- assertThat(BinaryStringData.EMPTY_UTF8.compareTo(str2)).isLessThan(0);
-
assertThat(str2.compareTo(BinaryStringData.EMPTY_UTF8)).isGreaterThan(0);
+ @ParameterizedTest(name = "{0}")
+ @EnumSource(Mode.class)
+ @DisplayName("approximate numerics accept case-insensitive/abbreviated
special values")
+ void toApproximateSpecialValues(Mode mode) {
+ for (String infinity : new String[] {"Infinity", "infinity",
"INF", "inf", "+inf"}) {
+ assertThat(toFloat(fromString(mode,
infinity))).isEqualTo(Float.POSITIVE_INFINITY);
+ assertThat(toDouble(fromString(mode, infinity)))
+ .isEqualTo(Double.POSITIVE_INFINITY);
+ }
+ for (String negInfinity : new String[] {"-Infinity", "-infinity",
"-INF", " -inf "}) {
+ assertThat(toFloat(fromString(mode, negInfinity)))
+ .isEqualTo(Float.NEGATIVE_INFINITY);
+ assertThat(toDouble(fromString(mode, negInfinity)))
+ .isEqualTo(Double.NEGATIVE_INFINITY);
+ }
+ for (String nan : new String[] {"NaN", "nan", "NAN"}) {
+ assertThat(toFloat(fromString(mode, nan))).isNaN();
+ assertThat(toDouble(fromString(mode, nan))).isNaN();
+ }
+ // Ordinary numbers are unaffected and signed NaN stays invalid.
+ assertThat(toDouble(fromString(mode, "1.5"))).isEqualTo(1.5);
+ assertThatThrownBy(() -> toFloat(fromString(mode, "-nan")))
+ .isInstanceOf(NumberFormatException.class);
+ // Only the trimmed token matches: surrounding whitespace is
allowed, interior is not.
+ assertThat(toDouble(fromString(mode, " -infinity ")))
+ .isEqualTo(Double.NEGATIVE_INFINITY);
+ assertThatThrownBy(() -> toFloat(fromString(mode, "- Infinity")))
+ .isInstanceOf(NumberFormatException.class);
+ }
Review Comment:
we have several loops where in each try to go through string variations of
special values...
can we instead split into several parameterized tests: one for nan, one for
infinity, one for negative infinity, one for numberformatexception?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]