1 /*
2  * Copyright (c) 2015, 2018, 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 8166744
27  * @summary Test Completion
28  * @modules jdk.internal.le/jdk.internal.org.jline.reader
29  *          jdk.jshell/jdk.internal.jshell.tool:+open
30  * @build HistoryTest
31  * @run testng HistoryTest
32  */
33 
34 import java.lang.reflect.Field;
35 import java.lang.reflect.Method;
36 import java.util.Locale;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39 
40 import org.testng.annotations.Test;
41 import jdk.internal.jshell.tool.JShellTool;
42 import jdk.internal.jshell.tool.JShellToolBuilder;
43 import jdk.internal.org.jline.reader.History;
44 import static org.testng.Assert.*;
45 import org.testng.annotations.BeforeMethod;
46 
47 public class HistoryTest extends ReplToolTesting {
48 
49     private JShellTool repl;
50 
51     @Override
testRawRun(Locale locale, String[] args)52     protected void testRawRun(Locale locale, String[] args) {
53         // turn on logging of launch failures
54         Logger.getLogger("jdk.jshell.execution").setLevel(Level.ALL);
55         repl = ((JShellToolBuilder) builder(locale))
56                 .rawTool();
57         try {
58             repl.start(args);
59         } catch (Exception ex) {
60             fail("Repl tool died with exception", ex);
61         }
62     }
63 
64     @Test
testHistory()65     public void testHistory() {
66         test(
67              a -> {if (!a) setCommandInput("void test() {\n");},
68              a -> {if (!a) setCommandInput("    System.err.println(1);\n");},
69              a -> {if (!a) setCommandInput("    System.err.println(1);\n");},
70              a -> {assertCommand(a, "} //test", "|  created method test()");},
71              a -> {
72                  if (!a) {
73                      try {
74                          previousAndAssert(getHistory(), "void test() {\n" +
75                                                          "    System.err.println(1);\n" +
76                                                          "    System.err.println(1);\n" +
77                                                          "} //test");
78                      } catch (Exception ex) {
79                          throw new IllegalStateException(ex);
80                      }
81                  }
82                  assertCommand(a, "int dummy;", "dummy ==> 0");
83              });
84         test(
85              a -> {if (!a) setCommandInput("void test2() {\n");},
86              a -> {assertCommand(a, "} //test2", "|  created method test2()");},
87              a -> {
88                  if (!a) {
89                      try {
90                          previousAndAssert(getHistory(), "void test2() {\n" +
91                                                          "} //test2");
92                          previousAndAssert(getHistory(), "/debug 0"); //added by test framework
93                          previousAndAssert(getHistory(), "/exit");
94                          previousAndAssert(getHistory(), "int dummy;");
95                          previousAndAssert(getHistory(), "void test() {\n" +
96                                                          "    System.err.println(1);\n" +
97                                                          "    System.err.println(1);\n" +
98                                                          "} //test");
99                      } catch (Exception ex) {
100                          throw new IllegalStateException(ex);
101                      }
102                  }
103                  assertCommand(a, "int dummy;", "dummy ==> 0");
104              });
105     }
106 
107     @Test
test8166744()108     public void test8166744() {
109         test(
110              a -> {if (!a) setCommandInput("class C {\n");},
111              a -> {if (!a) setCommandInput("void f() {\n");},
112              a -> {if (!a) setCommandInput("}\n");},
113              a -> {assertCommand(a, "}", "|  created class C");},
114              a -> {
115                  if (!a) {
116                      try {
117                          previousAndAssert(getHistory(), "class C {\n" +
118                                                          "void f() {\n" +
119                                                          "}\n" +
120                                                          "}");
121                          getHistory().add("class C {\n" +
122                                           "void f() {\n" +
123                                           "}\n" +
124                                           "}");
125                      } catch (Exception ex) {
126                          throw new IllegalStateException(ex);
127                      }
128                  }
129                  assertCommand(a, "int dummy;", "dummy ==> 0");
130              });
131         test(
132              a -> {if (!a) setCommandInput("class C {\n");},
133              a -> {if (!a) setCommandInput("void f() {\n");},
134              a -> {if (!a) setCommandInput("}\n");},
135              a -> {assertCommand(a, "}", "|  created class C");},
136              a -> {
137                  if (!a) {
138                      try {
139                          previousAndAssert(getHistory(), "class C {\n" +
140                                                          "void f() {\n" +
141                                                          "}\n" +
142                                                          "}");
143                          getHistory().add("class C {\n" +
144                                           "void f() {\n" +
145                                           "}\n" +
146                                           "}");
147                      } catch (Exception ex) {
148                          throw new IllegalStateException(ex);
149                      }
150                  }
151                  assertCommand(a, "int dummy;", "dummy ==> 0");
152              });
153     }
154 
155     @Test
testReadExistingHistory()156     public void testReadExistingHistory() {
157         prefsMap.put("HISTORY_LINE_0", "/debug 0");
158         prefsMap.put("HISTORY_LINE_1", "void test() {\\");
159         prefsMap.put("HISTORY_LINE_2", "    System.err.println(1);\\");
160         prefsMap.put("HISTORY_LINE_3", "    System.err.println(`\\\\\\\\\\");
161         prefsMap.put("HISTORY_LINE_4", "    \\\\\\");
162         prefsMap.put("HISTORY_LINE_5", "`);\\");
163         prefsMap.put("HISTORY_LINE_6", "} //test");
164         test(
165              a -> {assertCommand(a, "int i", "i ==> 0");},
166              a -> {
167                  if (!a) {
168                      try {
169                          previousAndAssert(getHistory(), "int i");
170                          previousAndAssert(getHistory(), "/debug 0"); //added by test framework
171                          previousAndAssert(getHistory(), "void test() {\n" +
172                                                          "    System.err.println(1);\n" +
173                                                          "    System.err.println(`\\\\\n" +
174                                                          "    \\\n" +
175                                                          "`);\n" +
176                                                          "} //test");
177                      } catch (Exception ex) {
178                          throw new IllegalStateException(ex);
179                      }
180                  }
181                   assertCommand(a, "/exit", "");
182              });
183         assertEquals(prefsMap.get("HISTORY_LINE_00"), "/debug 0");
184         assertEquals(prefsMap.get("HISTORY_LINE_01"), "void test() {\\");
185         assertEquals(prefsMap.get("HISTORY_LINE_02"), "    System.err.println(1);\\");
186         assertEquals(prefsMap.get("HISTORY_LINE_03"), "    System.err.println(`\\\\\\\\\\");
187         assertEquals(prefsMap.get("HISTORY_LINE_04"), "    \\\\\\");
188         assertEquals(prefsMap.get("HISTORY_LINE_05"), "`);\\");
189         assertEquals(prefsMap.get("HISTORY_LINE_06"), "} //test");
190         assertEquals(prefsMap.get("HISTORY_LINE_07"), "/debug 0");
191         assertEquals(prefsMap.get("HISTORY_LINE_08"), "int i");
192         assertEquals(prefsMap.get("HISTORY_LINE_09"), "/exit");
193         System.err.println("prefsMap: " + prefsMap);
194     }
195 
getHistory()196     private History getHistory() throws Exception {
197         Field input = repl.getClass().getDeclaredField("input");
198         input.setAccessible(true);
199         Object console = input.get(repl);
200         Method getHistory = console.getClass().getDeclaredMethod("getHistory");
201         getHistory.setAccessible(true);
202         return (History) getHistory.invoke(console);
203     }
204 
previousAndAssert(History history, String expected)205     private void previousAndAssert(History history, String expected) {
206         assertTrue(history.previous());
207         assertEquals(history.current().toString(), expected);
208     }
209 
210     @BeforeMethod
setUp()211     public void setUp() {
212         super.setUp();
213         System.setProperty("jshell.test.allow.incomplete.inputs", "false");
214     }
215 
216 }
217