| 1 | package be.nikiroo.utils.test_code; |
| 2 | |
| 3 | import java.util.Arrays; |
| 4 | import java.util.Date; |
| 5 | import java.util.HashMap; |
| 6 | import java.util.List; |
| 7 | import java.util.Map; |
| 8 | import java.util.Map.Entry; |
| 9 | |
| 10 | import be.nikiroo.utils.StringUtils; |
| 11 | import be.nikiroo.utils.StringUtils.Alignment; |
| 12 | import be.nikiroo.utils.test.TestCase; |
| 13 | import be.nikiroo.utils.test.TestLauncher; |
| 14 | |
| 15 | class StringUtilsTest extends TestLauncher { |
| 16 | public StringUtilsTest(String[] args) { |
| 17 | super("StringUtils test", args); |
| 18 | |
| 19 | addTest(new TestCase("Time serialisation") { |
| 20 | @Override |
| 21 | public void test() throws Exception { |
| 22 | for (long fullTime : new Long[] { 0l, 123456l, 123456000l, |
| 23 | new Date().getTime() }) { |
| 24 | // precise to the second, no more |
| 25 | long time = (fullTime / 1000) * 1000; |
| 26 | |
| 27 | String displayTime = StringUtils.fromTime(time); |
| 28 | assertNotNull("The stringified time for " + time |
| 29 | + " should not be null", displayTime); |
| 30 | assertEquals("The stringified time for " + time |
| 31 | + " should not be empty", false, displayTime.trim() |
| 32 | .isEmpty()); |
| 33 | |
| 34 | assertEquals("The time " + time |
| 35 | + " should be loop-convertable", time, |
| 36 | StringUtils.toTime(displayTime)); |
| 37 | |
| 38 | assertEquals("The time " + displayTime |
| 39 | + " should be loop-convertable", displayTime, |
| 40 | StringUtils.fromTime(StringUtils |
| 41 | .toTime(displayTime))); |
| 42 | } |
| 43 | } |
| 44 | }); |
| 45 | |
| 46 | addTest(new TestCase("MD5") { |
| 47 | @Override |
| 48 | public void test() throws Exception { |
| 49 | String mess = "The String we got is not what 'md5sum' said it should heve been"; |
| 50 | assertEquals(mess, "34ded48fcff4221d644be9a37e1cb1d9", |
| 51 | StringUtils.getMd5Hash("fanfan la tulipe")); |
| 52 | assertEquals(mess, "7691b0cb74ed0f94b4d8cd858abe1165", |
| 53 | StringUtils.getMd5Hash("je te do-o-o-o-o-o-nne")); |
| 54 | } |
| 55 | }); |
| 56 | |
| 57 | addTest(new TestCase("Padding") { |
| 58 | @Override |
| 59 | public void test() throws Exception { |
| 60 | for (String data : new String[] { "fanfan", "la tulipe", |
| 61 | "1234567890", "12345678901234567890", "1", "" }) { |
| 62 | String result = StringUtils.padString(data, -1); |
| 63 | assertEquals("A size of -1 is expected to produce a noop", |
| 64 | true, data.equals(result)); |
| 65 | for (int size : new Integer[] { 0, 1, 5, 10, 40 }) { |
| 66 | result = StringUtils.padString(data, size); |
| 67 | assertEquals( |
| 68 | "Padding a String at a certain size should give a String of the given size", |
| 69 | size, result.length()); |
| 70 | assertEquals( |
| 71 | "Padding a String should not change the content", |
| 72 | true, data.trim().startsWith(result.trim())); |
| 73 | |
| 74 | result = StringUtils.padString(data, size, false, null); |
| 75 | assertEquals( |
| 76 | "Padding a String without cutting should not shorten the String", |
| 77 | true, data.length() <= result.length()); |
| 78 | assertEquals( |
| 79 | "Padding a String without cutting should keep the whole content", |
| 80 | true, data.trim().equals(result.trim())); |
| 81 | |
| 82 | result = StringUtils.padString(data, size, false, |
| 83 | Alignment.RIGHT); |
| 84 | if (size > data.length()) { |
| 85 | assertEquals( |
| 86 | "Padding a String to the end should work as expected", |
| 87 | true, result.endsWith(data)); |
| 88 | } |
| 89 | |
| 90 | result = StringUtils.padString(data, size, false, |
| 91 | Alignment.JUSTIFY); |
| 92 | if (size > data.length()) { |
| 93 | String unspacedData = data.trim(); |
| 94 | String unspacedResult = result.trim(); |
| 95 | for (int i = 0; i < size; i++) { |
| 96 | unspacedData = unspacedData.replace(" ", " "); |
| 97 | unspacedResult = unspacedResult.replace(" ", |
| 98 | " "); |
| 99 | } |
| 100 | |
| 101 | assertEquals( |
| 102 | "Justified text trimmed with all spaces collapsed " |
| 103 | + "sould be identical to original text " |
| 104 | + "trimmed with all spaces collapsed", |
| 105 | unspacedData, unspacedResult); |
| 106 | } |
| 107 | |
| 108 | result = StringUtils.padString(data, size, false, |
| 109 | Alignment.CENTER); |
| 110 | if (size > data.length()) { |
| 111 | int before = 0; |
| 112 | for (int i = 0; i < result.length() |
| 113 | && result.charAt(i) == ' '; i++) { |
| 114 | before++; |
| 115 | } |
| 116 | |
| 117 | int after = 0; |
| 118 | for (int i = result.length() - 1; i >= 0 |
| 119 | && result.charAt(i) == ' '; i--) { |
| 120 | after++; |
| 121 | } |
| 122 | |
| 123 | if (result.trim().isEmpty()) { |
| 124 | after = before / 2; |
| 125 | if (before > (2 * after)) { |
| 126 | before = after + 1; |
| 127 | } else { |
| 128 | before = after; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | assertEquals( |
| 133 | "Padding a String on center should work as expected", |
| 134 | result.length(), before + data.length() |
| 135 | + after); |
| 136 | assertEquals( |
| 137 | "Padding a String on center should not uncenter the content", |
| 138 | true, Math.abs(before - after) <= 1); |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | }); |
| 144 | |
| 145 | addTest(new TestCase("Justifying") { |
| 146 | @Override |
| 147 | public void test() throws Exception { |
| 148 | Map<String, Map<Integer, Entry<Alignment, List<String>>>> source = new HashMap<String, Map<Integer, Entry<Alignment, List<String>>>>(); |
| 149 | addValue(source, Alignment.LEFT, "testy", -1, "testy"); |
| 150 | addValue(source, Alignment.RIGHT, "testy", -1, "testy"); |
| 151 | addValue(source, Alignment.CENTER, "testy", -1, "testy"); |
| 152 | addValue(source, Alignment.JUSTIFY, "testy", -1, "testy"); |
| 153 | addValue(source, Alignment.LEFT, "testy", 5, "testy"); |
| 154 | addValue(source, Alignment.LEFT, "testy", 3, "te-", "sty"); |
| 155 | addValue(source, Alignment.LEFT, |
| 156 | "Un petit texte qui se mettra sur plusieurs lignes", |
| 157 | 10, "Un petit", "texte qui", "se mettra", "sur", |
| 158 | "plusieurs", "lignes"); |
| 159 | addValue(source, Alignment.LEFT, |
| 160 | "Un petit texte qui se mettra sur plusieurs lignes", 7, |
| 161 | "Un", "petit", "texte", "qui se", "mettra", "sur", |
| 162 | "plusie-", "urs", "lignes"); |
| 163 | addValue(source, Alignment.RIGHT, |
| 164 | "Un petit texte qui se mettra sur plusieurs lignes", 7, |
| 165 | " Un", " petit", " texte", " qui se", " mettra", |
| 166 | " sur", "plusie-", " urs", " lignes"); |
| 167 | addValue(source, Alignment.CENTER, |
| 168 | "Un petit texte qui se mettra sur plusieurs lignes", 7, |
| 169 | " Un ", " petit ", " texte ", "qui se ", "mettra ", |
| 170 | " sur ", "plusie-", " urs ", "lignes "); |
| 171 | addValue(source, Alignment.JUSTIFY, |
| 172 | "Un petit texte qui se mettra sur plusieurs lignes", 7, |
| 173 | "Un pet-", "it tex-", "te qui", "se met-", "tra sur", |
| 174 | "plusie-", "urs li-", "gnes"); |
| 175 | addValue(source, Alignment.JUSTIFY, |
| 176 | "Un petit texte qui se mettra sur plusieurs lignes", |
| 177 | 14, "Un petit", "texte qui se", |
| 178 | "mettra sur", "plusieurs lig-", "nes"); |
| 179 | addValue(source, Alignment.JUSTIFY, "le dash-test", 9, |
| 180 | "le dash-", "test"); |
| 181 | |
| 182 | for (String data : source.keySet()) { |
| 183 | for (int size : source.get(data).keySet()) { |
| 184 | Alignment align = source.get(data).get(size).getKey(); |
| 185 | List<String> values = source.get(data).get(size) |
| 186 | .getValue(); |
| 187 | |
| 188 | List<String> result = StringUtils.justifyText(data, |
| 189 | size, align); |
| 190 | |
| 191 | // System.out.println("[" + data + " (" + size + ")" + |
| 192 | // "] -> ["); |
| 193 | // for (int i = 0; i < result.size(); i++) { |
| 194 | // String resultLine = result.get(i); |
| 195 | // System.out.println(i + ": " + resultLine); |
| 196 | // } |
| 197 | // System.out.println("]"); |
| 198 | |
| 199 | assertEquals(values, result); |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | }); |
| 204 | |
| 205 | addTest(new TestCase("unhtml") { |
| 206 | @Override |
| 207 | public void test() throws Exception { |
| 208 | Map<String, String> data = new HashMap<String, String>(); |
| 209 | data.put("aa", "aa"); |
| 210 | data.put("test with spaces ", "test with spaces "); |
| 211 | data.put("<a href='truc://target/'>link</a>", "link"); |
| 212 | data.put("<html>Digimon</html>", "Digimon"); |
| 213 | data.put("", ""); |
| 214 | data.put(" ", " "); |
| 215 | |
| 216 | for (Entry<String, String> entry : data.entrySet()) { |
| 217 | String result = StringUtils.unhtml(entry.getKey()); |
| 218 | assertEquals("Result is not what we expected", |
| 219 | entry.getValue(), result); |
| 220 | } |
| 221 | } |
| 222 | }); |
| 223 | |
| 224 | addTest(new TestCase("zip64") { |
| 225 | @Override |
| 226 | public void test() throws Exception { |
| 227 | String orig = "test"; |
| 228 | String zipped = StringUtils.base64(orig, true); |
| 229 | String unzipped = StringUtils.unbase64s(zipped, true); |
| 230 | assertEquals(orig, unzipped); |
| 231 | } |
| 232 | }); |
| 233 | |
| 234 | addTest(new TestCase("format/toNumber simple") { |
| 235 | @Override |
| 236 | public void test() throws Exception { |
| 237 | assertEquals(263l, StringUtils.toNumber("263")); |
| 238 | assertEquals(21200l, StringUtils.toNumber("21200")); |
| 239 | assertEquals(0l, StringUtils.toNumber("0")); |
| 240 | assertEquals("263", StringUtils.formatNumber(263l)); |
| 241 | assertEquals("21 k", StringUtils.formatNumber(21000l)); |
| 242 | assertEquals("0", StringUtils.formatNumber(0l)); |
| 243 | } |
| 244 | }); |
| 245 | |
| 246 | addTest(new TestCase("format/toNumber not 000") { |
| 247 | @Override |
| 248 | public void test() throws Exception { |
| 249 | assertEquals(263200l, StringUtils.toNumber("263.2 k")); |
| 250 | assertEquals(42000l, StringUtils.toNumber("42.0 k")); |
| 251 | assertEquals(12000000l, StringUtils.toNumber("12 M")); |
| 252 | assertEquals(2000000000l, StringUtils.toNumber("2 G")); |
| 253 | assertEquals("263 k", StringUtils.formatNumber(263012l)); |
| 254 | assertEquals("42 k", StringUtils.formatNumber(42012l)); |
| 255 | assertEquals("12 M", StringUtils.formatNumber(12012121l)); |
| 256 | assertEquals("7 G", StringUtils.formatNumber(7364635928l)); |
| 257 | } |
| 258 | }); |
| 259 | |
| 260 | addTest(new TestCase("format/toNumber decimals") { |
| 261 | @Override |
| 262 | public void test() throws Exception { |
| 263 | assertEquals(263200l, StringUtils.toNumber("263.2 k")); |
| 264 | assertEquals(1200l, StringUtils.toNumber("1.2 k")); |
| 265 | assertEquals(42700000l, StringUtils.toNumber("42.7 M")); |
| 266 | assertEquals(1220l, StringUtils.toNumber("1.22 k")); |
| 267 | assertEquals(1432l, StringUtils.toNumber("1.432 k")); |
| 268 | assertEquals(6938l, StringUtils.toNumber("6.938 k")); |
| 269 | assertEquals("1.3 k", StringUtils.formatNumber(1300l, 1)); |
| 270 | assertEquals("263.2020 k", StringUtils.formatNumber(263202l, 4)); |
| 271 | assertEquals("1.26 k", StringUtils.formatNumber(1267l, 2)); |
| 272 | assertEquals("42.7 M", StringUtils.formatNumber(42712121l, 1)); |
| 273 | assertEquals("5.09 G", StringUtils.formatNumber(5094837485l, 2)); |
| 274 | } |
| 275 | }); |
| 276 | } |
| 277 | |
| 278 | static private void addValue( |
| 279 | Map<String, Map<Integer, Entry<Alignment, List<String>>>> source, |
| 280 | final Alignment align, String input, int size, |
| 281 | final String... result) { |
| 282 | if (!source.containsKey(input)) { |
| 283 | source.put(input, |
| 284 | new HashMap<Integer, Entry<Alignment, List<String>>>()); |
| 285 | } |
| 286 | |
| 287 | source.get(input).put(size, new Entry<Alignment, List<String>>() { |
| 288 | @Override |
| 289 | public Alignment getKey() { |
| 290 | return align; |
| 291 | } |
| 292 | |
| 293 | @Override |
| 294 | public List<String> getValue() { |
| 295 | return Arrays.asList(result); |
| 296 | } |
| 297 | |
| 298 | @Override |
| 299 | public List<String> setValue(List<String> value) { |
| 300 | return null; |
| 301 | } |
| 302 | }); |
| 303 | } |
| 304 | } |