001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.util; 017 018import static org.hamcrest.core.Is.is; 019import static org.junit.Assert.assertArrayEquals; 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertThat; 022import static org.hamcrest.CoreMatchers.containsString; 023import java.io.ByteArrayInputStream; 024import java.io.ByteArrayOutputStream; 025import java.io.IOException; 026import java.io.InputStream; 027import java.io.PrintStream; 028import java.io.Reader; 029import java.io.StringReader; 030import java.util.List; 031import org.junit.Test; 032import org.modeshape.common.FixFor; 033 034public class StringUtilTest { 035 036 public void compareSeparatedLines( Object... lines ) { 037 ByteArrayOutputStream content = new ByteArrayOutputStream(); 038 PrintStream stream = new PrintStream(content); 039 for (Object line : lines) { 040 stream.println(line); 041 } 042 List<String> actualLines = StringUtil.splitLines(content.toString()); 043 assertArrayEquals(lines, actualLines.toArray()); 044 } 045 046 @Test 047 public void splitLinesShouldWorkCorrectly() { 048 compareSeparatedLines("Line 1", "Line 2", "Line 3", "Line 4"); 049 } 050 051 @Test( expected = IllegalArgumentException.class ) 052 public void createStringShouldFailIfNoPatternSupplied() { 053 StringUtil.createString(null, (Object[])null); 054 } 055 056 @Test 057 public void createStringShouldAllowNoParametersSupplied() { 058 assertThat(StringUtil.createString("test", (Object[])null), is("test")); 059 } 060 061 @Test 062 public void createStringShouldCreateStringFromPattern() { 063 String pattern = "This {0} is {1} should {2} not {3} last {4}"; 064 assertEquals("This one is two should three not four last five", StringUtil.createString(pattern, 065 "one", 066 "two", 067 "three", 068 "four", 069 "five")); 070 } 071 072 @Test( expected = IllegalArgumentException.class ) 073 public void createStringShouldFailIfTooFewArgumentsSupplied() { 074 String pattern = "This {0} is {1} should {2} not {3} last {4}"; 075 try { 076 StringUtil.createString(pattern, "one", "two", "three", "four"); 077 } catch (IllegalArgumentException err) { 078 System.err.println(err); 079 throw err; 080 } 081 } 082 083 @Test( expected = IllegalArgumentException.class ) 084 public void createStringShouldFailIfTooManyArgumentsSupplied() { 085 String pattern = "This {0} is {1} should {2} not {3} last {4}"; 086 try { 087 StringUtil.createString(pattern, "one", "two", "three", "four", "five", "six"); 088 } catch (IllegalArgumentException err) { 089 System.err.println(err); 090 throw err; 091 } 092 } 093 094 @Test 095 public void createStringExceptionMessageShouldbeGrammaticallyCorrect() { 096 String pattern = "One = {0}"; 097 try { 098 StringUtil.createString(pattern); 099 } catch (IllegalArgumentException err) { 100 assertThat(err.getMessage().startsWith("0 parameters supplied, but 1 parameter required"), is(true)); 101 } 102 pattern = "One"; 103 try { 104 StringUtil.createString(pattern, "one"); 105 } catch (IllegalArgumentException err) { 106 assertThat(err.getMessage().startsWith("1 parameter supplied, but 0 parameters required"), is(true)); 107 } 108 pattern = "One = {0}, Two = {1}"; 109 try { 110 StringUtil.createString(pattern); 111 } catch (IllegalArgumentException err) { 112 assertThat(err.getMessage().startsWith("0 parameters supplied, but 2 parameters required"), is(true)); 113 } 114 } 115 116 @Test 117 public void setLengthShouldTruncateStringsThatAreTooLong() { 118 assertEquals("This is the st", StringUtil.setLength("This is the string", 14, ' ')); 119 } 120 121 @Test 122 @FixFor( "MODE-2322" ) 123 public void shouldSupportPrimitiveArrays() { 124 String text = StringUtil.createString("Error converting \"{2}\" from {0} to a {1}", 125 byte[].class.getSimpleName(), 126 "BinaryValue", 127 new byte[] {-1}); 128 assertEquals("Error converting \"[-1]\" from byte[] to a BinaryValue", text); 129 } 130 131 @Test 132 public void setLengthShouldAppendCharacterForStringsThatAreTooShort() { 133 assertEquals("This ", StringUtil.setLength("This", 10, ' ')); 134 } 135 136 @Test 137 public void setLengthShouldNotRemoveLeadingWhitespace() { 138 assertEquals(" This ", StringUtil.setLength(" This", 10, ' ')); 139 assertEquals("\tThis ", StringUtil.setLength("\tThis", 10, ' ')); 140 } 141 142 @Test 143 public void setLengthShouldAppendCharacterForEmptyStrings() { 144 assertEquals(" ", StringUtil.setLength("", 10, ' ')); 145 } 146 147 @Test 148 public void setLengthShouldAppendCharacterForNullStrings() { 149 assertEquals(" ", StringUtil.setLength(null, 10, ' ')); 150 } 151 152 @Test 153 public void setLengthShouldReturnStringsThatAreTheDesiredLength() { 154 assertEquals("This is the string", StringUtil.setLength("This is the string", 18, ' ')); 155 } 156 157 @Test 158 public void justifyLeftShouldTruncateStringsThatAreTooLong() { 159 assertEquals("This is the st", StringUtil.justifyLeft("This is the string", 14, ' ')); 160 } 161 162 @Test 163 public void justifyLeftShouldAppendCharacterForStringsThatAreTooShort() { 164 assertEquals("This ", StringUtil.justifyLeft("This", 10, ' ')); 165 } 166 167 @Test 168 public void justifyLeftShouldRemoveLeadingWhitespace() { 169 assertEquals("This ", StringUtil.justifyLeft(" This", 10, ' ')); 170 assertEquals("This ", StringUtil.justifyLeft("\tThis", 10, ' ')); 171 } 172 173 @Test 174 public void justifyLeftShouldAppendCharacterForEmptyStrings() { 175 assertEquals(" ", StringUtil.justifyLeft("", 10, ' ')); 176 } 177 178 @Test 179 public void justifyLeftShouldAppendCharacterForNullStrings() { 180 assertEquals(" ", StringUtil.justifyLeft(null, 10, ' ')); 181 } 182 183 @Test 184 public void justifyLeftShouldReturnStringsThatAreTheDesiredLength() { 185 assertEquals("This is the string", StringUtil.justifyLeft("This is the string", 18, ' ')); 186 } 187 188 @Test 189 public void justifyRightShouldTruncateStringsThatAreTooLong() { 190 assertEquals(" is the string", StringUtil.justifyRight("This is the string", 14, ' ')); 191 } 192 193 @Test 194 public void justifyRightShouldPrependCharacterForStringsThatAreTooShort() { 195 assertEquals(" This", StringUtil.justifyRight("This", 10, ' ')); 196 } 197 198 @Test 199 public void justifyRightShouldPrependCharacterForEmptyStrings() { 200 assertEquals(" ", StringUtil.justifyRight("", 10, ' ')); 201 } 202 203 @Test 204 public void justifyRightShouldPrependCharacterForNullStrings() { 205 assertEquals(" ", StringUtil.justifyRight(null, 10, ' ')); 206 } 207 208 @Test 209 public void justifyRightShouldReturnStringsThatAreTheDesiredLength() { 210 assertEquals("This is the string", StringUtil.justifyRight("This is the string", 18, ' ')); 211 } 212 213 @Test 214 public void justifyCenterShouldTruncateStringsThatAreTooLong() { 215 assertEquals("This is the st", StringUtil.justifyCenter("This is the string", 14, ' ')); 216 } 217 218 @Test 219 public void justifyCenterShouldPrependAndAppendSameNumberOfCharacterForStringsThatAreTooShortButOfAnEvenLength() { 220 assertEquals(" This ", StringUtil.justifyCenter("This", 10, ' ')); 221 } 222 223 @Test 224 public void justifyCenterShouldPrependOneMoreCharacterThanAppendingForStringsThatAreTooShortButOfAnOddLength() { 225 assertEquals(" Thing ", StringUtil.justifyCenter("Thing", 10, ' ')); 226 } 227 228 @Test 229 public void justifyCenterShouldPrependCharacterForEmptyStrings() { 230 assertEquals(" ", StringUtil.justifyCenter("", 10, ' ')); 231 } 232 233 @Test 234 public void justifyCenterShouldPrependCharacterForNullStrings() { 235 assertEquals(" ", StringUtil.justifyCenter(null, 10, ' ')); 236 } 237 238 @Test 239 public void justifyCenterShouldReturnStringsThatAreTheDesiredLength() { 240 assertEquals("This is the string", StringUtil.justifyCenter("This is the string", 18, ' ')); 241 } 242 243 @Test 244 public void truncateShouldReturnEmptyStringIfNullReferenceIsSupplied() { 245 assertThat(StringUtil.truncate(null, 0), is("")); 246 assertThat(StringUtil.truncate(null, 1), is("")); 247 assertThat(StringUtil.truncate(null, 100), is("")); 248 } 249 250 @Test( expected = IllegalArgumentException.class ) 251 public void truncateShouldNotAllowNegativeLength() { 252 StringUtil.truncate("some string", -1); 253 } 254 255 @Test 256 public void truncateShouldReturnEmptyStringForMaximumLengthOfZero() { 257 String str = "This is the string with some text"; 258 assertThat(StringUtil.truncate(str, 0), is("")); 259 assertThat(StringUtil.truncate("", 0), is("")); 260 assertThat(StringUtil.truncate(str, 0, "123"), is("")); 261 assertThat(StringUtil.truncate("", 0, "123"), is("")); 262 } 263 264 @Test 265 public void truncateShouldNotTruncateStringShorterThanMaximumLength() { 266 String str = "This is the string with some text"; 267 assertThat(StringUtil.truncate(str, str.length() + 2), is(str)); 268 assertThat(StringUtil.truncate(str, str.length() + 2, null), is(str)); 269 assertThat(StringUtil.truncate(str, str.length() + 2, "really long suffix"), is(str)); 270 } 271 272 @Test 273 public void truncateShouldNotTruncateStringWithLengthEqualToMaximumLength() { 274 String str = "This is the string with some text"; 275 assertThat(StringUtil.truncate(str, str.length()), is(str)); 276 assertThat(StringUtil.truncate(str, str.length(), null), is(str)); 277 assertThat(StringUtil.truncate(str, str.length(), "really long suffix"), is(str)); 278 } 279 280 @Test 281 public void truncateShouldProperlyTruncateStringWithLengthGreaterThanMaximumLength() { 282 String str = "This is the string"; 283 assertThat(StringUtil.truncate(str, str.length() - 1), is("This is the st...")); 284 assertThat(StringUtil.truncate(str, str.length() - 1, null), is("This is the st...")); 285 assertThat(StringUtil.truncate(str, str.length() - 1, "X"), is("This is the striX")); 286 } 287 288 @Test 289 public void truncateShouldProperlyTruncateStringWithLengthGreaterThanMaximumLengthAndMaximumLengthLongerThanPrefixLength() { 290 String str = "This is the string"; 291 assertThat(StringUtil.truncate(str, 2), is("..")); 292 assertThat(StringUtil.truncate(str, 2, null), is("..")); 293 assertThat(StringUtil.truncate(str, 1, "XX"), is("X")); 294 } 295 296 @Test 297 public void readShouldReturnEmptyStringForNullInputStream() throws Exception { 298 assertThat(StringUtil.read((InputStream)null), is("")); 299 } 300 301 @Test 302 public void readShouldReturnEmptyStringForNullReader() throws Exception { 303 assertThat(StringUtil.read((Reader)null), is("")); 304 } 305 306 @Test 307 public void readShouldReadInputStreamCorrectlyAndShouldCloseStream() throws Exception { 308 // Read content shorter than buffer size ... 309 String content = "This is the way to grandma's house."; 310 InputStream stream = new ByteArrayInputStream(content.getBytes()); 311 InputStreamWrapper wrapper = new InputStreamWrapper(stream); 312 assertThat(wrapper.isClosed(), is(false)); 313 assertThat(StringUtil.read(wrapper), is(content)); 314 assertThat(wrapper.isClosed(), is(true)); 315 316 // Read content longer than buffer size ... 317 for (int i = 0; i != 10; ++i) { 318 content += content; // note this doubles each time! 319 } 320 stream = new ByteArrayInputStream(content.getBytes()); 321 wrapper = new InputStreamWrapper(stream); 322 assertThat(wrapper.isClosed(), is(false)); 323 assertThat(StringUtil.read(wrapper), is(content)); 324 assertThat(wrapper.isClosed(), is(true)); 325 } 326 327 @Test 328 public void readShouldReadReaderCorrectlyAndShouldCloseStream() throws Exception { 329 // Read content shorter than buffer size ... 330 String content = "This is the way to grandma's house."; 331 Reader reader = new StringReader(content); 332 ReaderWrapper wrapper = new ReaderWrapper(reader); 333 assertThat(wrapper.isClosed(), is(false)); 334 assertThat(StringUtil.read(wrapper), is(content)); 335 assertThat(wrapper.isClosed(), is(true)); 336 337 // Read content longer than buffer size ... 338 for (int i = 0; i != 10; ++i) { 339 content += content; // note this doubles each time! 340 } 341 reader = new StringReader(content); 342 wrapper = new ReaderWrapper(reader); 343 assertThat(wrapper.isClosed(), is(false)); 344 assertThat(StringUtil.read(wrapper), is(content)); 345 assertThat(wrapper.isClosed(), is(true)); 346 } 347 348 @Test 349 public void getStackTraceShouldReturnStackTrace() { 350 String msg = "This is the message for a test exception"; 351 Throwable t = new IllegalArgumentException(msg); 352 String trace = StringUtil.getStackTrace(t); 353 assertThat(trace, containsString(msg)); 354 assertThat(trace, containsString(this.getClass().getName())); 355 } 356 357 @Test( expected = IllegalArgumentException.class ) 358 public void normalizeShouldFailIfTextNull() { 359 StringUtil.normalize(null); 360 } 361 362 @Test 363 public void normalizeShouldRemoveLeadingTrailingWhitespace() { 364 assertThat(StringUtil.normalize(" \t\n test this \t"), is("test this")); 365 } 366 367 @Test 368 public void normalizeShouldReduceInternalWhitespace() { 369 assertThat(StringUtil.normalize("test \t\n\r this"), is("test this")); 370 } 371 372 @Test 373 public void normalizeShouldReturnEqualStringIfNothingToNormalize() { 374 assertThat(StringUtil.normalize("test this"), is("test this")); 375 } 376 377 protected class InputStreamWrapper extends InputStream { 378 379 private boolean closed = false; 380 private final InputStream stream; 381 382 protected InputStreamWrapper( InputStream stream ) { 383 this.stream = stream; 384 } 385 386 public boolean isClosed() { 387 return closed; 388 } 389 390 @Override 391 public int read() throws IOException { 392 return stream.read(); 393 } 394 395 @Override 396 public void close() throws IOException { 397 stream.close(); 398 this.closed = true; 399 } 400 401 } 402 403 protected class ReaderWrapper extends Reader { 404 405 private boolean closed = false; 406 private final Reader reader; 407 408 protected ReaderWrapper( Reader reader ) { 409 this.reader = reader; 410 } 411 412 public boolean isClosed() { 413 return closed; 414 } 415 416 @Override 417 public void close() throws IOException { 418 reader.close(); 419 this.closed = true; 420 } 421 422 @Override 423 public int read( char[] cbuf, 424 int off, 425 int len ) throws IOException { 426 return reader.read(cbuf, off, len); 427 } 428 } 429 430}