ToolFormatTest.java revision 3717:2a3e23ee1b65
1/* 2 * Copyright (c) 2016, 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/* 25 * @test 26 * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 27 * @summary Tests for output customization 28 * @library /tools/lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * jdk.jdeps/com.sun.tools.javap 32 * jdk.jshell/jdk.internal.jshell.tool 33 * @build KullaTesting TestingInputStream toolbox.ToolBox Compiler 34 * @run testng ToolFormatTest 35 */ 36import java.io.BufferedReader; 37import java.io.IOException; 38import java.io.StringReader; 39import java.util.ArrayList; 40import java.util.List; 41import java.util.logging.Level; 42import java.util.logging.Logger; 43import org.testng.annotations.Test; 44import static org.testng.Assert.assertEquals; 45import static org.testng.Assert.assertTrue; 46import static org.testng.Assert.fail; 47 48@Test 49public class ToolFormatTest extends ReplToolTesting { 50 51 public void testSetFormat() { 52 try { 53 test( 54 (a) -> assertCommandOutputStartsWith(a, "/set mode test -command", "| Created new feedback mode: test"), 55 (a) -> assertCommand(a, "/set format test pre '$ '", ""), 56 (a) -> assertCommand(a, "/set format test post ''", ""), 57 (a) -> assertCommand(a, "/set format test act 'ADD' added", ""), 58 (a) -> assertCommand(a, "/set format test act 'MOD' modified", ""), 59 (a) -> assertCommand(a, "/set format test act 'REP' replaced", ""), 60 (a) -> assertCommand(a, "/set format test act 'OVR' overwrote", ""), 61 (a) -> assertCommand(a, "/set format test act 'USE' used", ""), 62 (a) -> assertCommand(a, "/set format test act 'DRP' dropped", ""), 63 (a) -> assertCommand(a, "/set format test up 'UP-' update", ""), 64 (a) -> assertCommand(a, "/set format test action '{up}{act} '", ""), 65 (a) -> assertCommand(a, "/set format test resolve 'OK' ok", ""), 66 (a) -> assertCommand(a, "/set format test resolve 'DEF' defined", ""), 67 (a) -> assertCommand(a, "/set format test resolve 'NODEF' notdefined", ""), 68 (a) -> assertCommand(a, "/set format test fname ':{name} ' ", ""), 69 (a) -> assertCommand(a, "/set format test ftype '[{type}]' method,expression", ""), 70 (a) -> assertCommand(a, "/set format test result '={value} ' expression", ""), 71 (a) -> assertCommand(a, "/set format test display '{pre}{action}{ftype}{fname}{result}{resolve}'", ""), 72 (a) -> assertCommand(a, "/set format test display '{pre}HI this is enum' enum", ""), 73 (a) -> assertCommandOutputStartsWith(a, "/set feedback test", "$ Feedback mode: test"), 74 (a) -> assertCommand(a, "class D {}", "$ ADD :D OK"), 75 (a) -> assertCommand(a, "void m() {}", "$ ADD []:m OK"), 76 (a) -> assertCommand(a, "interface EX extends EEX {}", "$ ADD :EX NODEF"), 77 (a) -> assertCommand(a, "56", "$ ADD [int]:$4 =56 OK"), 78 (a) -> assertCommand(a, "class D { int hh; }", "$ REP :D OK$ UP-OVR :D OK"), 79 (a) -> assertCommand(a, "enum E {A,B}", "$ HI this is enum"), 80 (a) -> assertCommand(a, "int z() { return f(); }", "$ ADD []:z DEF"), 81 (a) -> assertCommand(a, "z()", "$ UP-USE []:z DEF"), 82 (a) -> assertCommand(a, "/drop z", "$ DRP []:z OK"), 83 (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal") 84 ); 85 } finally { 86 assertCommandCheckOutput(false, "/set feedback normal", s -> { 87 }); 88 } 89 } 90 91 public void testSetFormatOverride() { 92 test( 93 (a) -> assertCommand(a, "/set mode tm -c", "| Created new feedback mode: tm"), 94 (a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""), 95 (a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""), 96 (a) -> assertCommand(a, "/se fo tm x", 97 "| /set format tm x \"aaa\" \n" + 98 "| /set format tm x \"bbb\" class,method-added"), 99 (a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""), 100 (a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""), 101 (a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""), 102 (a) -> assertCommand(a, "/se fo tm x", 103 "| /set format tm x \"aaa\" \n" + 104 "| /set format tm x \"ccc\" class,method-added,modified\n" + 105 "| /set format tm x \"ddd\" class,method-added\n" + 106 "| /set format tm x \"eee\" method-added"), 107 (a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""), 108 (a) -> assertCommand(a, "/se fo tm x", 109 "| /set format tm x \"aaa\" \n" + 110 "| /set format tm x \"ccc\" class,method-added,modified\n" + 111 "| /set format tm x \"ddd\" class,method-added\n" + 112 "| /set format tm x \"EEE\" method-added,replaced"), 113 (a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""), 114 (a) -> assertCommand(a, "/se fo tm x", 115 "| /set format tm x \"aaa\" \n" + 116 "| /set format tm x \"ccc\" class,method-added,modified\n" + 117 "| /set format tm x \"ddd\" class,method-added\n" + 118 "| /set format tm x \"EEE\" method-added,replaced\n" + 119 "| /set format tm x \"fff\" method-added,replaced-ok"), 120 (a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""), 121 (a) -> assertCommand(a, "/se fo tm x", 122 "| /set format tm x \"aaa\" \n" + 123 "| /set format tm x \"ccc\" class,method-added,modified\n" + 124 "| /set format tm x \"ddd\" class,method-added\n" + 125 "| /set format tm x \"EEE\" method-added,replaced\n" + 126 "| /set format tm x \"ggg\" method-ok"), 127 (a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""), 128 (a) -> assertCommand(a, "/se fo tm x", 129 "| /set format tm x \"aaa\" \n" + 130 "| /set format tm x \"ccc\" class,method-added,modified\n" + 131 "| /set format tm x \"ddd\" class,method-added\n" + 132 "| /set format tm x \"hhh\" method"), 133 (a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""), 134 (a) -> assertCommand(a, "/se fo tm x", 135 "| /set format tm x \"aaa\" \n" + 136 "| /set format tm x \"iii\" class,method"), 137 (a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""), 138 (a) -> assertCommand(a, "/se fo tm x", 139 "| /set format tm x \"jjj\"") 140 ); 141 } 142 143 public void testSetFormatSelector() { 144 List<ReplTest> tests = new ArrayList<>(); 145 tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet", 146 "| Created new feedback mode: ate")); 147 tests.add((a) -> assertCommand(a, "/set feedback ate", "")); 148 StringBuilder sb = new StringBuilder(); 149 class KindList { 150 final String[] values; 151 final int matchIndex; 152 int current; 153 boolean match; 154 KindList(String[] values, int matchIndex) { 155 this.values = values; 156 this.matchIndex = matchIndex; 157 this.current = 1 << values.length; 158 } 159 boolean next() { 160 if (current <= 0) { 161 return false; 162 } 163 --current; 164 return true; 165 } 166 boolean append(boolean ahead) { 167 boolean any = false; 168 match = false; 169 for (int i = values.length - 1; i >= 0 ; --i) { 170 if ((current & (1 << i)) != 0) { 171 match |= i == matchIndex; 172 if (any) { 173 sb.append(","); 174 } else { 175 if (ahead) { 176 sb.append("-"); 177 } 178 } 179 sb.append(values[i]); 180 any = true; 181 } 182 } 183 match |= !any; 184 return ahead || any; 185 } 186 } 187 KindList klcase = new KindList(new String[] {"class", "method", "expression", "vardecl"}, 2); 188 while (klcase.next()) { 189 KindList klact = new KindList(new String[] {"added", "modified", "replaced"}, 0); 190 while (klact.next()) { 191 KindList klwhen = new KindList(new String[] {"update", "primary"}, 1); 192 while (klwhen.next()) { 193 sb.setLength(0); 194 klwhen.append( 195 klact.append( 196 klcase.append(false))); 197 boolean match = klcase.match && klact.match && klwhen.match; 198 String select = sb.toString(); 199 String yes = "+++" + select + "+++"; 200 String no = "---" + select + "---"; 201 String expect = match? yes : no; 202 tests.add((a) -> assertCommand(a, "/set format ate display '" + no + "'", "")); 203 tests.add((a) -> assertCommand(a, "/set format ate display '" + yes + "' " + select, "")); 204 tests.add((a) -> assertCommand(a, "\"" + select + "\"", expect)); 205 } 206 } 207 } 208 tests.add((a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")); 209 210 try { 211 test(tests.toArray(new ReplTest[tests.size()])); 212 } finally { 213 assertCommandCheckOutput(false, "/set feedback normal", s -> { 214 }); 215 } 216 } 217 218 public void testSetTruncation() { 219 try { 220 test( 221 (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", ""), 222 (a) -> assertCommand(a, "String s = java.util.stream.IntStream.range(65, 74)"+ 223 ".mapToObj(i -> \"\"+(char)i).reduce((a,b) -> a + b + a).get()", 224 "s ==> \"ABACABADABACABAEABACABADABACABAFABACABADABACABAEABACABADABACABAGABACABADABA ..."), 225 (a) -> assertCommandOutputStartsWith(a, "/set mode test -quiet", ""), 226 (a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""), 227 (a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""), 228 (a) -> assertCommand(a, "/set truncation test 20", ""), 229 (a) -> assertCommand(a, "/set truncation test", "| /set truncation test 20"), 230 (a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"), 231 (a) -> assertCommand(a, "/set trunc test 10 varvalue", ""), 232 (a) -> assertCommand(a, "/set trunc test 3 assignment", ""), 233 (a) -> assertCommandOutputContains(a, "/set truncation", 234 "/set truncation test 10 varvalue"), 235 (a) -> assertCommandOutputContains(a, "/set truncation test", 236 "/set truncation test 10 varvalue"), 237 (a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."), 238 (a) -> assertCommand(a, "r", "String:\"ABACA ..."), 239 (a) -> assertCommand(a, "r=s", "String:\"AB") 240 ); 241 } finally { 242 assertCommandCheckOutput(false, "/set feedback normal", s -> { 243 }); 244 } 245 } 246 247 public void testDefaultTruncation() { 248 test( 249 (a) -> assertCommand(a, "char[] cs = new char[2000];", null), 250 (a) -> assertCommand(a, "Arrays.fill(cs, 'A');", ""), 251 (a) -> assertCommandCheckOutput(a, "String s = new String(cs)", 252 (s) -> { 253 assertTrue(s.length() < 120, "Result too long (" + s.length() + ") -- " + s); 254 assertTrue(s.contains("AAAAAAAAAAAAAAAAAA"), "Bad value: " + s); 255 }), 256 (a) -> assertCommandCheckOutput(a, "s", 257 (s) -> { 258 assertTrue(s.length() > 300, "Result too short (" + s.length() + ") -- " + s); 259 assertTrue(s.contains("AAAAAAAAAAAAAAAAAA"), "Bad value: " + s); 260 }), 261 (a) -> assertCommandCheckOutput(a, "\"X\" + s", 262 (s) -> { 263 assertTrue(s.length() > 300, "Result too short (" + s.length() + ") -- " + s); 264 assertTrue(s.contains("XAAAAAAAAAAAAAAAAAA"), "Bad value: " + s); 265 }) 266 ); 267 } 268 269 public void testPrompt() { 270 test( 271 (a) -> assertCommand(a, "/set mode tp -quiet", "| Created new feedback mode: tp"), 272 (a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""), 273 (a) -> assertCommand(a, "/set prompt tp", 274 "| /set prompt tp \"aaa\" \"bbb\""), 275 (a) -> assertCommandOutputContains(a, "/set prompt", 276 "| /set prompt tp \"aaa\" \"bbb\""), 277 (a) -> assertCommand(a, "/set mode -retain tp", ""), 278 (a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""), 279 (a) -> assertCommand(a, "/set prompt tp", 280 "| /set prompt tp \"ccc\" \"ddd\""), 281 (a) -> assertCommandCheckOutput(a, "/set mode tp", 282 (s) -> { 283 try { 284 BufferedReader rdr = new BufferedReader(new StringReader(s)); 285 assertEquals(rdr.readLine(), "| /set mode tp -quiet", 286 "| /set mode tp -quiet"); 287 assertEquals(rdr.readLine(), "| /set prompt tp \"aaa\" \"bbb\"", 288 "| /set prompt tp \"aaa\" \"bbb\""); 289 String l = rdr.readLine(); 290 while (l.startsWith("| /set format tp ")) { 291 l = rdr.readLine(); 292 } 293 assertEquals(l, "| /set mode -retain tp", 294 "| /set mode -retain tp"); 295 assertEquals(rdr.readLine(), "| ", 296 "| "); 297 assertEquals(rdr.readLine(), "| /set mode tp -quiet", 298 "| /set mode tp -quiet"); 299 assertEquals(rdr.readLine(), "| /set prompt tp \"ccc\" \"ddd\"", 300 "| /set prompt tp \"ccc\" \"ddd\""); 301 } catch (IOException ex) { 302 fail("threw " + ex); 303 } 304 }) 305 ); 306 } 307 308 public void testShowFeedbackModes() { 309 test( 310 (a) -> assertCommandOutputContains(a, "/set feedback", "normal") 311 ); 312 } 313 314 public void testSetNewModeQuiet() { 315 try { 316 test( 317 (a) -> assertCommandOutputStartsWith(a, "/set mode nmq -quiet normal", "| Created new feedback mode: nmq"), 318 (a) -> assertCommand(a, "/set feedback nmq", ""), 319 (a) -> assertCommand(a, "/se mo nmq2 -q nor", ""), 320 (a) -> assertCommand(a, "/se fee nmq2", ""), 321 (a) -> assertCommand(a, "/set mode nmc -command normal", ""), 322 (a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"), 323 (a) -> assertCommandOutputStartsWith(a, "/set mode nm -command", 324 "| Created new feedback mode: nm"), 325 (a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"), 326 (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal") 327 ); 328 } finally { 329 assertCommandCheckOutput(false, "/set feedback normal", s -> { 330 }); 331 } 332 } 333 334 public void testSetError() { 335 try { 336 test( 337 (a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo", 338 "| Does not match any current feedback mode: foo"), 339 (a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb", 340 "| Does not match any current feedback mode: flurb"), 341 (a) -> assertCommandOutputStartsWith(a, "/set mode -command tee", 342 "| Created new feedback mode: tee"), 343 (a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command", 344 "| Mode to be created already exists: verbose"), 345 (a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal", 346 "| Created new feedback mode: te"), 347 (a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""), 348 (a) -> assertCommandOutputStartsWith(a, "/set feedback te", 349 ""), 350 (a) -> assertCommandOutputStartsWith(a, "/set xyz", 351 "ERROR: Invalid '/set' argument: xyz"), 352 (a) -> assertCommandOutputStartsWith(a, "/set f", 353 "ERROR: Ambiguous sub-command argument to '/set': f"), 354 (a) -> assertCommandOutputStartsWith(a, "/set feedback", 355 "| /set feedback te"), 356 (a) -> assertCommandOutputStartsWith(a, "/set feedback xyz", 357 "ERROR: Does not match any current feedback mode"), 358 (a) -> assertCommandOutputStartsWith(a, "/set feed", 359 "| /set feedback te"), 360 (a) -> assertCommandOutputStartsWith(a, "/set format xyz", 361 "ERROR: Does not match any current feedback mode"), 362 (a) -> assertCommandOutputStartsWith(a, "/set format t", 363 "ERROR: Matches more then one current feedback mode: t"), 364 (a) -> assertCommandOutputStartsWith(a, "/set format qqq", 365 "ERROR: Does not match any current feedback mode: qqq"), 366 (a) -> assertCommandOutputStartsWith(a, "/set format te fld", 367 "ERROR: Expected a field name:"), 368 (a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa", 369 "ERROR: Format 'aaa' must be quoted"), 370 (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog", 371 "ERROR: Not a valid selector"), 372 (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' import-frog", 373 "ERROR: Not a valid selector"), 374 (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' import-import", 375 "ERROR: Selector kind in multiple sections of"), 376 (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' import,added", 377 "ERROR: Different selector kinds in same sections of"), 378 (a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x", 379 "ERROR: Truncation length must be an integer: 20x"), 380 (a) -> assertCommandOutputStartsWith(a, "/set trunc qaz", 381 "ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"), 382 (a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added", 383 "ERROR: Different selector kinds in same sections of"), 384 (a) -> assertCommandOutputContains(a, "/set mode", 385 "| /set truncation verbose"), 386 (a) -> assertCommandOutputStartsWith(a, "/set mode -command", 387 "ERROR: Missing the feedback mode"), 388 (a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y", 389 "ERROR: Does not match any current feedback mode"), 390 (a) -> assertCommandOutputStartsWith(a, "/set prompt", 391 "| /set prompt"), 392 (a) -> assertCommandOutputStartsWith(a, "/set prompt te", 393 "| /set prompt te "), 394 (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz", 395 "ERROR: Format 'aaa' must be quoted"), 396 (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz", 397 "ERROR: Format 'xyz' must be quoted"), 398 (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa", 399 "ERROR: Format 'aaa' must be quoted"), 400 (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'", 401 "ERROR: Continuation prompt required"), 402 (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", 403 "| Feedback mode: normal") 404 ); 405 } finally { 406 assertCommandCheckOutput(false, "/set feedback normal", s -> { 407 }); 408 } 409 } 410 411 public void testSetHelp() { 412 try { 413 test( 414 (a) -> assertCommandOutputContains(a, "/help /set", "command to launch"), 415 (a) -> assertCommandOutputContains(a, "/help /set format", "display"), 416 (a) -> assertCommandOutputContains(a, "/hel /se for", "vardecl"), 417 (a) -> assertCommandOutputContains(a, "/help /set editor", "temporary file") 418 ); 419 } finally { 420 assertCommandCheckOutput(false, "/set feedback normal", s -> { 421 }); 422 } 423 } 424} 425