| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.fury.meta; |
| |
| import static org.testng.Assert.assertEquals; |
| import static org.testng.Assert.assertNotSame; |
| import static org.testng.AssertJUnit.assertSame; |
| |
| import org.apache.fury.util.StringUtils; |
| import org.testng.annotations.DataProvider; |
| import org.testng.annotations.Test; |
| |
| public class MetaStringTest { |
| |
| @Test |
| public void testEncodeMetaStringLowerSpecial() { |
| // special chars not matter for encodeLowerSpecial |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| byte[] encoded = encoder.encodeLowerSpecial("abc_def"); |
| assertEquals(encoded.length, 5); |
| // utf8 use 30 bytes, we use only 19 bytes |
| assertEquals(encoder.encode("org.apache.fury.benchmark.data").getBytes().length, 19); |
| // utf8 use 12 bytes, we use only 9 bytes. |
| assertEquals(encoder.encode("MediaContent").getBytes().length, 9); |
| MetaStringDecoder decoder = new MetaStringDecoder('_', '$'); |
| String decoded = decoder.decode(encoded, MetaString.Encoding.LOWER_SPECIAL, 7 * 5); |
| assertEquals(decoded, "abc_def"); |
| for (int i = 0; i < 128; i++) { |
| StringBuilder builder = new StringBuilder(); |
| for (int j = 0; j < i; j++) { |
| builder.append((char) ('a' + j % 26)); |
| } |
| String str = builder.toString(); |
| encoded = encoder.encodeLowerSpecial(str); |
| decoded = decoder.decode(encoded, MetaString.Encoding.LOWER_SPECIAL, i * 5); |
| assertEquals(decoded, str); |
| } |
| } |
| |
| @Test |
| public void testEncodeMetaStringLowerUpperDigitSpecial() { |
| char specialChar1 = '.'; |
| char specialChar2 = '_'; |
| MetaStringEncoder encoder = new MetaStringEncoder(specialChar1, specialChar2); |
| byte[] encoded = encoder.encodeLowerUpperDigitSpecial("ExampleInput123"); |
| assertEquals(encoded.length, 12); |
| MetaStringDecoder decoder = new MetaStringDecoder(specialChar1, specialChar2); |
| String decoded = decoder.decode(encoded, MetaString.Encoding.LOWER_UPPER_DIGIT_SPECIAL, 15 * 6); |
| assertEquals(decoded, "ExampleInput123"); |
| |
| for (int i = 1; i < 128; i++) { |
| String str = createString(i, specialChar1, specialChar2); |
| encoded = encoder.encodeLowerUpperDigitSpecial(str); |
| decoded = decoder.decode(encoded, MetaString.Encoding.LOWER_UPPER_DIGIT_SPECIAL, i * 6); |
| assertEquals(decoded, str, "Failed at " + i); |
| } |
| } |
| |
| private static String createString(int i, char specialChar1, char specialChar2) { |
| StringBuilder builder = new StringBuilder(); |
| for (int j = 0; j < i; j++) { |
| int n = j % 64; |
| char c; |
| if (n < 26) { |
| c = (char) ('a' + n); |
| } else if (n < 52) { |
| c = (char) ('A' + n - 26); |
| } else if (n < 62) { |
| c = (char) ('0' + n - 52); |
| } else if (n == 62) { |
| c = specialChar1; |
| } else { |
| c = specialChar2; |
| } |
| builder.append(c); |
| } |
| StringUtils.shuffle(builder); |
| return builder.toString(); |
| } |
| |
| @DataProvider |
| public static Object[][] specialChars() { |
| return new Object[][] {{'.', '_'}, {'.', '$'}, {'_', '$'}}; |
| } |
| |
| @Test(dataProvider = "specialChars") |
| public void testMetaString(char specialChar1, char specialChar2) { |
| MetaStringEncoder encoder = new MetaStringEncoder(specialChar1, specialChar2); |
| for (int i = 0; i < 128; i++) { |
| try { |
| String str = createString(i, specialChar1, specialChar2); |
| MetaString metaString = encoder.encode(str); |
| assertNotSame(metaString.getEncoding(), MetaString.Encoding.UTF_8); |
| assertEquals(metaString.getString(), str); |
| assertEquals(metaString.getSpecialChar1(), specialChar1); |
| assertEquals(metaString.getSpecialChar2(), specialChar2); |
| MetaStringDecoder decoder = new MetaStringDecoder(specialChar1, specialChar2); |
| String newStr = |
| decoder.decode( |
| metaString.getBytes(), metaString.getEncoding(), metaString.getNumBits()); |
| assertEquals(newStr, str); |
| } catch (Throwable e) { |
| throw new RuntimeException("Failed at " + i, e); |
| } |
| } |
| } |
| |
| @DataProvider(name = "emptyStringProvider") |
| public Object[][] emptyStringProvider() { |
| return new Object[][] { |
| {MetaString.Encoding.LOWER_SPECIAL}, |
| {MetaString.Encoding.LOWER_UPPER_DIGIT_SPECIAL}, |
| {MetaString.Encoding.FIRST_TO_LOWER_SPECIAL}, |
| {MetaString.Encoding.ALL_TO_LOWER_SPECIAL}, |
| {MetaString.Encoding.UTF_8} |
| }; |
| } |
| |
| @Test(dataProvider = "emptyStringProvider") |
| public void testEncodeEmptyString(MetaString.Encoding encoding) { |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| MetaString metaString = encoder.encode("", encoding); |
| assertEquals(metaString.getBytes().length, 0); |
| MetaStringDecoder decoder = new MetaStringDecoder('_', '$'); |
| String decoded = |
| decoder.decode(metaString.getBytes(), metaString.getEncoding(), metaString.getNumBits()); |
| assertEquals(decoded, ""); |
| } |
| |
| @Test |
| public void testEncodeCharactersOutsideOfLowerSpecial() { |
| // Contains characters outside LOWER_SPECIAL |
| String testString = "abcdefABCDEF1234!@#"; |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| MetaString encodedMetaString = encoder.encode(testString); |
| assertSame(encodedMetaString.getEncoding(), MetaString.Encoding.UTF_8); |
| } |
| |
| @Test |
| public void testAllToUpperSpecialEncoding() { |
| String testString = "ABC_DEF"; |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| MetaString encodedMetaString = encoder.encode(testString); |
| assertEquals(encodedMetaString.getEncoding(), MetaString.Encoding.LOWER_UPPER_DIGIT_SPECIAL); |
| |
| MetaStringDecoder decoder = new MetaStringDecoder('_', '$'); |
| String decodedString = |
| decoder.decode( |
| encodedMetaString.getBytes(), |
| encodedMetaString.getEncoding(), |
| encodedMetaString.getNumBits()); |
| assertEquals(decodedString, testString); |
| } |
| |
| @Test |
| public void testFirstToLowerSpecialEncoding() { |
| String testString = "Aabcdef"; |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| MetaString encodedMetaString = encoder.encode(testString); |
| assertEquals(encodedMetaString.getEncoding(), MetaString.Encoding.FIRST_TO_LOWER_SPECIAL); |
| |
| MetaStringDecoder decoder = new MetaStringDecoder('_', '$'); |
| String decodedString = |
| decoder.decode( |
| encodedMetaString.getBytes(), |
| encodedMetaString.getEncoding(), |
| encodedMetaString.getNumBits()); |
| assertEquals(decodedString, testString); |
| } |
| |
| @Test |
| public void testUtf8Encoding() { |
| String testString = "你好,世界"; // Non-Latin characters |
| MetaStringEncoder encoder = new MetaStringEncoder('_', '$'); |
| MetaString encodedMetaString = encoder.encode(testString); |
| assertEquals(encodedMetaString.getEncoding(), MetaString.Encoding.UTF_8); |
| |
| MetaStringDecoder decoder = new MetaStringDecoder('_', '$'); |
| String decodedString = |
| decoder.decode( |
| encodedMetaString.getBytes(), |
| encodedMetaString.getEncoding(), |
| encodedMetaString.getNumBits()); |
| assertEquals(decodedString, testString); |
| } |
| } |