1 /* 2 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 5067405 26 * @summary Basic test for classes which implement Appendable. 27 */ 28 29 import java.io.BufferedReader; 30 import java.io.BufferedWriter; 31 import java.io.ByteArrayOutputStream; 32 import java.io.CharArrayWriter; 33 import java.io.File; 34 import java.io.FileReader; 35 import java.io.FileWriter; 36 import java.io.IOException; 37 import java.io.OutputStreamWriter; 38 import java.io.PrintStream; 39 import java.io.PrintWriter; 40 import java.io.StringWriter; 41 import java.io.Writer; 42 import java.nio.ByteBuffer; 43 import java.nio.CharBuffer; 44 45 interface BasicRunnable extends Runnable { 46 void init(Appendable a, String csq, String exp); 47 Appendable reset(Appendable csq); 48 } 49 50 public class Basic { 51 52 private static final String s = "Beware the Jabberwock, my son!"; 53 private static CharArrayWriter gw = new CharArrayWriter(); 54 private static ByteArrayOutputStream gos = new ByteArrayOutputStream(); 55 56 private static File newFile() { 57 File f = null; 58 try { 59 f = File.createTempFile("append", ".txt"); 60 f.deleteOnExit(); 61 } catch (IOException x) { 62 fail(x); 63 } 64 return f; 65 } 66 private static File gf = newFile(); 67 68 private static int fail = 0; 69 private static int pass = 0; 70 71 private static Throwable first; 72 73 static void pass() { 74 pass++; 75 } 76 77 static void fail(Throwable ex) { 78 if (first == null) 79 first = ex; 80 System.err.println("FAILED: unexpected exception"); 81 fail++; 82 } 83 84 static void fail(String fs, Throwable ex) { 85 String s = "'" + fs + "': " + ex.getClass().getName() + " not thrown"; 86 if (first == null) 87 first = ex; 88 System.err.println("FAILED: " + s); 89 fail++; 90 } 91 92 static void fail(String fs, String exp, String got) { 93 String s = "'" + fs + "': Expected '" + exp + "', got '" + got + "'"; 94 if (first == null) 95 first = new RuntimeException(s); 96 System.err.println("FAILED: " + s); 97 fail++; 98 } 99 100 static void ck(String s, String exp, String got) { 101 if (!exp.equals(got)) 102 fail(s, exp, got); 103 else 104 pass(); 105 } 106 107 private static BasicRunnable testBufferedWriter = 108 new BasicRunnable() { 109 private String csn, exp; 110 public void init(Appendable bw, String csn, String exp) { 111 try { 112 ((BufferedWriter)bw).flush(); 113 } catch (IOException x) { 114 fail(x); 115 } 116 this.csn = csn; 117 this.exp = exp; 118 } 119 public void run() { 120 ck("BufferedWriter.append(" + csn + ")", exp, gw.toString()); 121 } 122 public Appendable reset(Appendable bw) { 123 gw.reset(); 124 return bw; 125 }}; 126 127 private static BasicRunnable testCharArrayWriter = 128 new BasicRunnable() { 129 private String csn, exp; 130 private CharArrayWriter cw; 131 public void init(Appendable cw, String csn, String exp) { 132 this.cw = (CharArrayWriter)cw; 133 this.csn = csn; 134 this.exp = exp; 135 } 136 public void run() { 137 ck("CharArrayWriter.append(" + csn + ")", exp, cw.toString()); 138 } 139 public Appendable reset(Appendable cw) { 140 ((CharArrayWriter)cw).reset(); 141 return cw; 142 }}; 143 144 private static BasicRunnable testFileWriter = 145 new BasicRunnable() { 146 private String csn, exp; 147 public void init(Appendable fw, String csn, String exp) { 148 try { 149 ((FileWriter)fw).flush(); 150 } catch (IOException x) { 151 fail(x); 152 } 153 this.csn = csn; 154 this.exp = exp; 155 } 156 public void run() { 157 StringBuilder sb = new StringBuilder(); 158 try { 159 BufferedReader in = new BufferedReader(new FileReader(gf)); 160 String line; 161 while (true) { 162 if ((line = in.readLine()) == null) 163 break; 164 sb.append(line); 165 } 166 } catch (IOException x) { 167 fail(x); 168 } 169 ck("FileWriter.append(" + csn + ")", exp, sb.toString()); 170 } 171 public Appendable reset(Appendable fw) { 172 try { 173 fw = new FileWriter(gf); 174 } catch (IOException x) { 175 fail(x); 176 } 177 return fw; 178 }}; 179 180 private static BasicRunnable testOutputStreamWriter = 181 new BasicRunnable() { 182 private String csn, exp; 183 public void init(Appendable osw, String csn, String exp) { 184 try { 185 ((OutputStreamWriter)osw).flush(); 186 } catch (IOException x) { 187 fail(x); 188 } 189 this.csn = csn; 190 this.exp = exp; 191 } 192 public void run() { 193 ck("OutputStreamWriter.append(" + csn + ")", exp, gos.toString()); 194 } 195 public Appendable reset(Appendable osw) { 196 gos.reset(); 197 return osw; 198 }}; 199 200 private static BasicRunnable testPrintWriter = 201 new BasicRunnable() { 202 private String csn, exp; 203 public void init(Appendable pw, String csn, String exp) { 204 ((PrintWriter)pw).flush(); 205 this.csn = csn; 206 this.exp = exp; 207 } 208 public void run() { 209 ck("PrintWriter.append(" + csn + ")", exp, gw.toString()); 210 } 211 public Appendable reset(Appendable pw) { 212 gw.reset(); 213 return pw; 214 }}; 215 216 private static BasicRunnable testStringWriter = 217 new BasicRunnable() { 218 private String csn, exp; 219 private StringWriter sw; 220 public void init(Appendable sw, String csn, String exp) { 221 this.sw = (StringWriter)sw; 222 this.csn = csn; 223 this.exp = exp; 224 } 225 public void run() { 226 ck("StringWriter.append(" + csn + ")", exp, sw.toString()); 227 } 228 public Appendable reset(Appendable sw) { 229 return new StringWriter(); 230 }}; 231 232 private static BasicRunnable testPrintStream = 233 new BasicRunnable() { 234 private String csn, exp; 235 public void init(Appendable ps, String csn, String exp) { 236 ((PrintStream)ps).flush(); 237 this.csn = csn; 238 this.exp = exp; 239 } 240 public void run() { 241 ck("PrintStream.append(" + csn + ")", exp, gos.toString()); 242 } 243 public Appendable reset(Appendable ps) { 244 gos.reset(); 245 return ps; 246 }}; 247 248 private static BasicRunnable testCharBuffer = 249 new BasicRunnable() { 250 private String csn, exp; 251 private CharBuffer cb; 252 public void init(Appendable cb, String csn, String exp) { 253 this.cb = (CharBuffer)cb; 254 this.csn = csn; 255 this.exp = exp; 256 } 257 public void run() { 258 cb.limit(cb.position()).rewind(); 259 ck("CharBuffer.append(" + csn + ")", exp, cb.toString()); 260 } 261 public Appendable reset(Appendable cb) { 262 ((CharBuffer)cb).clear(); 263 return cb; 264 }}; 265 266 private static BasicRunnable testStringBuffer = 267 new BasicRunnable() { 268 private String csn, exp; 269 private StringBuffer sb; 270 public void init(Appendable sb, String csn, String exp) { 271 this.sb = (StringBuffer)sb; 272 this.csn = csn; 273 this.exp = exp; 274 } 275 public void run() { 276 ck("StringBuffer.append(" + csn + ")", exp, sb.toString()); 277 } 278 public Appendable reset(Appendable sb) { 279 return new StringBuffer(); 280 }}; 281 282 private static BasicRunnable testStringBuilder = 283 new BasicRunnable() { 284 private String csn, exp; 285 private StringBuilder sb; 286 public void init(Appendable sb, String csn, String exp) { 287 this.sb = (StringBuilder)sb; 288 this.csn = csn; 289 this.exp = exp; 290 } 291 public void run() { 292 ck("StringBuilder.append(" + csn + ")", exp, sb.toString()); 293 } 294 public Appendable reset(Appendable sb) { 295 return new StringBuilder(); 296 }}; 297 298 private static void test(Appendable a, CharSequence csq, BasicRunnable thunk) { 299 // appends that should always work 300 int [][] sp = { { 0, 0 }, { 11, 11 }, { 11, 21 }, { 0, 7 }, 301 { 0, s.length() }, { s.length(), s.length() }, 302 }; 303 for (int j = 0; j < sp.length; j++) { 304 int start = sp[j][0]; 305 int end = sp[j][1]; 306 try { 307 thunk.init(a.append(csq, start, end), 308 csq.getClass().getName(), 309 s.subSequence(start, end).toString()); 310 thunk.run(); 311 a = thunk.reset(a); 312 } catch (IOException x) { 313 fail(x); 314 } 315 } 316 317 // appends that should always throw IndexOutOfBoundsException 318 int [][] sf = { { -1, 0 }, { 0, -1 }, { 11, 10 }, 319 { 0, s.length() + 1}, 320 }; 321 for (int j = 0; j < sf.length; j++) { 322 int start = sf[j][0]; 323 int end = sf[j][1]; 324 try { 325 a.append(csq, start, end); 326 fail("start = " + start + ", end = " + end, 327 new IndexOutOfBoundsException()); 328 a = thunk.reset(a); 329 } catch (IndexOutOfBoundsException x) { 330 pass(); 331 } catch (IOException x) { 332 fail(x); 333 } 334 } 335 336 // appendN with negative count 337 int[] neg = { -1, -2, -65537, Integer.MIN_VALUE + 1, Integer.MIN_VALUE }; 338 for (int j = 0; j < neg.length; j++) { 339 try { 340 a.appendN('%', neg[j]); 341 fail("repeat count = " + neg[j], new IllegalArgumentException()); 342 a = thunk.reset(a); 343 } catch (IllegalArgumentException x) { 344 pass(); 345 } catch (IOException x) { 346 fail(x); 347 } 348 } 349 350 // appends of null 351 int start = 1; 352 int end = 2; 353 try { 354 thunk.init(a.append(null, start, end), "null", 355 "null".subSequence(start, end).toString()); 356 thunk.run(); 357 a = thunk.reset(a); 358 } catch (IOException x) { 359 fail(x); 360 } 361 362 // appendN 363 for (int i = 128; i > 0; ) { 364 try { 365 i /= 2; 366 String s = ""; 367 for (int j = 0; j < i; j++) { 368 s += "@"; 369 } 370 thunk.init(a.appendN('@', i), "'@' x 0", s); 371 thunk.run(); 372 a = thunk.reset(a); 373 } catch (IOException x) { 374 fail(x); 375 } 376 } 377 } 378 379 public static void main(String [] args) throws Exception { 380 // CharSequences 381 CharBuffer cb = CharBuffer.allocate(128).put(s); 382 cb.limit(s.length()).rewind(); 383 CharBuffer dcb = ByteBuffer.allocateDirect(128).asCharBuffer().put(s); 384 dcb.limit(s.length()).rewind(); 385 CharSequence [] ca = { s, 386 new StringBuffer(s), 387 new StringBuilder(s), 388 cb, 389 dcb, 390 }; 391 392 // Appendables/Writers 393 Object [][] wa = { { new CharArrayWriter(), testCharArrayWriter }, 394 { new BufferedWriter(gw), testBufferedWriter }, 395 // abstract, no implementing classes in jdk 396 // { new FilterWriter(), testFilterWriter }, 397 { new FileWriter(gf), testFileWriter }, 398 { new OutputStreamWriter(gos), testOutputStreamWriter }, 399 // covered by previous two test cases 400 // { new PipedWriter(gw), testPipedWriter }, 401 { new PrintWriter(gw), testPrintWriter }, 402 { new StringWriter(), testStringWriter }, 403 }; 404 405 for (int i = 0; i < ca.length; i++) { 406 CharSequence a = ca[i]; 407 for (int j = 0; j < wa.length; j++) 408 test((Writer)wa[j][0], a, (BasicRunnable)wa[j][1]); 409 410 // other Appendables 411 test(new PrintStream(gos), a, testPrintStream); 412 test(CharBuffer.allocate(128), a, testCharBuffer); 413 test(ByteBuffer.allocateDirect(128).asCharBuffer(), a, testCharBuffer); 414 test(new StringBuffer(), a, testStringBuffer); 415 test(new StringBuilder(), a, testStringBuilder); 416 } 417 418 if (fail != 0) 419 throw new RuntimeException((fail + pass) + " tests: " 420 + fail + " failure(s), first", first); 421 else 422 System.out.println("all " + (fail + pass) + " tests passed"); 423 } 424 }