1 /*
2  * Copyright (c) 2016, 2017, 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 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102 8172179 8177847
27  * @summary Tests of jshell comand options, and undoing operations
28  * @modules jdk.jshell/jdk.internal.jshell.tool
29  *          jdk.compiler/com.sun.tools.javac.api
30  *          jdk.compiler/com.sun.tools.javac.main
31  * @library /tools/lib
32  * @build ToolCommandOptionTest ReplToolTesting
33  * @run testng ToolCommandOptionTest
34  */
35 import java.nio.file.Path;
36 import org.testng.annotations.Test;
37 import static org.testng.Assert.assertFalse;
38 import static org.testng.Assert.assertTrue;
39 
40 @Test
41 public class ToolCommandOptionTest extends ReplToolTesting {
42 
listTest()43     public void listTest() {
44         test(
45                 (a) -> assertCommand(a, "int x;",
46                         "x ==> 0"),
47                 (a) -> assertCommand(a, "/li",
48                         "1 : int x;"),
49                 (a) -> assertCommandOutputStartsWith(a, "/lis -st",
50                         "s1 : import"),
51                 (a) -> assertCommandOutputStartsWith(a, "/list -all",
52                         "s1 : import"),
53                 (a) -> assertCommandOutputContains(a, "/list -all",
54                         "1 : int x;"),
55                 (a) -> assertCommandOutputContains(a, "/list -history",
56                         "int x;"),
57                 (a) -> assertCommandOutputContains(a, "/li -h",
58                         "/lis -st"),
59                 (a) -> assertCommand(a, "/list -furball",
60                         "|  Unknown option: -furball -- /list -furball"),
61                 (a) -> assertCommand(a, "/list x",
62                         "1 : int x;"),
63                 (a) -> assertCommand(a, "/li x -start",
64                         "|  Options and snippets must not both be used: /list x -start"),
65                 (a) -> assertCommand(a, "/l -st -al",
66                         "|  Conflicting options -- /list -st -al")
67         );
68     }
69 
typesTest()70     public void typesTest() {
71         test(
72                 (a) -> assertCommand(a, "int x",
73                         "x ==> 0"),
74                 (a) -> assertCommand(a, "/types x",
75                         "|  This command does not accept the snippet 'x' : int x;"),
76                 (a) -> assertCommand(a, "class C {}",
77                         "|  created class C"),
78                 (a) -> assertCommand(a, "/ty",
79                         "|    class C"),
80                 (a) -> assertCommand(a, "/ty -st",
81                         ""),
82                 (a) -> assertCommand(a, "/types -all",
83                         "|    class C"),
84                 (a) -> assertCommand(a, "/types -furball",
85                         "|  Unknown option: -furball -- /types -furball"),
86                 (a) -> assertCommand(a, "/types C",
87                         "|    class C"),
88                 (a) -> assertCommand(a, "/types C -start",
89                         "|  Options and snippets must not both be used: /types C -start"),
90                 (a) -> assertCommand(a, "/ty -st -al",
91                         "|  Conflicting options -- /types -st -al")
92         );
93     }
94 
dropTest()95     public void dropTest() {
96         test(false, new String[]{"--no-startup"},
97                 (a) -> assertCommand(a, "int x = 5;",
98                         "x ==> 5"),
99                 (a) -> assertCommand(a, "x",
100                         "x ==> 5"),
101                 (a) -> assertCommand(a, "long y;",
102                         "y ==> 0"),
103                 (a) -> assertCommand(a, "/drop -furball",
104                         "|  Unknown option: -furball -- /drop -furball"),
105                 (a) -> assertCommand(a, "/drop -all",
106                         "|  Unknown option: -all -- /drop -all"),
107                 (a) -> assertCommandOutputStartsWith(a, "/drop z",
108                         "|  No such snippet: z"),
109                 (a) -> assertCommand(a, "/drop 2",
110                         ""),
111                 (a) -> assertCommandOutputStartsWith(a, "23qwl",
112                         "|  Error:"),
113                 (a) -> assertCommandOutputStartsWith(a, "/drop e1",
114                         "|  This command does not accept the snippet 'e1' : 23qwl"),
115                 (a) -> assertCommand(a, "/dr x y",
116                         "|  dropped variable x\n" +
117                         "|  dropped variable y"),
118                 (a) -> assertCommand(a, "/list",
119                         "")
120         );
121     }
122 
setEditorTest()123     public void setEditorTest() {
124         test(
125                 (a) -> assertCommand(a, "/set editor -furball",
126                         "|  Unknown option: -furball -- /set editor -furball"),
127                 (a) -> assertCommand(a, "/set editor -furball prog",
128                         "|  Unknown option: -furball -- /set editor -furball prog"),
129                 (a) -> assertCommand(a, "/set editor -furball -mattress",
130                         "|  Unknown option: -furball -mattress -- /set editor -furball -mattress"),
131                 (a) -> assertCommand(a, "/set editor -default prog",
132                         "|  Specify -default option, -delete option, or program -- /set editor -default prog"),
133                 (a) -> assertCommand(a, "/set editor prog",
134                         "|  Editor set to: prog"),
135                 (a) -> assertCommand(a, "/set editor prog -default",
136                         "|  Editor set to: prog -default"),
137                 (a) -> assertCommand(a, "/set editor",
138                         "|  /set editor prog -default"),
139                 (a) -> assertCommand(a, "/se ed prog -furball",
140                         "|  Editor set to: prog -furball"),
141                 (a) -> assertCommand(a, "/set editor",
142                         "|  /set editor prog -furball"),
143                 (a) -> assertCommand(a, "/se ed -delete",
144                         "|  Editor set to: -default"),
145                 (a) -> assertCommand(a, "/set editor",
146                         "|  /set editor -default"),
147                 (a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
148                         "|  Editor set to: prog arg1 -furball arg3 -default arg4"),
149                 (a) -> assertCommand(a, "/set editor",
150                         "|  /set editor prog arg1 -furball arg3 -default arg4"),
151                 (a) -> assertCommand(a, "/set editor -default",
152                         "|  Editor set to: -default"),
153                 (a) -> assertCommand(a, "/se edi -def",
154                         "|  Editor set to: -default"),
155                 (a) -> assertCommand(a, "/set editor",
156                         "|  /set editor -default")
157         );
158     }
159 
retainEditorTest()160     public void retainEditorTest() {
161         test(
162                 (a) -> assertCommand(a, "/set editor -retain -furball",
163                         "|  Unknown option: -furball -- /set editor -retain -furball"),
164                 (a) -> assertCommand(a, "/set editor -retain -furball prog",
165                         "|  Unknown option: -furball -- /set editor -retain -furball prog"),
166                 (a) -> assertCommand(a, "/set editor -retain -furball -mattress",
167                         "|  Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"),
168                 (a) -> assertCommand(a, "/set editor -retain -default prog",
169                         "|  Specify -default option, -delete option, or program -- /set editor -retain -default prog"),
170                 (a) -> assertCommand(a, "/set editor -retain -wait",
171                         "|  -wait applies to external editors"),
172                 (a) -> assertCommand(a, "/set editor -retain -default -wait",
173                         "|  -wait applies to external editors"),
174                 (a) -> assertCommand(a, "/set editor -retain prog",
175                         "|  Editor set to: prog\n" +
176                         "|  Editor setting retained: prog"),
177                 (a) -> assertCommand(a, "/set editor",
178                         "|  /set editor -retain prog"),
179                 (a) -> assertCommand(a, "/se ed other",
180                         "|  Editor set to: other"),
181                 (a) -> assertCommand(a, "/set editor",
182                         "|  /set editor -retain prog\n" +
183                         "|  /set editor other"),
184                 (a) -> assertCommand(a, "/se ed -delete",
185                         "|  Editor set to: prog"),
186                 (a) -> assertCommand(a, "/set editor",
187                         "|  /set editor -retain prog"),
188                 (a) -> assertCommand(a, "/set editor -retain prog -default",
189                         "|  Editor set to: prog -default\n" +
190                         "|  Editor setting retained: prog -default"),
191                 (a) -> assertCommand(a, "/set editor",
192                         "|  /set editor -retain prog -default"),
193                 (a) -> assertCommand(a, "/se ed -retain prog -furball",
194                         "|  Editor set to: prog -furball\n" +
195                         "|  Editor setting retained: prog -furball"),
196                 (a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4",
197                         "|  Editor set to: prog arg1 -furball arg3 -default arg4\n" +
198                         "|  Editor setting retained: prog arg1 -furball arg3 -default arg4"),
199                 (a) -> assertCommand(a, "/set editor",
200                         "|  /set editor -retain prog arg1 -furball arg3 -default arg4"),
201                 (a) -> assertCommand(a, "/set editor -retain -default",
202                         "|  Editor set to: -default\n" +
203                         "|  Editor setting retained: -default"),
204                 (a) -> assertCommand(a, "/set editor",
205                         "|  /set editor -retain -default"),
206                 (a) -> assertCommand(a, "/se e -ret -def",
207                         "|  Editor set to: -default\n" +
208                         "|  Editor setting retained: -default"),
209                 (a) -> assertCommand(a, "/set editor -retain",
210                         "|  Editor setting retained: -default")
211         );
212     }
213 
setEditorEnvTest()214     public void setEditorEnvTest() {
215         setEnvVar("EDITOR", "best one");
216         setEditorEnvSubtest();
217         setEnvVar("EDITOR", "not this");
218         setEnvVar("VISUAL", "best one");
219         setEditorEnvSubtest();
220         setEnvVar("VISUAL", "not this");
221         setEnvVar("JSHELLEDITOR", "best one");
222         setEditorEnvSubtest();
223     }
224 
setEditorEnvSubtest()225     private void setEditorEnvSubtest() {
226         test(
227                 (a) -> assertCommand(a, "/set editor",
228                         "|  /set editor best one"),
229                 (a) -> assertCommand(a, "/set editor prog",
230                         "|  Editor set to: prog"),
231                 (a) -> assertCommand(a, "/set editor",
232                         "|  /set editor prog"),
233                 (a) -> assertCommand(a, "/set editor -delete",
234                         "|  Editor set to: best one"),
235                 (a) -> assertCommand(a, "/set editor -retain stored editor",
236                         "|  Editor set to: stored editor\n" +
237                         "|  Editor setting retained: stored editor")
238         );
239         test(
240                 (a) -> assertCommand(a, "/set editor",
241                         "|  /set editor -retain stored editor"),
242                 (a) -> assertCommand(a, "/set editor -delete -retain",
243                         "|  Editor set to: best one")
244         );
245     }
246 
setStartTest()247     public void setStartTest() {
248         Compiler compiler = new Compiler();
249         Path startup = compiler.getPath("StartTest/startup.txt");
250         compiler.writeToFile(startup, "int iAmHere = 1234;");
251         test(
252                 (a) -> assertCommand(a, "/set start -furball",
253                         "|  Unknown option: -furball -- /set start -furball"),
254                 (a) -> assertCommand(a, "/set start -furball pyle",
255                         "|  Unknown option: -furball -- /set start -furball pyle"),
256                 (a) -> assertCommand(a, "/se st pyle -furball",
257                         "|  Unknown option: -furball -- /set st pyle -furball"),
258                 (a) -> assertCommand(a, "/set start -furball -mattress",
259                         "|  Unknown option: -furball -mattress -- /set start -furball -mattress"),
260                 (a) -> assertCommand(a, "/set start foo -default",
261                         "|  Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"),
262                 (a) -> assertCommand(a, "/set start frfg",
263                         "|  File 'frfg' for '/set start' is not found."),
264                 (a) -> assertCommand(a, "/set start DEFAULT frfg",
265                         "|  File 'frfg' for '/set start' is not found."),
266                 (a) -> assertCommand(a, "/set start -default",
267                         ""),
268                 (a) -> assertCommand(a, "/set start",
269                         "|  /set start -default"),
270                 (a) -> assertCommand(a, "/set start DEFAULT",
271                         ""),
272                 (a) -> assertCommand(a, "/set start",
273                         "|  /set start -default"),
274                 (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
275                         ""),
276                 (a) -> assertCommandOutputContains(a, "/set start",
277                         "/set start DEFAULT PRINTING", "void println", "import java.util.*"),
278                 (a) -> assertCommand(a, "/set start " + startup.toString(),
279                         ""),
280                 (a) -> assertCommandOutputContains(a, "/set start",
281                         "|  /set start " + startup + "\n" +
282                         "|  ---- " + startup + " @ ", " ----\n" +
283                         "|  int iAmHere = 1234;\n"),
284                 (a) -> assertCommand(a, "/se sta -no",
285                         ""),
286                 (a) -> assertCommand(a, "/set start",
287                         "|  /set start -none")
288         );
289     }
290 
retainStartTest()291     public void retainStartTest() {
292         Compiler compiler = new Compiler();
293         Path startup = compiler.getPath("StartTest/startup.txt");
294         compiler.writeToFile(startup, "int iAmHere = 1234;");
295         test(
296                 (a) -> assertCommand(a, "/set start -retain -furball",
297                         "|  Unknown option: -furball -- /set start -retain -furball"),
298                 (a) -> assertCommand(a, "/set start -retain -furball pyle",
299                         "|  Unknown option: -furball -- /set start -retain -furball pyle"),
300                 (a) -> assertCommand(a, "/se st -re pyle -furball",
301                         "|  Unknown option: -furball -- /set st -re pyle -furball"),
302                 (a) -> assertCommand(a, "/set start -retain -furball -mattress",
303                         "|  Unknown option: -furball -mattress -- /set start -retain -furball -mattress"),
304                 (a) -> assertCommand(a, "/set start -retain foo -default",
305                         "|  Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"),
306                 (a) -> assertCommand(a, "/set start -retain -default foo",
307                         "|  Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"),
308                 (a) -> assertCommand(a, "/set start -retain frfg",
309                         "|  File 'frfg' for '/set start' is not found."),
310                 (a) -> assertCommand(a, "/set start -retain -default",
311                         ""),
312                 (a) -> assertCommand(a, "/set start",
313                         "|  /set start -retain -default"),
314                 (a) -> assertCommand(a, "/set sta -no",
315                         ""),
316                 (a) -> assertCommand(a, "/set start",
317                         "|  /set start -retain -default\n" +
318                         "|  /set start -none"),
319                 (a) -> assertCommand(a, "/se st -ret",
320                         ""),
321                 (a) -> assertCommand(a, "/se sta",
322                         "|  /set start -retain -none"),
323                 (a) -> assertCommand(a, "/set start -retain " + startup.toString(),
324                         ""),
325                 (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
326                         ""),
327                 (a) -> assertCommandOutputStartsWith(a, "/set start",
328                         "|  /set start -retain " + startup.toString() + "\n" +
329                         "|  /set start DEFAULT PRINTING\n" +
330                         "|  ---- " + startup.toString() + " @ "),
331                 (a) -> assertCommandOutputContains(a, "/set start",
332                         "|  ---- DEFAULT ----\n",
333                         "|  ---- PRINTING ----\n",
334                         "|  int iAmHere = 1234;\n",
335                         "|  void println(String s)",
336                         "|  import java.io.*;")
337         );
338     }
339 
setModeTest()340     public void setModeTest() {
341         test(
342                 (a) -> assertCommandOutputContains(a, "/set mode",
343                         "|  /set format verbose unresolved"),
344                 (a) -> assertCommandOutputStartsWith(a, "/set mode *",
345                         "|  Expected a feedback mode name: *"),
346                 (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet",
347                         "|  Missing the feedback mode"),
348                 (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet *",
349                         "|  Expected a feedback mode name: *"),
350                 (a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing",
351                         "|  Unexpected arguments at end of command: thing"),
352                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
353                         "|  To create a new mode either the -command or the -quiet option must be used"),
354                 (a) -> assertCommand(a, "/set mode mymode -command",
355                         "|  Created new feedback mode: mymode"),
356                 (a) -> assertCommand(a, "/set mode mymode -delete",
357                         ""),
358                 (a) -> assertCommand(a, "/set mode mymode normal -command",
359                         "|  Created new feedback mode: mymode"),
360                 (a) -> assertCommand(a, "/set mode -del mymode",
361                         ""),
362                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command -quiet",
363                         "|  Conflicting options"),
364                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete -quiet",
365                         "|  Conflicting options"),
366                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command -delete",
367                         "|  Conflicting options"),
368                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d",
369                         "|  No feedback mode named: mymode"),
370                 (a) -> assertCommandOutputStartsWith(a, "/set mode normal -c",
371                         "|  Mode to be created already exists: normal"),
372                 (a) -> assertCommand(a, "/se mo -c mymode",
373                         "|  Created new feedback mode: mymode"),
374                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
375                         "|  /set mode mymode -command"),
376                 (a) -> assertCommand(a, "/set feedback mymode",
377                         "|  Feedback mode: mymode"),
378                 (a) -> assertCommand(a, "/se fe",
379                         "|  /set feedback mymode\n" +
380                         "|  \n" +
381                         "|  Available feedback modes:\n" +
382                         "|     concise\n" +
383                         "|     mymode\n" +
384                         "|     normal\n" +
385                         "|     silent\n" +
386                         "|     verbose"),
387                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
388                         "|  The current feedback mode 'mymode' cannot be deleted"),
389                 (a) -> assertCommand(a, "/set feedback no",
390                         "|  Feedback mode: normal"),
391                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
392                         ""),
393                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
394                         "|  To create a new mode either the -command or the -quiet option must be used -- \n" +
395                         "|  Does not match any current feedback mode: mymode -- /set mode mymode\n" +
396                         "|  Available feedback modes:"),
397                 (a) -> assertCommandCheckOutput(a, "/set feedback",
398                         (s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s))
399         );
400     }
401 
setModeSmashTest()402     public void setModeSmashTest() {
403         test(
404                 (a) -> assertCommand(a, "/set mode mymode -command",
405                         "|  Created new feedback mode: mymode"),
406                 (a) -> assertCommand(a, "/set feedback mymode",
407                         "|  Feedback mode: mymode"),
408                 (a) -> assertCommand(a, "/set format mymode display 'blurb'",
409                         ""),
410                 (a) -> assertCommand(a, "45",
411                         "blurb"),
412                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal",
413                         "|  To create a new mode either the -command or the -quiet option must be used"),
414                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal",
415                         "|  Mode to be created already exists: mymode"),
416                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
417                         "|  The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"),
418                 (a) -> assertCommand(a, "/set feedback normal",
419                         "|  Feedback mode: normal"),
420                 (a) -> assertCommand(a, "/set mode mymode -delete",
421                         ""),
422                 (a) -> assertCommand(a, "/set mode mymode -command normal",
423                         "|  Created new feedback mode: mymode"),
424                 (a) -> assertCommand(a, "/set feedback mymode",
425                         "|  Feedback mode: mymode"),
426                 (a) -> assertCommandOutputContains(a, "45",
427                         " ==> 45")
428         );
429     }
430 
retainModeTest()431     public void retainModeTest() {
432         test(
433                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain",
434                         "|  Missing the feedback mode"),
435                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain *",
436                         "|  Expected a feedback mode name: *"),
437                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal",
438                         "|  Unexpected arguments at end of command: normal"),
439                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode",
440                         "|  No feedback mode named: mymode"),
441                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete",
442                         "|  No feedback mode named: mymode"),
443                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode",
444                         "|  No feedback mode named: mymode"),
445                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal",
446                         "|  Not valid with a predefined mode: normal"),
447                 (a) -> assertCommand(a, "/set mode mymode verbose -command",
448                         "|  Created new feedback mode: mymode"),
449                 (a) -> assertCommand(a, "/set mode -retain mymode",
450                         ""),
451                 (a) -> assertCommand(a, "/set mode mymode -delete",
452                         ""),
453                 (a) -> assertCommand(a, "/set mode -retain mymode -delete",
454                         ""),
455                 (a) -> assertCommand(a, "/set mode kmode normal -command",
456                         "|  Created new feedback mode: kmode"),
457                 (a) -> assertCommand(a, "/set mode -retain kmode",
458                         ""),
459                 (a) -> assertCommand(a, "/set mode kmode -delete",
460                         ""),
461                 (a) -> assertCommand(a, "/set mode tmode normal -command",
462                         "|  Created new feedback mode: tmode"),
463                 (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
464                         "|  '/set feedback -retain <mode>' requires that <mode> is predefined or has been retained with '/set mode -retain'"),
465                 (a) -> assertCommand(a, "/set format tmode display 'YES'",
466                         ""),
467                 (a) -> assertCommand(a, "/set feedback tmode",
468                         "|  Feedback mode: tmode"),
469                 (a) -> assertCommand(a, "45",
470                         "YES"),
471                 (a) -> assertCommand(a, "/set mode -retain tmode",
472                         ""),
473                 (a) -> assertCommand(a, "/set feedback -retain tmode",
474                         "|  Feedback mode: tmode"),
475                 (a) -> assertCommand(a, "/set format tmode display 'blurb'",
476                         ""),
477                 (a) -> assertCommand(a, "/set format tmode display",
478                         "|  /set format tmode display \"blurb\""),
479                 (a) -> assertCommandOutputContains(a, "/set mode tmode",
480                         "|  /set format tmode display \"YES\""),
481                 (a) -> assertCommand(a, "45",
482                         "blurb")
483         );
484         test(
485                 (a) -> assertCommand(a, "/set format tmode display",
486                         "|  /set format tmode display \"YES\""),
487                 (a) -> assertCommandOutputContains(a, "/set mode tmode",
488                         "|  /set format tmode display \"YES\""),
489                 (a) -> assertCommand(a, "45",
490                         "YES"),
491                 (a) -> assertCommand(a, "/set feedback kmode",
492                         "|  Feedback mode: kmode"),
493                 (a) -> assertCommand(a, "/set feedback",
494                         "|  /set feedback -retain tmode\n" +
495                         "|  /set feedback kmode\n" +
496                         "|  \n" +
497                         "|  Retained feedback modes:\n" +
498                         "|     kmode\n" +
499                         "|     tmode\n" +
500                         "|  Available feedback modes:\n" +
501                         "|     concise\n" +
502                         "|     kmode\n" +
503                         "|     normal\n" +
504                         "|     silent\n" +
505                         "|     tmode\n" +
506                         "|     verbose"),
507                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
508                         "|  The current feedback mode 'kmode' cannot be deleted"),
509                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete",
510                         "|  The retained feedback mode 'tmode' cannot be deleted"),
511                 (a) -> assertCommand(a, "/set feedback -retain normal",
512                         "|  Feedback mode: normal"),
513                 (a) -> assertCommand(a, "/set mode -retain tmode -delete",
514                         ""),
515                 (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
516                         "")
517         );
518         test(
519                 (a) -> assertCommandOutputStartsWith(a, "/set feedback tmode",
520                         "|  Does not match any current feedback mode: tmode"),
521                 (a) -> assertCommandOutputStartsWith(a, "/set feedback kmode",
522                         "|  Does not match any current feedback mode: kmode"),
523                 (a) -> assertCommandOutputStartsWith(a, "/set feedback mymode",
524                         "|  Does not match any current feedback mode: mymode"),
525                 (a) -> assertCommandCheckOutput(a, "/set feedback",
526                         (s) -> assertFalse(s.contains("mymode"), "Didn't delete mymode: " + s)),
527                 (a) -> assertCommandCheckOutput(a, "/set feedback",
528                         (s) -> assertFalse(s.contains("kmode"), "Didn't delete kmode: " + s)),
529                 (a) -> assertCommandCheckOutput(a, "/set feedback",
530                         (s) -> assertFalse(s.contains("tmode"), "Didn't delete tmode: " + s))
531         );
532     }
533 
retainModeDeleteLocalTest()534     public void retainModeDeleteLocalTest() {
535         test(
536                 (a) -> assertCommand(a, "/set mode rmdlt normal -command",
537                         "|  Created new feedback mode: rmdlt"),
538                 (a) -> assertCommand(a, "/set mode rmdlt -delete -retain ",
539                         ""),
540                 (a) -> assertCommandCheckOutput(a, "/set feedback",
541                         (s) -> {
542                             assertTrue(s.contains("normal"), "Expected normal mode: " + s);
543                             assertFalse(s.contains("rmdlt"), "Didn't delete rmdlt: " + s);
544                         })
545         );
546     }
547 
548 }
549